Merge branch 'master' into dashboard

This commit is contained in:
decabeza
2019-03-26 16:45:48 +01:00
2476 changed files with 62613 additions and 84405 deletions

View File

@@ -0,0 +1,124 @@
shared_examples "admin_milestoneable" do |factory_name, path_name|
it_behaves_like "admin_progressable", factory_name, path_name
feature "Admin milestones" do
let!(:milestoneable) { create(factory_name) }
let(:path) { send(path_name, *resource_hierarchy_for(milestoneable)) }
context "Index" do
scenario "Displaying milestones" do
milestone = create(:milestone, milestoneable: milestoneable)
create(:image, imageable: milestone)
document = create(:document, documentable: milestone)
visit path
expect(page).to have_content("Milestone")
expect(page).to have_content(milestone.title)
expect(page).to have_content(milestone.id)
expect(page).to have_content(milestone.publication_date.to_date)
expect(page).to have_content(milestone.status.name)
expect(page).to have_link "Show image"
expect(page).to have_link document.title
end
scenario "Displaying no_milestones text" do
visit path
expect(page).to have_content("Milestone")
expect(page).to have_content("Don't have defined milestones")
end
end
context "New" do
scenario "Add milestone" do
status = create(:milestone_status)
visit path
click_link "Create new milestone"
select status.name, from: "milestone_status_id"
fill_in "Description", with: "New description milestone"
fill_in "milestone_publication_date", with: Date.current
click_button "Create milestone"
expect(page).to have_content "New description milestone"
expect(page).to have_content Date.current
expect(page).to have_content status.name
end
scenario "Status select is disabled if there are no statuses available" do
visit path
click_link "Create new milestone"
expect(find("#milestone_status_id").disabled?).to be true
end
scenario "Show validation errors on milestone form" do
visit path
click_link "Create new milestone"
fill_in "Description", with: "New description milestone"
click_button "Create milestone"
within "#new_milestone" do
expect(page).to have_content "can't be blank", count: 1
expect(page).to have_content "New description milestone"
end
end
scenario "Show validation errors with no description nor status" do
visit path
click_link "Create new milestone"
fill_in "Date", with: Date.current
click_button "Create milestone"
within "#new_milestone" do
expect(page).to have_content "can't be blank", count: 1
end
end
end
context "Edit" do
scenario "Change title, description and document names" do
milestone = create(:milestone, milestoneable: milestoneable)
create(:image, imageable: milestone)
document = create(:document, documentable: milestone)
visit path
expect(page).to have_link document.title
click_link milestone.title
expect(page).to have_css("img[alt='#{milestone.image.title}']")
fill_in "Description", with: "Changed description"
fill_in "milestone_publication_date", with: Date.current
fill_in "milestone_documents_attributes_0_title", with: "New document title"
click_button "Update milestone"
expect(page).to have_content "Changed description"
expect(page).to have_content Date.current
expect(page).to have_link "Show image"
expect(page).to have_link "New document title"
end
end
context "Delete" do
scenario "Remove milestone" do
create(:milestone, milestoneable: milestoneable, title: "Title will it remove")
visit path
click_link "Delete milestone"
expect(page).not_to have_content "Title will it remove"
end
end
end
end

View File

@@ -0,0 +1,122 @@
shared_examples "admin_progressable" do |factory_name, path_name|
let!(:progressable) { create(factory_name) }
feature "Manage progress bars" do
let(:progressable_path) { send(path_name, *resource_hierarchy_for(progressable)) }
let(:path) do
polymorphic_path([:admin, *resource_hierarchy_for(progressable.progress_bars.new)])
end
context "Index" do
scenario "Link to index path" do
create(:progress_bar, :secondary, progressable: progressable,
title: "Reading documents",
percentage: 20)
visit progressable_path
click_link "Manage progress bars"
expect(page).to have_content "Reading documents"
end
scenario "No progress bars" do
visit path
expect(page).to have_content("There are no progress bars")
end
end
context "New" do
scenario "Primary progress bar", :js do
visit path
click_link "Create new progress bar"
select "Primary", from: "Type"
expect(page).not_to have_field "Title"
expect(page).not_to have_content "Add language"
fill_in "Current progress", with: 43
click_button "Create Progress bar"
expect(page).to have_content "Progress bar created successfully"
expect(page).to have_content "43%"
expect(page).to have_content "Primary"
expect(page).to have_content "Primary progress bar"
end
scenario "Secondary progress bar", :js do
visit path
click_link "Create new progress bar"
select "Secondary", from: "Type"
expect(page).to have_content "Add language"
fill_in "Current progress", with: 36
fill_in "Title", with: "Plant trees"
click_button "Create Progress bar"
expect(page).to have_content "Progress bar created successfully"
expect(page).to have_content "36%"
expect(page).to have_content "Secondary"
expect(page).to have_content "Plant trees"
end
end
context "Edit" do
scenario "Primary progress bar", :js do
bar = create(:progress_bar, progressable: progressable)
visit path
within("#progress_bar_#{bar.id}") { click_link "Edit" }
expect(page).to have_field "Current progress"
expect(page).not_to have_field "Title"
expect(page).not_to have_content "Add language"
fill_in "Current progress", with: 44
click_button "Update Progress bar"
expect(page).to have_content "Progress bar updated successfully"
within("#progress_bar_#{bar.id}") do
expect(page).to have_content "44%"
end
end
scenario "Secondary progress bar", :js do
bar = create(:progress_bar, :secondary, progressable: progressable)
visit path
within("#progress_bar_#{bar.id}") { click_link "Edit" }
expect(page).to have_content "Add language"
fill_in "Current progress", with: 76
fill_in "Title", with: "Updated title"
click_button "Update Progress bar"
expect(page).to have_content "Progress bar updated successfully"
within("#progress_bar_#{bar.id}") do
expect(page).to have_content "76%"
expect(page).to have_content "Updated title"
end
end
end
context "Delete" do
scenario "Remove progress bar" do
bar = create(:progress_bar, progressable: progressable, percentage: 34)
visit path
within("#progress_bar_#{bar.id}") { click_link "Delete" }
expect(page).to have_content "Progress bar deleted successfully"
expect(page).not_to have_content "34%"
end
end
end
end

