diff --git a/spec/components/documents/document_component_spec.rb b/spec/components/documents/document_component_spec.rb new file mode 100644 index 000000000..eff800cba --- /dev/null +++ b/spec/components/documents/document_component_spec.rb @@ -0,0 +1,37 @@ +require "rails_helper" + +describe Documents::DocumentComponent do + let(:user) { create(:user) } + let(:proposal) { create(:proposal, author: user) } + let(:document) { create(:document, documentable: proposal) } + let(:component) { Documents::DocumentComponent.new(document, show_destroy_link: true) } + + describe "Delete document button" do + it "is not shown when no user is logged in" do + render_inline component + + expect(page).not_to have_button "Delete document" + end + + it "is shown when the author is logged in" do + sign_in(user) + render_inline component + + expect(page).to have_button "Delete document" + end + + it "is not shown when an administrator that isn't the author is logged in", :admin do + render_inline component + + expect(page).not_to have_button "Delete document" + end + + it "is not shown when a user that isn't the author is logged in" do + login_as(create(:user)) + + render_inline component + + expect(page).not_to have_button "Delete document" + end + end +end diff --git a/spec/shared/system/documentable.rb b/spec/shared/system/documentable.rb deleted file mode 100644 index 43277e9e6..000000000 --- a/spec/shared/system/documentable.rb +++ /dev/null @@ -1,107 +0,0 @@ -shared_examples "documentable" do |documentable_factory_name, documentable_path, documentable_path_arguments| - let(:user) { create(:user) } - let(:arguments) { {} } - let(:documentable) { create(documentable_factory_name, author: user) } - let!(:document) { create(:document, documentable: documentable, user: documentable.author) } - - before do - documentable_path_arguments.each do |argument_name, path_to_value| - arguments.merge!("#{argument_name}": documentable.send(path_to_value)) - end - end - - context "Show documents" do - scenario "Download action should be availabe to anyone and open in the same tab" do - visit send(documentable_path, arguments) - - within "#documents" do - expect(page).to have_link text: document.title - expect(page).to have_css "a[rel=nofollow]", text: document.title - expect(page).not_to have_css "a[target=_blank]" - end - end - - describe "Destroy action" do - scenario "Should not be able when no user logged in" do - visit send(documentable_path, arguments) - - expect(page).not_to have_button "Delete document" - end - - scenario "Should be able when documentable author is logged in" do - login_as documentable.author - visit send(documentable_path, arguments) - - expect(page).to have_button "Delete document" - end - - scenario "Administrators cannot destroy documentables they have not authored", :admin do - visit send(documentable_path, arguments) - - expect(page).not_to have_button "Delete document" - end - - scenario "Users cannot destroy documentables they have not authored" do - login_as(create(:user)) - visit send(documentable_path, arguments) - - expect(page).not_to have_button "Delete document" - end - end - - describe "When allow attached documents setting is enabled" do - before do - Setting["feature.allow_attached_documents"] = true - 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 - - scenario "Documents list should not be available" do - login_as(create(:user)) - visit send(documentable_path, arguments) - - expect(page).not_to have_css("#documents") - end - end - end - - context "Destroy" do - scenario "Should show success notice after successful document upload" do - login_as documentable.author - - visit send(documentable_path, arguments) - - within "#document_#{document.id}" do - accept_confirm { click_button "Delete document" } - end - - expect(page).to have_content "Document was deleted successfully." - expect(page).not_to have_content "Documents (0)" - - within "##{ActionView::RecordIdentifier.dom_id(documentable)}" do - expect(page).to have_css "h1", text: documentable.title - end - end - end -end diff --git a/spec/shared/system/mappable.rb b/spec/shared/system/mappable.rb index 680c15ea7..7669fdb08 100644 --- a/spec/shared/system/mappable.rb +++ b/spec/shared/system/mappable.rb @@ -21,7 +21,7 @@ shared_examples "mappable" do |mappable_factory_name, mappable_association_name, do_login_for user, management: management visit send(mappable_new_path, arguments) - send("fill_in_#{mappable_factory_name}_form") + send("fill_in_#{mappable_factory_name}") within ".map-location" do expect(page).not_to have_css(".map-icon") @@ -32,7 +32,7 @@ shared_examples "mappable" do |mappable_factory_name, mappable_association_name, do_login_for user, management: management visit send(mappable_new_path, arguments) - send("fill_in_#{mappable_factory_name}_form") + send("fill_in_#{mappable_factory_name}") find("#new_map_location").click within ".map-location" do @@ -44,7 +44,7 @@ shared_examples "mappable" do |mappable_factory_name, mappable_association_name, do_login_for user, management: management visit send(mappable_new_path, arguments) - send("fill_in_#{mappable_factory_name}_form") + send("fill_in_#{mappable_factory_name}") find("#new_map_location").click send("submit_#{mappable_factory_name}_form") @@ -57,7 +57,7 @@ shared_examples "mappable" do |mappable_factory_name, mappable_association_name, do_login_for user, management: management visit send(mappable_new_path, arguments) - send("fill_in_#{mappable_factory_name}_form") + send("fill_in_#{mappable_factory_name}") expect(page).to have_css ".map-location" send("submit_#{mappable_factory_name}_form") @@ -69,7 +69,7 @@ shared_examples "mappable" do |mappable_factory_name, mappable_association_name, do_login_for user, management: management visit send(mappable_new_path, arguments) - send("fill_in_#{mappable_factory_name}_form") + send("fill_in_#{mappable_factory_name}") expect(page).not_to have_css ".map-location" send("submit_#{mappable_factory_name}_form") @@ -171,7 +171,7 @@ shared_examples "mappable" do |mappable_factory_name, mappable_association_name, do_login_for user, management: management visit send(mappable_new_path, arguments) - send("fill_in_#{mappable_factory_name}_form") + send("fill_in_#{mappable_factory_name}") send("submit_#{mappable_factory_name}_form") expect(page).not_to have_content "Map location can't be blank" diff --git a/spec/shared/system/nested_documentable.rb b/spec/shared/system/nested_documentable.rb deleted file mode 100644 index c45e6c053..000000000 --- a/spec/shared/system/nested_documentable.rb +++ /dev/null @@ -1,318 +0,0 @@ -shared_examples "nested documentable" do |login_as_name, documentable_factory_name, path, - documentable_path_arguments, fill_resource_method_name, - submit_button, documentable_success_notice, management: false| - let!(:administrator) { create(:user) } - let!(:user) { create(:user, :level_two) } - let!(:arguments) { {} } - if documentable_factory_name == "dashboard_action" - let!(:documentable) { create(documentable_factory_name) } - else - let!(:documentable) { create(documentable_factory_name, author: user) } - end - let!(:user_to_login) { send(login_as_name) } - let(:management) { management } - - before do - create(:administrator, user: administrator) - - documentable_path_arguments&.each do |argument_name, path_to_value| - arguments.merge!("#{argument_name}": documentable.send(path_to_value)) - end - end - - describe "at #{path}" do - scenario "Should show new document link when max documents allowed limit is not reached" do - do_login_for user_to_login, management: management - visit send(path, arguments) - - expect(page).to have_link id: "new_document_link" - end - - scenario "Should not show new document link when - documentable max documents allowed limit is reached" do - do_login_for user_to_login, management: management - visit send(path, arguments) - - documentable.class.max_documents_allowed.times.each do - click_link "Add new document" - end - - expect(page).not_to have_css "#new_document_link" - end - - scenario "Should not show max documents warning when no documents added" do - do_login_for user_to_login, management: management - visit send(path, arguments) - - expect(page).not_to have_css ".max-documents-notice" - end - - scenario "Should show max documents warning when max documents allowed limit is reached" do - do_login_for user_to_login, management: management - visit send(path, arguments) - documentable.class.max_documents_allowed.times.each do - documentable_attach_new_file(file_fixture("empty.pdf")) - end - - expect(page).to have_css ".max-documents-notice" - expect(page).to have_content "Remove document" - end - - scenario "Should hide max documents warning after any document removal" do - do_login_for user_to_login, management: management - visit send(path, arguments) - - documentable.class.max_documents_allowed.times.each do - click_link "Add new document" - end - - all("a", text: "Cancel").last.click - - expect(page).not_to have_css ".max-documents-notice" - end - - scenario "Should update nested document file name after choosing a file" do - do_login_for user_to_login, management: management - visit send(path, arguments) - - click_link "Add new document" - within "#nested-documents" do - attach_file "Choose document", file_fixture("empty.pdf") - - expect(page).to have_css ".loading-bar.complete" - end - - expect(page).to have_css ".file-name", text: "empty.pdf" - end - - scenario "Should update nested document file title with - file name after choosing a file when no title defined" do - do_login_for user_to_login, management: management - visit send(path, arguments) - - documentable_attach_new_file(file_fixture("empty.pdf")) - - expect_document_has_title(0, "empty.pdf") - end - - scenario "Should not update nested document file title with - file name after choosing a file when title already defined" do - do_login_for user_to_login, management: management - visit send(path, arguments) - - click_link "Add new document" - within "#nested-documents" do - input = find("input[name$='[title]']") - fill_in input[:id], with: "My Title" - attach_file "Choose document", file_fixture("empty.pdf") - - expect(page).to have_css ".loading-bar.complete" - end - - expect_document_has_title(0, "My Title") - end - - scenario "Should update loading bar style after valid file upload" do - do_login_for user_to_login, management: management - visit send(path, arguments) - - documentable_attach_new_file(file_fixture("empty.pdf")) - - expect(page).to have_css ".loading-bar.complete" - end - - scenario "Should update loading bar style after invalid file upload" do - do_login_for user_to_login, management: management - visit send(path, arguments) - - documentable_attach_new_file(file_fixture("logo_header.gif"), false) - - expect(page).to have_css ".loading-bar.errors" - end - - scenario "Should update document cached_attachment field after valid file upload" do - do_login_for user_to_login, management: management - visit send(path, arguments) - - click_link "Add new document" - - cached_attachment_field = find("input[name$='[cached_attachment]']", visible: :hidden) - expect(cached_attachment_field.value).to be_empty - - attach_file "Choose document", file_fixture("empty.pdf") - - expect(page).to have_css(".loading-bar.complete") - expect(cached_attachment_field.value).not_to be_empty - end - - scenario "Should not update document cached_attachment field after invalid file upload" do - do_login_for user_to_login, management: management - visit send(path, arguments) - - documentable_attach_new_file(file_fixture("logo_header.gif"), false) - - cached_attachment_field = find("input[name$='[cached_attachment]']", visible: :hidden) - expect(cached_attachment_field.value).to be_empty - end - - scenario "Should show document errors after documentable submit with - empty document fields" do - do_login_for user_to_login, management: management - visit send(path, arguments) - - click_link "Add new document" - click_button submit_button - - within "#nested-documents .document-fields" do - expect(page).to have_content("can't be blank", count: 2) - end - end - - scenario "Should delete document after valid file upload and click on remove button" do - do_login_for user_to_login, management: management - visit send(path, arguments) - - documentable_attach_new_file(file_fixture("empty.pdf")) - click_link "Remove document" - - expect(page).not_to have_css("#nested-documents .document-fields") - end - - scenario "Should show successful notice when - resource filled correctly without any nested documents" do - do_login_for user_to_login, 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 documentable_success_notice - end - - scenario "Should show successful notice when - resource filled correctly and after valid file uploads" do - do_login_for user_to_login, management: management - visit send(path, arguments) - send(fill_resource_method_name) if fill_resource_method_name - - documentable_attach_new_file(file_fixture("empty.pdf")) - click_button submit_button - - expect(page).to have_content documentable_success_notice - end - - scenario "Should show new document after successful creation with one uploaded file", - unless: documentable_factory_name == "dashboard_action" do - do_login_for user_to_login, management: management - visit send(path, arguments) - send(fill_resource_method_name) if fill_resource_method_name - - documentable_attach_new_file(file_fixture("empty.pdf")) - click_button submit_button - - expect(page).to have_content documentable_success_notice - - documentable_redirected_to_resource_show_or_navigate_to - - expect(page).to have_content "Documents" - expect(page).to have_content "empty.pdf" - - # Review - # Doble check why the file is stored with a name different to empty.pdf - expect(page).to have_link href: /.pdf\Z/ - end - - scenario "Should show resource with new document after successful creation with - maximum allowed uploaded files", unless: documentable_factory_name == "dashboard_action" do - do_login_for user_to_login, management: management - visit send(path, arguments) - - send(fill_resource_method_name) if fill_resource_method_name - - %w[clippy empty logo].take(documentable.class.max_documents_allowed).each do |filename| - documentable_attach_new_file(file_fixture("#{filename}.pdf")) - end - - click_button submit_button - - expect(page).to have_content documentable_success_notice - - documentable_redirected_to_resource_show_or_navigate_to - - expect(page).to have_content "Documents (#{documentable.class.max_documents_allowed})" - end - - if path.include? "edit" - scenario "Should show persisted documents and remove nested_field" do - create(:document, documentable: documentable) - do_login_for user_to_login, management: management - visit send(path, arguments) - - expect(page).to have_css ".document-fields", count: 1 - end - - scenario "Should not show add document button when - documentable has reached maximum of documents allowed" do - create_list(:document, documentable.class.max_documents_allowed, documentable: documentable) - do_login_for user_to_login, management: management - visit send(path, arguments) - - expect(page).not_to have_css "#new_document_link" - end - - scenario "Should show add document button after destroy one document" do - create_list(:document, documentable.class.max_documents_allowed, documentable: documentable) - do_login_for user_to_login, management: management - visit send(path, arguments) - last_document = all("#nested-documents .document-fields").last - within last_document do - click_link "Remove document" - end - - expect(page).to have_link id: "new_document_link" - end - - scenario "Should remove nested field after remove document" do - create(:document, documentable: documentable) - do_login_for user_to_login, management: management - visit send(path, arguments) - click_link "Remove document" - - expect(page).not_to have_css ".document-fields" - end - - scenario "Same attachment URL after editing the title" do - do_login_for user_to_login, management: management - - visit send(path, arguments) - documentable_attach_new_file(file_fixture("empty.pdf")) - within_fieldset("Documents") { fill_in "Title", with: "Original" } - click_button submit_button - - expect(page).to have_content documentable_success_notice - - original_url = find_link(text: "Original")[:href] - - visit send(path, arguments) - within_fieldset("Documents") { fill_in "Title", with: "Updated" } - click_button submit_button - - expect(page).to have_content documentable_success_notice - expect(find_link(text: "Updated")[:href]).to eq original_url - end - end - - describe "When allow attached documents setting is disabled" do - before do - Setting["feature.allow_attached_documents"] = false - end - - scenario "Add new document button should not be available" do - do_login_for user_to_login, management: management - visit send(path, arguments) - - expect(page).not_to have_content("Add new document") - end - end - end -end diff --git a/spec/support/common_actions.rb b/spec/support/common_actions.rb index b12fe944c..d1411f2bf 100644 --- a/spec/support/common_actions.rb +++ b/spec/support/common_actions.rb @@ -2,14 +2,13 @@ Dir["./spec/support/common_actions/*.rb"].each { |f| require f } Dir["./spec/support/common_actions/custom/*.rb"].each { |f| require f } module CommonActions + include Attachables include Budgets include Comments include Cookies include Debates - include Documents include Emails include GraphQLAPI - include Images include Maps include Notifications include Polls @@ -43,12 +42,24 @@ module CommonActions end def fill_in_proposal - fill_in_new_proposal_title with: "Help refugees" - fill_in "Proposal summary", with: "In summary, what we want is..." - fill_in_ckeditor "Proposal text", with: "This is very important because..." - fill_in "External video URL", with: "https://www.youtube.com/watch?v=yPQfcG-eimk" - fill_in "Full name of the person submitting the proposal", with: "Isabel Garcia" - check "I agree to the Privacy Policy and the Terms and conditions of use" + fill_in_new_proposal_title with: "Proposal title" + fill_in "Proposal summary", with: "Proposal summary" + check :proposal_terms_of_service + end + + def fill_in_budget + fill_in "Name", with: "Budget name" + end + + def fill_in_dashboard_action + fill_in :dashboard_action_title, with: "Dashboard title" + fill_in_ckeditor "Description", with: "Dashboard description" + end + + def fill_in_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 fill_in_new_proposal_title(with:) diff --git a/spec/support/common_actions/attachables.rb b/spec/support/common_actions/attachables.rb new file mode 100644 index 000000000..505f73f37 --- /dev/null +++ b/spec/support/common_actions/attachables.rb @@ -0,0 +1,91 @@ +module Attachables + def imageable_attach_new_file(path, success: true) + attach_new_file("Add image", "nested-image", "image", "Choose image", path, success) + end + + def documentable_attach_new_file(path, success: true) + attach_new_file("Add new document", "nested-documents", "document", "Choose document", path, success) + end + + def attach_new_file(link_text, wrapper_id, field_class, input_label, path, success) + click_link link_text + + within "##{wrapper_id}" do + attach_file input_label, path + within ".#{field_class}-fields" do + if success + expect(page).to have_css ".loading-bar.complete" + else + expect(page).to have_css ".loading-bar.errors" + end + end + end + end + + def admin_section?(path) + path.starts_with?("/admin/") + end + + def management_section?(path) + path.starts_with?("/management/") + end + + def edit_path?(path) + path.ends_with?("/edit") + end + + def fill_in_required_fields(factory, path) + return if edit_path?(path) + + case factory + when :budget then fill_in_budget + when :budget_investment then fill_in_budget_investment + when :dashboard_action then fill_in_dashboard_action + when :proposal then fill_in_proposal + end + end + + def attachable_path_for(factory, attachable) + case factory + when :budget then new_admin_budgets_wizard_budget_path + when :budget_investment + [ + new_budget_investment_path(budget_id: attachable.budget_id), + new_management_budget_investment_path(budget_id: attachable.budget_id) + ].sample + when :dashboard_action then new_admin_dashboard_action_path + when :future_poll_question_option then new_admin_option_image_path(option_id: attachable.id) + when :proposal then [new_proposal_path, edit_proposal_path(attachable)].sample + end + end + + def submit_button_text_for(factory, path) + case factory + when :budget then "Continue to groups" + when :budget_investment then "Create Investment" + when :dashboard_action then "Save" + when :future_poll_question_option then "Save image" + when :proposal + if edit_path?(path) + "Save changes" + else + "Create proposal" + end + end + end + + def notice_text_for(factory, path) + case factory + when :budget then "New participatory budget created successfully!" + when :budget_investment then "Budget Investment created successfully." + when :dashboard_action then "Action created successfully" + when :future_poll_question_option then "Image uploaded successfully" + when :proposal + if edit_path?(path) + "Proposal updated successfully" + else + "Proposal created successfully" + end + end + end +end diff --git a/spec/support/common_actions/documents.rb b/spec/support/common_actions/documents.rb deleted file mode 100644 index b0936646d..000000000 --- a/spec/support/common_actions/documents.rb +++ /dev/null @@ -1,48 +0,0 @@ -module Documents - def documentable_redirected_to_resource_show_or_navigate_to - find("a", text: "Not now, go to my proposal") - click_link "Not now, go to my proposal" - rescue - nil - end - - def documentable_attach_new_file(path, success = true) - click_link "Add new document" - - document = all(".document-fields").last - attach_file "Choose document", path - - within document do - if success - expect(page).to have_css ".loading-bar.complete" - else - expect(page).to have_css ".loading-bar.errors" - end - end - end - - def expect_document_has_title(index, title) - document = all(".document-fields")[index] - - within document do - expect(find("input[name$='[title]']").value).to eq title - end - end - - def documentable_fill_new_valid_proposal - fill_in_new_proposal_title with: "Proposal title #{rand(9999)}" - fill_in "Proposal summary", with: "Proposal summary" - check :proposal_terms_of_service - end - - def documentable_fill_new_valid_dashboard_action - fill_in :dashboard_action_title, with: "Dashboard title" - fill_in_ckeditor "Description", with: "Dashboard description" - end - - def documentable_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 -end diff --git a/spec/support/common_actions/images.rb b/spec/support/common_actions/images.rb deleted file mode 100644 index df59a48cb..000000000 --- a/spec/support/common_actions/images.rb +++ /dev/null @@ -1,16 +0,0 @@ -module Images - def imageable_attach_new_file(path, success = true) - click_link "Add image" - within "#nested-image" do - image = find(".image-fields") - attach_file "Choose image", path - within image do - if success - expect(page).to have_css(".loading-bar.complete") - else - expect(page).to have_css(".loading-bar.errors") - end - end - end - end -end diff --git a/spec/support/common_actions/maps.rb b/spec/support/common_actions/maps.rb index bde0f93c6..15aa6ff6e 100644 --- a/spec/support/common_actions/maps.rb +++ b/spec/support/common_actions/maps.rb @@ -1,11 +1,5 @@ module Maps - def fill_in_proposal_form - fill_in_new_proposal_title with: "Help 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" expect(page).to have_content "Proposal created successfully." @@ -16,14 +10,7 @@ module Maps end end - def fill_in_budget_investment_form - 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 submit_budget_investment_form - check :budget_investment_terms_of_service click_button "Create Investment" expect(page).to have_content "Budget Investment created successfully" end diff --git a/spec/system/admin/dashboard/actions_spec.rb b/spec/system/admin/dashboard/actions_spec.rb index 302f2edc4..e0909cdda 100644 --- a/spec/system/admin/dashboard/actions_spec.rb +++ b/spec/system/admin/dashboard/actions_spec.rb @@ -1,15 +1,6 @@ require "rails_helper" describe "Admin dashboard actions", :admin do - it_behaves_like "nested documentable", - "administrator", - "dashboard_action", - "new_admin_dashboard_action_path", - {}, - "documentable_fill_new_valid_dashboard_action", - "Save", - "Action created successfully" - context "when visiting index" do context "and no actions defined" do before do diff --git a/spec/system/budgets/investments_spec.rb b/spec/system/budgets/investments_spec.rb index 8cd5eaf96..e4fd1c897 100644 --- a/spec/system/budgets/investments_spec.rb +++ b/spec/system/budgets/investments_spec.rb @@ -1110,20 +1110,6 @@ describe "Budget Investments" do "budget_investment_path", { budget_id: "budget_id", id: "id" } - it_behaves_like "documentable", - "budget_investment", - "budget_investment_path", - { budget_id: "budget_id", id: "id" } - - it_behaves_like "nested documentable", - "user", - "budget_investment", - "new_budget_investment_path", - { budget_id: "budget_id" }, - "documentable_fill_new_valid_budget_investment", - "Create Investment", - "Budget Investment created successfully." - it_behaves_like "mappable", "budget_investment", "investment", diff --git a/spec/system/documents_spec.rb b/spec/system/documents_spec.rb deleted file mode 100644 index b1abac580..000000000 --- a/spec/system/documents_spec.rb +++ /dev/null @@ -1,28 +0,0 @@ -require "rails_helper" - -describe "Documents" do - describe "Metadata" do - scenario "download document without metadata" do - login_as(create(:user)) - visit new_proposal_path - - fill_in_new_proposal_title with: "debate" - fill_in "Proposal summary", with: "In summary, what we want is..." - fill_in "Full name of the person submitting the proposal", with: "Isabel Garcia" - documentable_attach_new_file(file_fixture("logo_with_metadata.pdf")) - check "I agree to the Privacy Policy and the Terms and conditions of use" - click_button "Create proposal" - - expect(page).to have_content "Proposal created successfully" - - io = URI.parse(find_link(text: "PDF")[:href]).open - reader = PDF::Reader.new(io) - - expect(reader.info[:Keywords]).not_to eq "Test Metadata" - expect(reader.info[:Author]).not_to eq "Test Developer" - expect(reader.info[:Title]).not_to eq "logo_with_metadata.pdf" - expect(reader.info[:Producer]).not_to eq "Test Producer" - expect(reader.info).to eq({}) - end - end -end diff --git a/spec/system/management/budget_investments_spec.rb b/spec/system/management/budget_investments_spec.rb index 5bcf5d256..0e2f76675 100644 --- a/spec/system/management/budget_investments_spec.rb +++ b/spec/system/management/budget_investments_spec.rb @@ -7,16 +7,6 @@ describe "Budget Investments" do let(:heading) { create(:budget_heading, group: group, name: "Health") } let(:user) { create(:user, :level_two) } - it_behaves_like "nested documentable", - "user", - "budget_investment", - "new_management_budget_investment_path", - { budget_id: "budget_id" }, - "documentable_fill_new_valid_budget_investment", - "Create Investment", - "Budget Investment created successfully.", - management: true - it_behaves_like "mappable", "budget_investment", "investment", diff --git a/spec/system/nested_documentable_spec.rb b/spec/system/nested_documentable_spec.rb new file mode 100644 index 000000000..13eacb4a1 --- /dev/null +++ b/spec/system/nested_documentable_spec.rb @@ -0,0 +1,283 @@ +require "rails_helper" + +describe "Nested documentable" do + factories = [ + :budget_investment, + :dashboard_action, + :proposal + ] + + let(:factory) { factories.sample } + let!(:documentable) { create(factory) } + let!(:user) { create(:user, :level_two) } + let(:path) { attachable_path_for(factory, documentable) } + let(:submit_button_text) { submit_button_text_for(factory, path) } + let(:notice_text) { notice_text_for(factory, path) } + + context "New and edit path" do + before do + Setting["uploads.documents.max_amount"] = 1 + create(:administrator, user: user) if admin_section?(path) + documentable.update!(author: user) if edit_path?(path) + end + + scenario "Shows or hides new document link depending on max documents limit" do + do_login_for(user, management: management_section?(path)) + visit path + + expect(page).to have_link "Add new document" + + documentable_attach_new_file(file_fixture("empty.pdf")) + + expect(page).not_to have_link "Add new document" + + click_link "Remove document" + + expect(page).to have_link "Add new document" + end + + scenario "Shows or hides max documents warning depending on max documents limit" do + do_login_for(user, management: management_section?(path)) + visit path + + expect(page).not_to have_css ".max-documents-notice" + expect(page).not_to have_content "Remove document" + + documentable_attach_new_file(file_fixture("empty.pdf")) + + expect(page).to have_css ".max-documents-notice" + + click_link "Remove document" + + expect(page).not_to have_css ".max-documents-notice" + end + + scenario "Should update file name and title after choosing a file with no title defined" do + do_login_for(user, management: management_section?(path)) + visit path + + documentable_attach_new_file(file_fixture("empty.pdf")) + + expect(page).to have_css ".file-name", text: "empty.pdf" + expect(page).to have_field("Title", with: "empty.pdf") + end + + scenario "Should not change existing titles except when removing the document" do + do_login_for(user, management: management_section?(path)) + visit path + + click_link "Add new document" + + expect(page).not_to have_link "Add new document" + + within "#nested-documents" do + fill_in "Title", with: "My Title" + attach_file "Choose document", file_fixture("empty.pdf") + + expect(page).to have_css ".loading-bar.complete" + expect(page).to have_field "Title", with: "My Title" + + click_link "Remove document" + + expect(page).not_to have_css ".document-fields" + expect(page).not_to have_field "Title" + end + + click_link "Add new document" + + within "#nested-documents" do + expect(page).to have_field "Title", with: "" + expect(page).not_to have_field "Title", with: "My Title" + end + end + + scenario "Should update document cached_attachment field after valid file upload" do + do_login_for(user, management: management_section?(path)) + visit path + + click_link "Add new document" + + cached_attachment_field = find("input[name$='[cached_attachment]']", visible: :hidden) + expect(cached_attachment_field.value).to be_empty + + attach_file "Choose document", file_fixture("empty.pdf") + + expect(page).to have_css(".loading-bar.complete") + expect(cached_attachment_field.value).not_to be_empty + end + + scenario "Should not update document cached_attachment field after invalid file upload" do + do_login_for(user, management: management_section?(path)) + visit path + + documentable_attach_new_file(file_fixture("logo_header.gif"), success: false) + + cached_attachment_field = find("input[name$='[cached_attachment]']", visible: :hidden) + expect(cached_attachment_field.value).to be_empty + end + + scenario "Should show document errors after documentable submit with empty document fields" do + do_login_for(user, management: management_section?(path)) + visit path + + click_link "Add new document" + click_button submit_button_text + + within "#nested-documents .document-fields" do + expect(page).to have_content("can't be blank", count: 2) + end + end + + scenario "Should show successful notice when resource filled correctly without any nested documents" do + do_login_for(user, management: management_section?(path)) + visit path + + fill_in_required_fields(factory, path) + click_button submit_button_text + + expect(page).to have_content notice_text + end + + scenario "Should show successful notice when resource filled correctly and after valid file uploads" do + Setting["uploads.documents.max_amount"] = 3 + do_login_for(user, management: management_section?(path)) + visit path + + fill_in_required_fields(factory, path) + + %w[clippy empty logo].each do |filename| + click_link "Add new document" + + attach_file "Choose document", file_fixture("#{filename}.pdf") + + within all(".document-fields").last do + expect(page).to have_css ".loading-bar.complete" + end + end + + expect(page).not_to have_link "Add new document" + + click_button submit_button_text + + expect(page).to have_content notice_text + if factory != :dashboard_action + within "#documents" do + expect(page).to have_content "Documents (3)" + expect(page).to have_link href: /.pdf\Z/, count: 3 + expect(page).to have_link text: "empty.pdf" + expect(page).to have_css "a[rel=nofollow]" + expect(page).to have_link text: "clippy.pdf" + expect(page).to have_css "a[rel=nofollow]" + expect(page).to have_link text: "logo.pdf" + expect(page).to have_css "a[rel=nofollow]" + expect(page).not_to have_css "a[target=_blank]" + end + end + end + + describe "Metadata" do + let(:factory) { (factories - [:dashboard_action]).sample } + + scenario "download document without metadata" do + do_login_for(user, management: management_section?(path)) + visit path + + fill_in_required_fields(factory, path) + documentable_attach_new_file(file_fixture("logo_with_metadata.pdf")) + click_button submit_button_text + + expect(page).to have_content notice_text + + io = URI.parse(find_link(text: "PDF")[:href]).open + reader = PDF::Reader.new(io) + + expect(reader.info[:Keywords]).not_to eq "Test Metadata" + expect(reader.info[:Author]).not_to eq "Test Developer" + expect(reader.info[:Title]).not_to eq "logo_with_metadata.pdf" + expect(reader.info[:Producer]).not_to eq "Test Producer" + expect(reader.info).to eq({}) + end + end + + describe "When allow attached documents setting is disabled" do + before { Setting["feature.allow_attached_documents"] = false } + + scenario "Add new document button should not be available" do + do_login_for(user, management: management_section?(path)) + visit path + + expect(page).not_to have_content("Add new document") + end + end + end + + describe "Only for edit path" do + let!(:proposal) { create(:proposal, author: user) } + + scenario "Should show persisted documents and remove nested_field" do + Setting["uploads.documents.max_amount"] = 1 + create(:document, documentable: proposal) + login_as user + visit edit_proposal_path(proposal) + + expect(page).not_to have_link "Add new document" + expect(page).to have_css ".document-fields", count: 1 + + click_link "Remove document" + + expect(page).to have_link "Add new document" + expect(page).not_to have_css ".document-fields" + end + + scenario "Same attachment URL after editing the title" do + login_as user + visit edit_proposal_path(proposal) + + documentable_attach_new_file(file_fixture("empty.pdf")) + within_fieldset("Documents") { fill_in "Title", with: "Original" } + click_button "Save changes" + + expect(page).to have_content "Proposal updated successfully" + + original_url = find_link(text: "Original")[:href] + + visit edit_proposal_path(proposal) + within_fieldset("Documents") { fill_in "Title", with: "Updated" } + click_button "Save changes" + + expect(page).to have_content "Proposal updated successfully" + expect(find_link(text: "Updated")[:href]).to eq original_url + end + end + + context "Show path" do + let(:factory) { (factories - [:dashboard_action]).sample } + let(:path) { polymorphic_path(documentable) } + + scenario "Documents list should not be available when allow attached documents setting is disabled" do + Setting["feature.allow_attached_documents"] = false + create(:document, documentable: documentable) + visit path + + expect(page).not_to have_css("#documents") + end + + context "Destroy" do + scenario "Should show success notice after successful document upload" do + create(:document, documentable: documentable) + documentable.update!(author: user) + login_as(user) + visit path + + accept_confirm { click_button "Delete document" } + + expect(page).to have_content "Document was deleted successfully." + expect(page).not_to have_content "Documents (0)" + + within "##{ActionView::RecordIdentifier.dom_id(documentable)}" do + expect(page).to have_css "h1", text: documentable.title + end + end + end + end +end diff --git a/spec/system/nested_imageable_spec.rb b/spec/system/nested_imageable_spec.rb index 26038a0d0..936432999 100644 --- a/spec/system/nested_imageable_spec.rb +++ b/spec/system/nested_imageable_spec.rb @@ -11,50 +11,15 @@ describe "Nested imageable" do 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 + let(:path) { attachable_path_for(factory, imageable) } + let(:submit_button_text) { submit_button_text_for(factory, path) } + let(:notice_text) { notice_text_for(factory, path) } 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?) + create(:administrator, user: user) if admin_section?(path) + imageable.update!(author: user) if edit_path?(path) + do_login_for(user, management: management_section?(path)) visit path end @@ -96,7 +61,7 @@ describe "Nested imageable" do end scenario "Should not update image cached_attachment field after invalid file upload" do - imageable_attach_new_file(file_fixture("logo_header.png"), false) + imageable_attach_new_file(file_fixture("logo_header.png"), success: false) cached_attachment_field = find("input[name$='[cached_attachment]']", visible: :hidden) @@ -136,7 +101,7 @@ describe "Nested imageable" 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 + fill_in_required_fields(factory, path) click_button submit_button_text @@ -145,7 +110,7 @@ describe "Nested imageable" do end scenario "Should show successful notice when resource filled correctly and after valid file uploads" do - fill_in_required_fields + fill_in_required_fields(factory, path) imageable_attach_new_file(file_fixture("clippy.jpg")) @@ -155,7 +120,7 @@ describe "Nested imageable" do end scenario "Should show new image after successful creation with one uploaded file" do - fill_in_required_fields + fill_in_required_fields(factory, path) imageable_attach_new_file(file_fixture("clippy.jpg")) @@ -205,42 +170,4 @@ describe "Nested imageable" do 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 77f2ad1c3..42c7f566b 100644 --- a/spec/system/proposals_spec.rb +++ b/spec/system/proposals_spec.rb @@ -559,7 +559,7 @@ describe "Proposals" do scenario "Default whole city" do create(:geozone) - author = create(:user) + author = create(:user, :level_two) login_as(author) visit new_proposal_path @@ -1295,26 +1295,6 @@ describe "Proposals" do it_behaves_like "imageable", "proposal", "proposal_path", { id: "id" } - it_behaves_like "documentable", "proposal", "proposal_path", { id: "id" } - - it_behaves_like "nested documentable", - "user", - "proposal", - "new_proposal_path", - {}, - "documentable_fill_new_valid_proposal", - "Create proposal", - "Proposal created successfully" - - it_behaves_like "nested documentable", - "user", - "proposal", - "edit_proposal_path", - { id: "id" }, - nil, - "Save changes", - "Proposal updated successfully" - it_behaves_like "mappable", "proposal", "proposal",