Merge pull request #5989 from consuldemocracy/nested-documentable-specs

Make nested documentable specs faster
This commit is contained in:
Sebastia
2025-06-10 09:30:18 +02:00
committed by GitHub
16 changed files with 447 additions and 681 deletions

View File

@@ -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

View File

@@ -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

View File

@@ -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"

View File

@@ -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

View File

@@ -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:)

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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",

View File

@@ -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

View File

@@ -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",

View File

@@ -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

View File

@@ -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

View File

@@ -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",