View File

@@ -68,13 +68,40 @@ shared_examples "documentable" do |documentable_factory_name,
end
describe "When allow attached documents setting is disabled" do
describe "When allow attached documents setting is enabled" do
before do
Setting['feature.allow_attached_documents'] = false
Setting["feature.allow_attached_documents"] = true
end
after do
Setting['feature.allow_attached_documents'] = true
Setting["feature.allow_attached_documents"] = false
end
scenario "Documents list should be available" do
login_as(user)
visit send(documentable_path, arguments)
expect(page).to have_css("#documents")
expect(page).to have_content("Documents (1)")
end
scenario "Documents list increase documents number" do
create(:document, documentable: documentable, user: documentable.author)
login_as(user)
visit send(documentable_path, arguments)
expect(page).to have_css("#documents")
expect(page).to have_content("Documents (2)")
end
end
describe "When allow attached documents setting is disabled" do
before do
Setting["feature.allow_attached_documents"] = false
end
after do
Setting["feature.allow_attached_documents"] = true
end
scenario "Documents list should not be available" do
@@ -101,7 +128,7 @@ shared_examples "documentable" do |documentable_factory_name,
expect(page).to have_content "Document was deleted successfully."
end
scenario "Should update documents tab count after successful deletion" do
scenario "Should hide documents tab if there is no documents" do
login_as documentable.author
visit send(documentable_path, arguments)
@@ -110,7 +137,7 @@ shared_examples "documentable" do |documentable_factory_name,
click_on "Destroy document"
end
expect(page).to have_content "Documents (0)"
expect(page).not_to have_content "Documents (0)"
end
scenario "Should redirect to documentable path after successful deletion" do

View File

@@ -3,7 +3,7 @@ shared_examples "followable" do |followable_class_name, followable_path, followa
let!(:arguments) { {} }
let!(:followable) { create(followable_class_name) }
let!(:followable_dom_name) { followable_class_name.tr('_', '-') }
let!(:followable_dom_name) { followable_class_name.tr("_", "-") }
before do
followable_path_arguments.each do |argument_name, path_to_value|

View File

