+
+<%= javascript_pack_tag "decidim_participatory_processes_admin" %>
\ No newline at end of file
diff --git a/config/i18n-tasks.yml b/config/i18n-tasks.yml
index 7a81861781..db9522009e 100644
--- a/config/i18n-tasks.yml
+++ b/config/i18n-tasks.yml
@@ -119,6 +119,7 @@ ignore_missing:
- decidim.term_customizer.admin.actions.*
- decidim.term_customizer.admin.add_translations.index.*
- decidim.term_customizer.admin.models.translations.fields.*
+ - decidim.participatory_processes.admin.participatory_processes.form.*
# Consider these keys used:
ignore_unused:
diff --git a/config/initializers/half_signup.rb b/config/initializers/half_signup.rb
index 29512c6406..33b729485b 100644
--- a/config/initializers/half_signup.rb
+++ b/config/initializers/half_signup.rb
@@ -1,5 +1,7 @@
# frozen_string_literal: true
+return unless defined?(Decidim::HalfSignup)
+
Decidim::HalfSignup.configure do |config|
config.show_tos_page_after_signup = Rails.application.secrets.dig(:decidim, :half_signup, :show_tos_page_after_signup)
config.auth_code_length = 4
diff --git a/db/migrate/20241118114335_add_emitter_to_decidim_participatory_process.decidim_emitter.rb b/db/migrate/20241118114335_add_emitter_to_decidim_participatory_process.decidim_emitter.rb
new file mode 100644
index 0000000000..ba525aa3c4
--- /dev/null
+++ b/db/migrate/20241118114335_add_emitter_to_decidim_participatory_process.decidim_emitter.rb
@@ -0,0 +1,14 @@
+# This migration comes from decidim_emitter (originally 20240417082337)
+class AddEmitterToDecidimParticipatoryProcess < ActiveRecord::Migration[6.1]
+ def up
+ # Ensure that the column is a string and check if it exists
+ add_column :decidim_participatory_processes, :emitter, :string, if_not_exists: true
+ change_column :decidim_participatory_processes, :emitter, :string
+
+ add_column :decidim_participatory_processes, :emitter_name, :text, if_not_exists: true
+ end
+
+ def down
+ remove_column :decidim_participatory_processes, :emitter_name, if_exists: true
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index b817eee201..4432bd4822 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.
-ActiveRecord::Schema.define(version: 2024_10_28_094242) do
+ActiveRecord::Schema.define(version: 2024_11_18_114335) do
# These are extensions that must be enabled in order to support this database
enable_extension "ltree"
@@ -1518,6 +1518,8 @@
t.float "longitude"
t.boolean "display_linked_assemblies", default: false
t.bigint "decidim_participatory_process_type_id"
+ t.string "emitter"
+ t.text "emitter_name"
t.index ["decidim_area_id"], name: "index_decidim_participatory_processes_on_decidim_area_id"
t.index ["decidim_organization_id", "slug"], name: "index_unique_process_slug_and_organization", unique: true
t.index ["decidim_organization_id"], name: "index_decidim_processes_on_decidim_organization_id"
diff --git a/spec/factories.rb b/spec/factories.rb
index febc0d8333..2c9271e1b1 100644
--- a/spec/factories.rb
+++ b/spec/factories.rb
@@ -4,6 +4,7 @@
require "decidim/proposals/test/factories"
require "decidim/budgets/test/factories"
require "decidim/debates/test/factories"
+require "decidim/emitter/test/factories"
require "decidim/meetings/test/factories"
require "decidim/accountability/test/factories"
require "decidim/system/test/factories"
diff --git a/spec/shared/manage_processes_examples.rb b/spec/shared/manage_processes_examples.rb
new file mode 100644
index 0000000000..b72c16f0a4
--- /dev/null
+++ b/spec/shared/manage_processes_examples.rb
@@ -0,0 +1,194 @@
+# frozen_string_literal: true
+
+shared_examples "manage processes examples" do
+ context "when viewing the processes list" do
+ let!(:process_group) { create(:participatory_process_group, organization: organization) }
+ let!(:process_with_group) { create(:participatory_process, organization: organization, participatory_process_group: process_group) }
+ let!(:process_without_group) { create(:participatory_process, organization: organization) }
+ let(:model_name) { participatory_process.class.model_name }
+ let(:resource_controller) { Decidim::ParticipatoryProcesses::Admin::ParticipatoryProcessesController }
+
+ def filter_by_group(group_title)
+ visit current_path
+ within(".card-title") do
+ click_button("Process Groups")
+ click_link(group_title)
+ end
+ end
+
+ it "allows the user to filter processes by process_group" do
+ filter_by_group(translated(process_group.title))
+
+ expect(page).to have_content(translated(process_with_group.title))
+ expect(page).not_to have_content(translated(process_without_group.title))
+ end
+
+ describe "listing processes" do
+ it_behaves_like "filtering collection by published/unpublished"
+ it_behaves_like "filtering collection by private/public"
+ end
+
+ context "when processes are filtered by process_group" do
+ before { filter_by_group(translated(process_group.title)) }
+
+ it "allows the user to edit the process_group" do
+ click_link translated(process_group.title)
+
+ expect(page).to have_content("Edit process group")
+ end
+
+ describe "listing processes filtered by group" do
+ it_behaves_like "filtering collection by published/unpublished" do
+ let!(:published_space) { process_with_group }
+ let!(:unpublished_space) { create(:participatory_process, :unpublished, organization: organization, participatory_process_group: process_group) }
+ end
+
+ it_behaves_like "filtering collection by private/public" do
+ let!(:public_space) { process_with_group }
+ let!(:private_space) { create(:participatory_process, :private, organization: organization, participatory_process_group: process_group) }
+ end
+ end
+ end
+ end
+
+ context "when previewing processes" do
+ context "when the process is unpublished" do
+ let!(:participatory_process) { create(:participatory_process, :unpublished, organization: organization) }
+
+ it "allows the user to preview the unpublished process" do
+ within find("tr", text: translated(participatory_process.title)) do
+ click_link "Preview"
+ end
+
+ expect(page).to have_css(".process-header")
+ expect(page).to have_content(translated(participatory_process.title))
+ end
+ end
+
+ context "when the process is published" do
+ let!(:participatory_process) { create(:participatory_process, organization: organization) }
+
+ it "allows the user to preview the published process" do
+ within find("tr", text: translated(participatory_process.title)) do
+ click_link "Preview"
+ end
+
+ expect(page).to have_current_path decidim_participatory_processes.participatory_process_path(participatory_process)
+ expect(page).to have_content(translated(participatory_process.title))
+ end
+ end
+ end
+
+ context "when viewing a missing process" do
+ it_behaves_like "a 404 page" do
+ let(:target_path) { decidim_admin_participatory_processes.participatory_process_path(99_999_999) }
+ end
+ end
+
+ context "when updating a participatory process" do
+ let(:image3_filename) { "city3.jpeg" }
+ let(:image3_path) { Decidim::Dev.asset(image3_filename) }
+
+ before do
+ click_link translated(participatory_process.title)
+ end
+
+ it "updates a participatory_process" do
+ fill_in_i18n(
+ :participatory_process_title,
+ "#participatory_process-title-tabs",
+ en: "My new title",
+ es: "Mi nuevo título",
+ ca: "El meu nou títol"
+ )
+ dynamically_attach_file(:participatory_process_banner_image, image3_path, remove_before: true)
+
+ page.execute_script("$('#participatory_process_end_date').focus()")
+ page.find(".datepicker-dropdown .day", text: "22").click
+
+ within ".edit_participatory_process" do
+ find("*[type=submit]").click
+ end
+
+ expect(page).to have_admin_callout("successfully")
+
+ within ".container" do
+ expect(page).to have_selector("input[value='My new title']")
+ expect(page).to have_css("img[src*='#{image3_filename}']")
+ end
+ end
+ end
+
+ context "when publishing a process" do
+ let!(:participatory_process) { create(:participatory_process, :unpublished, organization: organization) }
+
+ before do
+ click_link translated(participatory_process.title)
+ end
+
+ it "publishes the process" do
+ click_link "Publish"
+ expect(page).to have_content("successfully published")
+ expect(page).to have_content("Unpublish")
+ expect(page).to have_current_path decidim_admin_participatory_processes.edit_participatory_process_path(participatory_process)
+
+ participatory_process.reload
+ expect(participatory_process).to be_published
+ end
+ end
+
+ context "when unpublishing a process" do
+ let!(:participatory_process) { create(:participatory_process, organization: organization) }
+
+ before do
+ click_link translated(participatory_process.title)
+ end
+
+ it "unpublishes the process" do
+ click_link "Unpublish"
+ expect(page).to have_content("successfully unpublished")
+ expect(page).to have_content("Publish")
+ expect(page).to have_current_path decidim_admin_participatory_processes.edit_participatory_process_path(participatory_process)
+
+ participatory_process.reload
+ expect(participatory_process).not_to be_published
+ end
+ end
+
+ context "when there are multiple organizations in the system" do
+ let!(:external_participatory_process) { create(:participatory_process) }
+
+ before do
+ visit decidim_admin_participatory_processes.participatory_processes_path
+ end
+
+ it "doesn't let the admin manage processes form other organizations" do
+ within "table" do
+ expect(page).to have_no_content(external_participatory_process.title["en"])
+ end
+ end
+ end
+
+ context "when the process has a scope" do
+ let(:scope) { create(:scope, organization: organization) }
+
+ before do
+ participatory_process.update!(scopes_enabled: true, scope: scope)
+ end
+
+ it "disables the scope for a participatory process" do
+ click_link translated(participatory_process.title)
+
+ uncheck :participatory_process_scopes_enabled
+
+ expect(page).to have_selector("#participatory_process_scope_id.disabled")
+ expect(page).to have_selector("#participatory_process_scope_id .picker-values div input[disabled]", visible: :all)
+
+ within ".edit_participatory_process" do
+ find("*[type=submit]").click
+ end
+
+ expect(page).to have_admin_callout("successfully")
+ end
+ end
+end
diff --git a/spec/shared/participatory_process_administration_by_admin_shared_context.rb b/spec/shared/participatory_process_administration_by_admin_shared_context.rb
new file mode 100644
index 0000000000..014fd52a16
--- /dev/null
+++ b/spec/shared/participatory_process_administration_by_admin_shared_context.rb
@@ -0,0 +1,8 @@
+# frozen_string_literal: true
+
+shared_context "when admin administrating a participatory process" do
+ let!(:user) do
+ create(:user, :admin, :confirmed, organization: organization)
+ end
+ include_context "when administrating a participatory process"
+end
diff --git a/spec/shared/participatory_process_administration_shared_context.rb b/spec/shared/participatory_process_administration_shared_context.rb
new file mode 100644
index 0000000000..ff0cc89db9
--- /dev/null
+++ b/spec/shared/participatory_process_administration_shared_context.rb
@@ -0,0 +1,6 @@
+# frozen_string_literal: true
+
+shared_context "when administrating a participatory process" do
+ let(:organization) { create(:organization) }
+ let!(:participatory_process) { create(:participatory_process, organization: organization) }
+end
diff --git a/spec/system/admin/admin_manages_participatory_processes_spec.rb b/spec/system/admin/admin_manages_participatory_processes_spec.rb
new file mode 100644
index 0000000000..ec97e30dbb
--- /dev/null
+++ b/spec/system/admin/admin_manages_participatory_processes_spec.rb
@@ -0,0 +1,560 @@
+# frozen_string_literal: true
+
+require "spec_helper"
+require "decidim/core/test/shared_examples/has_contextual_help"
+
+describe "Participatory Processes", type: :system do
+ let(:organization) { create(:organization) }
+ let(:show_metrics) { true }
+ let(:show_statistics) { true }
+ let(:hashtag) { true }
+ let(:base_description) { { en: "Description", ca: "Descripció", es: "Descripción" } }
+ let(:short_description) { { en: "Short description", ca: "Descripció curta", es: "Descripción corta" } }
+ let(:base_process) do
+ create(
+ :participatory_process,
+ :active,
+ organization: organization,
+ description: base_description,
+ short_description: short_description,
+ show_metrics: show_metrics,
+ show_statistics: show_statistics
+ )
+ end
+
+ before do
+ switch_to_host(organization.host)
+ end
+
+ context "when there are no processes and directly accessing form URL" do
+ it_behaves_like "a 404 page" do
+ let(:target_path) { decidim_participatory_processes.participatory_processes_path }
+ end
+ end
+
+ context "when there are no processes and accessing from the homepage" do
+ it "does not show the menu link" do
+ visit decidim.root_path
+
+ within ".main-nav" do
+ expect(page).to have_no_content("Processes")
+ end
+ end
+ end
+
+ context "when the process does not exist" do
+ it_behaves_like "a 404 page" do
+ let(:target_path) { decidim_participatory_processes.participatory_process_path(99_999_999) }
+ end
+ end
+
+ context "when there are some processes and all are unpublished" do
+ before do
+ create(:participatory_process, :unpublished, organization: organization)
+ create(:participatory_process, :published)
+ end
+
+ context "and directly accessing from URL" do
+ it_behaves_like "a 404 page" do
+ let(:target_path) { decidim_participatory_processes.participatory_processes_path }
+ end
+ end
+
+ context "and accessing from the homepage" do
+ it "the menu link is not shown" do
+ visit decidim.root_path
+
+ within ".main-nav" do
+ expect(page).to have_no_content("Processes")
+ end
+ end
+ end
+ end
+
+ context "when there are some published processes" do
+ let!(:participatory_process) { base_process }
+ let!(:promoted_process) { create(:participatory_process, :promoted, organization: organization) }
+ let!(:unpublished_process) { create(:participatory_process, :unpublished, organization: organization) }
+ let!(:past_process) { create :participatory_process, :past, organization: organization }
+ let!(:upcoming_process) { create :participatory_process, :upcoming, organization: organization }
+ let!(:grouped_process) { create :participatory_process, organization: organization }
+ let!(:group) { create :participatory_process_group, participatory_processes: [grouped_process], organization: organization }
+
+ it_behaves_like "shows contextual help" do
+ let(:index_path) { decidim_participatory_processes.participatory_processes_path }
+ let(:manifest_name) { :participatory_processes }
+ end
+
+ it_behaves_like "editable content for admins" do
+ let(:target_path) { decidim_participatory_processes.participatory_processes_path }
+ end
+
+ context "when requesting the processes path" do
+ before do
+ visit decidim_participatory_processes.participatory_processes_path
+ end
+
+ it_behaves_like "accessible page"
+
+ context "when emitter is defined", :slow do
+ context "when no emitter" do
+ it "doesn't displays logo or text" do
+ within "#participatory_process_#{promoted_process.id}" do
+ expect(page).not_to have_css(".emitter-header")
+ end
+ end
+ end
+
+ context "when emitter" do
+ let(:base_process) do
+ create(
+ :participatory_process,
+ :active,
+ :with_emitter,
+ organization: organization,
+ description: { en: "Description", ca: "Descripció", es: "Descripción" },
+ short_description: { en: "Short description", ca: "Descripció curta", es: "Descripción corta" },
+ show_metrics: show_metrics,
+ show_statistics: show_statistics,
+ developer_group: { en: "Developer group" }
+ )
+ end
+
+ it "displays logo and text" do
+ within "#participatory_process_#{base_process.id}" do
+ within ".emitter-header" do
+ expect(page).to have_css("img", count: 1)
+ expect(page).to have_content("Consultation published by Developer group")
+ end
+ end
+ end
+ end
+ end
+
+ context "and accessing from the homepage" do
+ it "the menu link is not shown" do
+ visit decidim.root_path
+
+ within ".main-nav" do
+ expect(page).to have_content("Processes")
+ click_link "Processes"
+ end
+
+ expect(page).to have_current_path decidim_participatory_processes.participatory_processes_path
+ end
+ end
+
+ context "with highlighted processes" do
+ before do
+ promoted_process.title["en"] = "D'Artagnan #{promoted_process.title["en"]}"
+ promoted_process.save!
+ visit decidim_participatory_processes.participatory_processes_path
+ end
+
+ it_behaves_like "accessible page"
+
+ context "when emitter is defined", :slow do
+ context "when no emitter" do
+ it "doesn't displays logo or text" do
+ within "#participatory_process_#{promoted_process.id}" do
+ expect(page).not_to have_css(".emitter-header")
+ end
+ end
+ end
+
+ context "when emitter" do
+ let(:base_process) do
+ create(
+ :participatory_process,
+ :active,
+ :with_emitter,
+ organization: organization,
+ description: { en: "Description", ca: "Descripció", es: "Descripción" },
+ short_description: { en: "Short description", ca: "Descripció curta", es: "Descripción corta" },
+ show_metrics: show_metrics,
+ show_statistics: show_statistics,
+ developer_group: { en: "Developer group" }
+ )
+ end
+
+ it "displays logo and text" do
+ within "#participatory_process_#{base_process.id}" do
+ within ".emitter-header" do
+ expect(page).to have_css("img", count: 1)
+ expect(page).to have_content("Consultation published by Developer group")
+ end
+ end
+ end
+ end
+
+ it "lists all the highlighted processes" do
+ within "#highlighted-processes" do
+ expect(page).to have_content(translated(promoted_process.title, locale: :en))
+ expect(page).to have_selector(".card--full", count: 1)
+ end
+ end
+ end
+
+ it "lists the active processes" do
+ within "#processes-grid" do
+ within "#processes-grid h3" do
+ expect(page).to have_content("3 ACTIVE PROCESSES")
+ end
+
+ expect(page).to have_content(translated(participatory_process.title, locale: :en))
+ expect(page).to have_content(translated(promoted_process.title, locale: :en))
+ expect(page).to have_content(translated(group.title, locale: :en))
+ expect(page).to have_selector(".card", count: 3)
+
+ expect(page).to have_no_content(translated(unpublished_process.title, locale: :en))
+ expect(page).to have_no_content(translated(past_process.title, locale: :en))
+ expect(page).to have_no_content(translated(upcoming_process.title, locale: :en))
+ expect(page).to have_no_content(translated(grouped_process.title, locale: :en))
+ end
+ end
+
+ it "links to the individual process page" do
+ first(".card__link", text: translated(participatory_process.title, locale: :en)).click
+
+ expect(page).to have_current_path decidim_participatory_processes.participatory_process_path(participatory_process)
+ end
+
+ context "with active steps" do
+ let!(:step) { create(:participatory_process_step, participatory_process: participatory_process) }
+ let!(:active_step) do
+ create(:participatory_process_step,
+ :active,
+ participatory_process: participatory_process,
+ title: { en: "Active step", ca: "Fase activa", es: "Fase activa" })
+ end
+
+ it "links to the active step" do
+ visit decidim_participatory_processes.participatory_processes_path
+
+ within find("#processes-grid .column", text: translated(participatory_process.title)) do
+ within ".card__footer" do
+ expect(page).to have_content("Current phase:\nActive step")
+ end
+ end
+ end
+
+ context "when the active step has CTA text and url set" do
+ let(:cta_path) { "my_path" }
+ let(:cta_text) { { en: "Take action!", ca: "Take action!", es: "Take action!" } }
+
+ before do
+ active_step.update!(cta_path: cta_path, cta_text: cta_text)
+ end
+
+ it "shows a CTA button" do
+ visit decidim_participatory_processes.participatory_processes_path
+
+ within "#participatory_process_#{participatory_process.id}" do
+ expect(page).to have_link("Take action!")
+ end
+ end
+
+ context "when cta_text is empty in current locale" do
+ let(:cta_text) { { en: "", ca: "Take action!", es: "Take action!" } }
+
+ it "displays the regular cta button" do
+ visit decidim_participatory_processes.participatory_processes_path
+
+ within "#participatory_process_#{participatory_process.id}" do
+ expect(page).not_to have_link("Take action!")
+ expect(page).to have_link("More info")
+ end
+ end
+ end
+
+ context "when process is promoted" do
+ let(:cta_text) { { en: "Take promoted action!", ca: "Take promoted action!", es: "Take promoted action!" } }
+ let!(:active_step) do
+ create(:participatory_process_step,
+ :active,
+ participatory_process: promoted_process,
+ title: { en: "Active step", ca: "Fase activa", es: "Fase activa" })
+ end
+
+ it "shows a CTA button" do
+ visit decidim_participatory_processes.participatory_processes_path
+
+ within "#highlighted-processes" do
+ expect(page).to have_link("Take promoted action!")
+ end
+ end
+ end
+
+ context "when user switch locale" do
+ before do
+ visit decidim_participatory_processes.participatory_processes_path
+ within_language_menu do
+ click_link "Català"
+ end
+ end
+
+ it "displays the regular cta button" do
+ within "#participatory_process_#{participatory_process.id}" do
+ expect(page).to have_link("Take action!", href: "/processes/#{participatory_process.slug}/my_path")
+ end
+ end
+ end
+ end
+ end
+
+ context "when there are promoted participatory process groups" do
+ let!(:promoted_group) { create(:participatory_process_group, :promoted, :with_participatory_processes, organization: organization) }
+ let(:promoted_items_titles) { page.all("#highlighted-processes .card__title").map(&:text) }
+
+ before do
+ promoted_group.title["en"] = "D'Artagnan #{promoted_group.title["en"]}"
+ promoted_group.save!
+ visit decidim_participatory_processes.participatory_processes_path
+ end
+
+ it "shows a highligted processes section" do
+ expect(page).to have_content("HIGHLIGHTED PROCESSES")
+ end
+
+ it "lists only promoted groups" do
+ expect(promoted_items_titles).to include(translated(promoted_group.title, locale: :en))
+ expect(promoted_items_titles).not_to include(translated(group.title, locale: :en))
+ end
+
+ it "lists all the highlighted process groups" do
+ within "#highlighted-processes" do
+ expect(page).to have_content(translated(promoted_group.title, locale: :en))
+ expect(page).to have_selector(".card--full", count: 2)
+ end
+ end
+
+ context "and promoted group has defined a CTA content block" do
+ let(:cta_settings) do
+ {
+ button_url: "https://example.org/action",
+ button_text_en: "cta text",
+ description_en: "cta description"
+ }
+ end
+
+ before do
+ create(
+ :content_block,
+ organization: organization,
+ scope_name: :participatory_process_group_homepage,
+ scoped_resource_id: promoted_group.id,
+ manifest_name: :cta,
+ settings: cta_settings
+ )
+ visit decidim_participatory_processes.participatory_processes_path
+ end
+
+ it "shows a CTA button inside group card" do
+ within("#highlighted-processes") do
+ expect(page).to have_link(cta_settings[:button_text_en], href: cta_settings[:button_url])
+ end
+ end
+
+ context "and promoted group belongs to another organization" do
+ let!(:promoted_group) { create(:participatory_process_group, :promoted, :with_participatory_processes) }
+
+ it "shows a CTA button inside group card" do
+ within("#highlighted-processes") do
+ expect(page).not_to have_link(cta_settings[:button_text_en], href: cta_settings[:button_url])
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+
+ context "when going to the participatory process page" do
+ let!(:participatory_process) { base_process }
+ let!(:proposals_component) { create(:extended_proposal_component, :published, participatory_space: participatory_process, manifest_name: :proposals) }
+ let!(:meetings_component) { create(:component, :unpublished, participatory_space: participatory_process, manifest_name: :meetings) }
+
+ before do
+ create_list(:extended_proposal, 3, component: proposals_component)
+ allow(Decidim).to receive(:component_manifests).and_return([proposals_component.manifest, meetings_component.manifest])
+ end
+
+ it_behaves_like "editable content for admins" do
+ let(:target_path) { decidim_participatory_processes.participatory_process_path(participatory_process) }
+ end
+
+ context "when requesting the participatory process path" do
+ before do
+ visit decidim_participatory_processes.participatory_process_path(participatory_process)
+ end
+
+ context "when requesting the process path" do
+ it "shows the details of the given process" do
+ within "main" do
+ expect(page).to have_content(translated(participatory_process.title, locale: :en))
+ expect(page).to have_content(translated(participatory_process.subtitle, locale: :en))
+ expect(page).to have_content(translated(participatory_process.description, locale: :en))
+ expect(page).to have_content(translated(participatory_process.short_description, locale: :en))
+ expect(page).to have_content(translated(participatory_process.meta_scope, locale: :en))
+ expect(page).to have_content(translated(participatory_process.developer_group, locale: :en))
+ expect(page).to have_content(translated(participatory_process.local_area, locale: :en))
+ expect(page).to have_content(translated(participatory_process.target, locale: :en))
+ expect(page).to have_content(translated(participatory_process.participatory_scope, locale: :en))
+ expect(page).to have_content(translated(participatory_process.participatory_structure, locale: :en))
+ expect(page).to have_content(I18n.l(participatory_process.end_date, format: :long))
+ expect(page).to have_content(participatory_process.hashtag)
+ end
+ end
+
+ it_behaves_like "has attachments" do
+ let(:attached_to) { participatory_process }
+ end
+
+ it_behaves_like "has attachment collections" do
+ let(:attached_to) { participatory_process }
+ let(:collection_for) { participatory_process }
+ end
+
+ context "and it belongs to a group" do
+ let!(:group) { create :participatory_process_group, participatory_processes: [participatory_process], organization: organization }
+
+ it "has a link to the group the process belongs to" do
+ visit decidim_participatory_processes.participatory_process_path(participatory_process)
+
+ expect(page).to have_link(translated(group.title, locale: :en), href: decidim_participatory_processes.participatory_process_group_path(group))
+ end
+ end
+
+ context "when it has some linked processes" do
+ let(:published_process) { create :participatory_process, :published, organization: organization }
+ let(:unpublished_process) { create :participatory_process, :unpublished, organization: organization }
+
+ it "only shows the published linked processes" do
+ participatory_process
+ .link_participatory_space_resources(
+ [published_process, unpublished_process],
+ "related_processes"
+ )
+ visit decidim_participatory_processes.participatory_process_path(participatory_process)
+ expect(page).to have_content(translated(published_process.title))
+ expect(page).to have_no_content(translated(unpublished_process.title))
+ end
+ end
+
+ context "and the process has some components" do
+ it "shows the components" do
+ within ".process-nav" do
+ expect(page).to have_content(translated(proposals_component.name, locale: :en).upcase)
+ expect(page).to have_no_content(translated(meetings_component.name, locale: :en).upcase)
+ end
+ end
+
+ context "and the process metrics are enabled" do
+ let(:organization) { create(:organization) }
+ let(:metrics) do
+ Decidim.metrics_registry.filtered(highlight: true, scope: "participatory_process").each do |metric_registry|
+ create(:metric, metric_type: metric_registry.metric_name, day: Time.zone.today - 1.week, organization: organization, participatory_space_type: Decidim::ParticipatoryProcess.name, participatory_space_id: participatory_process.id, cumulative: 5, quantity: 2)
+ end
+ end
+
+ before do
+ metrics
+ visit current_path
+ end
+
+ it "shows the metrics charts" do
+ expect(page).to have_css("h3.section-heading", text: "METRICS")
+
+ within "#metrics" do
+ expect(page).to have_css("input#metrics-space_type[value='Decidim::ParticipatoryProcess']", visible: :hidden)
+ expect(page).to have_css("input#metrics-space_id[value='#{participatory_process.id}']", visible: :hidden)
+ Decidim.metrics_registry.filtered(highlight: true, scope: "participatory_process").each do |metric_registry|
+ expect(page).to have_css(%(##{metric_registry.metric_name}_chart))
+ end
+ end
+ end
+
+ it "renders a link to all metrics" do
+ within "#metrics" do
+ expect(page).to have_link("Show all metrics")
+ end
+ end
+
+ it "click link" do
+ click_link("Show all metrics")
+ have_current_path(decidim_participatory_processes.all_metrics_participatory_process_path(participatory_process))
+ end
+ end
+
+ context "and the process statistics are enabled" do
+ let(:show_statistics) { true }
+
+ it "the stats for those components are visible" do
+ within ".section-statistics" do
+ expect(page).to have_css("h3.section-heading", text: "STATISTICS")
+ expect(page).to have_css(".statistic__title", text: "PROPOSALS")
+ expect(page).to have_css(".statistic__number", text: "3")
+ expect(page).to have_no_css(".statistic__title", text: "MEETINGS")
+ expect(page).to have_no_css(".statistic__number", text: "0")
+ end
+ end
+ end
+
+ context "and the process statistics are not enabled" do
+ let(:show_statistics) { false }
+
+ it "the stats for those components are not visible" do
+ expect(page).to have_no_css("h3.section-heading", text: "STATISTICS")
+ expect(page).to have_no_css(".statistic__title", text: "PROPOSALS")
+ expect(page).to have_no_css(".statistic__number", text: "3")
+ end
+ end
+
+ context "and the process metrics are not enabled" do
+ let(:show_metrics) { false }
+
+ it "the metrics for the participatory processes are not rendered" do
+ expect(page).to have_no_css("h4.section-heading", text: "METRICS")
+ end
+
+ it "has no link to all metrics" do
+ expect(page).to have_no_link("Show all metrics")
+ end
+ end
+
+ context "and the process doesn't have hashtag" do
+ let(:hashtag) { false }
+
+ it "the hashtags for those components are not visible" do
+ expect(page).to have_no_content("#")
+ end
+ end
+ end
+
+ context "when assemblies are linked to participatory process" do
+ let!(:published_assembly) { create(:assembly, :published, organization: organization) }
+ let!(:unpublished_assembly) { create(:assembly, :unpublished, organization: organization) }
+ let!(:private_assembly) { create(:assembly, :published, :private, :opaque, organization: organization) }
+ let!(:transparent_assembly) { create(:assembly, :published, :private, :transparent, organization: organization) }
+
+ before do
+ published_assembly.link_participatory_space_resources(participatory_process, "included_participatory_processes")
+ unpublished_assembly.link_participatory_space_resources(participatory_process, "included_participatory_processes")
+ private_assembly.link_participatory_space_resources(participatory_process, "included_participatory_processes")
+ transparent_assembly.link_participatory_space_resources(participatory_process, "included_participatory_processes")
+ visit decidim_participatory_processes.participatory_process_path(participatory_process)
+ end
+
+ it "display related assemblies" do
+ expect(page).to have_content("RELATED ASSEMBLIES")
+ expect(page).to have_content(translated(published_assembly.title))
+ expect(page).to have_content(translated(transparent_assembly.title))
+ expect(page).to have_no_content(translated(unpublished_assembly.title))
+ expect(page).to have_no_content(translated(private_assembly.title))
+ end
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/spec/system/participatory_processes_spec.rb b/spec/system/participatory_processes_spec.rb
index cacfdff136..f635bb873b 100644
--- a/spec/system/participatory_processes_spec.rb
+++ b/spec/system/participatory_processes_spec.rb
@@ -94,6 +94,41 @@
it_behaves_like "accessible page"
+ context "when emitter is defined", :slow do
+ context "when no emitter" do
+ it "doesn't displays logo or text" do
+ within "#participatory_process_#{promoted_process.id}" do
+ expect(page).not_to have_css(".emitter-header")
+ end
+ end
+ end
+
+ context "when emitter" do
+ let(:base_process) do
+ create(
+ :participatory_process,
+ :active,
+ :with_emitter,
+ organization: organization,
+ description: { en: "Description", ca: "Descripció", es: "Descripción" },
+ short_description: { en: "Short description", ca: "Descripció curta", es: "Descripción corta" },
+ show_metrics: show_metrics,
+ show_statistics: show_statistics,
+ developer_group: { en: "Developer group" }
+ )
+ end
+
+ it "displays logo and text" do
+ within "#participatory_process_#{base_process.id}" do
+ within ".emitter-header" do
+ expect(page).to have_css("img", count: 1)
+ expect(page).to have_content("Consultation published by Developer group")
+ end
+ end
+ end
+ end
+ end
+
context "and accessing from the homepage" do
it "the menu link is not shown" do
visit decidim.root_path
@@ -116,6 +151,41 @@
it_behaves_like "accessible page"
+ context "when emitter is defined", :slow do
+ context "when no emitter" do
+ it "doesn't displays logo or text" do
+ within "#participatory_process_#{promoted_process.id}" do
+ expect(page).not_to have_css(".emitter-header")
+ end
+ end
+ end
+
+ context "when emitter" do
+ let(:base_process) do
+ create(
+ :participatory_process,
+ :active,
+ :with_emitter,
+ organization: organization,
+ description: { en: "Description", ca: "Descripció", es: "Descripción" },
+ short_description: { en: "Short description", ca: "Descripció curta", es: "Descripción corta" },
+ show_metrics: show_metrics,
+ show_statistics: show_statistics,
+ developer_group: { en: "Developer group" }
+ )
+ end
+
+ it "displays logo and text" do
+ within "#participatory_process_#{base_process.id}" do
+ within ".emitter-header" do
+ expect(page).to have_css("img", count: 1)
+ expect(page).to have_content("Consultation published by Developer group")
+ end
+ end
+ end
+ end
+ end
+
it "lists all the highlighted processes" do
within "#highlighted-processes" do
expect(page).to have_content(translated(promoted_process.title, locale: :en))