diff --git a/.rubocop.yml b/.rubocop.yml index bd287aa83..0a5d2c226 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -694,6 +694,9 @@ Style/ArrayIntersect: Style/BlockDelimiters: Enabled: true +Style/CaseLikeIf: + Enabled: true + Style/ClassCheck: Enabled: true diff --git a/app/controllers/management/budgets/investments_controller.rb b/app/controllers/management/budgets/investments_controller.rb index c03ced8bb..5d1b32577 100644 --- a/app/controllers/management/budgets/investments_controller.rb +++ b/app/controllers/management/budgets/investments_controller.rb @@ -26,8 +26,8 @@ class Management::Budgets::InvestmentsController < Management::BaseController @investment.heading = @budget.headings.first if @budget.single_heading? if @investment.save - notice = t("flash.actions.create.notice", resource_name: Budget::Investment.model_name.human, count: 1) - redirect_to management_budget_investment_path(@budget, @investment), notice: notice + redirect_to management_budget_investment_path(@budget, @investment), + notice: t("flash.actions.create.budget_investment") else render :new end diff --git a/spec/shared/system/nested_imageable.rb b/spec/shared/system/nested_imageable.rb deleted file mode 100644 index 6121f0a0f..000000000 --- a/spec/shared/system/nested_imageable.rb +++ /dev/null @@ -1,246 +0,0 @@ -shared_examples "nested imageable" do |imageable_factory_name, path, imageable_path_arguments, - fill_resource_method_name, submit_button, imageable_success_notice, - has_many_images = false, management: false| - let!(:user) { create(:user, :level_two) } - let!(:arguments) { {} } - let!(:imageable) { create(imageable_factory_name) } - let(:management) { management } - - before do - create(:administrator, user: user) - - imageable_path_arguments&.each do |argument_name, path_to_value| - arguments.merge!("#{argument_name}": imageable.send(path_to_value)) - end - - imageable.update(author: user) if imageable.respond_to?(:author) - end - - describe "at #{path}" do - scenario "Should show new image link when imageable has not an associated image defined" do - do_login_for user, management: management - visit send(path, arguments) - - expect(page).to have_css "#new_image_link" - end - - scenario "Should hide new image link after adding one image" do - do_login_for user, management: management - visit send(path, arguments) - - click_link "Add image" - - expect(page).not_to have_css "#new_image_link" - end - - scenario "Should update image file name after choosing any file" do - do_login_for user, management: management - visit send(path, arguments) - - click_link "Add image" - attach_file "Choose image", file_fixture("clippy.jpg") - - expect(page).to have_css ".file-name", text: "clippy.jpg" - end - - scenario "Should update image file title after choosing a file when no title is defined" do - do_login_for user, management: management - visit send(path, arguments) - - imageable_attach_new_file(file_fixture("clippy.jpg")) - - expect_image_has_title("clippy.jpg") - end - - scenario "Should not update image file title after choosing a file when a title is already defined" do - do_login_for user, management: management - visit send(path, arguments) - - click_link "Add image" - input_title = find(".image-fields input[name$='[title]']") - fill_in input_title[:id], with: "Title" - attach_file "Choose image", file_fixture("clippy.jpg") - - if has_many_images - expect(find("input[id$='_title']").value).to eq "Title" - else - expect(find("##{imageable_factory_name}_image_attributes_title").value).to eq "Title" - end - end - - scenario "Should update loading bar style after valid file upload" do - do_login_for user, management: management - visit send(path, arguments) - - imageable_attach_new_file(file_fixture("clippy.jpg")) - - expect(page).to have_css ".loading-bar.complete" - end - - scenario "Should update loading bar style after invalid file upload" do - do_login_for user, management: management - visit send(path, arguments) - - imageable_attach_new_file(file_fixture("logo_header.png"), false) - - expect(page).to have_css ".loading-bar.errors" - end - - scenario "Should update image cached_attachment field after valid file upload" do - do_login_for user, management: management - visit send(path, arguments) - - click_link "Add image" - - cached_attachment_field = find("input[name$='[cached_attachment]']", visible: :hidden) - expect(cached_attachment_field.value).to be_empty - - attach_file "Choose image", file_fixture("clippy.jpg") - - expect(page).to have_css(".loading-bar.complete") - expect(cached_attachment_field.value).not_to be_empty - end - - scenario "Should not update image cached_attachment field after invalid file upload" do - do_login_for user, management: management - visit send(path, arguments) - - imageable_attach_new_file(file_fixture("logo_header.png"), false) - - cached_attachment_field = find("input[name$='[cached_attachment]']", visible: :hidden) - - expect(cached_attachment_field.value).to be_empty - end - - scenario "Should show image errors after invalid form submit" do - do_login_for user, management: management - visit send(path, arguments) - - click_link "Add image" - click_button submit_button - - within "#nested-image .image-fields" do - expect(page).to have_content("can't be blank", count: 2) - end - end - - scenario "Render image preview after sending the form with validation errors", - unless: imageable_factory_name == "poll_question_option" do - do_login_for user, management: management - visit send(path, arguments) - - imageable_attach_new_file(file_fixture("clippy.jpg")) - within_fieldset("Descriptive image") { fill_in "Title", with: "" } - click_button submit_button - - expect(page).to have_content "can't be blank" - expect(page).to have_css "img[src$='clippy.jpg']" - end - - scenario "Should remove image after valid file upload and click on remove button" do - do_login_for user, management: management - visit send(path, arguments) - - imageable_attach_new_file(file_fixture("clippy.jpg")) - - within "#nested-image .image-fields" do - click_link "Remove image" - end - - expect(page).not_to have_css "#nested-image .image-fields" - end - - scenario "Should show successful notice when resource filled correctly without any nested images", - unless: has_many_images do - do_login_for user, management: management - visit send(path, arguments) - - send(fill_resource_method_name) if fill_resource_method_name - click_button submit_button - expect(page).to have_content imageable_success_notice - end - - scenario "Should show successful notice when resource filled correctly and after valid file uploads" do - do_login_for user, management: management - visit send(path, arguments) - send(fill_resource_method_name) if fill_resource_method_name - - imageable_attach_new_file(file_fixture("clippy.jpg")) - - expect(page).to have_css ".loading-bar.complete" - - click_button submit_button - - expect(page).to have_content imageable_success_notice - end - - scenario "Should show new image after successful creation with one uploaded file" do - do_login_for user, management: management - visit send(path, arguments) - send(fill_resource_method_name) if fill_resource_method_name - - imageable_attach_new_file(file_fixture("clippy.jpg")) - - expect(page).to have_css ".loading-bar.complete" - - click_button submit_button - - expect(page).to have_content imageable_success_notice - - imageable_redirected_to_resource_show_or_navigate_to(imageable) - - expect(page).to have_css "figure img" - expect(page).to have_css "figure figcaption" if show_caption_for?(imageable_factory_name) - end - - scenario "Different URLs for different images" do - do_login_for user, management: management - visit send(path, arguments) - - imageable_attach_new_file(file_fixture("clippy.jpg")) - - original_src = find(:fieldset, "Descriptive image").find("img")[:src] - - click_link "Remove image" - imageable_attach_new_file(file_fixture("custom_map.jpg")) - - updated_src = find(:fieldset, "Descriptive image").find("img")[:src] - - expect(updated_src).not_to eq original_src - end - - if path.include? "edit" - scenario "show persisted image" do - create(:image, imageable: imageable) - do_login_for user, management: management - - visit send(path, arguments) - - expect(page).to have_css ".image-fields", count: 1 - expect(page).not_to have_css "a#new_image_link" - end - - scenario "remove nested field after removing the image" do - create(:image, imageable: imageable) - do_login_for user, management: management - - visit send(path, arguments) - click_link "Remove image" - - expect(page).not_to have_css ".image-fields" - expect(page).to have_link id: "new_image_link" - end - - scenario "don't duplicate fields after removing and adding an image" do - create(:image, imageable: imageable) - do_login_for user, management: management - - visit send(path, arguments) - click_link "Remove image" - click_link "Add image" - - expect(page).to have_css ".image-fields", count: 1, visible: :all - end - end - end -end diff --git a/spec/support/common_actions/images.rb b/spec/support/common_actions/images.rb index 33a3d5aa3..df59a48cb 100644 --- a/spec/support/common_actions/images.rb +++ b/spec/support/common_actions/images.rb @@ -1,13 +1,4 @@ module Images - def imageable_redirected_to_resource_show_or_navigate_to(imageable) - case imageable.class.to_s - when "Budget" - visit edit_admin_budget_path(Budget.last) - when "Proposal" - click_link "Not now, go to my proposal" rescue Capybara::ElementNotFound - end - end - def imageable_attach_new_file(path, success = true) click_link "Add image" within "#nested-image" do @@ -22,32 +13,4 @@ module Images end end end - - def imageable_fill_new_valid_proposal - fill_in_new_proposal_title with: "Proposal title" - fill_in "Proposal summary", with: "Proposal summary" - check :proposal_terms_of_service - end - - def imageable_fill_new_valid_budget - fill_in "Name", with: "Budget name" - end - - def imageable_fill_new_valid_budget_investment - fill_in_new_investment_title with: "Budget investment title" - fill_in_ckeditor "Description", with: "Budget investment description" - check :budget_investment_terms_of_service - end - - def expect_image_has_title(title) - image = find(".image-fields") - - within image do - expect(find("input[name$='[title]']").value).to eq title - end - end - - def show_caption_for?(imageable_factory_name) - imageable_factory_name != "budget" - end end diff --git a/spec/system/admin/budgets_spec.rb b/spec/system/admin/budgets_spec.rb index 82d017138..e150448d7 100644 --- a/spec/system/admin/budgets_spec.rb +++ b/spec/system/admin/budgets_spec.rb @@ -1,14 +1,6 @@ require "rails_helper" describe "Admin budgets", :admin do - it_behaves_like "nested imageable", - "budget", - "new_admin_budgets_wizard_budget_path", - {}, - "imageable_fill_new_valid_budget", - "Continue to groups", - "New participatory budget created successfully!" - context "Load" do before { create(:budget, slug: "budget_slug") } diff --git a/spec/system/admin/poll/questions/options/images/images_spec.rb b/spec/system/admin/poll/questions/options/images/images_spec.rb index 53558072e..ae4035f6f 100644 --- a/spec/system/admin/poll/questions/options/images/images_spec.rb +++ b/spec/system/admin/poll/questions/options/images/images_spec.rb @@ -4,15 +4,6 @@ describe "Images", :admin do let(:future_poll) { create(:poll, :future) } let(:current_poll) { create(:poll) } - it_behaves_like "nested imageable", - "future_poll_question_option", - "new_admin_option_image_path", - { option_id: "id" }, - nil, - "Save image", - "Image uploaded successfully", - true - context "Index" do scenario "Option with no images" do option = create(:poll_question_option) diff --git a/spec/system/budgets/investments_spec.rb b/spec/system/budgets/investments_spec.rb index f9a08fdda..b18ff6e81 100644 --- a/spec/system/budgets/investments_spec.rb +++ b/spec/system/budgets/investments_spec.rb @@ -610,7 +610,7 @@ describe "Budget Investments" do click_button "Create Investment" - expect(page).to have_content "Investment created successfully" + expect(page).to have_content "Budget Investment created successfully" expect(page).to have_content "Build a skyscraper" expect(page).to have_content "I want to live in a high tower over the clouds" expect(page).to have_content "City center" @@ -678,7 +678,7 @@ describe "Budget Investments" do click_button "Create Investment" - expect(page).to have_content "Investment created successfully" + expect(page).to have_content "Budget Investment created successfully" expect(page).to have_content "Build a skyscraper" expect(page).to have_content "I want to live in a high tower over the clouds" expect(page).to have_content "City center" @@ -1118,14 +1118,6 @@ describe "Budget Investments" do "budget_investment_path", { budget_id: "budget_id", id: "id" } - it_behaves_like "nested imageable", - "budget_investment", - "new_budget_investment_path", - { budget_id: "budget_id" }, - "imageable_fill_new_valid_budget_investment", - "Create Investment", - "Budget Investment created successfully." - it_behaves_like "documentable", "budget_investment", "budget_investment_path", diff --git a/spec/system/emails_spec.rb b/spec/system/emails_spec.rb index 0612d6087..f97b521b9 100644 --- a/spec/system/emails_spec.rb +++ b/spec/system/emails_spec.rb @@ -358,7 +358,7 @@ describe "Emails" do check "budget_investment_terms_of_service" click_button "Create Investment" - expect(page).to have_content "Investment created successfully" + expect(page).to have_content "Budget Investment created successfully" email = open_last_email diff --git a/spec/system/management/budget_investments_spec.rb b/spec/system/management/budget_investments_spec.rb index 7fcbe2763..5bcf5d256 100644 --- a/spec/system/management/budget_investments_spec.rb +++ b/spec/system/management/budget_investments_spec.rb @@ -14,16 +14,7 @@ describe "Budget Investments" do { budget_id: "budget_id" }, "documentable_fill_new_valid_budget_investment", "Create Investment", - "Investment created successfully.", - management: true - - it_behaves_like "nested imageable", - "budget_investment", - "new_management_budget_investment_path", - { budget_id: "budget_id" }, - "imageable_fill_new_valid_budget_investment", - "Create Investment", - "Investment created successfully.", + "Budget Investment created successfully.", management: true it_behaves_like "mappable", @@ -73,7 +64,7 @@ describe "Budget Investments" do click_button "Create Investment" - expect(page).to have_content "Investment created successfully." + expect(page).to have_content "Budget Investment created successfully." expect(page).to have_content "Health" expect(page).to have_content "Build a park in my neighborhood" diff --git a/spec/system/nested_imageable_spec.rb b/spec/system/nested_imageable_spec.rb new file mode 100644 index 000000000..26038a0d0 --- /dev/null +++ b/spec/system/nested_imageable_spec.rb @@ -0,0 +1,246 @@ +require "rails_helper" + +describe "Nested imageable" do + factories = [ + :budget, + :budget_investment, + :future_poll_question_option, + :proposal + ] + + let(:factory) { factories.sample } + let!(:imageable) { create(factory) } + let!(:user) { create(:user, :level_two) } + let(:path) do + case factory + when :budget then new_admin_budgets_wizard_budget_path + when :budget_investment + [ + new_budget_investment_path(budget_id: imageable.budget_id), + new_management_budget_investment_path(budget_id: imageable.budget_id) + ].sample + when :future_poll_question_option then new_admin_option_image_path(option_id: imageable.id) + when :proposal then [new_proposal_path, edit_proposal_path(imageable)].sample + end + end + let(:submit_button_text) do + case factory + when :budget then "Continue to groups" + when :budget_investment then "Create Investment" + when :future_poll_question_option then "Save image" + when :proposal + if edit_path? + "Save changes" + else + "Create proposal" + end + end + end + let(:notice_text) do + case factory + when :budget then "New participatory budget created successfully!" + when :budget_investment then "Budget Investment created successfully." + when :future_poll_question_option then "Image uploaded successfully" + when :proposal + if edit_path? + "Proposal updated successfully" + else + "Proposal created successfully" + end + end + end + + context "New and edit path" do + before do + create(:administrator, user: user) if admin_section? || management_section? + imageable.update!(author: user) if edit_path? + do_login_for(user, management: management_section?) + visit path + end + + scenario "Handles image link visibility, upload, and file updates correctly" do + expect(page).to have_css "#new_image_link" + + imageable_attach_new_file(file_fixture("clippy.jpg")) + + expect(page).not_to have_css "#new_image_link" + expect(page).to have_css ".file-name", text: "clippy.jpg" + within ".image-fields" do + expect(find("input[name$='[title]']").value).to eq "clippy.jpg" + end + end + + scenario "Should not update image file title after choosing a file when a title is already defined" do + click_link "Add image" + input_title = find(".image-fields input[name$='[title]']") + fill_in input_title[:id], with: "Title" + attach_file "Choose image", file_fixture("clippy.jpg") + + if factory == :future_poll_question_option + expect(find("input[id$='_title']").value).to eq "Title" + else + expect(find("##{factory}_image_attributes_title").value).to eq "Title" + end + end + + scenario "Should update image cached_attachment field after valid file upload" do + click_link "Add image" + + cached_attachment_field = find("input[name$='[cached_attachment]']", visible: :hidden) + expect(cached_attachment_field.value).to be_empty + + attach_file "Choose image", file_fixture("clippy.jpg") + + expect(page).to have_css(".loading-bar.complete") + expect(cached_attachment_field.value).not_to be_empty + end + + scenario "Should not update image cached_attachment field after invalid file upload" do + imageable_attach_new_file(file_fixture("logo_header.png"), false) + + cached_attachment_field = find("input[name$='[cached_attachment]']", visible: :hidden) + + expect(cached_attachment_field.value).to be_empty + end + + scenario "Should show image errors after invalid form submit" do + click_link "Add image" + click_button submit_button_text + + within "#nested-image .image-fields" do + expect(page).to have_content("can't be blank", count: 2) + end + end + + scenario "Render image preview after sending the form with validation errors" do + imageable_attach_new_file(file_fixture("clippy.jpg")) + within_fieldset("Descriptive image") { fill_in "Title", with: "" } + + click_button submit_button_text + + expect(page).to have_content "can't be blank" + expect(page).to have_css "img[src$='clippy.jpg']" + end + + scenario "Should remove image after valid file upload and click on remove button" do + imageable_attach_new_file(file_fixture("clippy.jpg")) + + within "#nested-image .image-fields" do + click_link "Remove image" + end + + expect(page).not_to have_css "#nested-image .image-fields" + end + + context "Budgets, investments and proposals" do + let(:factory) { (factories - [:future_poll_question_option]).sample } + + scenario "Should show successful notice when resource filled correctly without any nested images" do + fill_in_required_fields + + click_button submit_button_text + + expect(page).to have_content notice_text + end + end + + scenario "Should show successful notice when resource filled correctly and after valid file uploads" do + fill_in_required_fields + + imageable_attach_new_file(file_fixture("clippy.jpg")) + + click_button submit_button_text + + expect(page).to have_content notice_text + end + + scenario "Should show new image after successful creation with one uploaded file" do + fill_in_required_fields + + imageable_attach_new_file(file_fixture("clippy.jpg")) + + click_button submit_button_text + + expect(page).to have_content notice_text + + if factory == :budget + click_link "Go back to edit budget" + else + expect(page).to have_css "figure figcaption" + end + expect(page).to have_css "figure img" + end + + scenario "Different URLs for different images" do + imageable_attach_new_file(file_fixture("clippy.jpg")) + + original_src = find(:fieldset, "Descriptive image").find("img")[:src] + + click_link "Remove image" + imageable_attach_new_file(file_fixture("custom_map.jpg")) + + updated_src = find(:fieldset, "Descriptive image").find("img")[:src] + + expect(updated_src).not_to eq original_src + end + end + + context "Only for edit path" do + let(:proposal) { create(:proposal, :with_image, author: user) } + + scenario "handles image fields correctly" do + login_as(user) + visit edit_proposal_path(proposal) + + expect(page).to have_css ".image-fields", count: 1 + expect(page).not_to have_css "a#new_image_link" + + click_link "Remove image" + + expect(page).not_to have_css ".image-fields" + expect(page).to have_link id: "new_image_link" + + click_link "Add image" + + expect(page).to have_css ".image-fields", count: 1, visible: :all + end + end + + def fill_in_required_fields + return if edit_path? + + case factory + when :budget then fill_budget + when :budget_investment then fill_budget_investment + when :proposal then fill_proposal + end + end + + def fill_proposal + fill_in_new_proposal_title with: "Proposal title" + fill_in "Proposal summary", with: "Proposal summary" + check :proposal_terms_of_service + end + + def fill_budget + fill_in "Name", with: "Budget name" + end + + def fill_budget_investment + fill_in_new_investment_title with: "Budget investment title" + fill_in_ckeditor "Description", with: "Budget investment description" + check :budget_investment_terms_of_service + end + + def admin_section? + path.starts_with?("/admin/") + end + + def management_section? + path.starts_with?("/management/") + end + + def edit_path? + path.ends_with?("/edit") + end +end diff --git a/spec/system/proposals_spec.rb b/spec/system/proposals_spec.rb index 4ea70abe0..840255e4b 100644 --- a/spec/system/proposals_spec.rb +++ b/spec/system/proposals_spec.rb @@ -1291,22 +1291,6 @@ describe "Proposals" do it_behaves_like "imageable", "proposal", "proposal_path", { id: "id" } - it_behaves_like "nested imageable", - "proposal", - "new_proposal_path", - {}, - "imageable_fill_new_valid_proposal", - "Create proposal", - "Proposal created successfully" - - it_behaves_like "nested imageable", - "proposal", - "edit_proposal_path", - { id: "id" }, - nil, - "Save changes", - "Proposal updated successfully" - it_behaves_like "documentable", "proposal", "proposal_path", { id: "id" } it_behaves_like "nested documentable", diff --git a/spec/system/tags/budget_investments_spec.rb b/spec/system/tags/budget_investments_spec.rb index f032c6041..8f49284dd 100644 --- a/spec/system/tags/budget_investments_spec.rb +++ b/spec/system/tags/budget_investments_spec.rb @@ -76,7 +76,7 @@ describe "Tags" do click_button "Create Investment" - expect(page).to have_content "Investment created successfully." + expect(page).to have_content "Budget Investment created successfully." expect(page).to have_content tag_economia.name expect(page).to have_content tag_medio_ambiente.name end @@ -93,7 +93,7 @@ describe "Tags" do find(".js-add-tag-link", text: tag_economia.name).click click_button "Create Investment" - expect(page).to have_content "Investment created successfully." + expect(page).to have_content "Budget Investment created successfully." expect(page).to have_content "Build a skyscraper" within ".tags" do @@ -117,7 +117,7 @@ describe "Tags" do find(".js-add-tag-link", text: "Education").click click_button "Create Investment" - expect(page).to have_content "Investment created successfully." + expect(page).to have_content "Budget Investment created successfully." expect(page).to have_content "Build a skyscraper" within ".tags" do @@ -141,7 +141,7 @@ describe "Tags" do find(".js-add-tag-link", text: "Education").click click_button "Create Investment" - expect(page).to have_content "Investment created successfully." + expect(page).to have_content "Budget Investment created successfully." expect(page).to have_content "Build a skyscraper" within ".tags" do @@ -181,7 +181,7 @@ describe "Tags" do click_button "Create Investment" - expect(page).to have_content "Investment created successfully." + expect(page).to have_content "Budget Investment created successfully." expect(page).to have_content "user_id1" expect(page).to have_content "a3" expect(page).to have_content "scriptalert('hey');script"