@@ -1,4 +1,10 @@
shared_examples "mappable" do |mappable_factory_name, mappable_association_name, mappable_new_path, mappable_edit_path, mappable_show_path, mappable_path_arguments|
shared_examples "mappable" do |mappable_factory_name,
mappable_association_name,
mappable_new_path,
mappable_edit_path,
mappable_show_path,
mappable_path_arguments,
management = false|
include ActionView::Helpers
@@ -6,9 +12,10 @@ shared_examples "mappable" do |mappable_factory_name, mappable_association_name,
let!(:arguments) { {} }
let!(:mappable) { create(mappable_factory_name.to_s.to_sym) }
let!(:map_location) { create(:map_location, "#{mappable_factory_name}_map_location".to_sym, "#{mappable_association_name}": mappable) }
let(:management) { management }
before do
Setting['feature.map'] = true
Setting["feature.map"] = true
end
describe "At #{mappable_new_path}" do
@@ -16,7 +23,7 @@ shared_examples "mappable" do |mappable_factory_name, mappable_association_name,
before { set_arguments(arguments, mappable, mappable_path_arguments) }
scenario "Should not show marker by default on create #{mappable_factory_name}", :js do
login_as user
do_login_for user
visit send(mappable_new_path, arguments)
send("fill_in_#{mappable_factory_name}_form")
@@ -27,7 +34,7 @@ shared_examples "mappable" do |mappable_factory_name, mappable_association_name,
end
scenario "Should show marker on create #{mappable_factory_name} when click on map", :js do
login_as user
do_login_for user
visit send(mappable_new_path, arguments)
send("fill_in_#{mappable_factory_name}_form")
@@ -39,7 +46,7 @@ shared_examples "mappable" do |mappable_factory_name, mappable_association_name,
end
scenario "Should create #{mappable_factory_name} with map", :js do
login_as user
do_login_for user
visit send(mappable_new_path, arguments)
send("fill_in_#{mappable_factory_name}_form")
@@ -50,7 +57,7 @@ shared_examples "mappable" do |mappable_factory_name, mappable_association_name,
end
scenario "Can not display map on #{mappable_factory_name} when not fill marker on map", :js do
login_as user
do_login_for user
visit send(mappable_new_path, arguments)
send("fill_in_#{mappable_factory_name}_form")
@@ -62,8 +69,8 @@ shared_examples "mappable" do |mappable_factory_name, mappable_association_name,
end
scenario "Can not display map on #{mappable_factory_name} when feature.map is disabled", :js do
Setting['feature.map'] = false
login_as user
Setting["feature.map"] = false
do_login_for user
visit send(mappable_new_path, arguments)
send("fill_in_#{mappable_factory_name}_form")
@@ -73,8 +80,8 @@ shared_examples "mappable" do |mappable_factory_name, mappable_association_name,
expect(page).not_to have_css(".map_location")
end
scenario 'Errors on create' do
login_as user
scenario "Errors on create" do
do_login_for user
visit send(mappable_new_path, arguments)
send("submit_#{mappable_factory_name}_form")
@@ -82,8 +89,8 @@ shared_examples "mappable" do |mappable_factory_name, mappable_association_name,
expect(page).to have_content "Map location can't be blank"
end
scenario 'Skip map', :js do
login_as user
scenario "Skip map", :js do
do_login_for user
visit send(mappable_new_path, arguments)
send("fill_in_#{mappable_factory_name}_form")
@@ -93,8 +100,8 @@ shared_examples "mappable" do |mappable_factory_name, mappable_association_name,
expect(page).not_to have_content "Map location can't be blank"
end
scenario 'Toggle map', :js do
login_as user
scenario "Toggle map", :js do
do_login_for user
visit send(mappable_new_path, arguments)
check "#{mappable_factory_name}_skip_map"
@@ -115,7 +122,7 @@ shared_examples "mappable" do |mappable_factory_name, mappable_association_name,
before { skip } if mappable_edit_path.blank?
scenario "Should edit map on #{mappable_factory_name} and contain default values", :js do
login_as mappable.author
do_login_for mappable.author
visit send(mappable_edit_path, id: mappable.id)
@@ -124,7 +131,7 @@ shared_examples "mappable" do |mappable_factory_name, mappable_association_name,
end
scenario "Should edit default values from map on #{mappable_factory_name} edit page", :js do
login_as mappable.author
do_login_for mappable.author
visit send(mappable_edit_path, id: mappable.id)
find(".map_location").click
@@ -137,7 +144,7 @@ shared_examples "mappable" do |mappable_factory_name, mappable_association_name,
end
scenario "Should edit mappable on #{mappable_factory_name} without change map", :js do
login_as mappable.author
do_login_for mappable.author
visit send(mappable_edit_path, id: mappable.id)
fill_in "#{mappable_factory_name}_title", with: "New title"
@@ -150,7 +157,7 @@ shared_examples "mappable" do |mappable_factory_name, mappable_association_name,
end
scenario "Can not display map on #{mappable_factory_name} edit when remove map marker", :js do
login_as mappable.author
do_login_for mappable.author
visit send(mappable_edit_path, id: mappable.id)
click_link "Remove map marker"
@@ -161,8 +168,8 @@ shared_examples "mappable" do |mappable_factory_name, mappable_association_name,
end
scenario "Can not display map on #{mappable_factory_name} edit when feature.map is disabled", :js do
Setting['feature.map'] = false
login_as mappable.author
Setting["feature.map"] = false
do_login_for mappable.author
visit send(mappable_edit_path, id: mappable.id)
fill_in "#{mappable_factory_name}_title", with: "New title"
@@ -171,9 +178,9 @@ shared_examples "mappable" do |mappable_factory_name, mappable_association_name,
expect(page).not_to have_css(".map_location")
end
scenario 'No errors on update', :js do
scenario "No errors on update", :js do
skip ""
login_as mappable.author
do_login_for mappable.author
visit send(mappable_edit_path, id: mappable.id)
click_link "Remove map marker"
@@ -182,8 +189,8 @@ shared_examples "mappable" do |mappable_factory_name, mappable_association_name,
expect(page).not_to have_content "Map location can't be blank"
end
scenario 'No need to skip map on update' do
login_as mappable.author
scenario "No need to skip map on update" do
do_login_for mappable.author
visit send(mappable_edit_path, id: mappable.id)
click_link "Remove map marker"
@@ -196,7 +203,10 @@ shared_examples "mappable" do |mappable_factory_name, mappable_association_name,
describe "At #{mappable_show_path}" do
before { set_arguments(arguments, mappable, mappable_path_arguments) }
before do
set_arguments(arguments, mappable, mappable_path_arguments)
do_login_for(user) if management
end
scenario "Should display map on #{mappable_factory_name} show page", :js do
arguments[:id] = mappable.id
@@ -217,7 +227,7 @@ shared_examples "mappable" do |mappable_factory_name, mappable_association_name,
end
scenario "Should not display map on #{mappable_factory_name} show page when feature.map is disable", :js do
Setting['feature.map'] = false
Setting["feature.map"] = false
arguments[:id] = mappable.id
visit send(mappable_show_path, arguments)
@@ -229,18 +239,27 @@ shared_examples "mappable" do |mappable_factory_name, mappable_association_name,
end
def do_login_for(user)
if management
login_as_manager
login_managed_user(user)
else
login_as(user)
end
end
def fill_in_proposal_form
fill_in 'proposal_title', with: 'Help refugees'
fill_in 'proposal_question', with: '¿Would you like to give assistance to war refugees?'
fill_in 'proposal_summary', with: 'In summary, what we want is...'
fill_in "proposal_title", with: "Help refugees"
fill_in "proposal_question", with: "¿Would you like to give assistance to war refugees?"
fill_in "proposal_summary", with: "In summary, what we want is..."
end
def submit_proposal_form
check :proposal_terms_of_service
click_button 'Create proposal'
click_button "Create proposal"
if page.has_content?('Not now, go to my proposal')
click_link 'Not now, go to my proposal'
if page.has_content?("Not now, go to my proposal")
click_link "Not now, go to my proposal"
end
end
@@ -260,7 +279,7 @@ end
def submit_budget_investment_form
check :budget_investment_terms_of_service
click_button 'Create Investment'
click_button "Create Investment"
end
def set_arguments(arguments, mappable, mappable_path_arguments)

