From cdde53f71c6ac1cac5cd6cba463baafe5ee69265 Mon Sep 17 00:00:00 2001 From: Alexandru Emil Lupu Date: Sat, 2 Dec 2023 20:31:41 +0200 Subject: [PATCH] Adjust tests --- decidim-custom_proposal_states.gemspec | 5 + .../admin_manages_accountability_spec.rb | 125 ++++++++- spec/budgets/admin_manages_projects_spec.rb | 255 +++++++++++++++++- .../admin_manages_sortitions_spec.rb | 117 +++++++- 4 files changed, 497 insertions(+), 5 deletions(-) diff --git a/decidim-custom_proposal_states.gemspec b/decidim-custom_proposal_states.gemspec index 604a2ee..31b33a6 100644 --- a/decidim-custom_proposal_states.gemspec +++ b/decidim-custom_proposal_states.gemspec @@ -20,4 +20,9 @@ Gem::Specification.new do |s| s.add_dependency "decidim-core", "~> 0.26.0" s.add_dependency "decidim-proposals", "~> 0.26.0" + s.add_development_dependency "decidim-accountability", "~> 0.26.0" + s.add_development_dependency "decidim-budgets", "~> 0.26.0" + s.add_development_dependency "decidim-dev", "~> 0.26.0" + s.add_development_dependency "decidim-elections", "~> 0.26.0" + s.add_development_dependency "decidim-sortitions", "~> 0.26.0" end diff --git a/spec/accountability/admin_manages_accountability_spec.rb b/spec/accountability/admin_manages_accountability_spec.rb index 11e245c..2e5cd81 100644 --- a/spec/accountability/admin_manages_accountability_spec.rb +++ b/spec/accountability/admin_manages_accountability_spec.rb @@ -5,8 +5,11 @@ describe "Admin manages accountability", type: :system do let(:manifest_name) { "accountability" } + let!(:result) { create :result, scope: scope, component: current_component } + let!(:child_result) { create :result, scope: scope, component: current_component, parent: result } + let!(:status) { create :status, key: "ongoing", name: { en: "Ongoing" }, component: current_component } - include_context "when managing an accountability component as an admin" + include_context "when managing a component as an admin" before do switch_to_host(organization.host) @@ -15,6 +18,124 @@ end describe "results" do - it_behaves_like "manage results" + describe "admin form" do + before { click_on "New Result", match: :first } + + it_behaves_like "having a rich text editor", "new_result", "full" + + it "displays the proposals picker" do + expect(page).to have_content("Choose proposals") + end + + context "when proposal linking is disabled" do + before do + allow(Decidim::Accountability).to receive(:enable_proposal_linking).and_return(false) + + # Reload the page with the updated settings + visit current_path + end + + it "does not display the proposal picker" do + expect(page).not_to have_content "Choose proposals" + end + end + end + + context "when having existing proposals" do + let!(:proposal_component) { create(:proposal_component, participatory_space: participatory_space) } + let!(:proposals) { create_list :proposal, 5, component: proposal_component, skip_injection: true } + + it "updates a result" do + within find("tr", text: translated(result.title)) do + click_link "Edit" + end + + within ".edit_result" do + fill_in_i18n( + :result_title, + "#result-title-tabs", + en: "My new title", + es: "Mi nuevo título", + ca: "El meu nou títol" + ) + + proposals_pick(select_data_picker(:result_proposals, multiple: true), proposals.last(2)) + + find("*[type=submit]").click + end + + expect(page).to have_admin_callout("successfully") + + within "table" do + expect(page).to have_content("My new title") + end + end + + it "creates a new result", :slow do + click_link "New Result", match: :first + + within ".new_result" do + fill_in_i18n( + :result_title, + "#result-title-tabs", + en: "My result", + es: "Mi result", + ca: "El meu result" + ) + fill_in_i18n_editor( + :result_description, + "#result-description-tabs", + en: "A longer description", + es: "Descripción más larga", + ca: "Descripció més llarga" + ) + + proposals_pick(select_data_picker(:result_proposals, multiple: true), proposals.first(2)) + scope_pick(select_data_picker(:result_decidim_scope_id), scope) + select translated(category.name), from: :result_decidim_category_id + + find("*[type=submit]").click + end + + expect(page).to have_admin_callout("successfully") + + within "table" do + expect(page).to have_content("My result") + end + end + end + + it "allows the user to preview the result" do + within find("tr", text: translated(result.title)) do + klass = "action-icon--preview" + href = resource_locator(result).path + target = "blank" + + expect(page).to have_selector( + :xpath, + "//a[contains(@class,'#{klass}')][@href='#{href}'][@target='#{target}']" + ) + end + end + + describe "deleting a result" do + let!(:result2) { create(:result, component: current_component) } + + before do + visit current_path + end + + it "deletes a result" do + within find("tr", text: translated(result2.title)) do + accept_confirm { click_link "Delete" } + end + + expect(page).to have_admin_callout("successfully") + + within "table" do + expect(page).to have_no_content(translated(result2.title)) + end + end + end end end diff --git a/spec/budgets/admin_manages_projects_spec.rb b/spec/budgets/admin_manages_projects_spec.rb index bb997d0..090efa6 100644 --- a/spec/budgets/admin_manages_projects_spec.rb +++ b/spec/budgets/admin_manages_projects_spec.rb @@ -21,6 +21,257 @@ end end - it_behaves_like "manage projects" - it_behaves_like "import proposals to projects" + context "when importing proposals to projects" do + let!(:proposals) { create_list :proposal, 3, :accepted, component: origin_component } + let!(:rejected_proposals) { create_list :proposal, 3, :rejected, component: origin_component } + let!(:origin_component) { create :proposal_component, participatory_space: current_component.participatory_space } + let!(:default_budget) { 2333 } + + include Decidim::ComponentPathHelper + + it "imports proposals from one component to a budget component" do + click_link "Import proposals to projects" + + within ".import_proposals" do + select origin_component.name["en"], from: :proposals_import_origin_component_id + fill_in "Default budget", with: default_budget + check :proposals_import_import_all_accepted_proposals + end + + click_button "Import proposals to projects" + + expect(page).to have_content("3 proposals successfully imported") + + proposals.each do |project| + expect(page).to have_content(project.title["en"]) + end + end + end + + describe "admin form" do + before do + within ".process-content" do + page.find(".button--title.new").click + end + end + + it_behaves_like "having a rich text editor", "new_project", "full" + + it "displays the proposals picker" do + expect(page).to have_content("Choose proposals") + end + + context "when proposal linking is disabled" do + before do + allow(Decidim::Budgets).to receive(:enable_proposal_linking).and_return(false) + + # Reload the page with the updated settings + visit current_path + end + + it "does not display the proposal picker" do + expect(page).not_to have_content "Choose proposals" + end + end + end + + it "updates a project" do + within find("tr", text: translated(project.title)) do + click_link "Edit" + end + + within ".edit_project" do + fill_in_i18n( + :project_title, + "#project-title-tabs", + en: "My new title", + es: "Mi nuevo título", + ca: "El meu nou títol" + ) + + find("*[type=submit]").click + end + + expect(page).to have_admin_callout("successfully") + + within "table" do + expect(page).to have_content("My new title") + end + end + + context "when previewing projects" do + it "allows the user to preview the project" do + within find("tr", text: translated(project.title)) do + klass = "action-icon--preview" + href = resource_locator([project.budget, project]).path + target = "blank" + + expect(page).to have_selector( + :xpath, + "//a[contains(@class,'#{klass}')][@href='#{href}'][@target='#{target}']" + ) + end + end + end + + context "when seeing finished and pending votes" do + let!(:project) { create(:project, budget_amount: 70_000_000, budget: budget) } + + let!(:finished_orders) do + orders = create_list(:order, 10, budget: budget) + orders.each do |order| + order.update!(line_items: [create(:line_item, project: project, order: order)]) + order.reload + order.update!(checked_out_at: Time.zone.today) + end + end + + let!(:pending_orders) do + create_list(:order, 5, budget: budget, checked_out_at: nil) + end + + it "shows the order count" do + visit current_path + expect(page).to have_content("Finished votes: \n10") + expect(page).to have_content("Pending votes: \n5") + end + end + + it "creates a new project", :slow do + find(".card-title a.button.new").click + + within ".new_project" do + fill_in_i18n( + :project_title, + "#project-title-tabs", + en: "My project", + es: "Mi proyecto", + ca: "El meu projecte" + ) + fill_in_i18n_editor( + :project_description, + "#project-description-tabs", + en: "A longer description", + es: "Descripción más larga", + ca: "Descripció més llarga" + ) + fill_in :project_budget_amount, with: 22_000_000 + + scope_pick select_data_picker(:project_decidim_scope_id), scope + select translated(category.name), from: :project_decidim_category_id + + find("*[type=submit]").click + end + + expect(page).to have_admin_callout("successfully") + + within "table" do + expect(page).to have_content("My project") + end + end + + context "when deleting a project" do + let!(:project2) { create(:project, budget: budget) } + + before do + visit current_path + end + + it "deletes a project" do + within find("tr", text: translated(project2.title)) do + accept_confirm { click_link "Delete" } + end + + expect(page).to have_admin_callout("successfully") + + within "table" do + expect(page).to have_no_content(translated(project2.title)) + end + end + end + + context "when having existing proposals" do + let!(:proposal_component) { create(:proposal_component, participatory_space: participatory_space) } + let!(:proposals) { create_list :proposal, 5, component: proposal_component, skip_injection: true } + + it "updates a project" do + within find("tr", text: translated(project.title)) do + click_link "Edit" + end + + within ".edit_project" do + fill_in_i18n( + :project_title, + "#project-title-tabs", + en: "My new title", + es: "Mi nuevo título", + ca: "El meu nou títol" + ) + + proposals_pick(select_data_picker(:project_proposals, multiple: true), proposals.last(2)) + + find("*[type=submit]").click + end + + expect(page).to have_admin_callout("successfully") + + within "table" do + expect(page).to have_content("My new title") + end + end + + it "removes proposals from project", :slow do + project.link_resources(proposals, "included_proposals") + not_removed_projects_title = project.linked_resources(:proposals, "included_proposals").first.title + expect(project.linked_resources(:proposals, "included_proposals").count).to eq(5) + + within find("tr", text: translated(project.title)) do + click_link "Edit" + end + + within ".edit_project" do + proposals_remove(select_data_picker(:project_proposals, multiple: true), proposals.last(4)) + + find("*[type=submit]").click + end + + expect(page).to have_admin_callout("successfully") + expect(project.linked_resources(:proposals, "included_proposals").count).to eq(1) + expect(project.linked_resources(:proposals, "included_proposals").first.title).to eq(not_removed_projects_title) + end + + it "creates a new project", :slow do + find(".card-title a.button.new").click + + within ".new_project" do + fill_in_i18n( + :project_title, + "#project-title-tabs", + en: "My project", + es: "Mi project", + ca: "El meu project" + ) + fill_in_i18n_editor( + :project_description, + "#project-description-tabs", + en: "A longer description", + es: "Descripción más larga", + ca: "Descripció més llarga" + ) + fill_in :project_budget_amount, with: 22_000_000 + + proposals_pick(select_data_picker(:project_proposals, multiple: true), proposals.first(2)) + scope_pick(select_data_picker(:project_decidim_scope_id), scope) + select translated(category.name), from: :project_decidim_category_id + + find("*[type=submit]").click + end + + expect(page).to have_admin_callout("successfully") + + within "table" do + expect(page).to have_content("My project") + end + end + end end diff --git a/spec/sortitions/admin_manages_sortitions_spec.rb b/spec/sortitions/admin_manages_sortitions_spec.rb index 202ced1..e1ac24b 100644 --- a/spec/sortitions/admin_manages_sortitions_spec.rb +++ b/spec/sortitions/admin_manages_sortitions_spec.rb @@ -7,5 +7,120 @@ include_context "when managing a component as an admin" - it_behaves_like "manage sortitions" + describe "creation" do + let!(:proposal_component) do + create(:proposal_component, :published, participatory_space: current_component.participatory_space) + end + + before do + click_link "New sortition" + end + + it "Requires a title" do + within "form" do + expect(page).to have_content(/Title/i) + end + end + + it "can be related to a category" do + within "form" do + expect(page).to have_content(/Categories of the set of proposals in which you want to apply the draw/i) + end + end + + it "Requires a random number" do + within "form" do + expect(page).to have_content(/Result of die roll/i) + end + end + + it "Requires the number of proposals to select" do + within "form" do + expect(page).to have_content(/Number of proposals to be selected/i) + end + end + + it "Requires the proposals component" do + within "form" do + expect(page).to have_content(/Proposals set/i) + end + end + + it "Requires the witnesses" do + within "form" do + expect(page).to have_content(/Witnesses/i) + end + end + + it "Requires additional information" do + within "form" do + expect(page).to have_content(/Sortition information/i) + end + end + + context "when creates a sortition" do + let(:sortition_dice) { ::Faker::Number.between(from: 1, to: 6) } + let(:sortition_target_items) { ::Faker::Number.between(from: 1, to: 10) } + let!(:proposal) { create :proposal, component: proposal_component } + + it_behaves_like "having a rich text editor for field", ".tabs-content[data-tabs-content='sortition-additional_info-tabs']", "full" + it_behaves_like "having a rich text editor for field", ".tabs-content[data-tabs-content='sortition-witnesses-tabs']", "content" + + it "shows the sortition details" do + within ".new_sortition" do + fill_in :sortition_dice, with: sortition_dice + fill_in :sortition_target_items, with: sortition_target_items + select translated(proposal_component.name), from: :sortition_decidim_proposals_component_id + fill_in_i18n_editor( + :sortition_witnesses, + "#sortition-witnesses-tabs", + en: "Witnesses", + es: "Testigos", + ca: "Testimonis" + ) + fill_in_i18n_editor( + :sortition_additional_info, + "#sortition-additional_info-tabs", + en: "additional info", + es: "Información adicional", + ca: "Informació adicional" + ) + + fill_in_i18n( + :sortition_title, + "#sortition-title-tabs", + en: "Title", + es: "Título", + ca: "Títol" + ) + + accept_confirm { find("*[type=submit]").click } + end + + expect(page).to have_admin_callout("successfully") + expect(page).to have_content(/Title/i) + + sortition = Decidim::Sortitions::Sortition.last + within ".sortition" do + expect(page).to have_content(/Draw time/i) + expect(page).to have_content(/Dice/i) + expect(page).to have_content(/Items to select/i) + expect(page).to have_content(/Category/i) + expect(page).to have_content(/All categories/i) + expect(page).to have_content(/Proposals component/i) + expect(page).to have_content(translated(proposal_component.name)) + expect(page).to have_content(/Seed/i) + expect(page).to have_content(sortition.seed) + end + + within ".proposals" do + expect(page).to have_content(/Proposals selected for draw/i) + expect(sortition.proposals).not_to be_empty + sortition.proposals.each do |p| + expect(page).to have_content(translated(p.title)) + end + end + end + end + end end