View File

@@ -0,0 +1,59 @@
shared_examples "milestoneable" do |factory_name, path_name|
it_behaves_like "progressable", factory_name, path_name
let!(:milestoneable) { create(factory_name) }
feature "Show milestones" do
let(:path) { send(path_name, *resource_hierarchy_for(milestoneable)) }
scenario "Show milestones", :js do
create(:milestone, milestoneable: milestoneable,
description_en: "Last milestone with a link to https://consul.dev",
description_es: "Último hito con el link https://consul.dev",
publication_date: Date.tomorrow)
first_milestone = create(:milestone, milestoneable: milestoneable,
description: "First milestone",
publication_date: Date.yesterday)
image = create(:image, imageable: first_milestone)
document = create(:document, documentable: first_milestone)
login_as(create(:user))
visit path
find("#tab-milestones-label").click
within("#tab-milestones") do
expect(first_milestone.description).to appear_before("Last milestone with a link to https://consul.dev")
expect(page).to have_content(Date.tomorrow)
expect(page).to have_content(Date.yesterday)
expect(page).not_to have_content(Date.current)
expect(page.find("#image_#{first_milestone.id}")["alt"]).to have_content(image.title)
expect(page).to have_link(document.title)
expect(page).to have_link("https://consul.dev")
expect(page).to have_content(first_milestone.status.name)
end
select("Español", from: "locale-switcher")
find("#tab-milestones-label").click
within("#tab-milestones") do
expect(page).to have_content("Último hito con el link https://consul.dev")
expect(page).to have_link("https://consul.dev")
end
end
scenario "Show no_milestones text", :js do
login_as(create(:user))
visit path
find("#tab-milestones-label").click
within("#tab-milestones") do
expect(page).to have_content("Don't have defined milestones")
end
end
end
end

View File

@@ -56,11 +56,11 @@ shared_examples "nested documentable" do |login_as_name, documentable_factory_na
login_as user_to_login
visit send(path, arguments)
documentable.class.max_documents_allowed.times.each do
documentable_attach_new_file(Rails.root.join('spec/fixtures/files/empty.pdf'))
documentable_attach_new_file(Rails.root.join("spec/fixtures/files/empty.pdf"))
end
expect(page).to have_css ".max-documents-notice", visible: true
expect(page).to have_content 'Remove document'
expect(page).to have_content "Remove document"
end
scenario "Should hide max documents warning after any document removal", :js do
@@ -85,7 +85,7 @@ shared_examples "nested documentable" do |login_as_name, documentable_factory_na
document = find(".document input[type=file]", visible: false)
attach_file(
document[:id],
Rails.root.join('spec/fixtures/files/empty.pdf'),
Rails.root.join("spec/fixtures/files/empty.pdf"),
make_visible: true
)
end
@@ -98,7 +98,7 @@ shared_examples "nested documentable" do |login_as_name, documentable_factory_na
login_as user_to_login
visit send(path, arguments)
documentable_attach_new_file(Rails.root.join('spec/fixtures/files/empty.pdf'))
documentable_attach_new_file(Rails.root.join("spec/fixtures/files/empty.pdf"))
expect_document_has_title(0, "empty.pdf")
end
@@ -115,7 +115,7 @@ shared_examples "nested documentable" do |login_as_name, documentable_factory_na
document_input = find("input[type=file]", visible: false)
attach_file(
document_input[:id],
Rails.root.join('spec/fixtures/files/empty.pdf'),
Rails.root.join("spec/fixtures/files/empty.pdf"),
make_visible: true
)
end
@@ -127,7 +127,7 @@ shared_examples "nested documentable" do |login_as_name, documentable_factory_na
login_as user_to_login
visit send(path, arguments)
documentable_attach_new_file(Rails.root.join('spec/fixtures/files/empty.pdf'))
documentable_attach_new_file(Rails.root.join("spec/fixtures/files/empty.pdf"))
expect(page).to have_css ".loading-bar.complete"
end
@@ -137,7 +137,7 @@ shared_examples "nested documentable" do |login_as_name, documentable_factory_na
visit send(path, arguments)
documentable_attach_new_file(
Rails.root.join("spec/fixtures/files/logo_header.gif"),
Rails.root.join("spec/fixtures/files/logo_header.png"),
false
)
@@ -148,7 +148,7 @@ shared_examples "nested documentable" do |login_as_name, documentable_factory_na
login_as user_to_login
visit send(path, arguments)
documentable_attach_new_file(Rails.root.join('spec/fixtures/files/empty.pdf'))
documentable_attach_new_file(Rails.root.join("spec/fixtures/files/empty.pdf"))
expect_document_has_cached_attachment(0, ".pdf")
end
@@ -158,7 +158,7 @@ shared_examples "nested documentable" do |login_as_name, documentable_factory_na
visit send(path, arguments)
documentable_attach_new_file(
Rails.root.join("spec/fixtures/files/logo_header.gif"),
Rails.root.join("spec/fixtures/files/logo_header.png"),
false
)
@@ -182,7 +182,7 @@ shared_examples "nested documentable" do |login_as_name, documentable_factory_na
login_as user_to_login
visit send(path, arguments)
documentable_attach_new_file(Rails.root.join('spec/fixtures/files/empty.pdf'))
documentable_attach_new_file(Rails.root.join("spec/fixtures/files/empty.pdf"))
click_link "Remove document"
expect(page).not_to have_css("#nested-documents .document")
@@ -205,7 +205,7 @@ shared_examples "nested documentable" do |login_as_name, documentable_factory_na
visit send(path, arguments)
send(fill_resource_method_name) if fill_resource_method_name
documentable_attach_new_file(Rails.root.join('spec/fixtures/files/empty.pdf'))
documentable_attach_new_file(Rails.root.join("spec/fixtures/files/empty.pdf"))
click_on submit_button
expect(page).to have_content documentable_success_notice
@@ -219,7 +219,7 @@ shared_examples "nested documentable" do |login_as_name, documentable_factory_na
visit send(path, arguments)
send(fill_resource_method_name) if fill_resource_method_name
documentable_attach_new_file(Rails.root.join('spec/fixtures/files/empty.pdf'))
documentable_attach_new_file(Rails.root.join("spec/fixtures/files/empty.pdf"))
click_on submit_button
documentable_redirected_to_resource_show_or_navigate_to
@@ -297,11 +297,11 @@ shared_examples "nested documentable" do |login_as_name, documentable_factory_na
describe "When allow attached documents setting is disabled" do
before do
Setting['feature.allow_attached_documents'] = false
Setting["feature.allow_attached_documents"] = false
end
after do
Setting['feature.allow_attached_documents'] = true
Setting["feature.allow_attached_documents"] = true
end
scenario "Add new document button should not be available" do

View File

@@ -13,7 +13,7 @@ shared_examples "nested imageable" do |imageable_factory_name, path,
before do
Setting['feature.allow_images'] = true
Setting["feature.allow_images"] = true
imageable_path_arguments&.each do |argument_name, path_to_value|
arguments.merge!("#{argument_name}": imageable.send(path_to_value))
@@ -23,7 +23,7 @@ shared_examples "nested imageable" do |imageable_factory_name, path,
end
after do
Setting['feature.allow_images'] = nil
Setting["feature.allow_images"] = nil
end
describe "at #{path}" do
@@ -52,7 +52,7 @@ shared_examples "nested imageable" do |imageable_factory_name, path,
image_input = find(".image").find("input[type=file]", visible: false)
attach_file(
image_input[:id],
Rails.root.join('spec/fixtures/files/clippy.jpg'),
Rails.root.join("spec/fixtures/files/clippy.jpg"),
make_visible: true
)
@@ -65,7 +65,7 @@ shared_examples "nested imageable" do |imageable_factory_name, path,
imageable_attach_new_file(
imageable_factory_name,
Rails.root.join('spec/fixtures/files/clippy.jpg')
Rails.root.join("spec/fixtures/files/clippy.jpg")
)
expect_image_has_title("clippy.jpg")
@@ -81,7 +81,7 @@ shared_examples "nested imageable" do |imageable_factory_name, path,
image_input = find(".image").find("input[type=file]", visible: false)
attach_file(
image_input[:id],
Rails.root.join('spec/fixtures/files/clippy.jpg'),
Rails.root.join("spec/fixtures/files/clippy.jpg"),
make_visible: true
)
@@ -98,7 +98,7 @@ shared_examples "nested imageable" do |imageable_factory_name, path,
imageable_attach_new_file(
imageable_factory_name,
Rails.root.join('spec/fixtures/files/clippy.jpg')
Rails.root.join("spec/fixtures/files/clippy.jpg")
)
expect(page).to have_selector ".loading-bar.complete"
@@ -110,7 +110,7 @@ shared_examples "nested imageable" do |imageable_factory_name, path,
imageable_attach_new_file(
imageable_factory_name,
Rails.root.join('spec/fixtures/files/logo_header.png'),
Rails.root.join("spec/fixtures/files/logo_header.png"),
false
)
@@ -123,7 +123,7 @@ shared_examples "nested imageable" do |imageable_factory_name, path,
imageable_attach_new_file(
imageable_factory_name,
Rails.root.join('spec/fixtures/files/clippy.jpg')
Rails.root.join("spec/fixtures/files/clippy.jpg")
)
expect_image_has_cached_attachment(".jpg")
@@ -135,7 +135,7 @@ shared_examples "nested imageable" do |imageable_factory_name, path,
imageable_attach_new_file(
imageable_factory_name,
Rails.root.join('spec/fixtures/files/logo_header.png'),
Rails.root.join("spec/fixtures/files/logo_header.png"),
false
)
@@ -164,7 +164,7 @@ shared_examples "nested imageable" do |imageable_factory_name, path,
imageable_attach_new_file(
imageable_factory_name,
Rails.root.join('spec/fixtures/files/clippy.jpg')
Rails.root.join("spec/fixtures/files/clippy.jpg")
)
within "#nested-image .image" do
@@ -194,7 +194,7 @@ shared_examples "nested imageable" do |imageable_factory_name, path,
imageable_attach_new_file(
imageable_factory_name,
Rails.root.join('spec/fixtures/files/clippy.jpg')
Rails.root.join("spec/fixtures/files/clippy.jpg")
)
click_on submit_button
@@ -209,7 +209,7 @@ shared_examples "nested imageable" do |imageable_factory_name, path,
imageable_attach_new_file(
imageable_factory_name,
Rails.root.join('spec/fixtures/files/clippy.jpg')
Rails.root.join("spec/fixtures/files/clippy.jpg")
)
click_on submit_button

View File

@@ -0,0 +1,45 @@
shared_examples "progressable" do |factory_name, path_name|
feature "Progress bars", :js do
let!(:progressable) { create(factory_name) }
let(:path) { send(path_name, *resource_hierarchy_for(progressable)) }
scenario "With main progress bar" do
create(:progress_bar, progressable: progressable)
visit path
find("#tab-milestones-label").click
within("#tab-milestones") do
expect(page).to have_content "Progress"
end
end
scenario "With main and secondary progress bar" do
create(:progress_bar, progressable: progressable)
create(:progress_bar, :secondary, progressable: progressable, title: "Build laboratory")
visit path
find("#tab-milestones-label").click
within("#tab-milestones") do
expect(page).to have_content "Progress"
expect(page).to have_content "Build laboratory"
end
end
scenario "No main progress bar" do
create(:progress_bar, :secondary, progressable: progressable, title: "Defeat Evil Lords")
visit path
find("#tab-milestones-label").click
within("#tab-milestones") do
expect(page).not_to have_content "Progress"
expect(page).not_to have_content "Defeat Evil Lords"
end
end
end
end

View File

@@ -1,11 +1,11 @@
shared_examples "relationable" do |relationable_model_name|
let(:relationable) { create(relationable_model_name.name.parameterize('_').to_sym) }
let(:relationable) { create(relationable_model_name.name.parameterize("_").to_sym) }
let(:related1) { create([:proposal, :debate, :budget_investment].sample) }
let(:related2) { create([:proposal, :debate, :budget_investment].sample) }
let(:user) { create(:user) }
scenario 'related contents are listed' do
scenario "related contents are listed" do
related_content = create(:related_content, parent_relationable: relationable, child_relationable: related1, author: build(:user))
visit relationable.url
@@ -19,21 +19,21 @@ shared_examples "relationable" do |relationable_model_name|
end
end
scenario 'related contents list is not rendered if there are no relations' do
scenario "related contents list is not rendered if there are no relations" do
visit relationable.url
expect(page).not_to have_css("#related-content-list")
end
scenario 'related contents can be added' do
scenario "related contents can be added" do
login_as(user)
visit relationable.url
expect(page).to have_selector('#related_content', visible: false)
expect(page).to have_selector("#related_content", visible: false)
click_on("Add related content")
expect(page).to have_selector('#related_content', visible: true)
expect(page).to have_selector("#related_content", visible: true)
within("#related_content") do
fill_in 'url', with: "#{Setting['url'] + related1.url}"
fill_in "url", with: "#{Setting["url"] + related1.url}"
click_button "Add"
end
@@ -57,21 +57,21 @@ shared_examples "relationable" do |relationable_model_name|
end
end
scenario 'if related content URL is invalid returns error' do
scenario "if related content URL is invalid returns error" do
login_as(user)
visit relationable.url
click_on("Add related content")
within("#related_content") do
fill_in 'url', with: "http://invalidurl.com"
fill_in "url", with: "http://invalidurl.com"
click_button "Add"
end
expect(page).to have_content("Link not valid. Remember to start with #{Setting[:url]}.")
end
scenario 'returns error when relating content URL to itself' do
scenario "returns error when relating content URL to itself" do
login_as(user)
visit relationable.url
@@ -85,7 +85,7 @@ shared_examples "relationable" do |relationable_model_name|
expect(page).to have_content("Link not valid. You cannot relate a content to itself")
end
scenario 'related content can be scored positively', :js do
scenario "related content can be scored positively", :js do
related_content = create(:related_content, parent_relationable: relationable, child_relationable: related1, author: build(:user))
login_as(user)
@@ -102,7 +102,7 @@ shared_examples "relationable" do |relationable_model_name|
end
scenario 'related content can be scored negatively', :js do
scenario "related content can be scored negatively", :js do
related_content = create(:related_content, parent_relationable: relationable, child_relationable: related1, author: build(:user))
login_as(user)
@@ -118,7 +118,7 @@ shared_examples "relationable" do |relationable_model_name|
expect(related_content.opposite_related_content.related_content_scores.find_by(user_id: user.id, related_content_id: related_content.opposite_related_content.id).value).to eq(-1)
end
scenario 'if related content has negative score it will be hidden' do
scenario "if related content has negative score it will be hidden" do
related_content = create(:related_content, parent_relationable: relationable, child_relationable: related1, author: build(:user))
2.times do

View File

@@ -1,4 +1,4 @@
shared_examples "translatable" do |factory_name, path_name, fields|
shared_examples "translatable" do |factory_name, path_name, input_fields, textarea_fields = {}|
let(:language_texts) do
{
es: "en español",
@@ -10,13 +10,38 @@ shared_examples "translatable" do |factory_name, path_name, fields|
let(:translatable_class) { build(factory_name).class }
let(:input_fields) { input_fields } # So it's accessible by methods
let(:textarea_fields) { textarea_fields } # So it's accessible by methods
let(:path_name) { path_name } # So it's accessible by methods
let(:fields) { input_fields + textarea_fields.keys }
let(:attributes) do
fields.product(%i[en es]).map do |field, locale|
[:"#{field}_#{locale}", text_for(field, locale)]
end.to_h
end
let(:translatable) { create(factory_name, attributes) }
let(:optional_fields) do
fields.select do |field|
translatable.translations.last.dup.tap { |duplicate| duplicate.send(:"#{field}=", "") }.valid?
end
end
let(:required_fields) do
fields - optional_fields
end
let(:translatable) do
if factory_name == "budget_phase"
budget = create(:budget)
budget.phases.first.update attributes
budget.phases.first
else
create(factory_name, attributes)
end
end
let(:path) { send(path_name, *resource_hierarchy_for(translatable)) }
before { login_as(create(:administrator).user) }
@@ -31,23 +56,37 @@ shared_examples "translatable" do |factory_name, path_name, fields|
visit path
select "Français", from: "translation_locale"
fields.each do |field|
fill_in field_for(field, :fr), with: text_for(field, :fr)
end
fields.each { |field| fill_in_field field, :fr, with: text_for(field, :fr) }
click_button update_button_text
visit path
field = fields.sample
expect(page).to have_field(field_for(field, :en), with: text_for(field, :en))
expect_page_to_have_translatable_field field, :en, with: text_for(field, :en)
click_link "Español"
expect(page).to have_field(field_for(field, :es), with: text_for(field, :es))
expect_page_to_have_translatable_field field, :es, with: text_for(field, :es)
click_link "Français"
expect(page).to have_field(field_for(field, :fr), with: text_for(field, :fr))
expect_page_to_have_translatable_field field, :fr, with: text_for(field, :fr)
end
scenario "Add an invalid translation", :js do
skip("can't have invalid translations") if required_fields.empty?
field = required_fields.sample
visit path
select "Français", from: "translation_locale"
fill_in_field field, :fr, with: ""
click_button update_button_text
expect(page).to have_css "#error_explanation"
click_link "Français"
expect_page_to_have_translatable_field field, :fr, with: ""
end
scenario "Update a translation", :js do
@@ -57,17 +96,60 @@ shared_examples "translatable" do |factory_name, path_name, fields|
field = fields.sample
updated_text = "Corrección de #{text_for(field, :es)}"
fill_in field_for(field, :es), with: updated_text
fill_in_field field, :es, with: updated_text
click_button update_button_text
visit path
expect(page).to have_field(field_for(field, :en), with: text_for(field, :en))
expect_page_to_have_translatable_field field, :en, with: text_for(field, :en)
select('Español', from: 'locale-switcher')
select("Español", from: "locale-switcher")
expect(page).to have_field(field_for(field, :es), with: updated_text)
expect_page_to_have_translatable_field field, :es, with: updated_text
end
scenario "Update a translation with invalid data", :js do
skip("can't have invalid translations") if required_fields.empty?
field = required_fields.sample
visit path
click_link "Español"
expect_page_to_have_translatable_field field, :es, with: text_for(field, :es)
fill_in_field field, :es, with: ""
click_button update_button_text
expect(page).to have_css "#error_explanation"
click_link "Español"
expect_page_to_have_translatable_field field, :es, with: ""
end
scenario "Update a translation not having the current locale", :js do
translatable.translations.destroy_all
translatable.translations.create(
fields.map { |field| [field, text_for(field, :fr)] }.to_h.merge(locale: :fr)
)
visit path
expect(page).not_to have_link "English"
expect(page).to have_link "Français"
click_button update_button_text
expect(page).not_to have_css "#error_explanation"
path = updated_path_for(translatable)
visit path
expect(page).not_to have_link "English"
expect(page).to have_link "Français"
end
scenario "Remove a translation", :js do
@@ -84,39 +166,58 @@ shared_examples "translatable" do |factory_name, path_name, fields|
expect(page).not_to have_link "Español"
end
scenario 'Change value of a translated field to blank', :js do
possible_blanks = fields.select do |field|
translatable.dup.tap { |duplicate| duplicate.send(:"#{field}=", '') }.valid?
end
scenario "Remove a translation with invalid data", :js do
skip("can't have invalid translations") if required_fields.empty?
skip("can't have translatable blank fields") if possible_blanks.empty?
field = possible_blanks.sample
field = required_fields.sample
visit path
expect(page).to have_field(field_for(field, :en), with: text_for(field, :en))
fill_in field_for(field, :en), with: ''
click_link "Español"
click_link "Remove language"
click_link "English"
fill_in_field field, :en, with: ""
click_button update_button_text
expect(page).to have_css "#error_explanation"
expect_page_to_have_translatable_field field, :en, with: ""
expect(page).not_to have_link "Español"
visit path
click_link "Español"
expect_page_to_have_translatable_field field, :es, with: text_for(field, :es)
end
scenario "Change value of a translated field to blank", :js do
skip("can't have translatable blank fields") if optional_fields.empty?
field = optional_fields.sample
visit path
expect_page_to_have_translatable_field field, :en, with: text_for(field, :en)
fill_in_field field, :en, with: ""
click_button update_button_text
visit path
expect(page).to have_field(field_for(field, :en), with: '')
expect_page_to_have_translatable_field field, :en, with: ""
end
scenario "Add a translation for a locale with non-underscored name", :js do
visit path
field = fields.sample
select "Português brasileiro", from: "translation_locale"
fill_in field_for(field, :pt_br), with: text_for(field, :"pt-BR")
fields.each { |field| fill_in_field field, :"pt-BR", with: text_for(field, :"pt-BR") }
click_button update_button_text
visit path
select('Português brasileiro', from: 'locale-switcher')
select("Português brasileiro", from: "locale-switcher")
expect(page).to have_field(field_for(field, :pt_br), with: text_for(field, :"pt-BR"))
field = fields.sample
expect_page_to_have_translatable_field field, :"pt-BR", with: text_for(field, :"pt-BR")
end
end
@@ -126,7 +227,7 @@ shared_examples "translatable" do |factory_name, path_name, fields|
expect(find("a.js-globalize-locale-link.is-active")).to have_content "English"
select('Español', from: 'locale-switcher')
select("Español", from: "locale-switcher")
expect(find("a.js-globalize-locale-link.is-active")).to have_content "Español"
end
@@ -145,11 +246,11 @@ shared_examples "translatable" do |factory_name, path_name, fields|
visit path
field = fields.sample
expect(page).to have_field(field_for(field, :en), with: text_for(field, :en))
expect_page_to_have_translatable_field field, :en, with: text_for(field, :en)
click_link "Español"
expect(page).to have_field(field_for(field, :es), with: text_for(field, :es))
expect_page_to_have_translatable_field field, :es, with: text_for(field, :es)
end
scenario "Select a locale and add it to the form", :js do
@@ -161,22 +262,68 @@ shared_examples "translatable" do |factory_name, path_name, fields|
click_link "Français"
expect(page).to have_field(field_for(fields.sample, :fr))
expect_page_to_have_translatable_field fields.sample, :fr, with: ""
end
end
end
def updated_path_for(resource)
send(path_name, *resource_hierarchy_for(resource.reload))
end
def text_for(field, locale)
I18n.with_locale(locale) do
"#{translatable_class.human_attribute_name(field)} #{language_texts[locale]}"
end
end
def field_for(field, locale)
def field_for(field, locale, visible: true)
if translatable_class.name == "I18nContent"
"contents_content_#{translatable.key}values_#{field}_#{locale}"
else
"#{translatable_class.model_name.singular}_#{field}_#{locale}"
within(".translatable-fields[data-locale='#{locale}']") do
find("input[id$='_#{field}'], textarea[id$='_#{field}']", visible: visible)[:id]
end
end
end
def fill_in_field(field, locale, with:)
if input_fields.include?(field)
fill_in field_for(field, locale), with: with
else
fill_in_textarea(field, textarea_fields[field], locale, with: with)
end
end
def fill_in_textarea(field, textarea_type, locale, with:)
if textarea_type == :markdownit
click_link class: "fullscreen-toggle"
fill_in field_for(field, locale), with: with
click_link class: "fullscreen-toggle"
elsif textarea_type == :ckeditor
fill_in_ckeditor field_for(field, locale, visible: false), with: with
end
end
def expect_page_to_have_translatable_field(field, locale, with:)
if input_fields.include?(field)
if translatable_class.name == "I18nContent" && with.blank?
expect(page).to have_field field_for(field, locale)
else
expect(page).to have_field field_for(field, locale), with: with
end
else
textarea_type = textarea_fields[field]
if textarea_type == :markdownit
click_link class: "fullscreen-toggle"
expect(page).to have_field field_for(field, locale), with: with
click_link class: "fullscreen-toggle"
elsif textarea_type == :ckeditor
within("div.js-globalize-attribute[data-locale='#{locale}'] .ckeditor [id$='#{field}']") do
within_frame(textarea_fields.keys.index(field)) { expect(page).to have_content with }
end
end
end
end
@@ -184,16 +331,24 @@ end
# even share the same colour.
def update_button_text
case translatable_class.name
when "Budget::Investment::Milestone"
when "Milestone"
"Update milestone"
when "AdminNotification"
"Update notification"
when "Poll"
"Update poll"
when "Poll::Question"
when "Budget"
"Update Budget"
when "Poll::Question", "Poll::Question::Answer", "ActivePoll"
"Save"
when "SiteCustomization::Page"
"Update Custom page"
when "Widget::Card"
"Save card"
when "Budget::Group"
"Save group"
when "Budget::Heading"
"Save heading"
else
"Save changes"
end