Cross-site scripting (XSS) in the decidim admin activity log
Description
decidim is a Free Open-Source participatory democracy, citizen participation and open government for cities and organizations. The admin panel is subject to potential Cross-site scripting (XSS) attach in case an admin assigns a valuator to a proposal, or does any other action that generates an admin activity log where one of the resources has an XSS crafted. This issue has been addressed in release version 0.27.7, 0.28.2, and newer. Users are advised to upgrade. Users unable to upgrade may redirect the pages /admin and /admin/logs to other admin pages to prevent this access (i.e. /admin/organization/edit).
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
decidim-adminRubyGems | < 0.27.7 | 0.27.7 |
decidim-adminRubyGems | >= 0.28.0, < 0.28.2 | 0.28.2 |
Affected products
1Patches
49d79f09a2d38Backport 'Refactor malformed titles in admin logs (part 2)' to v0.27 (#13085)
22 files changed · +245 −133
decidim-admin/lib/decidim/admin/test/manage_attachment_collections_examples.rb+12 −11 modified@@ -2,6 +2,7 @@ shared_examples "manage attachment collections examples" do let!(:attachment_collection) { create(:attachment_collection, collection_for: collection_for) } + let(:attributes) { attributes_for(:attachment_collection) } before do visit current_path @@ -30,17 +31,13 @@ fill_in_i18n( :attachment_collection_name, "#attachment_collection-name-tabs", - en: "Application forms", - es: "Formularios de solicitud", - ca: "Formularis de sol·licitud" + **attributes[:name].except("machine_translations") ) fill_in_i18n( :attachment_collection_description, "#attachment_collection-description-tabs", - en: "Contains the application forms", - es: "Contiene los formularios de solicitud", - ca: "Conté els formularis de sol·licitud" + **attributes[:description].except("machine_translations") ) find("*[type=submit]").click @@ -49,8 +46,11 @@ expect(page).to have_admin_callout("successfully") within "#attachment_collections table" do - expect(page).to have_link("Application forms") + expect(page).to have_content(translated(attributes[:name])) end + + visit decidim_admin.root_path + expect(page).to have_content("created the #{translated(attributes[:name])} attachment collection") end it "can update an attachment collection" do @@ -64,9 +64,7 @@ fill_in_i18n( :attachment_collection_name, "#attachment_collection-name-tabs", - en: "Latest application forms", - es: "Últimos formularios de solicitud", - ca: "Últims formularis de sol·licitud" + **attributes[:name].except("machine_translations") ) find("*[type=submit]").click @@ -75,8 +73,11 @@ expect(page).to have_admin_callout("successfully") within "#attachment_collections table" do - expect(page).to have_link("Latest application forms") + expect(page).to have_content(translated(attributes[:name])) end + + visit decidim_admin.root_path + expect(page).to have_content("updated the #{translated(attributes[:name])} attachment collection") end context "when deleting a attachment collection" do
decidim-admin/lib/decidim/admin/test/manage_categories_examples.rb+11 −8 modified@@ -1,6 +1,7 @@ # frozen_string_literal: true shared_examples "manage categories examples" do + let(:attributes) { attributes_for(:category) } it "lists all the categories for the process" do within "#categories table" do expect(page).to have_content(translated(category.name, locale: :en)) @@ -25,9 +26,7 @@ fill_in_i18n( :category_name, "#category-name-tabs", - en: "My category", - es: "Mi categoría", - ca: "La meva categoria" + **attributes[:name].except("machine_translations") ) find("*[type=submit]").click @@ -36,8 +35,11 @@ expect(page).to have_admin_callout("successfully") within "#categories table" do - expect(page).to have_content("My category") + expect(page).to have_content(translated(attributes[:name])) end + + visit decidim_admin.root_path + expect(page).to have_content("added the #{translated(attributes[:name])} category to the") end it "updates a category" do @@ -51,9 +53,7 @@ fill_in_i18n( :category_name, "#category-name-tabs", - en: "My new name", - es: "Mi nuevo nombre", - ca: "El meu nou nom" + **attributes[:name].except("machine_translations") ) find("*[type=submit]").click @@ -62,8 +62,11 @@ expect(page).to have_admin_callout("successfully") within "#categories table" do - expect(page).to have_content("My new name") + expect(page).to have_content(translated(attributes[:name])) end + + visit decidim_admin.root_path + expect(page).to have_content("updated the #{translated(attributes[:name])} category in the") end context "when deleting a category" do
decidim-admin/lib/decidim/admin/test/manage_moderations_examples.rb+0 −9 modified@@ -77,15 +77,6 @@ expect(page).to have_admin_callout("Resource successfully unreported") end - it "user can hide a resource" do - within "tr[data-id=\"#{moderation.id}\"]" do - click_link "Hide" - end - - expect(page).to have_admin_callout("Resource successfully hidden") - expect(page).to have_no_content(moderation.reportable.reported_content_url) - end - it "user can sort by report count" do moderations.each_with_index { |moderation, index| moderation.update(report_count: index + 1) } moderations_ordered_by_report_count_asc = moderations.sort_by(&:report_count)
decidim-admin/spec/system/admin_manage_moderated_users_spec.rb+22 −0 modified@@ -176,5 +176,27 @@ it_behaves_like "a paginated collection", url: true end + + context "when the user is blocked" do + let!(:first_user) { create(:user, :confirmed, organization: organization) } + + before do + visit decidim_admin.moderated_users_path + end + + it "displays the proper log" do + within find("tr", text: first_user.name) do + click_link "Block" + end + fill_in :block_user_justification, with: "This user is a spammer" * 2 # to have at least 15 chars + + click_on I18n.t("decidim.admin.block_user.new.action") + + expect(first_user.reload).to be_blocked + + visit decidim_admin.root_path + expect(page).to have_content("blocked user") + end + end end end
decidim-admin/spec/system/admin_manages_global_moderations_spec.rb+12 −0 modified@@ -28,6 +28,18 @@ it_behaves_like "manage moderations" do let(:moderations_link_text) { "Global moderations" } + + it "user can hide a resource" do + within "tr[data-id=\"#{moderation.id}\"]" do + click_link "Hide" + end + + expect(page).to have_admin_callout("Resource successfully hidden") + expect(page).to have_no_content(moderation.reportable.reported_content_url) + + visit decidim_admin.root_path + expect(page).to have_content("hid a resource of type") + end end it_behaves_like "sorted moderations" do
decidim-admin/spec/system/admin_manages_help_sections_spec.rb+3 −0 modified@@ -30,6 +30,9 @@ help_content = Decidim::ContextualHelpSection.find_content(organization, :participatory_processes) expect(help_content).to include("en" => "<p>Well hello!</p>") + + visit decidim_admin.root_path + expect(page).to have_content("updated the Participatory processes help section") end it "destroys the section when it is empty" do
decidim-admin/spec/system/admin_manages_newsletters_spec.rb+11 −8 modified@@ -7,6 +7,7 @@ describe "Admin manages newsletters", type: :system do let(:organization) { create(:organization) } + let!(:attributes) { attributes_for(:newsletter, organization: organization) } let(:user) { create(:user, :admin, :confirmed, name: "Sarah Kerrigan", organization: organization) } let!(:deliverable_users) { create_list(:user, 5, :confirmed, newsletter_notifications_at: Time.current, organization: organization) } @@ -43,9 +44,7 @@ fill_in_i18n( :newsletter_subject, "#newsletter-subject-tabs", - en: "A fancy newsletter for %{name}", - es: "Un correo electrónico muy chulo para %{name}", - ca: "Un correu electrònic flipant per a %{name}" + **attributes[:subject].except("machine_translations") ) fill_in_i18n_editor( @@ -84,7 +83,10 @@ end expect(page).to have_content("Preview") - expect(page).to have_content("A fancy newsletter for #{user.name}") + expect(page).to have_content(translated(attributes[:subject])) + + visit decidim_admin.root_path + expect(page).to have_content("created the #{translated(attributes[:subject])} newsletter") end end @@ -128,9 +130,7 @@ fill_in_i18n( :newsletter_subject, "#newsletter-subject-tabs", - en: "A fancy newsletter", - es: "Un correo electrónico muy chulo", - ca: "Un correu electrònic flipant" + **attributes[:subject].except("machine_translations") ) fill_in_i18n_editor( @@ -145,7 +145,10 @@ end expect(page).to have_content("Preview") - expect(page).to have_content("A fancy newsletter") + expect(page).to have_content(translated(attributes[:subject])) + + visit decidim_admin.root_path + expect(page).to have_content("updated the #{translated(attributes[:subject])} newsletter") end end
decidim-admin/spec/system/admin_manages_organization_areas_spec.rb+11 −8 modified@@ -7,6 +7,7 @@ let(:admin) { create :user, :admin, :confirmed } let(:organization) { admin.organization } + let(:attributes) { attributes_for(:area) } before do switch_to_host(organization.host) @@ -26,9 +27,7 @@ click_link "Add" within ".new_area" do - fill_in_i18n :area_name, "#area-name-tabs", en: "My area", - es: "Mi area", - ca: "La meva area" + fill_in_i18n :area_name, "#area-name-tabs", **attributes[:name].except("machine_translations") select area_type.name["en"], from: :area_area_type_id find("*[type=submit]").click @@ -37,8 +36,11 @@ expect(page).to have_admin_callout("successfully") within "table" do - expect(page).to have_content("My area") + expect(page).to have_content(translated(attributes[:name])) end + + visit decidim_admin.root_path + expect(page).to have_content("created the #{translated(attributes[:name])} area") end context "with existing areas" do @@ -61,17 +63,18 @@ end within ".edit_area" do - fill_in_i18n :area_name, "#area-name-tabs", en: "Another area", - es: "Otra area", - ca: "Una altra area" + fill_in_i18n :area_name, "#area-name-tabs", **attributes[:name].except("machine_translations") find("*[type=submit]").click end expect(page).to have_admin_callout("successfully") within "table" do - expect(page).to have_content("Another area") + expect(page).to have_content(translated(attributes[:name])) end + + visit decidim_admin.root_path + expect(page).to have_content("updated the #{translated(attributes[:name])} area") end it "can delete them" do
decidim-admin/spec/system/admin_manages_organization_area_types_spec.rb+13 −10 modified@@ -5,6 +5,7 @@ describe "Admin manages area types", type: :system do let(:admin) { create :user, :admin, :confirmed } let(:organization) { admin.organization } + let(:attributes) { attributes_for(:area_type) } before do switch_to_host(organization.host) @@ -23,17 +24,13 @@ fill_in_i18n( :area_type_name, "#area_type-name-tabs", - en: "Sectorial en", - es: "Sectorial es", - ca: "Sectorial ca" + **attributes[:name].except("machine_translations") ) fill_in_i18n( :area_type_plural, "#area_type-plural-tabs", - en: "Sectorials en", - es: "Sectoriales es", - ca: "Sectorials ca" + **attributes[:plural].except("machine_translations") ) find("*[type=submit]").click @@ -42,8 +39,11 @@ expect(page).to have_admin_callout("successfully") within "table" do - expect(page).to have_content("Sectorial en") + expect(page).to have_content(translated(attributes[:name])) end + + visit decidim_admin.root_path + expect(page).to have_content("created the #{translated(attributes[:name])} area type") end context "with existing area_types" do @@ -68,22 +68,25 @@ fill_in_i18n( :area_type_name, "#area_type-name-tabs", - en: "Not Sectorial en" + **attributes[:name].except("machine_translations") ) fill_in_i18n( :area_type_plural, "#area_type-plural-tabs", - en: "This is the new pluarl" + **attributes[:plural].except("machine_translations") ) find("*[type=submit]").click end expect(page).to have_admin_callout("successfully") within "table" do - expect(page).to have_content("Not Sectorial en") + expect(page).to have_content(translated(attributes[:name])) end + + visit decidim_admin.root_path + expect(page).to have_content("updated the #{translated(attributes[:name])} area type") end it "can delete them" do
decidim-admin/spec/system/admin_manages_organization_scopes_spec.rb+11 −8 modified@@ -7,6 +7,7 @@ let(:admin) { create :user, :admin, :confirmed } let(:organization) { admin.organization } + let!(:attributes) { attributes_for(:scope) } before do switch_to_host(organization.host) @@ -26,9 +27,7 @@ click_link "Add" within ".new_scope" do - fill_in_i18n :scope_name, "#scope-name-tabs", en: "My nice district", - es: "Mi lindo distrito", - ca: "El meu bonic barri" + fill_in_i18n :scope_name, "#scope-name-tabs", **attributes[:name].except("machine_translations") fill_in "Code", with: "MY-DISTRICT" select scope_type.name["en"], from: :scope_scope_type_id @@ -38,8 +37,11 @@ expect(page).to have_admin_callout("successfully") within "table" do - expect(page).to have_content("My nice district") + expect(page).to have_content(translated(attributes[:name])) end + + visit decidim_admin.root_path + expect(page).to have_content("created the #{translated(attributes[:name])} scope") end context "with existing scopes" do @@ -55,17 +57,18 @@ end within ".edit_scope" do - fill_in_i18n :scope_name, "#scope-name-tabs", en: "Another district", - es: "Otro distrito", - ca: "Un altre districte" + fill_in_i18n :scope_name, "#scope-name-tabs", **attributes[:name].except("machine_translations") find("*[type=submit]").click end expect(page).to have_admin_callout("successfully") within "table" do - expect(page).to have_content("Another district") + expect(page).to have_content(translated(attributes[:name])) end + + visit decidim_admin.root_path + expect(page).to have_content("updated the #{translated(attributes[:name])} scope") end it "can delete them" do
decidim-admin/spec/system/admin_manages_organization_scope_types_spec.rb+13 −10 modified@@ -5,6 +5,7 @@ describe "Admin manages scope types", type: :system do let(:admin) { create :user, :admin, :confirmed } let(:organization) { admin.organization } + let!(:attributes) { attributes_for(:scope_type) } before do switch_to_host(organization.host) @@ -23,17 +24,13 @@ fill_in_i18n( :scope_type_name, "#scope_type-name-tabs", - en: "Territorial en", - es: "Territorial es", - ca: "Territorial ca" + **attributes[:name].except("machine_translations") ) fill_in_i18n( :scope_type_plural, "#scope_type-plural-tabs", - en: "Territorials en", - es: "Territoriales es", - ca: "Territorials ca" + **attributes[:plural].except("machine_translations") ) find("*[type=submit]").click @@ -42,8 +39,11 @@ expect(page).to have_admin_callout("successfully") within "table" do - expect(page).to have_content("Territorial en") + expect(page).to have_content(translated(attributes[:name])) end + + visit decidim_admin.root_path + expect(page).to have_content("created the #{translated(attributes[:name])} scope type") end context "with existing scope_types" do @@ -68,22 +68,25 @@ fill_in_i18n( :scope_type_name, "#scope_type-name-tabs", - en: "Not Territorial en" + **attributes[:name].except("machine_translations") ) fill_in_i18n( :scope_type_plural, "#scope_type-plural-tabs", - en: "This is the new pluarl" + **attributes[:plural].except("machine_translations") ) find("*[type=submit]").click end expect(page).to have_admin_callout("successfully") within "table" do - expect(page).to have_content("Not Territorial en") + expect(page).to have_content(translated(attributes[:name])) end + + visit decidim_admin.root_path + expect(page).to have_content("updated the #{translated(attributes[:name])} scope type") end it "can delete them" do
decidim-admin/spec/system/admin_manages_organization_spec.rb+5 −1 modified@@ -6,6 +6,7 @@ include ActionView::Helpers::SanitizeHelper let(:organization) { create(:organization) } + let(:attributes) { attributes_for(:organization) } let(:user) { create(:user, :admin, :confirmed, organization: organization) } before do @@ -17,7 +18,7 @@ it "updates the values from the form" do visit decidim_admin.edit_organization_path - fill_in "Name", with: "My super-uber organization" + fill_in :organization_name, with: attributes[:name] %w(X Facebook Instagram YouTube GitHub).each do |network| within "#organization_social_handlers" do @@ -38,6 +39,9 @@ click_button "Update" expect(page).to have_content("updated successfully") + + visit decidim_admin.root_path + expect(page).to have_content("updated the organization settings") end it "marks the comments_max_length as required" do
decidim-admin/spec/system/static_pages_spec.rb+13 −10 modified@@ -137,6 +137,7 @@ describe "Managing pages" do let!(:topic) { create(:static_page_topic, organization: organization) } + let(:attributes) { attributes_for(:static_page) } before do login_as admin, scope: :user @@ -163,17 +164,13 @@ fill_in_i18n( :static_page_title, "#static_page-title-tabs", - en: "Welcome to Decidim", - es: "Te damos la bienvendida a Decidim", - ca: "Et donem la benvinguda a Decidim" + **attributes[:title].except("machine_translations") ) fill_in_i18n_editor( :static_page_content, "#static_page-content-tabs", - en: "<p>Some HTML content</p>", - es: "<p>Contenido HTML</p>", - ca: "<p>Contingut HTML</p>" + **attributes[:content].except("machine_translations") ) select topic.title[I18n.locale.to_s], from: "Topic" @@ -183,8 +180,11 @@ expect(page).to have_admin_callout("successfully") within find(".card", text: topic.title[I18n.locale.to_s]) do - expect(page).to have_css("tr", text: "Welcome to Decidim") + expect(page).to have_css("tr", text: translated(attributes[:title])) end + + visit decidim_admin.root_path + expect(page).to have_content("created the #{translated(attributes[:title])} static page") end context "with existing pages" do @@ -214,12 +214,12 @@ fill_in_i18n( :static_page_title, "#static_page-title-tabs", - en: "Not welcomed anymore" + **attributes[:title].except("machine_translations") ) fill_in_i18n_editor( :static_page_content, "#static_page-content-tabs", - en: "This is the new <strong>content</strong>" + **attributes[:content].except("machine_translations") ) select topic.title[I18n.locale.to_s], from: "Topic" find("*[type=submit]").click @@ -228,8 +228,11 @@ expect(page).to have_admin_callout("successfully") within find(".card", text: topic.title[I18n.locale.to_s]) do - expect(page).to have_css("tr", text: "Not welcomed anymore") + expect(page).to have_css("tr", text: translated(attributes[:title])) end + + visit decidim_admin.root_path + expect(page).to have_content("updated the #{translated(attributes[:title])} static page") end it "can delete them" do
decidim-assemblies/spec/shared/manage_assembly_components_examples.rb+16 −10 modified@@ -1,6 +1,8 @@ # frozen_string_literal: true shared_examples "manage assembly components" do + let!(:attributes) { attributes_for(:component, participatory_space: assembly) } + before do switch_to_host(organization.host) login_as user, scope: :user @@ -20,9 +22,7 @@ fill_in_i18n( :component_name, "#component-name-tabs", - en: "My component", - ca: "La meva funcionalitat", - es: "Mi funcionalitat" + **attributes[:name].except("machine_translations") ) within ".global-settings" do @@ -49,12 +49,17 @@ it "is successfully created" do expect(page).to have_admin_callout("successfully") - expect(page).to have_content("My component") + expect(page).to have_content(translated(attributes[:name])) + end + + it "has a successful admin log" do + visit decidim_admin.root_path + expect(page).to have_content("created #{translated(attributes[:name])} in #{translated(assembly.title)}") end context "and then edit it" do before do - within find("tr", text: "My component") do + within "tr", text: translated(attributes[:name]) do click_link "Configure" end end @@ -103,9 +108,7 @@ fill_in_i18n( :component_name, "#component-name-tabs", - en: "My updated component", - ca: "La meva funcionalitat actualitzada", - es: "Mi funcionalidad actualizada" + **attributes[:name].except("machine_translations") ) within ".global-settings" do @@ -120,9 +123,9 @@ end expect(page).to have_admin_callout("successfully") - expect(page).to have_content("My updated component") + expect(page).to have_content(translated(attributes[:name])) - within find("tr", text: "My updated component") do + within "tr", text: translated(attributes[:name]) do click_link "Configure" end @@ -133,6 +136,9 @@ within ".default-step-settings" do expect(all("input[type=checkbox]").first).to be_checked end + + visit decidim_admin.root_path + expect(page).to have_content("updated #{translated(attributes[:name])} in #{translated(assembly.title)}") end end
decidim-assemblies/spec/shared/manage_assembly_private_users_examples.rb+3 −0 modified@@ -33,6 +33,9 @@ within "#private_users table" do expect(page).to have_content(other_user.email) end + + visit decidim_admin.root_path + expect(page).to have_content("invited #{other_user.name} to be a private participant") end describe "when import a batch of private users from csv" do
decidim-conferences/spec/shared/manage_conference_components_examples.rb+16 −10 modified@@ -1,6 +1,8 @@ # frozen_string_literal: true shared_examples "manage conference components" do + let!(:attributes) { attributes_for(:component, participatory_space: conference) } + before do switch_to_host(organization.host) login_as user, scope: :user @@ -20,9 +22,7 @@ fill_in_i18n( :component_name, "#component-name-tabs", - en: "My component", - ca: "La meva funcionalitat", - es: "Mi funcionalitat" + **attributes[:name].except("machine_translations") ) within ".global-settings" do @@ -49,12 +49,17 @@ it "is successfully created" do expect(page).to have_admin_callout("successfully") - expect(page).to have_content("My component") + expect(page).to have_content(translated(attributes[:name])) + end + + it "has a successful admin log" do + visit decidim_admin.root_path + expect(page).to have_content("created #{translated(attributes[:name])} in #{translated(conference.title)}") end context "and then edit it" do before do - within find("tr", text: "My component") do + within "tr", text: translated(attributes[:name]) do click_link "Configure" end end @@ -103,9 +108,7 @@ fill_in_i18n( :component_name, "#component-name-tabs", - en: "My updated component", - ca: "La meva funcionalitat actualitzada", - es: "Mi funcionalidad actualizada" + **attributes[:name].except("machine_translations") ) within ".global-settings" do @@ -120,9 +123,9 @@ end expect(page).to have_admin_callout("successfully") - expect(page).to have_content("My updated component") + expect(page).to have_content(translated(attributes[:name])) - within find("tr", text: "My updated component") do + within "tr", text: translated(attributes[:name]) do click_link "Configure" end @@ -133,6 +136,9 @@ within ".default-step-settings" do expect(all("input[type=checkbox]").first).to be_checked end + + visit decidim_admin.root_path + expect(page).to have_content("updated #{translated(attributes[:name])} in #{translated(conference.title)}") end end
decidim-core/app/presenters/decidim/admin_log/organization_presenter.rb+1 −1 modified@@ -26,7 +26,7 @@ def diff_fields_mapping def settings_attributes_mapping { - name: :string, + name: :i18n, default_locale: :locale, reference_prefix: :string, twitter_handler: :string,
decidim-initiatives/spec/system/admin/admin_manages_initiative_components_spec.rb+15 −10 modified@@ -7,6 +7,7 @@ let(:user) { create(:user, :admin, :confirmed, organization: organization) } let!(:initiative) { create(:initiative, organization: organization) } + let!(:attributes) { attributes_for(:component, participatory_space: initiative) } before do switch_to_host(organization.host) @@ -27,9 +28,7 @@ fill_in_i18n( :component_name, "#component-name-tabs", - en: "My component", - ca: "El meu component", - es: "Mi componente" + **attributes[:name].except("machine_translations") ) within ".global-settings" do @@ -59,12 +58,17 @@ expect(page).to have_content("successfully") end - expect(page).to have_content("My component") + expect(page).to have_content(translated(attributes[:name])) + end + + it "has a successful admin log" do + visit decidim_admin.root_path + expect(page).to have_content("created #{translated(attributes[:name])} in #{translated(initiative.title)}") end context "and then edit it" do before do - within find("tr", text: "My component") do + within "tr", text: translated(attributes[:name]) do page.find(".action-icon--configure").click end end @@ -115,9 +119,7 @@ fill_in_i18n( :component_name, "#component-name-tabs", - en: "My updated component", - ca: "El meu component actualitzat", - es: "Mi componente actualizado" + **attributes[:name].except("machine_translations") ) within ".global-settings" do @@ -135,9 +137,9 @@ expect(page).to have_content("successfully") end - expect(page).to have_content("My updated component") + expect(page).to have_content(translated(attributes[:name])) - within find("tr", text: "My updated component") do + within "tr", text: translated(attributes[:name]) do page.find(".action-icon--configure").click end @@ -148,6 +150,9 @@ within ".default-step-settings" do expect(all("input[type=checkbox]").first).to be_checked end + + visit decidim_admin.root_path + expect(page).to have_content("updated #{translated(attributes[:name])} in #{translated(initiative.title)}") end end
decidim-initiatives/spec/system/admin/admin_manages_initiatives_types_spec.rb+17 −9 modified@@ -6,6 +6,7 @@ let(:organization) { create(:organization) } let(:user) { create(:user, :admin, :confirmed, organization: organization) } let!(:initiatives_type) { create(:initiatives_type, organization: organization) } + let(:attributes) { attributes_for(:initiatives_type) } before do switch_to_host(organization.host) @@ -26,13 +27,13 @@ fill_in_i18n( :initiatives_type_title, "#initiatives_type-title-tabs", - en: "My initiative type" + **attributes[:title].except("machine_translations") ) fill_in_i18n_editor( :initiatives_type_description, "#initiatives_type-description-tabs", - en: "A longer description" + **attributes[:description].except("machine_translations") ) select("Online", from: "Signature type") @@ -41,9 +42,10 @@ click_button "Create" - within ".callout-wrapper" do - expect(page).to have_content("A new initiative type has been successfully created") - end + expect(page).to have_admin_callout("A new initiative type has been successfully created") + + visit decidim_admin.root_path + expect(page).to have_content("created the #{translated(attributes[:title])} initiatives type") end end @@ -56,7 +58,12 @@ fill_in_i18n( :initiatives_type_title, "#initiatives_type-title-tabs", - en: "My updated initiative type" + **attributes[:title].except("machine_translations") + ) + fill_in_i18n_editor( + :initiatives_type_description, + "#initiatives_type-description-tabs", + **attributes[:description].except("machine_translations") ) select("Mixed", from: "Signature type") @@ -68,9 +75,10 @@ click_button "Update" - within ".callout-wrapper" do - expect(page).to have_content("The initiative type has been successfully updated") - end + expect(page).to have_admin_callout("The initiative type has been successfully updated") + + visit decidim_admin.root_path + expect(page).to have_content("updated the #{translated(attributes[:title])} initiatives type") end end
decidim-initiatives/spec/system/admin/update_initiative_spec.rb+21 −0 modified@@ -15,6 +15,8 @@ def submit_and_validate context "when initiative update" do context "and user is admin" do + let(:attributes) { attributes_for(:initiative, organization: organization) } + before do switch_to_host(organization.host) login_as user, scope: :user @@ -29,6 +31,25 @@ def submit_and_validate submit_and_validate end + it "updates the initiative" do + page.find(".action-icon--edit").click + + fill_in_i18n( + :initiative_title, + "#initiative-title-tabs", + **attributes[:title].except("machine_translations") + ) + fill_in_i18n_editor( + :initiative_description, + "#initiative-description-tabs", + **attributes[:description].except("machine_translations") + ) + submit_and_validate + + visit decidim_admin.root_path + expect(page).to have_content("updated the #{translated(attributes[:title])} initiative") + end + context "when initiative is in created state" do before do initiative.created!
decidim-participatory_processes/spec/shared/manage_participatory_process_private_users_examples.rb+3 −0 modified@@ -33,6 +33,9 @@ within "#private_users table" do expect(page).to have_content(other_user.email) end + + visit decidim_admin.root_path + expect(page).to have_content("invited #{other_user.name} to be a private participant") end describe "when import a batch of private users from csv" do
decidim-participatory_processes/spec/shared/manage_process_components_examples.rb+16 −10 modified@@ -4,6 +4,8 @@ let!(:participatory_process) do create(:participatory_process, :with_steps, organization: organization) end + let!(:attributes) { attributes_for(:component, participatory_space: participatory_process) } + let(:step_id) { participatory_process.steps.first.id } before do @@ -30,9 +32,7 @@ fill_in_i18n( :component_name, "#component-name-tabs", - en: "My component", - ca: "La meva funcionalitat", - es: "Mi funcionalitat" + **attributes[:name].except("machine_translations") ) within ".global-settings" do @@ -59,12 +59,17 @@ it "is successfully created" do expect(page).to have_admin_callout("successfully") - expect(page).to have_content("My component") + expect(page).to have_content(translated(attributes[:name])) + end + + it "has a successful admin log" do + visit decidim_admin.root_path + expect(page).to have_content("created #{translated(attributes[:name])} in #{translated(participatory_process.title)}") end context "and then edit it" do before do - within find("tr", text: "My component") do + within "tr", text: translated(attributes[:name]) do click_link "Configure" end end @@ -194,9 +199,7 @@ fill_in_i18n( :component_name, "#component-name-tabs", - en: "My updated component", - ca: "La meva funcionalitat actualitzada", - es: "Mi funcionalidad actualizada" + **attributes[:name].except("machine_translations") ) within ".global-settings" do @@ -211,9 +214,9 @@ end expect(page).to have_admin_callout("successfully") - expect(page).to have_content("My updated component") + expect(page).to have_content(translated(attributes[:name])) - within find("tr", text: "My updated component") do + within "tr", text: translated(attributes[:name]) do click_link "Configure" end @@ -224,6 +227,9 @@ within ".step-settings" do expect(all("input[type=checkbox]").first).to be_checked end + + visit decidim_admin.root_path + expect(page).to have_content("updated #{translated(attributes[:name])} in #{translated(participatory_process.title)}") end context "when the process doesn't have active steps" do
ff755e23814aBackport 'Refactor malformed titles in admin logs (part 1)' to v0.27 (#13084)
67 files changed · +624 −682
decidim-accountability/spec/shared/manage_results_examples.rb+14 −23 modified@@ -29,20 +29,15 @@ 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 } + let(:attributes) { attributes_for(:result, component: current_component) } 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" - ) + fill_in_i18n(:result_title, "#result-title-tabs", **attributes[:title].except("machine_translations")) proposals_pick(select_data_picker(:result_proposals, multiple: true), proposals.last(2)) @@ -52,28 +47,20 @@ expect(page).to have_admin_callout("successfully") within "table" do - expect(page).to have_content("My new title") + expect(page).to have_content(translated(attributes[:title])) end + + visit decidim_admin.root_path + expect(page).to have_content("updated result") + expect(page).to have_content(translated(attributes[:title])) 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" - ) + fill_in_i18n(:result_title, "#result-title-tabs", **attributes[:title].except("machine_translations")) + fill_in_i18n_editor(:result_description, "#result-description-tabs", **attributes[:description].except("machine_translations")) proposals_pick(select_data_picker(:result_proposals, multiple: true), proposals.first(2)) scope_pick(select_data_picker(:result_decidim_scope_id), scope) @@ -85,8 +72,12 @@ expect(page).to have_admin_callout("successfully") within "table" do - expect(page).to have_content("My result") + expect(page).to have_content(translated(attributes[:title])) end + + visit decidim_admin.root_path + expect(page).to have_content("created result") + expect(page).to have_content(attributes[:title]["en"]) end end
decidim-accountability/spec/shared/manage_statuses_examples.rb+13 −20 modified@@ -1,6 +1,8 @@ # frozen_string_literal: true RSpec.shared_examples "manage statuses" do + let(:attributes) { attributes_for(:status) } + it "updates a status" do within find("tr", text: status.key) do click_link "Edit" @@ -10,9 +12,7 @@ fill_in_i18n( :status_name, "#status-name-tabs", - en: "My new name", - es: "Mi nuevo nombre", - ca: "El meu nou nom" + **attributes[:name].except("machine_translations") ) find("*[type=submit]").click @@ -21,8 +21,11 @@ expect(page).to have_admin_callout("successfully") within "table" do - expect(page).to have_content("My new name") + expect(page).to have_content(translated(attributes[:name])) end + + visit decidim_admin.root_path + expect(page).to have_content("updated the #{translated(attributes[:name])} status") end it "creates a new status" do @@ -31,21 +34,8 @@ within ".new_status" do fill_in :status_key, with: "status_key_1" - fill_in_i18n( - :status_name, - "#status-name-tabs", - en: "A longer name", - es: "Nombre más larga", - ca: "Nom més llarga" - ) - - fill_in_i18n( - :status_description, - "#status-description-tabs", - en: "A longer description", - es: "Descripción más larga", - ca: "Descripció més llarga" - ) + fill_in_i18n(:status_name, "#status-name-tabs", **attributes[:name].except("machine_translations")) + fill_in_i18n(:status_description, "#status-description-tabs", **attributes[:description].except("machine_translations")) fill_in :status_progress, with: 75 @@ -56,8 +46,11 @@ within "table" do expect(page).to have_content("status_key_1") - expect(page).to have_content("A longer name") + expect(page).to have_content(translated(attributes[:name])) end + + visit decidim_admin.root_path + expect(page).to have_content("created the #{translated(attributes[:name])} status") end describe "deleting a result" do
decidim-accountability/spec/shared/manage_timeline_examples.rb+48 −0 added@@ -0,0 +1,48 @@ +# frozen_string_literal: true + +RSpec.shared_examples "manage timeline" do + let(:attributes) { attributes_for(:timeline_entry, result: result) } + + it "updates a timeline entry", versioning: true do + visit current_path + click_on "Edit", match: :first + + within ".edit_timeline_entry" do + fill_in :timeline_entry_entry_date, with: Date.current.strftime("%d/%m/%Y") + fill_in_i18n(:timeline_entry_title, "#timeline_entry-title-tabs", **attributes[:title].except("machine_translations")) + fill_in_i18n_editor(:timeline_entry_description, "#timeline_entry-description-tabs", **attributes[:description].except("machine_translations")) + + find("*[type=submit]").click + end + + expect(page).to have_admin_callout("successfully") + + within "table" do + expect(page).to have_content(translated(attributes[:title])) + end + + visit decidim_admin.root_path + expect(page).to have_content("updated the #{translated(attributes[:title])} timeline entry") + end + + it "creates a timeline entry", versioning: true do + click_on "New Timeline entry", match: :first + + within ".new_timeline_entry" do + fill_in :timeline_entry_entry_date, with: Date.current.strftime("%d/%m/%Y") + fill_in_i18n(:timeline_entry_title, "#timeline_entry-title-tabs", **attributes[:title].except("machine_translations")) + fill_in_i18n_editor(:timeline_entry_description, "#timeline_entry-description-tabs", **attributes[:description].except("machine_translations")) + + find("*[type=submit]").click + end + + expect(page).to have_admin_callout("successfully") + + within "table" do + expect(page).to have_content(translated(attributes[:title])) + end + + visit decidim_admin.root_path + expect(page).to have_content("created the #{translated(attributes[:title])} timeline entry") + end +end
decidim-accountability/spec/system/admin/admin_manages_accountability_spec.rb+13 −0 modified@@ -34,4 +34,17 @@ it_behaves_like "manage statuses" end + + describe "timeline" do + before do + visit_component_admin + within "tr", text: translated(result.title) do + click_on "Project evolution" + end + end + + let!(:timeline_entry) { create(:timeline_entry, result: result) } + + it_behaves_like "manage timeline" + end end
decidim-admin/lib/decidim/admin/test/manage_attachment_collections_examples.rb+3 −3 modified@@ -18,9 +18,9 @@ click_link translated(attachment_collection.name, locale: :en) end - expect(page).to have_selector("input#attachment_collection_name_en[value='#{translated(attachment_collection.name, locale: :en)}']") - expect(page).to have_selector("input#attachment_collection_weight[value='#{attachment_collection.weight}']") - expect(page).to have_selector("input#attachment_collection_description_en[value='#{translated(attachment_collection.description, locale: :en)}']") + expect(page).to have_selector(%(input#attachment_collection_name_en[value="#{translated(attachment_collection.name, locale: :en)}"])) + expect(page).to have_selector(%(input#attachment_collection_weight[value="#{attachment_collection.weight}"])) + expect(page).to have_selector(%(input#attachment_collection_description_en[value="#{translated(attachment_collection.description, locale: :en)}"])) end it "can add attachment collections to a process" do
decidim-admin/lib/decidim/admin/test/manage_attachments_examples.rb+3 −3 modified@@ -22,9 +22,9 @@ click_link translated(attachment.title, locale: :en) end - expect(page).to have_selector("input#attachment_title_en[value='#{translated(attachment.title, locale: :en)}']") - expect(page).to have_selector("input#attachment_description_en[value='#{translated(attachment.description, locale: :en)}']") - expect(page).to have_selector("input#attachment_weight[value='#{attachment.weight}']") + expect(page).to have_selector(%(input#attachment_title_en[value="#{translated(attachment.title, locale: :en)}"])) + expect(page).to have_selector(%(input#attachment_description_en[value="#{translated(attachment.description, locale: :en)}"])) + expect(page).to have_selector(%(input#attachment_weight[value="#{attachment.weight}"])) expect(page).to have_select("attachment_attachment_collection_id", selected: translated(attachment_collection.name, locale: :en)) expect(page).to have_css("img[src~='#{attachment.url}']") end
decidim-admin/lib/decidim/admin/test/manage_categories_examples.rb+1 −1 modified@@ -12,7 +12,7 @@ click_link translated(category.name, locale: :en) end - expect(page).to have_selector("input#category_name_en[value='#{translated(category.name, locale: :en)}']") + expect(page).to have_selector(%(input#category_name_en[value="#{translated(category.name, locale: :en)}"])) expect(page).to have_selector("input#category_weight[value='#{category.weight}']") expect(page).to have_selector("select#category_parent_id")
decidim-assemblies/spec/shared/manage_assemblies_examples.rb+25 −12 modified@@ -6,40 +6,53 @@ let(:image3_path) { Decidim::Dev.asset(image3_filename) } let(:assembly_parent_id_options) { page.find("#assembly_parent_id").find_all("option").map(&:value) } + let(:attributes) { attributes_for(:assembly, organization: organization) } before do click_link translated(assembly.title) end it "updates an assembly" do - fill_in_i18n( - :assembly_title, - "#assembly-title-tabs", - en: "My new title", - es: "Mi nuevo título", - ca: "El meu nou títol" - ) + fill_in_i18n(:assembly_title, "#assembly-title-tabs", **attributes[:title].except("machine_translations")) dynamically_attach_file(:assembly_banner_image, image3_path, remove_before: true) within ".edit_assembly" do expect(assembly_parent_id_options).not_to include(assembly.id) - fill_in "assembly[creation_date]", with: Date.yesterday - fill_in "assembly[included_at]", with: Date.current - fill_in "assembly[duration]", with: Date.tomorrow - fill_in "assembly[closing_date]", with: Date.tomorrow + fill_in_i18n(:assembly_subtitle, "#assembly-subtitle-tabs", **attributes[:subtitle].except("machine_translations")) + fill_in_i18n_editor(:assembly_short_description, "#assembly-short_description-tabs", **attributes[:short_description].except("machine_translations")) + fill_in_i18n_editor(:assembly_description, "#assembly-description-tabs", **attributes[:description].except("machine_translations")) + fill_in_i18n_editor(:assembly_purpose_of_action, "#assembly-purpose_of_action-tabs", **attributes[:purpose_of_action].except("machine_translations")) + fill_in_i18n_editor(:assembly_composition, "#assembly-composition-tabs", **attributes[:composition].except("machine_translations")) + fill_in_i18n_editor(:assembly_internal_organisation, "#assembly-internal_organisation-tabs", **attributes[:internal_organisation].except("machine_translations")) + fill_in_i18n_editor(:assembly_announcement, "#assembly-announcement-tabs", **attributes[:announcement].except("machine_translations")) + fill_in_i18n_editor(:assembly_closing_date_reason, "#assembly-closing_date_reason-tabs", **attributes[:closing_date_reason].except("machine_translations")) + + fill_in_i18n(:assembly_participatory_scope, "#assembly-participatory_scope-tabs", **attributes[:participatory_scope].except("machine_translations")) + fill_in_i18n(:assembly_participatory_structure, "#assembly-participatory_structure-tabs", **attributes[:participatory_structure].except("machine_translations")) + fill_in_i18n(:assembly_meta_scope, "#assembly-meta_scope-tabs", **attributes[:meta_scope].except("machine_translations")) + fill_in_i18n(:assembly_local_area, "#assembly-local_area-tabs", **attributes[:local_area].except("machine_translations")) + fill_in_i18n(:assembly_target, "#assembly-target-tabs", **attributes[:target].except("machine_translations")) + + fill_in :assembly_creation_date, with: Date.yesterday.strftime("%d/%m/%Y"), fill_options: { clear: :backspace } + fill_in :assembly_included_at, with: Date.current.strftime("%d/%m/%Y"), fill_options: { clear: :backspace } + fill_in :assembly_duration, with: Date.tomorrow.strftime("%d/%m/%Y"), fill_options: { clear: :backspace } + fill_in :assembly_closing_date, with: Date.tomorrow.strftime("%d/%m/%Y"), fill_options: { clear: :backspace } 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_selector(%(input[value="#{translated(attributes[:title])}"])) expect(page).to have_css("img[src*='#{image3_filename}']") expect(page).to have_css("input[value='#{Date.yesterday}']") expect(page).to have_css("input[value='#{Date.current}']") expect(page).to have_css("input[value='#{Date.tomorrow}']", count: 2) end + + visit decidim_admin.root_path + expect(page).to have_content("updated the #{translated(attributes[:title])} assembly") end end
decidim-assemblies/spec/shared/manage_assembly_admins_examples.rb+9 −3 modified@@ -2,6 +2,7 @@ shared_examples "manage assembly admins examples" do let(:other_user) { create :user, organization: organization, email: "my_email@example.org" } + let(:attributes) { attributes_for(:user, organization: organization) } let!(:assembly_admin) do create :assembly_admin, @@ -23,12 +24,12 @@ end end - it "creates a new assembly admin" do + it "creates a new assembly admin", versioning: true do find(".card-title a.new").click within ".new_assembly_user_role" do fill_in :assembly_user_role_email, with: other_user.email - fill_in :assembly_user_role_name, with: "John Doe" + fill_in :assembly_user_role_name, with: attributes[:name] select "Administrator", from: :assembly_user_role_role find("*[type=submit]").click @@ -39,6 +40,9 @@ within "#assembly_admins table" do expect(page).to have_content(other_user.email) end + + visit decidim_admin.root_path + expect(page).to have_content("invited #{other_user.name} to the #{translated(assembly.title)} assembly") end describe "when managing different users" do @@ -47,7 +51,7 @@ visit current_path end - it "updates a assembly admin" do + it "updates a assembly admin", versioning: true do within "#assembly_admins" do within find("#assembly_admins tr", text: other_user.email) do click_link "Edit" @@ -65,6 +69,8 @@ within "#assembly_admins table" do expect(page).to have_content("Collaborator") end + visit decidim_admin.root_path + expect(page).to have_content("changed the role of #{other_user.name} in the #{translated(assembly.title)} assembly") end it "deletes a assembly_user_role" do
decidim-assemblies/spec/shared/manage_assembly_members_examples.rb+18 −12 modified@@ -10,18 +10,18 @@ context "without existing user" do let!(:assembly_member) { create(:assembly_member, assembly: assembly) } + let(:attributes) { attributes_for(:assembly_member, assembly: assembly) } - it "creates a new assembly member" do + it "creates a new assembly member", versioning: true do find(".card-title a.new").click execute_script("$('#assembly_member_designation_date').focus()") find(".datepicker-days .active").click within ".new_assembly_member" do - fill_in( - :assembly_member_full_name, - with: "Daisy O'connor" - ) + fill_in(:assembly_member_full_name, with: attributes[:full_name]) + fill_in(:assembly_member_gender, with: attributes[:gender]) + fill_in(:assembly_member_birthplace, with: attributes[:birthplace]) end dynamically_attach_file(:assembly_member_non_user_avatar, Decidim::Dev.asset("avatar.jpg")) do @@ -38,8 +38,11 @@ expect(page).to have_current_path decidim_admin_assemblies.assembly_members_path(assembly) within "#assembly_members table" do - expect(page).to have_content("Daisy O'connor") + expect(page).to have_content(attributes[:full_name]) end + + visit decidim_admin.root_path + expect(page).to have_content("created the #{attributes[:full_name]} member") end end @@ -99,6 +102,7 @@ describe "when managing other assembly members" do let!(:assembly_member) { create(:assembly_member, assembly: assembly) } + let(:attributes) { attributes_for(:assembly_member, assembly: assembly) } before do visit current_path @@ -110,16 +114,15 @@ end end - it "updates an assembly member" do + it "updates an assembly member", versioning: true do within find("#assembly_members tr", text: assembly_member.full_name) do click_link "Edit" end within ".edit_assembly_member" do - fill_in( - :assembly_member_full_name, - with: "Alicia O'connor" - ) + fill_in(:assembly_member_full_name, with: attributes[:full_name]) + fill_in(:assembly_member_gender, with: attributes[:gender]) + fill_in(:assembly_member_birthplace, with: attributes[:birthplace]) find("*[type=submit]").click end @@ -128,8 +131,11 @@ expect(page).to have_current_path decidim_admin_assemblies.assembly_members_path(assembly) within "#assembly_members table" do - expect(page).to have_content("Alicia O'connor") + expect(page).to have_content(attributes[:full_name]) end + + visit decidim_admin.root_path + expect(page).to have_content("updated the #{assembly_member.full_name} member") end it "deletes the assembly member" do
decidim-assemblies/spec/system/admin/admin_manages_assemblies_spec.rb+21 −30 modified@@ -14,6 +14,7 @@ let(:image2_filename) { "city2.jpeg" } let(:image2_path) { Decidim::Dev.asset(image2_filename) } + let(:attributes) { attributes_for(:assembly, organization: organization) } before do click_link "New assembly" @@ -25,36 +26,23 @@ it_behaves_like "having a rich text editor for field", "#closing_date_reason_div", "content" - it "creates a new assembly" do + it "creates a new assembly", versioning: true do within ".new_assembly" do - fill_in_i18n( - :assembly_title, - "#assembly-title-tabs", - en: "My assembly", - es: "Mi proceso participativo", - ca: "El meu procés participatiu" - ) - fill_in_i18n( - :assembly_subtitle, - "#assembly-subtitle-tabs", - en: "Subtitle", - es: "Subtítulo", - ca: "Subtítol" - ) - fill_in_i18n_editor( - :assembly_short_description, - "#assembly-short_description-tabs", - en: "Short description", - es: "Descripción corta", - ca: "Descripció curta" - ) - fill_in_i18n_editor( - :assembly_description, - "#assembly-description-tabs", - en: "A longer description", - es: "Descripción más larga", - ca: "Descripció més llarga" - ) + fill_in_i18n(:assembly_title, "#assembly-title-tabs", **attributes[:title].except("machine_translations")) + fill_in_i18n(:assembly_subtitle, "#assembly-subtitle-tabs", **attributes[:subtitle].except("machine_translations")) + fill_in_i18n_editor(:assembly_short_description, "#assembly-short_description-tabs", **attributes[:short_description].except("machine_translations")) + fill_in_i18n_editor(:assembly_description, "#assembly-description-tabs", **attributes[:description].except("machine_translations")) + fill_in_i18n_editor(:assembly_purpose_of_action, "#assembly-purpose_of_action-tabs", **attributes[:purpose_of_action].except("machine_translations")) + fill_in_i18n_editor(:assembly_composition, "#assembly-composition-tabs", **attributes[:composition].except("machine_translations")) + fill_in_i18n_editor(:assembly_internal_organisation, "#assembly-internal_organisation-tabs", **attributes[:internal_organisation].except("machine_translations")) + fill_in_i18n_editor(:assembly_announcement, "#assembly-announcement-tabs", **attributes[:announcement].except("machine_translations")) + fill_in_i18n_editor(:assembly_closing_date_reason, "#assembly-closing_date_reason-tabs", **attributes[:closing_date_reason].except("machine_translations")) + + fill_in_i18n(:assembly_participatory_scope, "#assembly-participatory_scope-tabs", **attributes[:participatory_scope].except("machine_translations")) + fill_in_i18n(:assembly_participatory_structure, "#assembly-participatory_structure-tabs", **attributes[:participatory_structure].except("machine_translations")) + fill_in_i18n(:assembly_meta_scope, "#assembly-meta_scope-tabs", **attributes[:meta_scope].except("machine_translations")) + fill_in_i18n(:assembly_local_area, "#assembly-local_area-tabs", **attributes[:local_area].except("machine_translations")) + fill_in_i18n(:assembly_target, "#assembly-target-tabs", **attributes[:target].except("machine_translations")) fill_in :assembly_slug, with: "slug" fill_in :assembly_hashtag, with: "#hashtag" @@ -72,8 +60,11 @@ within ".container" do expect(page).to have_current_path decidim_admin_assemblies.assemblies_path(q: { parent_id_eq: parent_assembly&.id }) - expect(page).to have_content("My assembly") + expect(page).to have_content(translated(attributes[:title])) end + + visit decidim_admin.root_path + expect(page).to have_content("created the #{translated(attributes[:title])} assembly") end end
decidim-assemblies/spec/system/admin/admin_manages_assemblies_types_spec.rb+14 −11 modified@@ -2,11 +2,12 @@ require "spec_helper" -describe "Admin manages assemblies", type: :system do +describe "Admin manages assemblies types", type: :system do include Decidim::SanitizeHelper let(:admin) { create :user, :admin, :confirmed } let(:organization) { admin.organization } + let(:attributes) { attributes_for(:assemblies_type) } describe "Managing assemblies types" do before do @@ -15,21 +16,22 @@ visit decidim_admin_assemblies.assemblies_types_path end - it "can create new assemblies types" do + it "can create new assemblies types", versioning: true do click_link "New assembly type" within ".new_assembly_type" do - fill_in_i18n :assemblies_type_title, "#assemblies_type-title-tabs", en: "My assembly type", - es: "Mi assembly type", - ca: "La meva assembly type" + fill_in_i18n :assemblies_type_title, "#assemblies_type-title-tabs", **attributes[:title].except("machine_translations") find("*[type=submit]").click end expect(page).to have_admin_callout("successfully") within "table" do - expect(page).to have_content("My assembly type") + expect(page).to have_content(translated(attributes[:title])) end + + visit decidim_admin.root_path + expect(page).to have_content("created the #{translated(attributes[:title])} assembly type") end context "with existing assemblies types" do @@ -45,23 +47,24 @@ end end - it "can edit them" do + it "can edit them", versioning: true do within find("tr", text: translated(assembly_type.title)) do click_link "Edit" end within ".edit_assembly_type" do - fill_in_i18n :assemblies_type_title, "#assemblies_type-title-tabs", en: "Another assembly type", - es: "Otra assembly type", - ca: "Una altra assembly type" + fill_in_i18n :assemblies_type_title, "#assemblies_type-title-tabs", **attributes[:title].except("machine_translations") find("*[type=submit]").click end expect(page).to have_admin_callout("successfully") within "table" do - expect(page).to have_content("Another assembly type") + expect(page).to have_content(translated(attributes[:title])) end + + visit decidim_admin.root_path + expect(page).to have_content("updated the #{translated(attributes[:title])} assembly type") end it "can delete them" do
decidim-blogs/spec/shared/manage_posts_examples.rb+22 −34 modified@@ -1,67 +1,50 @@ # frozen_string_literal: true -shared_examples "manage posts" do +# we really need the audit_check variable, as it seems that a process admin should not be able to see the admin logs +# Therefore, as long we do have the logs checks in this shared example, we need to have the config flag. +shared_examples "manage posts" do |audit_check: true| it_behaves_like "having a rich text editor for field", ".tabs-content[data-tabs-content='post-body-tabs']", "full" do before do within find("tr", text: translated(post1.title)) do click_link "Edit" end end end + let(:attributes) { attributes_for(:post) } - it "updates a post" do + it "updates a post", versioning: true do within find("tr", text: translated(post1.title)) do click_link "Edit" end within ".edit_post" do expect(page).to have_select("post_decidim_author_id", selected: author.name) - fill_in_i18n( - :post_title, - "#post-title-tabs", - en: "My new title", - es: "Mi nuevo título", - ca: "El meu nou títol" - ) - fill_in_i18n_editor( - :post_body, - "#post-body-tabs", - en: "A longer description", - es: "Descripción más larga", - ca: "Descripció més llarga" - ) + fill_in_i18n(:post_title, "#post-title-tabs", **attributes[:title].except("machine_translations")) + fill_in_i18n_editor(:post_body, "#post-body-tabs", **attributes[:body].except("machine_translations")) find("*[type=submit]").click end expect(page).to have_admin_callout("successfully") within "table" do - expect(page).to have_content("My new title") + expect(page).to have_content(translated(attributes[:title])) expect(page).to have_content("Post title 2") expect(page).to have_content(author.name) end + + if audit_check == true + visit decidim_admin.root_path + expect(page).to have_content("updated the #{translated(attributes[:title])} blog post") + end end - it "creates a new post", :slow do + it "creates a new post", versioning: true do find(".card-title a.button").click - fill_in_i18n( - :post_title, - "#post-title-tabs", - en: "My post", - es: "Mi post", - ca: "El meu post" - ) - - fill_in_i18n_editor( - :post_body, - "#post-body-tabs", - en: "A description", - es: "Descripción", - ca: "Descripció" - ) + fill_in_i18n(:post_title, "#post-title-tabs", **attributes[:title].except("machine_translations")) + fill_in_i18n_editor(:post_body, "#post-body-tabs", **attributes[:body].except("machine_translations")) within ".new_post" do find("*[type=submit]").click @@ -70,10 +53,15 @@ expect(page).to have_admin_callout("successfully") within "table" do - expect(page).to have_content("My post") + expect(page).to have_content(translated(attributes[:title])) expect(page).to have_content("Post title 1") expect(page).to have_content("Post title 2") end + + if audit_check == true + visit decidim_admin.root_path + expect(page).to have_content("created the #{translated(attributes[:title])} blog post") + end end describe "deleting a post" do
decidim-blogs/spec/system/process_admin_manages_post_spec.rb+1 −1 modified@@ -10,5 +10,5 @@ include_context "when managing a component as a process admin" - it_behaves_like "manage posts" + it_behaves_like "manage posts", audit_check: false end
decidim-budgets/app/views/decidim/budgets/admin/projects/index.html.erb+1 −1 modified@@ -3,7 +3,7 @@ <div class="card-divider"> <h2 class="card-title flex--sbc"> <div> - <%= link_to decidim_escape_translated(budget.title), budgets_path %> > + <%= link_to decidim_escape_translated(budget.title).html_safe, budgets_path %> > <%= t(".title") %> <span id="js-selected-resources-count" class="component-counter component-counter--inline" title="<%= t("decidim.budgets.admin.projects.index.selected") %>"></span> </div>
decidim-budgets/spec/shared/manage_projects_examples.rb+16 −25 modified@@ -140,24 +140,14 @@ end end - it "creates a new project", :slow do + let(:attributes) { attributes_for(:project) } + + it "creates a new project", versioning: true 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_i18n(:project_title, "#project-title-tabs", **attributes[:title].except("machine_translations")) + fill_in_i18n_editor(:project_description, "#project-description-tabs", **attributes[:description].except("machine_translations")) fill_in :project_budget_amount, with: 22_000_000 scope_pick select_data_picker(:project_decidim_scope_id), scope @@ -169,8 +159,10 @@ expect(page).to have_admin_callout("successfully") within "table" do - expect(page).to have_content("My project") + expect(page).to have_content(translated(attributes[:title])) end + visit decidim_admin.root_path + expect(page).to have_content("created the #{translated(attributes[:title])} project") end context "when deleting a project" do @@ -196,20 +188,16 @@ 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 } + let(:attributes) { attributes_for(:project) } - it "updates a project" do + it "updates a project", versioning: true 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" - ) + fill_in_i18n(:project_title, "#project-title-tabs", **attributes[:title].except("machine_translations")) + fill_in_i18n_editor(:project_description, "#project-description-tabs", **attributes[:description].except("machine_translations")) proposals_pick(select_data_picker(:project_proposals, multiple: true), proposals.last(2)) @@ -219,8 +207,11 @@ expect(page).to have_admin_callout("successfully") within "table" do - expect(page).to have_content("My new title") + expect(page).to have_content(translated(attributes[:title])) end + + visit decidim_admin.root_path + expect(page).to have_content("updated the #{translated(attributes[:title])} project") end it "removes proposals from project", :slow do
decidim-budgets/spec/system/admin_manages_budgets_spec.rb+17 −27 modified@@ -3,12 +3,12 @@ require "spec_helper" describe "Admin manages budgets", type: :system do - let(:budget) { create :budget, component: current_component } + let!(:budget) { create :budget, component: current_component } let(:manifest_name) { "budgets" } + let(:attributes) { attributes_for(:budget) } include_context "when managing a component as an admin" before do - budget switch_to_host(organization.host) login_as user, scope: :user visit_component_admin @@ -20,26 +20,15 @@ it_behaves_like "having a rich text editor", "new_budget", "content" end - it "creates a new budget" do + it "creates a new budget", versioning: true do within ".card-title" do click_link "New Budget" end within ".new_budget" do - fill_in_i18n( - :budget_title, - "#budget-title-tabs", - en: "My Budget", - es: "Mi Presupuesto", - ca: "El meu Pressupost" - ) - fill_in_i18n_editor( - :budget_description, - "#budget-description-tabs", - en: "Long description", - es: "Descripción más larga", - ca: "Descripció més llarga" - ) + fill_in_i18n(:budget_title, "#budget-title-tabs", **attributes[:title].except("machine_translations")) + fill_in_i18n_editor(:budget_description, "#budget-description-tabs", **attributes[:description].except("machine_translations")) + fill_in :budget_weight, with: 1 fill_in :budget_total_budget, with: 100_000_00 scope_pick select_data_picker(:budget_decidim_scope_id), scope @@ -54,24 +43,22 @@ end within "table" do - expect(page).to have_content("My Budget") + expect(page).to have_content(translated(attributes[:title])) end + + visit decidim_admin.root_path + expect(page).to have_content("created the #{translated(attributes[:title])} budget") end - describe "updating a budget" do + describe "updating a budget", versioning: true do it "updates a budget" do within find("tr", text: translated(budget.title)) do page.find(".action-icon--edit").click end within ".edit_budget" do - fill_in_i18n( - :budget_title, - "#budget-title-tabs", - en: "My new title", - es: "Mi nuevo título", - ca: "El meu nou títol" - ) + fill_in_i18n(:budget_title, "#budget-title-tabs", **attributes[:title].except("machine_translations")) + fill_in_i18n_editor(:budget_description, "#budget-description-tabs", **attributes[:description].except("machine_translations")) find("*[type=submit]").click end @@ -81,8 +68,11 @@ end within "table" do - expect(page).to have_content("My new title") + expect(page).to have_content(translated(attributes[:title])) end + + visit decidim_admin.root_path + expect(page).to have_content("updated the #{translated(attributes[:title])} budget") end end
decidim-budgets/spec/system/admin_manages_projects_spec.rb+1 −2 modified@@ -5,13 +5,12 @@ describe "Admin manages projects", type: :system do let(:manifest_name) { "budgets" } - let(:budget) { create :budget, component: current_component } + let!(:budget) { create :budget, component: current_component } let!(:project) { create :project, budget: budget } include_context "when managing a component as an admin" before do - budget switch_to_host(organization.host) login_as user, scope: :user visit_component_admin
decidim-conferences/spec/shared/manage_conference_admins_examples.rb+8 −3 modified@@ -2,6 +2,7 @@ shared_examples "manage conference admins examples" do let(:other_user) { create :user, organization: organization, email: "my_email@example.org" } + let(:attributes) { attributes_for(:user, organization: organization) } let!(:conference_admin) do create :conference_admin, @@ -23,12 +24,12 @@ end end - it "creates a new conference admin" do + it "creates a new conference admin", versioning: true do find(".card-title a.new").click within ".new_conference_user_role" do fill_in :conference_user_role_email, with: other_user.email - fill_in :conference_user_role_name, with: "John Doe" + fill_in :conference_user_role_name, with: attributes[:name] select "Administrator", from: :conference_user_role_role find("*[type=submit]").click @@ -39,6 +40,8 @@ within "#conference_admins table" do expect(page).to have_content(other_user.email) end + visit decidim_admin.root_path + expect(page).to have_content("invited #{other_user.name} to the #{translated(conference.title)} conference") end describe "when managing different users" do @@ -47,7 +50,7 @@ visit current_path end - it "updates a conference admin" do + it "updates a conference admin", versioning: true do within "#conference_admins" do within find("#conference_admins tr", text: other_user.email) do click_link "Edit" @@ -65,6 +68,8 @@ within "#conference_admins table" do expect(page).to have_content("Collaborator") end + visit decidim_admin.root_path + expect(page).to have_content("changed the role of #{other_user.name} in the #{translated(conference.title)} conference") end it "deletes a conference_user_role" do
decidim-conferences/spec/shared/manage_conferences_examples.rb+22 −39 modified@@ -7,6 +7,7 @@ let(:image2_filename) { "city2.jpeg" } let(:image2_path) { Decidim::Dev.asset(image2_filename) } + let(:attributes) { attributes_for(:conference) } before do click_link "New Conference" @@ -17,36 +18,13 @@ end it_behaves_like "having a rich text editor for field", "#conference_registrations_terms", "content" - it "creates a new conference" do + it "creates a new conference", versioning: true do within ".new_conference" do - fill_in_i18n( - :conference_title, - "#conference-title-tabs", - en: "My conference", - es: "Mi proceso participativo", - ca: "El meu procés participatiu" - ) - fill_in_i18n( - :conference_slogan, - "#conference-slogan-tabs", - en: "Slogan", - es: "Eslogan", - ca: "Eslógan" - ) - fill_in_i18n_editor( - :conference_short_description, - "#conference-short_description-tabs", - en: "Short description", - es: "Descripción corta", - ca: "Descripció curta" - ) - fill_in_i18n_editor( - :conference_description, - "#conference-description-tabs", - en: "A longer description", - es: "Descripción más larga", - ca: "Descripció més llarga" - ) + fill_in_i18n(:conference_title, "#conference-title-tabs", **attributes[:title].except("machine_translations")) + fill_in_i18n(:conference_slogan, "#conference-slogan-tabs", **attributes[:slogan].except("machine_translations")) + fill_in_i18n_editor(:conference_short_description, "#conference-short_description-tabs", **attributes[:short_description].except("machine_translations")) + fill_in_i18n_editor(:conference_description, "#conference-description-tabs", **attributes[:description].except("machine_translations")) + fill_in_i18n_editor(:conference_objectives, "#conference-objectives-tabs", **attributes[:objectives].except("machine_translations")) fill_in :conference_slug, with: "slug" fill_in :conference_hashtag, with: "#hashtag" @@ -66,39 +44,44 @@ within ".container" do expect(page).to have_current_path decidim_admin_conferences.conferences_path - expect(page).to have_content("My conference") + expect(page).to have_content(translated(attributes[:title])) end + + visit decidim_admin.root_path + expect(page).to have_content("created the #{translated(attributes[:title])} conference") end end describe "updating a conference" do let(:image3_filename) { "city3.jpeg" } let(:image3_path) { Decidim::Dev.asset(image3_filename) } + let(:attributes) { attributes_for(:conference) } before do click_link translated(conference.title) end - it "updates a conference" do - fill_in_i18n( - :conference_title, - "#conference-title-tabs", - en: "My new title", - es: "Mi nuevo título", - ca: "El meu nou títol" - ) + it "updates a conference", versioning: true do dynamically_attach_file(:conference_banner_image, image3_path, remove_before: true) within ".edit_conference" do + fill_in_i18n(:conference_title, "#conference-title-tabs", **attributes[:title].except("machine_translations")) + fill_in_i18n(:conference_slogan, "#conference-slogan-tabs", **attributes[:slogan].except("machine_translations")) + fill_in_i18n_editor(:conference_short_description, "#conference-short_description-tabs", **attributes[:short_description].except("machine_translations")) + fill_in_i18n_editor(:conference_description, "#conference-description-tabs", **attributes[:description].except("machine_translations")) + fill_in_i18n_editor(:conference_objectives, "#conference-objectives-tabs", **attributes[:objectives].except("machine_translations")) 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_selector(%(input[value="#{translated(attributes[:title])}"])) expect(page).to have_css("img[src*='#{image3_filename}']") end + + visit decidim_admin.root_path + expect(page).to have_content("updated the #{translated(attributes[:title])} conference") end end
decidim-conferences/spec/shared/manage_conference_speakers_examples.rb+17 −12 modified@@ -2,6 +2,7 @@ shared_examples "manage conference speakers examples" do let!(:conference_speaker) { create(:conference_speaker, conference: conference) } + let(:attributes) { attributes_for(:conference_speaker, conference: conference) } before do switch_to_host(organization.host) @@ -17,14 +18,14 @@ end context "without existing user" do - it "creates a new conference speaker" do + it "creates a new conference speaker", versioning: true do find(".card-title a.new").click within ".new_conference_speaker" do - fill_in( - :conference_speaker_full_name, - with: "Daisy O'connor" - ) + fill_in(:conference_speaker_full_name, with: attributes[:full_name]) + fill_in_i18n(:conference_speaker_position, "#conference_speaker-position-tabs", **attributes[:position].except("machine_translations")) + fill_in_i18n(:conference_speaker_affiliation, "#conference_speaker-affiliation-tabs", **attributes[:affiliation].except("machine_translations")) + fill_in_i18n_editor(:conference_speaker_short_bio, "#conference_speaker-short_bio-tabs", **attributes[:short_bio].except("machine_translations")) find("*[type=submit]").click end @@ -33,8 +34,10 @@ expect(page).to have_current_path decidim_admin_conferences.conference_speakers_path(conference) within "#conference_speakers table" do - expect(page).to have_content("Daisy O'connor") + expect(page).to have_content(attributes[:full_name]) end + visit decidim_admin.root_path + expect(page).to have_content("created the #{attributes[:full_name]} speaker in the") end end @@ -65,16 +68,16 @@ visit current_path end - it "updates an conference speaker" do + it "updates an conference speaker", versioning: true do within find("#conference_speakers tr", text: conference_speaker.full_name) do click_link "Edit" end within ".edit_conference_speaker" do - fill_in( - :conference_speaker_full_name, - with: "Alicia O'connor" - ) + fill_in(:conference_speaker_full_name, with: attributes[:full_name]) + fill_in_i18n(:conference_speaker_position, "#conference_speaker-position-tabs", **attributes[:position].except("machine_translations")) + fill_in_i18n(:conference_speaker_affiliation, "#conference_speaker-affiliation-tabs", **attributes[:affiliation].except("machine_translations")) + fill_in_i18n_editor(:conference_speaker_short_bio, "#conference_speaker-short_bio-tabs", **attributes[:short_bio].except("machine_translations")) find("*[type=submit]").click end @@ -83,8 +86,10 @@ expect(page).to have_current_path decidim_admin_conferences.conference_speakers_path(conference) within "#conference_speakers table" do - expect(page).to have_content("Alicia O'connor") + expect(page).to have_content(attributes[:full_name]) end + visit decidim_admin.root_path + expect(page).to have_content("updated the #{conference_speaker.full_name} speaker in the") end it "deletes the conference speaker" do
decidim-conferences/spec/shared/manage_media_links_examples.rb+13 −14 modified@@ -1,6 +1,8 @@ # frozen_string_literal: true shared_examples "manage media links examples" do + let!(:attributes) { attributes_for(:media_link, conference: conference) } + before do switch_to_host(organization.host) login_as user, scope: :user @@ -13,14 +15,12 @@ click_link "New Media Link" end - it "creates a new media link" do + it "creates a new media link", versioning: true do within ".new_media_link" do fill_in_i18n( :conference_media_link_title, "#conference_media_link-title-tabs", - en: "Media Link en", - es: "Media Link es", - ca: "Media Link ca" + **attributes[:title].except("machine_translations") ) fill_in :conference_media_link_link, with: "https://decidim.org" @@ -34,8 +34,11 @@ within ".container" do expect(page).to have_current_path decidim_admin_conferences.conference_media_links_path(conference) - expect(page).to have_content("Media Link en") + expect(page).to have_content(translated(attributes[:title])) end + + visit decidim_admin.root_path + expect(page).to have_content("created the #{translated(attributes[:title])} media link") end end @@ -52,19 +55,13 @@ end end - it "updates a conference media links" do + it "updates a conference media links", versioning: true do within find("#media_links tr", text: translated(media_link.title)) do click_link "Edit" end within ".edit_media_link" do - fill_in_i18n( - :conference_media_link_title, - "#conference_media_link-title-tabs", - en: "Media Link update en", - es: "Media Link update es", - ca: "Media Link update ca" - ) + fill_in_i18n(:conference_media_link_title, "#conference_media_link-title-tabs", **attributes[:title].except("machine_translations")) fill_in :conference_media_link_link, with: "https://decidim.org" fill_in :conference_media_link_weight, with: 2 @@ -77,8 +74,10 @@ expect(page).to have_current_path decidim_admin_conferences.conference_media_links_path(conference) within "#media_links table" do - expect(page).to have_content("Media Link update en") + expect(page).to have_content(translated(attributes[:title])) end + visit decidim_admin.root_path + expect(page).to have_content("updated the #{translated(media_link.title)} media link") end it "deletes the conference media link" do
decidim-conferences/spec/shared/manage_partners_examples.rb+31 −6 modified@@ -2,6 +2,7 @@ shared_examples "manage partners examples" do let!(:conference_partner) { create(:partner, conference: conference) } + let!(:attributes) { attributes_for(:partner, conference: conference) } before do switch_to_host(organization.host) @@ -17,20 +18,42 @@ end describe "when managing other conference partners" do + let(:image1_filename) { "city.jpeg" } + let(:image1_path) { Decidim::Dev.asset(image1_filename) } + before do visit current_path end - it "updates a conference partners" do + it "creates a conference partner", versioning: true do + click_on "New Partner" + dynamically_attach_file(:conference_partner_logo, image1_path) + + within ".new_partner" do + fill_in(:conference_partner_name, with: attributes[:name]) + + select("Collaborator", from: :conference_partner_partner_type) + + find("*[type=submit]").click + end + expect(page).to have_admin_callout("successfully") + expect(page).to have_current_path decidim_admin_conferences.conference_partners_path(conference) + + within "#partners table" do + expect(page).to have_content(attributes[:name]) + expect(page).to have_content("Collaborator") + end + visit decidim_admin.root_path + expect(page).to have_content("created the partner #{attributes[:name]}") + end + + it "updates a conference partners", versioning: true do within find("#partners tr", text: conference_partner.name) do click_link "Edit" end within ".edit_partner" do - fill_in( - :conference_partner_name, - with: "Partner name" - ) + fill_in(:conference_partner_name, with: attributes[:name]) select( "Collaborator", @@ -44,9 +67,11 @@ expect(page).to have_current_path decidim_admin_conferences.conference_partners_path(conference) within "#partners table" do - expect(page).to have_content("Partner name") + expect(page).to have_content(attributes[:name]) expect(page).to have_content("Collaborator") end + visit decidim_admin.root_path + expect(page).to have_content("updated the partner #{conference_partner.name}") end context "when the partner type is already a Collaborator" do
decidim-conferences/spec/shared/manage_registration_types_examples.rb+30 −8 modified@@ -2,6 +2,7 @@ shared_examples "manage registration types examples" do let!(:registration_type) { create(:registration_type, conference: conference) } + let(:attributes) { attributes_for(:registration_type, conference: conference) } before do switch_to_host(organization.host) @@ -21,19 +22,37 @@ visit current_path end + it "creates a conference registration types", versioning: true do + click_on "New Registration type" + + within ".new_registration_type" do + fill_in_i18n(:conference_registration_type_title, "#conference_registration_type-title-tabs", **attributes[:title].except("machine_translations")) + fill_in_i18n_editor(:conference_registration_type_description, "#conference_registration_type-description-tabs", **attributes[:description].except("machine_translations")) + + fill_in(:conference_registration_type_weight, with: 4) + + find("*[type=submit]").click + end + + expect(page).to have_admin_callout("successfully") + expect(page).to have_current_path decidim_admin_conferences.conference_registration_types_path(conference) + + within "#registration_types table" do + expect(page).to have_content(translated(attributes[:title])) + end + + visit decidim_admin.root_path + expect(page).to have_content("created the #{translated(attributes[:title])} registration type") + end + it "updates a conference registration types" do within find("#registration_types tr", text: translated(registration_type.title)) do click_link "Edit" end within ".edit_registration_type" do - fill_in_i18n( - :conference_registration_type_title, - "#conference_registration_type-title-tabs", - en: "Registration type title", - es: "Registration type title es", - ca: "Registration type title ca" - ) + fill_in_i18n(:conference_registration_type_title, "#conference_registration_type-title-tabs", **attributes[:title].except("machine_translations")) + fill_in_i18n_editor(:conference_registration_type_description, "#conference_registration_type-description-tabs", **attributes[:description].except("machine_translations")) find("*[type=submit]").click end @@ -42,8 +61,11 @@ expect(page).to have_current_path decidim_admin_conferences.conference_registration_types_path(conference) within "#registration_types table" do - expect(page).to have_content("Registration type title") + expect(page).to have_content(translated(attributes[:title])) end + + visit decidim_admin.root_path + expect(page).to have_content("updated the #{translated(registration_type.title)} registration type") end it "deletes the conference registration type" do
decidim-conferences/spec/system/media_spec.rb+1 −1 modified@@ -86,7 +86,7 @@ def visit_conference it "shows them ordered" do within "div.wrapper .documents" do - expect(decidim_escape_translated(first_document.title).gsub(""", "\"")).to appear_before(decidim_escape_translated(last_document.title).gsub(""", "\"")) + expect(decidim_escape_translated(first_document.title).gsub("'", "\'")).to appear_before(decidim_escape_translated(last_document.title).gsub("'", "\'")) end within "div.wrapper .images" do
decidim-core/app/cells/decidim/follow_button_cell.rb+1 −1 modified@@ -46,7 +46,7 @@ def icon_options def render_screen_reader_title_for(resource) content_tag :span, class: "show-for-sr" do - decidim_html_escape(resource_title(resource)) + decidim_sanitize_translated(resource_title(resource)) end end
decidim-core/app/presenters/decidim/log/resource_presenter.rb+7 −1 modified@@ -10,6 +10,8 @@ module Log # overwrite `BasePresenter#resource_presenter` to return your custom resource presenter. # The only requirement for custom renderers is that they should respond to `present`. class ResourcePresenter + include Decidim::SanitizeHelper + # Public: Initializes the presenter. # # resource - An instance of a model that can be located by @@ -65,7 +67,11 @@ def resource_path # # Returns an HTML-safe String. def present_resource_name - h.translated_attribute extra["title"] + if resource.present? && resource.respond_to?(:presenter) && resource.presenter.respond_to?(:title) + resource.presenter.title(html_escape: true) + else + decidim_escape_translated(extra["title"]).html_safe + end end end end
decidim-core/app/services/decidim/log/diff_changeset_calculator.rb+1 −1 modified@@ -86,7 +86,7 @@ def generate_i18n_changeset(attribute, values, type) locales.flat_map do |locale| previous_value = values.first.try(:[], locale) new_value = values.last.try(:[], locale) - if previous_value == new_value + if previous_value == new_value || (previous_value.nil? && new_value.blank?) nil else label = generate_label(attribute, locale)
decidim-core/lib/decidim/core/test/factories.rb+3 −3 modified@@ -9,7 +9,7 @@ require "decidim/comments/test/factories" def generate_component_name(locales, manifest_name, skip_injection: false) - prepend = skip_injection ? "" : "<script>alert(\"#{manifest_name}\");</script>" + prepend = skip_injection ? "" : "<script>alert('#{manifest_name}');</script>" Decidim::Components::Namer.new(locales, manifest_name).i18n_name.transform_values { |v| [prepend, v].compact_blank.join(" ") } end @@ -26,7 +26,7 @@ def generate_localized_word(field = nil, skip_injection: false) if skip_injection Faker::Lorem.word else - "<script>alert(\"#{field}\");</script> #{Faker::Lorem.word}" + "<script>alert('#{field}');</script> #{Faker::Lorem.word}" end end end @@ -38,7 +38,7 @@ def generate_localized_title(field = nil, skip_injection: false) if skip_injection generate(:title) else - "<script>alert(\"#{field}\");</script> #{generate(:title)}" + "<script>alert('#{field}');</script> #{generate(:title)}" end end end
decidim-core/lib/decidim/core/test/shared_examples/has_attachment_collections.rb+3 −3 modified@@ -39,9 +39,9 @@ it "shows them ordered" do within ".attachments .documents" do - expect(decidim_escape_translated(first_attachment_collection.name).gsub(""", - "\"")).to appear_before(decidim_escape_translated(last_attachment_collection.name).gsub(""", - "\"")) + expect(decidim_escape_translated(first_attachment_collection.name).gsub("'", + "\'")).to appear_before(decidim_escape_translated(last_attachment_collection.name).gsub("'", + "\'")) end end end
decidim-core/lib/decidim/core/test/shared_examples/has_attachments.rb+1 −1 modified@@ -35,7 +35,7 @@ it "shows them ordered" do within "div.wrapper .documents" do - expect(decidim_escape_translated(first_document.title).gsub(""", "\"")).to appear_before(decidim_escape_translated(last_document.title).gsub(""", "\"")) + expect(decidim_escape_translated(first_document.title).gsub("'", "\'")).to appear_before(decidim_escape_translated(last_document.title).gsub("'", "\'")) end within "div.wrapper .images" do
decidim-debates/app/models/decidim/debates/debate.rb+6 −0 modified@@ -56,6 +56,12 @@ class Debate < Debates::ApplicationRecord } scope_search_multi :with_any_state, [:open, :closed] + # Returns the presenter for this debate, to be used in the views. + # Required by ResourceRenderer. + def presenter + Decidim::Debates::DebatePresenter.new(self) + end + def self.log_presenter_class_for(_log) Decidim::Debates::AdminLog::DebatePresenter end
decidim-debates/app/presenters/decidim/debates/admin_log/debate_presenter.rb+0 −4 modified@@ -15,10 +15,6 @@ module AdminLog class DebatePresenter < Decidim::Log::BasePresenter private - def resource_presenter - @resource_presenter ||= Decidim::Debates::Log::ResourcePresenter.new(action_log.resource, h, action_log.extra["resource"]) - end - def diff_fields_mapping { description: "Decidim::Debates::AdminLog::ValueTypes::DebateTitleDescriptionPresenter",
decidim-debates/app/presenters/decidim/debates/admin_log/value_types/debate_title_description_presenter.rb+1 −1 modified@@ -10,7 +10,7 @@ class DebateTitleDescriptionPresenter < Decidim::Log::ValueTypes::DefaultPresent def present return unless value - renderer = Decidim::ContentRenderers::HashtagRenderer.new(h.translated_attribute(value)) + renderer = Decidim::ContentRenderers::HashtagRenderer.new(h.decidim_escape_translated(value)) renderer.render(links: false).html_safe end end
decidim-debates/app/presenters/decidim/debates/log/resource_presenter.rb+0 −18 removed@@ -1,18 +0,0 @@ -# frozen_string_literal: true - -module Decidim - module Debates - module Log - class ResourcePresenter < Decidim::Log::ResourcePresenter - private - - # Private: Presents resource name. - # - # Returns an HTML-safe String. - def present_resource_name - Decidim::Debates::DebatePresenter.new(resource).title - end - end - end - end -end
decidim-debates/spec/shared/manage_debates_examples.rb+30 −63 modified@@ -2,6 +2,7 @@ RSpec.shared_examples "manage debates" do let!(:debate) { create :debate, category: category, component: current_component } + let(:attributes) { attributes_for(:debate, :closed, component: current_component) } before { visit_component_admin } @@ -25,19 +26,15 @@ end describe "updating a debate" do - it "updates a debate" do + it "updates a debate", versioning: true do within find("tr", text: translated(debate.title)) do page.find(".action-icon--edit").click end within ".edit_debate" do - fill_in_i18n( - :debate_title, - "#debate-title-tabs", - en: "My new title", - es: "Mi nuevo título", - ca: "El meu nou títol" - ) + fill_in_i18n(:debate_title, "#debate-title-tabs", **attributes[:title].except("machine_translations")) + fill_in_i18n_editor(:debate_description, "#debate-description-tabs", **attributes[:description].except("machine_translations")) + fill_in_i18n_editor(:debate_instructions, "#debate-instructions-tabs", **attributes[:instructions].except("machine_translations")) find("*[type=submit]").click end @@ -47,8 +44,11 @@ end within "table" do - expect(page).to have_content("My new title") + expect(page).to have_content(translated(attributes[:title])) end + + visit decidim_admin.root_path + expect(page).to have_content("updated the #{translated(attributes[:title])} debate on the") end context "when the debate has an author" do @@ -74,33 +74,15 @@ end end - it "creates a new finite debate" do + it "creates a new finite debate", versioning: true do within ".card-title" do click_link "New Debate" end within ".new_debate" do - fill_in_i18n( - :debate_title, - "#debate-title-tabs", - en: "My debate", - es: "Mi debate", - ca: "El meu debat" - ) - fill_in_i18n_editor( - :debate_description, - "#debate-description-tabs", - en: "Long description", - es: "Descripción más larga", - ca: "Descripció més llarga" - ) - fill_in_i18n_editor( - :debate_instructions, - "#debate-instructions-tabs", - en: "Long instructions", - es: "Instrucciones más largas", - ca: "Instruccions més llargues" - ) + fill_in_i18n(:debate_title, "#debate-title-tabs", **attributes[:title].except("machine_translations")) + fill_in_i18n_editor(:debate_description, "#debate-description-tabs", **attributes[:description].except("machine_translations")) + fill_in_i18n_editor(:debate_instructions, "#debate-instructions-tabs", **attributes[:instructions].except("machine_translations")) choose "Finite" end @@ -126,8 +108,11 @@ end within "table" do - expect(page).to have_content("My debate") + expect(page).to have_content(translated(attributes[:title])) end + + visit decidim_admin.root_path + expect(page).to have_content("created the #{translated(attributes[:title])} debate on the") end it "creates a new open debate" do @@ -136,27 +121,9 @@ end within ".new_debate" do - fill_in_i18n( - :debate_title, - "#debate-title-tabs", - en: "My debate", - es: "Mi debate", - ca: "El meu debat" - ) - fill_in_i18n_editor( - :debate_description, - "#debate-description-tabs", - en: "Long description", - es: "Descripción más larga", - ca: "Descripció més llarga" - ) - fill_in_i18n_editor( - :debate_instructions, - "#debate-instructions-tabs", - en: "Long instructions", - es: "Instrucciones más largas", - ca: "Instruccions més llargues" - ) + fill_in_i18n(:debate_title, "#debate-title-tabs", **attributes[:title].except("machine_translations")) + fill_in_i18n_editor(:debate_description, "#debate-description-tabs", **attributes[:description].except("machine_translations")) + fill_in_i18n_editor(:debate_instructions, "#debate-instructions-tabs", **attributes[:instructions].except("machine_translations")) choose "Open" end @@ -175,8 +142,11 @@ end within "table" do - expect(page).to have_content("My debate") + expect(page).to have_content(translated(attributes[:title])) end + + visit decidim_admin.root_path + expect(page).to have_content("created the #{translated(attributes[:title])} debate on the") end describe "deleting a debate" do @@ -213,20 +183,14 @@ end end - describe "closing a debate" do + describe "closing a debate", versioning: true do it "closes a debate" do within find("tr", text: translated(debate.title)) do page.find(".action-icon--close").click end within ".edit_close_debate" do - fill_in_i18n_editor( - :debate_conclusions, - "#debate-conclusions-tabs", - en: "The debate was great", - es: "El debate fué genial", - ca: "El debat ha anat molt bé" - ) + fill_in_i18n_editor(:debate_conclusions, "#debate-conclusions-tabs", **attributes[:conclusions].except("machine_translations")) find("*[type=submit]").click end @@ -242,7 +206,10 @@ end end - expect(page).to have_content("The debate was great") + expect(page).to have_content(strip_tags(translated(attributes[:conclusions])).strip) + + visit decidim_admin.root_path + expect(page).to have_content("performed some action on #{translated(debate.title)} in") end context "when the debate has an author" do
decidim-meetings/app/presenters/decidim/meetings/admin_log/meeting_presenter.rb+0 −4 modified@@ -15,10 +15,6 @@ module AdminLog class MeetingPresenter < Decidim::Log::BasePresenter private - def resource_presenter - @resource_presenter ||= Decidim::Meetings::Log::ResourcePresenter.new(action_log.resource, h, action_log.extra["resource"]) - end - def diff_fields_mapping { address: :string,
decidim-meetings/app/presenters/decidim/meetings/admin_log/value_types/meeting_title_description_presenter.rb+1 −1 modified@@ -10,7 +10,7 @@ class MeetingTitleDescriptionPresenter < Decidim::Log::ValueTypes::DefaultPresen def present return unless value - renderer = Decidim::ContentRenderers::HashtagRenderer.new(h.translated_attribute(value)) + renderer = Decidim::ContentRenderers::HashtagRenderer.new(h.decidim_escape_translated(value)) renderer.render(links: false).html_safe end end
decidim-meetings/app/presenters/decidim/meetings/log/resource_presenter.rb+0 −18 removed@@ -1,18 +0,0 @@ -# frozen_string_literal: true - -module Decidim - module Meetings - module Log - class ResourcePresenter < Decidim::Log::ResourcePresenter - private - - # Private: Presents resource name. - # - # Returns an HTML-safe String. - def present_resource_name - Decidim::Meetings::MeetingPresenter.new(resource).title - end - end - end - end -end
decidim-meetings/spec/cells/decidim/meetings/meeting_highlighted_list_item_cell_spec.rb+1 −1 modified@@ -19,7 +19,7 @@ module Decidim::Meetings context "when title contains special html entities" do it "escapes them correctly" do - expect(subject.to_s).to include(decidim_escape_translated(meeting.title).gsub(""", "\"")) + expect(subject.to_s).to include(decidim_escape_translated(meeting.title).gsub("'", "\'")) end end end
decidim-meetings/spec/cells/decidim/meetings/meeting_list_item_cell_spec.rb+1 −1 modified@@ -17,7 +17,7 @@ module Decidim::Meetings context "when title contains special html entities" do it "escapes them correctly" do - expect(subject.to_s).to include(decidim_escape_translated(meeting.title).gsub(""", "\"")) + expect(subject.to_s).to include(decidim_escape_translated(meeting.title).gsub("'", "\'")) end end end
decidim-meetings/spec/system/admin/admin_manages_meetings_spec.rb+25 −38 modified@@ -10,6 +10,12 @@ let(:latitude) { 40.1234 } let(:longitude) { 2.1234 } let(:service_titles) { ["This is the first service", "This is the second service"] } + let(:base_date) { Time.new.utc } + let(:meeting_start_date) { base_date.strftime("%d/%m/%Y") } + let(:meeting_start_time) { base_date.utc.strftime("%H:%M") } + let(:meeting_end_date) { ((base_date + 2.days) + 1.month).strftime("%d/%m/%Y") } + let(:meeting_end_time) { (base_date + 4.hours).strftime("%H:%M") } + let(:attributes) { attributes_for(:meeting, component: current_component) } include_context "when managing a component as an admin" @@ -153,13 +159,12 @@ end within ".edit_meeting" do - fill_in_i18n( - :meeting_title, - "#meeting-title-tabs", - en: "My new title", - es: "Mi nuevo título", - ca: "El meu nou títol" - ) + fill_in_i18n(:meeting_title, "#meeting-title-tabs", **attributes[:title].except("machine_translations")) + + fill_in_i18n(:meeting_location, "#meeting-location-tabs", **attributes[:location].except("machine_translations")) + fill_in_i18n(:meeting_location_hints, "#meeting-location_hints-tabs", **attributes[:location_hints].except("machine_translations")) + fill_in_i18n_editor(:meeting_description, "#meeting-description-tabs", **attributes[:description].except("machine_translations")) + fill_in_geocoding :meeting_address, with: address find("*[type=submit]").click @@ -168,8 +173,11 @@ expect(page).to have_admin_callout("successfully") within "table" do - expect(page).to have_content("My new title") + expect(page).to have_content(translated(attributes[:title])) end + + visit decidim_admin.root_path + expect(page).to have_content("updated the #{translated(attributes[:title])} meeting on the") end it "sets registration enabled to true when registration type is on this platform" do @@ -265,40 +273,16 @@ expect(page).to have_current_path(meeting_path) end - it "creates a new meeting", :slow, :serves_geocoding_autocomplete do # rubocop:disable RSpec/ExampleLength + it "creates a new meeting", :slow, :serves_geocoding_autocomplete do find(".card-title a.button").click - fill_in_i18n( - :meeting_title, - "#meeting-title-tabs", - en: "My meeting", - es: "Mi meeting", - ca: "El meu meeting" - ) + fill_in_i18n(:meeting_title, "#meeting-title-tabs", **attributes[:title].except("machine_translations")) select "In person", from: :meeting_type_of_meeting - fill_in_i18n( - :meeting_location, - "#meeting-location-tabs", - en: "Location", - es: "Location", - ca: "Location" - ) - fill_in_i18n( - :meeting_location_hints, - "#meeting-location_hints-tabs", - en: "Location hints", - es: "Location hints", - ca: "Location hints" - ) - fill_in_i18n_editor( - :meeting_description, - "#meeting-description-tabs", - en: "A longer description", - es: "Descripción más larga", - ca: "Descripció més llarga" - ) + fill_in_i18n(:meeting_location, "#meeting-location-tabs", **attributes[:location].except("machine_translations")) + fill_in_i18n(:meeting_location_hints, "#meeting-location_hints-tabs", **attributes[:location_hints].except("machine_translations")) + fill_in_i18n_editor(:meeting_description, "#meeting-description-tabs", **attributes[:description].except("machine_translations")) fill_in_geocoding :meeting_address, with: address fill_in_services @@ -325,8 +309,11 @@ expect(page).to have_admin_callout("successfully") within "table" do - expect(page).to have_content("My meeting") + expect(page).to have_content(translated(attributes[:title])) end + + visit decidim_admin.root_path + expect(page).to have_content("created the #{translated(attributes[:title])} meeting on the") end context "when using the front-end geocoder", :serves_geocoding_autocomplete do
decidim-pages/spec/system/admin_spec.rb+8 −9 modified@@ -21,25 +21,24 @@ visit_component_admin end - it_behaves_like "having a rich text editor for field", ".tabs-content[data-tabs-content='page-body-tabs']", "full" + let!(:attributes) { attributes_for(:static_page) } - it "updates the page" do - new_body = { - en: "<p>New body</p>", - ca: "<p>Nou cos</p>", - es: "<p>Nuevo cuerpo</p>" - } + it_behaves_like "having a rich text editor for field", ".tabs-content[data-tabs-content='page-body-tabs']", "full" + it "updates the page", versioning: true do within "form.edit_page" do - fill_in_i18n_editor(:page_body, "#page-body-tabs", new_body) + fill_in_i18n_editor(:page_body, "#page-body-tabs", **attributes[:content].except("machine_translations")) find("*[type=submit]").click end expect(page).to have_admin_callout("successfully") visit_component - expect(page).to have_content("New body") + expect(page).to have_content(translated(component.name).upcase) + + visit decidim_admin.root_path + expect(page).to have_content("updated the #{translated(component.name)} page") end end
decidim-participatory_processes/app/cells/decidim/participatory_processes/process_m_cell.rb+1 −1 modified@@ -43,7 +43,7 @@ def resource_image_path def step_cta_text if translated_in_current_locale?(model.active_step&.cta_text) - translated_attribute(model.active_step.cta_text) + decidim_escape_translated(model.active_step.cta_text) else t(model.cta_button_text_key_accessible, resource_name: title, scope: "layouts.decidim.participatory_processes.participatory_process") end
decidim-participatory_processes/lib/decidim/participatory_processes/test/factories.rb+1 −0 modified@@ -124,6 +124,7 @@ end title { generate_localized_title(:participatory_process_step_title, skip_injection: skip_injection) } description { generate_localized_description(:participatory_process_step_description, skip_injection: skip_injection) } + cta_text { generate_localized_description(:participatory_process_step_cta_text, skip_injection: skip_injection) } start_date { 1.month.ago } end_date { 2.months.from_now } position { nil }
decidim-participatory_processes/spec/shared/manage_process_admins_examples.rb+10 −3 modified@@ -2,6 +2,7 @@ shared_examples "manage process admins examples" do let(:other_user) { create :user, organization: organization, email: "my_email@example.org" } + let(:attributes) { attributes_for(:user, organization: organization) } let!(:process_admin) do create :process_admin, @@ -23,12 +24,12 @@ end end - it "creates a new process admin" do + it "creates a new process admin", versioning: true do find(".card-title a.new").click within ".new_participatory_process_user_role" do fill_in :participatory_process_user_role_email, with: other_user.email - fill_in :participatory_process_user_role_name, with: "John Doe" + fill_in :participatory_process_user_role_name, with: attributes[:name] select "Administrator", from: :participatory_process_user_role_role find("*[type=submit]").click @@ -39,6 +40,9 @@ within "#process_admins table" do expect(page).to have_content(other_user.email) end + + visit decidim_admin.root_path + expect(page).to have_content("invited the participant #{other_user.name} to the #{translated(participatory_process.title)} participatory process") end describe "when managing different users" do @@ -48,7 +52,7 @@ visit current_path end - it "updates a process admin" do + it "updates a process admin", versioning: true do within "#process_admins" do within find("#process_admins tr", text: other_user.email) do click_link "Edit" @@ -66,6 +70,9 @@ within "#process_admins table" do expect(page).to have_content("Administrator") end + + visit decidim_admin.root_path + expect(page).to have_content("changed the role of the participant #{other_user.name} in the #{translated(participatory_process.title)} participatory process") end it "deletes a participatory_process_user_role" do
decidim-participatory_processes/spec/shared/manage_processes_examples.rb+17 −8 modified@@ -88,19 +88,25 @@ def filter_by_group(group_title) context "when updating a participatory process" do let(:image3_filename) { "city3.jpeg" } let(:image3_path) { Decidim::Dev.asset(image3_filename) } + let(:attributes) { attributes_for(:participatory_process, organization: organization) } 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" - ) + fill_in_i18n(:participatory_process_title, "#participatory_process-title-tabs", **attributes[:title].except("machine_translations")) + fill_in_i18n(:participatory_process_subtitle, "#participatory_process-subtitle-tabs", **attributes[:subtitle].except("machine_translations")) + fill_in_i18n_editor(:participatory_process_short_description, "#participatory_process-short_description-tabs", **attributes[:short_description].except("machine_translations")) + fill_in_i18n_editor(:participatory_process_description, "#participatory_process-description-tabs", **attributes[:description].except("machine_translations")) + fill_in_i18n_editor(:participatory_process_announcement, "#participatory_process-announcement-tabs", **attributes[:announcement].except("machine_translations")) + fill_in_i18n(:participatory_process_developer_group, "#participatory_process-developer_group-tabs", **attributes[:developer_group].except("machine_translations")) + fill_in_i18n(:participatory_process_local_area, "#participatory_process-local_area-tabs", **attributes[:local_area].except("machine_translations")) + fill_in_i18n(:participatory_process_meta_scope, "#participatory_process-meta_scope-tabs", **attributes[:meta_scope].except("machine_translations")) + fill_in_i18n(:participatory_process_target, "#participatory_process-target-tabs", **attributes[:target].except("machine_translations")) + fill_in_i18n(:participatory_process_participatory_scope, "#participatory_process-participatory_scope-tabs", **attributes[:participatory_scope].except("machine_translations")) + fill_in_i18n(:participatory_process_participatory_structure, "#participatory_process-participatory_structure-tabs", **attributes[:participatory_structure].except("machine_translations")) + dynamically_attach_file(:participatory_process_banner_image, image3_path, remove_before: true) page.execute_script("$('#participatory_process_end_date').focus()") @@ -113,9 +119,12 @@ def filter_by_group(group_title) expect(page).to have_admin_callout("successfully") within ".container" do - expect(page).to have_selector("input[value='My new title']") + expect(page).to have_selector(%(input[value="#{translated(attributes[:title])}"])) expect(page).to have_css("img[src*='#{image3_filename}']") end + + visit decidim_admin.root_path + expect(page).to have_content("updated the #{translated(attributes[:title])} participatory process") end end
decidim-participatory_processes/spec/shared/manage_process_steps_examples.rb+17 −18 modified@@ -9,6 +9,7 @@ active: active ) end + let(:attributes) { attributes_for(:participatory_process_step, participatory_process: participatory_process) } before do switch_to_host(organization.host) @@ -21,23 +22,20 @@ before { find(".card-title a.button").click } end - it "creates a new participatory_process" do + it "creates a new participatory_process", versioning: true do find(".card-title a.button").click fill_in_i18n( :participatory_process_step_title, "#participatory_process_step-title-tabs", - en: "My participatory process step", - es: "Mi fase de proceso participativo", - ca: "La meva fase de procés participatiu" + **attributes[:title].except("machine_translations") ) fill_in_i18n_editor( :participatory_process_step_description, "#participatory_process_step-description-tabs", - en: "A longer description", - es: "Descripción más larga", - ca: "Descripció més llarga" + **attributes[:description].except("machine_translations") ) + fill_in_i18n(:participatory_process_step_cta_text, "#participatory_process_step-cta_text-tabs", **attributes[:cta_text].except("machine_translations")) page.execute_script("$('#participatory_process_step_start_date').focus()") page.find(".datepicker-dropdown .day:not(.new)", text: "12").click @@ -56,37 +54,38 @@ expect(page).to have_admin_callout("successfully") within "#steps table" do - expect(page).to have_content("My participatory process step") + expect(page).to have_content(translated(attributes[:title])) expect(page).to have_content("12,") expect(page).to have_content("22,") end + visit decidim_admin.root_path + expect(page).to have_content("created the #{translated(attributes[:title])} phase in") end - it "updates a participatory_process_step" do + it "updates a participatory_process_step", versioning: true do within "#steps" do within find("tr", text: translated(process_step.title)) do click_link "Edit" end end within ".edit_participatory_process_step" do - fill_in_i18n( - :participatory_process_step_title, - "#participatory_process_step-title-tabs", - en: "My new title", - es: "Mi nuevo título", - ca: "El meu nou títol" - ) + fill_in_i18n(:participatory_process_step_title, "#participatory_process_step-title-tabs", **attributes[:title].except("machine_translations")) + fill_in_i18n_editor(:participatory_process_step_description, "#participatory_process_step-description-tabs", **attributes[:description].except("machine_translations")) + fill_in_i18n(:participatory_process_step_cta_text, "#participatory_process_step-cta_text-tabs", **attributes[:cta_text].except("machine_translations")) find("*[type=submit]").click end expect(page).to have_admin_callout("successfully") within "#steps table" do - expect(page).to have_content("My new title") - click_link("My new title") + expect(page).to have_content(translated(attributes[:title])) + click_link(translated(attributes[:title])) end + + visit decidim_admin.root_path + expect(page).to have_content("updated the #{translated(attributes[:title])} phase in") end context "when deleting a participatory process step" do
decidim-participatory_processes/spec/system/admin/admin_manages_participatory_processes_spec.rb+16 −28 modified@@ -24,6 +24,7 @@ let(:image2_filename) { "city2.jpeg" } let(:image2_path) { Decidim::Dev.asset(image2_filename) } + let(:attributes) { attributes_for(:participatory_process, organization: organization) } before do click_link "New process" @@ -35,34 +36,18 @@ it "creates a new participatory process" do within ".new_participatory_process" do - fill_in_i18n( - :participatory_process_title, - "#participatory_process-title-tabs", - en: "My participatory process", - es: "Mi proceso participativo", - ca: "El meu procés participatiu" - ) - fill_in_i18n( - :participatory_process_subtitle, - "#participatory_process-subtitle-tabs", - en: "Subtitle", - es: "Subtítulo", - ca: "Subtítol" - ) - fill_in_i18n_editor( - :participatory_process_short_description, - "#participatory_process-short_description-tabs", - en: "Short description", - es: "Descripción corta", - ca: "Descripció curta" - ) - fill_in_i18n_editor( - :participatory_process_description, - "#participatory_process-description-tabs", - en: "A longer description", - es: "Descripción más larga", - ca: "Descripció més llarga" - ) + fill_in_i18n(:participatory_process_title, "#participatory_process-title-tabs", **attributes[:title].except("machine_translations")) + fill_in_i18n(:participatory_process_subtitle, "#participatory_process-subtitle-tabs", **attributes[:subtitle].except("machine_translations")) + fill_in_i18n_editor(:participatory_process_short_description, "#participatory_process-short_description-tabs", **attributes[:short_description].except("machine_translations")) + fill_in_i18n_editor(:participatory_process_description, "#participatory_process-description-tabs", **attributes[:description].except("machine_translations")) + fill_in_i18n_editor(:participatory_process_announcement, "#participatory_process-announcement-tabs", **attributes[:announcement].except("machine_translations")) + + fill_in_i18n(:participatory_process_developer_group, "#participatory_process-developer_group-tabs", **attributes[:developer_group].except("machine_translations")) + fill_in_i18n(:participatory_process_local_area, "#participatory_process-local_area-tabs", **attributes[:local_area].except("machine_translations")) + fill_in_i18n(:participatory_process_meta_scope, "#participatory_process-meta_scope-tabs", **attributes[:meta_scope].except("machine_translations")) + fill_in_i18n(:participatory_process_target, "#participatory_process-target-tabs", **attributes[:target].except("machine_translations")) + fill_in_i18n(:participatory_process_participatory_scope, "#participatory_process-participatory_scope-tabs", **attributes[:participatory_scope].except("machine_translations")) + fill_in_i18n(:participatory_process_participatory_structure, "#participatory_process-participatory_structure-tabs", **attributes[:participatory_structure].except("machine_translations")) group_title = participatory_process_groups.first.title["en"] select group_title, from: :participatory_process_participatory_process_group_id @@ -86,6 +71,9 @@ expect(page).to have_content("Phases") expect(page).to have_content("Introduction") end + + visit decidim_admin.root_path + expect(page).to have_content("created the #{translated(attributes[:title])} participatory process") end end
decidim-participatory_processes/spec/system/admin/admin_manages_participatory_process_groups_spec.rb+24 −49 modified@@ -8,7 +8,7 @@ let!(:participatory_processes) do create_list(:participatory_process, 3, organization: organization) end - + let(:attributes) { attributes_for(:participatory_process_group, organization: organization) } let(:image1_filename) { "city.jpeg" } let(:image1_path) { Decidim::Dev.asset(image1_filename) } @@ -22,33 +22,16 @@ before { find(".card-title .new").click } end - it "creates a new participatory process group" do + it "creates a new participatory process group", versioning: true do find(".card-title .new").click within ".new_participatory_process_group" do - fill_in_i18n( - :participatory_process_group_title, - "#participatory_process_group-title-tabs", - en: "My group", - es: "Mi grupo", - ca: "El meu grup" - ) - fill_in_i18n_editor( - :participatory_process_group_description, - "#participatory_process_group-description-tabs", - en: "A longer description", - es: "Descripción más larga", - ca: "Descripció més llarga" - ) + fill_in_i18n(:participatory_process_group_title, "#participatory_process_group-title-tabs", **attributes[:title].except("machine_translations")) + fill_in_i18n(:participatory_process_group_developer_group, "#participatory_process_group-developer_group-tabs", **attributes[:developer_group].except("machine_translations")) + fill_in_i18n_editor(:participatory_process_group_description, "#participatory_process_group-description-tabs", **attributes[:description].except("machine_translations")) + fill_in :participatory_process_group_hashtag, with: "hashtag" fill_in :participatory_process_group_group_url, with: "http://example.org" - fill_in_i18n( - :participatory_process_group_developer_group, - "#participatory_process_group-developer_group-tabs", - en: "X corporation", - es: "La corporación X", - ca: "La corporació X" - ) select participatory_processes.first.title["en"], from: :participatory_process_group_participatory_process_ids end @@ -59,12 +42,17 @@ end expect(page).to have_admin_callout("successfully") - expect(page).to have_field(:participatory_process_group_title_en, with: "My group") + expect(page).to have_field(:participatory_process_group_title_en, with: translated(attributes[:title])) expect(page).to have_field(:participatory_process_group_hashtag, with: "hashtag") expect(page).to have_field(:participatory_process_group_group_url, with: "http://example.org") - expect(page).to have_field(:participatory_process_group_developer_group_en, with: "X corporation") + expect(page).to have_field(:participatory_process_group_developer_group_en, with: translated(attributes[:developer_group])) expect(page).to have_select("Related processes", selected: participatory_processes.first.title["en"]) expect(page).to have_css("img[src*='#{image1_filename}']") + + expect(page).to have_admin_callout("successfully") + + visit decidim_admin.root_path + expect(page).to have_content("created the #{translated(attributes[:title])} participatory process group") end context "with existing groups" do @@ -84,29 +72,13 @@ end within ".edit_participatory_process_group" do - fill_in_i18n( - :participatory_process_group_title, - "#participatory_process_group-title-tabs", - en: "My old group", - es: "Mi grupo antiguo", - ca: "El meu grup antic" - ) - fill_in_i18n_editor( - :participatory_process_group_description, - "#participatory_process_group-description-tabs", - en: "New description", - es: "Nueva descripción", - ca: "Nova descripció" - ) + fill_in_i18n(:participatory_process_group_title, "#participatory_process_group-title-tabs", **attributes[:title].except("machine_translations")) + fill_in_i18n_editor(:participatory_process_group_description, "#participatory_process_group-description-tabs", **attributes[:description].except("machine_translations")) + fill_in :participatory_process_group_hashtag, with: "new_hashtag" fill_in :participatory_process_group_group_url, with: "http://new-example.org" - fill_in_i18n( - :participatory_process_group_developer_group, - "#participatory_process_group-developer_group-tabs", - en: "Z corporation", - es: "La corporación Z", - ca: "La corporació Z" - ) + fill_in_i18n(:participatory_process_group_developer_group, "#participatory_process_group-developer_group-tabs", **attributes[:developer_group].except("machine_translations")) + select participatory_processes.last.title["en"], from: :participatory_process_group_participatory_process_ids end @@ -117,13 +89,16 @@ end expect(page).to have_admin_callout("successfully") - expect(page).to have_field(:participatory_process_group_title_en, with: "My old group") - expect(page).to have_content("New description") + expect(page).to have_field(:participatory_process_group_title_en, with: translated(attributes[:title])) + expect(page).to have_content(strip_tags(translated(attributes[:description])).strip) expect(page).to have_field(:participatory_process_group_hashtag, with: "new_hashtag") expect(page).to have_field(:participatory_process_group_group_url, with: "http://new-example.org") - expect(page).to have_field(:participatory_process_group_developer_group_en, with: "Z corporation") + expect(page).to have_field(:participatory_process_group_developer_group_en, with: translated(attributes[:developer_group])) expect(page).to have_select("Related processes", selected: participatory_processes.last.title["en"]) expect(page).to have_css("img[src*='#{image2_filename}']") + + visit decidim_admin.root_path + expect(page).to have_content("updated the #{translated(attributes[:title])} participatory process group") end it "validates the group attributes" do
decidim-participatory_processes/spec/system/admin/admin_manages_participatory_process_types_spec.rb+14 −17 modified@@ -8,6 +8,7 @@ let!(:participatory_processes) do create_list(:participatory_process, 3, organization: organization) end + let(:attributes) { attributes_for(:participatory_process_type, organization: organization) } describe "Managing participatory process types" do before do @@ -16,25 +17,23 @@ visit decidim_admin_participatory_processes.participatory_process_types_path end - it "can create new participatory process types" do + it "can create new participatory process types", versioning: true do click_link "New process type" within ".new_participatory_process_type" do - fill_in_i18n( - :participatory_process_type_title, - "#participatory_process_type-title-tabs", - en: "My participatory process type", - es: "Mi tipo de proceso participativo", - ca: "El meu tipus de procés participatiu " - ) + fill_in_i18n(:participatory_process_type_title, "#participatory_process_type-title-tabs", **attributes[:title].except("machine_translations")) + find("*[type=submit]").click end expect(page).to have_admin_callout("successfully") within "table" do - expect(page).to have_content("My participatory process type") + expect(page).to have_content(translated(attributes[:title])) end + + visit decidim_admin.root_path + expect(page).to have_content("created the #{translated(attributes[:title])} participatory process type") end context "with existing participatory process types" do @@ -56,21 +55,19 @@ end within ".edit_participatory_process_type" do - fill_in_i18n( - :participatory_process_type_title, - "#participatory_process_type-title-tabs", - en: "Another participatory process type", - es: "Otro tipo de proceso participativo", - ca: "Un altre tipus de procés participatiu" - ) + fill_in_i18n(:participatory_process_type_title, "#participatory_process_type-title-tabs", **attributes[:title].except("machine_translations")) + find("*[type=submit]").click end expect(page).to have_admin_callout("successfully") within "table" do - expect(page).to have_content("Another participatory process type") + expect(page).to have_content(translated(attributes[:title])) end + + visit decidim_admin.root_path + expect(page).to have_content("updated the #{translated(attributes[:title])} participatory process type") end it "can delete them" do
decidim-participatory_processes/spec/types/participatory_process_step_type_spec.rb+1 −1 modified@@ -80,7 +80,7 @@ module ParticipatoryProcesses let(:query) { '{ callToActionText { locales translation(locale:"en") } }' } it "returns the step's call to action text" do - expect(response["callToActionText"]["locales"]).to include(*model.cta_text.keys) + expect(response["callToActionText"]["locales"]).to include(*model.cta_text.except("machine_translations").keys) expect(response["callToActionText"]["translation"]).to eq(model.cta_text["en"]) end end
decidim-proposals/app/presenters/decidim/proposals/admin_log/proposal_presenter.rb+1 −5 modified@@ -15,13 +15,9 @@ module AdminLog class ProposalPresenter < Decidim::Log::BasePresenter private - def resource_presenter - @resource_presenter ||= Decidim::Proposals::Log::ResourcePresenter.new(action_log.resource, h, action_log.extra["resource"]) - end - def diff_fields_mapping { - title: "Decidim::Proposals::AdminLog::ValueTypes::ProposalTitleBodyPresenter", + title: :i18n, body: "Decidim::Proposals::AdminLog::ValueTypes::ProposalTitleBodyPresenter", state: "Decidim::Proposals::AdminLog::ValueTypes::ProposalStatePresenter", answered_at: :date,
decidim-proposals/app/presenters/decidim/proposals/admin_log/value_types/proposal_title_body_presenter.rb+1 −3 modified@@ -5,12 +5,10 @@ module Proposals module AdminLog module ValueTypes class ProposalTitleBodyPresenter < Decidim::Log::ValueTypes::DefaultPresenter - include Decidim::TranslatableAttributes - def present return unless value - translated_value = translated_attribute(value) + translated_value = h.decidim_escape_translated(value) return if translated_value.blank? renderer = Decidim::ContentRenderers::HashtagRenderer.new(translated_value)
decidim-proposals/app/presenters/decidim/proposals/log/resource_presenter.rb+0 −22 removed@@ -1,22 +0,0 @@ -# frozen_string_literal: true - -module Decidim - module Proposals - module Log - class ResourcePresenter < Decidim::Log::ResourcePresenter - private - - # Private: Presents resource name. - # - # Returns an HTML-safe String. - def present_resource_name - if resource.present? - Decidim::Proposals::ProposalPresenter.new(resource).title - else - super - end - end - end - end - end -end
decidim-proposals/app/presenters/decidim/proposals/log/valuation_assignment_presenter.rb+1 −1 modified@@ -11,7 +11,7 @@ class ValuationAssignmentPresenter < Decidim::Log::ResourcePresenter # Returns an HTML-safe String. def present_resource_name if resource.present? - Decidim::Proposals::ProposalPresenter.new(resource.proposal).title + resource.proposal.presenter.title(html_escape: true) else super end
decidim-proposals/lib/decidim/proposals/test/factories.rb+7 −1 modified@@ -433,7 +433,13 @@ transient do skip_injection { false } end - body { Faker::Lorem.sentences(number: 3).join("\n") } + body do + if skip_injection + generate(:title) + else + "<script>alert(\"proposal_note_body\");</script> #{generate(:title)}" + end + end proposal { build(:proposal, skip_injection: skip_injection) } author { build(:user, organization: proposal.organization, skip_injection: skip_injection) } end
decidim-proposals/spec/presenters/decidim/log/resource_presenter_spec.rb+1 −6 renamed@@ -2,7 +2,7 @@ require "spec_helper" -describe Decidim::Proposals::Log::ResourcePresenter, type: :helper do +describe Decidim::Log::ResourcePresenter, type: :helper do let(:presenter) { described_class.new(resource, helper, extra) } let(:resource) { create(:proposal, title: Faker::Book.unique.title) } let(:extra) do @@ -12,11 +12,6 @@ end let(:resource_path) { Decidim::ResourceLocatorPresenter.new(resource).path } - before do - helper.extend(Decidim::ApplicationHelper) - helper.extend(Decidim::TranslationsHelper) - end - context "when the resource exists" do it "links to its public page with the name of the proposal" do html = presenter.present
decidim-proposals/spec/presenters/decidim/proposals/admin_log/value_types/proposal_title_body_presenter_spec.rb+10 −3 modified@@ -2,16 +2,23 @@ require "spec_helper" -describe Decidim::Proposals::AdminLog::ValueTypes::ProposalTitleBodyPresenter do - subject { described_class.new(value, _helpers) } +describe Decidim::Proposals::AdminLog::ValueTypes::ProposalTitleBodyPresenter, type: :helper do + subject { described_class.new(value, helper) } + + before do + module FooBar + include Decidim::SanitizeHelper + end + + helper.extend FooBar + end let(:value) do { "en" => "My value", "es" => "My title in Spanish" } end - let(:_helpers) { nil } describe "#present" do it "handles i18n fields" do
decidim-proposals/spec/shared/manage_proposals_examples.rb+9 −5 modified@@ -66,6 +66,8 @@ end context "when process is not related to any scope" do + let(:attributes) { attributes_for(:proposal, component: current_component) } + it "can be related to a scope" do click_link "New proposal" @@ -74,12 +76,12 @@ end end - it "creates a new proposal", :slow do + it "creates a new proposal", versioning: true do click_link "New proposal" within ".new_proposal" do - fill_in_i18n :proposal_title, "#proposal-title-tabs", en: "Make decidim great again" - fill_in_i18n_editor :proposal_body, "#proposal-body-tabs", en: "Decidim is great but it can be better" + fill_in_i18n :proposal_title, "#proposal-title-tabs", **attributes[:title].except("machine_translations") + fill_in_i18n_editor :proposal_body, "#proposal-body-tabs", **attributes[:body].except("machine_translations") select translated(category.name), from: :proposal_category_id scope_pick select_data_picker(:proposal_scope_id), scope find("*[type=submit]").click @@ -90,11 +92,13 @@ within "table" do proposal = Decidim::Proposals::Proposal.last - expect(page).to have_content("Make decidim great again") - expect(translated(proposal.body)).to eq("<p>Decidim is great but it can be better</p>") + expect(page).to have_content(translated(attributes[:title])) + expect(translated(proposal.body)).to eq("<p>#{strip_tags(translated(attributes[:body]))}</p>") expect(proposal.category).to eq(category) expect(proposal.scope).to eq(scope) end + visit decidim_admin.root_path + expect(page).to have_content("created the #{translated(attributes[:title])} proposal") end end
decidim-proposals/spec/system/admin/admin_edits_proposal_spec.rb+10 −6 modified@@ -22,25 +22,29 @@ end describe "editing an official proposal" do - let(:new_title) { "This is my proposal new title" } - let(:new_body) { "This is my proposal new body" } + let(:attributes) { attributes_for(:proposal, component: current_component) } it "can be updated" do visit_component_admin find("a.action-icon--edit-proposal").click expect(page).to have_content "Update proposal" - fill_in_i18n :proposal_title, "#proposal-title-tabs", en: new_title - fill_in_i18n_editor :proposal_body, "#proposal-body-tabs", en: new_body + fill_in_i18n :proposal_title, "#proposal-title-tabs", **attributes[:title].except("machine_translations") + fill_in_i18n_editor :proposal_body, "#proposal-body-tabs", **attributes[:body].except("machine_translations") click_button "Update" preview_window = window_opened_by { find("a.action-icon--preview").click } within_window preview_window do - expect(page).to have_content(new_title) - expect(page).to have_content(new_body) + expect(page).to have_content(translated(attributes[:title])) + expect(page).to have_content(strip_tags(translated(attributes[:body])).strip) end + + expect(page).to have_admin_callout("successfully") + + visit decidim_admin.root_path + expect(page).to have_content("updated the #{translated(attributes[:title])} official proposal") end context "when the proposal has some votes" do
decidim-proposals/spec/system/admin/admin_manages_proposal_valuators_spec.rb+5 −0 modified@@ -52,6 +52,11 @@ expect(page).to have_selector("td.valuators-count", text: 1) end end + + it "displays log" do + visit decidim_admin.root_path + expect(page).to have_content("assigned the #{translated(proposal.title)} proposal to a valuator") + end end end
decidim-proposals/spec/system/admin/index_proposal_notes_spec.rb+8 −4 modified@@ -9,6 +9,7 @@ let(:manifest_name) { "proposals" } let(:proposal) { create(:proposal, component: component) } let(:participatory_space) { component.participatory_space } + let(:attributes) { attributes_for(:proposal_note) } let(:body) { "New awesome body" } let(:proposal_notes_count) { 5 } @@ -32,24 +33,27 @@ it "shows proposal notes for the current proposal" do proposal_notes.each do |proposal_note| expect(page).to have_content(proposal_note.author.name) - expect(page).to have_content(proposal_note.body) + expect(page).to have_content(decidim_sanitize_translated(proposal_note.body)) end expect(page).to have_selector("form") end context "when the form has a text inside body" do - it "creates a proposal note", :slow do + it "creates a proposal note", versioning: true do within ".new_proposal_note" do - fill_in :proposal_note_body, with: body + fill_in :proposal_note_body, with: attributes[:body] find("*[type=submit]").click end expect(page).to have_admin_callout("successfully") within ".comment-thread .card:last-child" do - expect(page).to have_content("New awesome body") + expect(page).to have_content(decidim_sanitize_translated(attributes[:body])) end + + visit decidim_admin.root_path + expect(page).to have_content("left a private note on the #{translated(proposal.title)} proposal") end end
decidim-proposals/spec/system/amendable/amendment_diff_spec.rb+2 −2 modified@@ -133,14 +133,14 @@ end context "and the proposal author is reviewing an emendation to their proposal before accepting it" do - let(:user) { proposal.creator_author } + let!(:user) { proposal.creator_author } before do proposal.update(title: { en: "Updated long enough title" }, body: { en: "Updated one liner body" }) # The last version of the emendation should hold the amending attribute values. emendation.update(title: { en: "Amended long enough title" }, body: { en: "Amended one liner body" }) - visit emendation_path login_as user, scope: :user + visit emendation_path visit decidim.review_amend_path(amendment) end
decidim-proposals/spec/system/collaborative_drafts_spec.rb+1 −1 modified@@ -91,7 +91,7 @@ end let(:html_body) { strip_tags(collaborative_draft.body).gsub(/\n/, " ").strip } - let(:stripped_body) { %(alert("collaborative_draft_body"); #{html_body}) } + let(:stripped_body) { %(alert('collaborative_draft_body'); #{html_body}) } it "shows the title" do expect(page).to have_content(collaborative_draft.title)
decidim-sortitions/spec/shared/manage_sortitions_examples.rb+9 −23 modified@@ -56,37 +56,20 @@ 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 } + let(:attributes) { attributes_for(:sortition, component: current_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 + it "shows the sortition details", versioning: true 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" - ) + + fill_in_i18n_editor(:sortition_witnesses, "#sortition-witnesses-tabs", **attributes[:witnesses].except("machine_translations")) + fill_in_i18n_editor(:sortition_additional_info, "#sortition-additional_info-tabs", **attributes[:additional_info].except("machine_translations")) + fill_in_i18n(:sortition_title, "#sortition-title-tabs", **attributes[:title].except("machine_translations")) accept_confirm { find("*[type=submit]").click } end @@ -114,6 +97,9 @@ expect(page).to have_content(translated(p.title)) end end + + visit decidim_admin.root_path + expect(page).to have_content("created the #{translated(attributes[:title])} sortition") end end end
decidim-sortitions/spec/shared/update_sortitions_examples.rb+7 −16 modified@@ -3,6 +3,7 @@ shared_examples "update sortitions" do describe "update sortition data" do let!(:sortition) { create(:sortition, component: current_component) } + let(:attributes) { attributes_for(:sortition, component: current_component) } before do visit_component_admin @@ -24,28 +25,18 @@ end context "when updates a sortition" do - it "Redirects to sortitions view" do + it "Redirects to sortitions view", versioning: true do within ".edit_sortition" do - 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" - ) + fill_in_i18n_editor(:sortition_additional_info, "#sortition-additional_info-tabs", **attributes[:additional_info].except("machine_translations")) + fill_in_i18n(:sortition_title, "#sortition-title-tabs", **attributes[:title].except("machine_translations")) find("*[type=submit]").click end expect(page).to have_admin_callout("successfully") + + visit decidim_admin.root_path + expect(page).to have_content("updated the #{translated(attributes[:title])} sortition") end end end
23fc8d702a49Backport 'Refactor malformed titles in admin logs (part 2)' to v0.28 (#13083)
20 files changed · +214 −118
decidim-admin/lib/decidim/admin/test/manage_attachment_collections_examples.rb+12 −11 modified@@ -2,6 +2,7 @@ shared_examples "manage attachment collections examples" do let!(:attachment_collection) { create(:attachment_collection, collection_for:) } + let(:attributes) { attributes_for(:attachment_collection) } before do visit current_path @@ -30,17 +31,13 @@ fill_in_i18n( :attachment_collection_name, "#attachment_collection-name-tabs", - en: "Application forms", - es: "Formularios de solicitud", - ca: "Formularis de sol·licitud" + **attributes[:name].except("machine_translations") ) fill_in_i18n( :attachment_collection_description, "#attachment_collection-description-tabs", - en: "Contains the application forms", - es: "Contiene los formularios de solicitud", - ca: "Conté els formularis de sol·licitud" + **attributes[:description].except("machine_translations") ) find("*[type=submit]").click @@ -49,8 +46,11 @@ expect(page).to have_admin_callout("successfully") within "#attachment_collections table" do - expect(page).to have_text("Application forms") + expect(page).to have_content(translated(attributes[:name])) end + + visit decidim_admin.root_path + expect(page).to have_content("created the #{translated(attributes[:name])} attachment collection") end it "can update an attachment collection" do @@ -64,9 +64,7 @@ fill_in_i18n( :attachment_collection_name, "#attachment_collection-name-tabs", - en: "Latest application forms", - es: "Últimos formularios de solicitud", - ca: "Últims formularis de sol·licitud" + **attributes[:name].except("machine_translations") ) find("*[type=submit]").click @@ -75,8 +73,11 @@ expect(page).to have_admin_callout("successfully") within "#attachment_collections table" do - expect(page).to have_text("Latest application forms") + expect(page).to have_content(translated(attributes[:name])) end + + visit decidim_admin.root_path + expect(page).to have_content("updated the #{translated(attributes[:name])} attachment collection") end context "when deleting a attachment collection" do
decidim-admin/lib/decidim/admin/test/manage_categories_examples.rb+11 −8 modified@@ -1,6 +1,7 @@ # frozen_string_literal: true shared_examples "manage categories examples" do + let(:attributes) { attributes_for(:category) } it "lists all the categories for the process" do within "#categories table" do expect(page).to have_content(translated(category.name, locale: :en)) @@ -25,9 +26,7 @@ fill_in_i18n( :category_name, "#category-name-tabs", - en: "My category", - es: "Mi categoría", - ca: "La meva categoria" + **attributes[:name].except("machine_translations") ) find("*[type=submit]").click @@ -36,8 +35,11 @@ expect(page).to have_admin_callout("successfully") within "#categories table" do - expect(page).to have_content("My category") + expect(page).to have_content(translated(attributes[:name])) end + + visit decidim_admin.root_path + expect(page).to have_content("added the #{translated(attributes[:name])} category to the") end it "updates a category" do @@ -51,9 +53,7 @@ fill_in_i18n( :category_name, "#category-name-tabs", - en: "My new name", - es: "Mi nuevo nombre", - ca: "El meu nou nom" + **attributes[:name].except("machine_translations") ) find("*[type=submit]").click @@ -62,8 +62,11 @@ expect(page).to have_admin_callout("successfully") within "#categories table" do - expect(page).to have_content("My new name") + expect(page).to have_content(translated(attributes[:name])) end + + visit decidim_admin.root_path + expect(page).to have_content("updated the #{translated(attributes[:name])} category in the") end context "when deleting a category" do
decidim-admin/lib/decidim/admin/test/manage_hide_content_examples.rb+4 −0 modified@@ -54,6 +54,10 @@ click_button I18n.t("decidim.admin.block_user.new.action") expect(content.reload).to be_hidden + + visit decidim_admin.root_path + expect(page).to have_content("blocked user") + expect(page).to have_content("hid a resource of type") end end end
decidim-admin/spec/system/admin_manages_help_sections_spec.rb+3 −0 modified@@ -28,6 +28,9 @@ help_content = Decidim::ContextualHelpSection.find_content(organization, :participatory_processes) expect(help_content).to include("en" => "<p>Well hello!</p>") + + visit decidim_admin.root_path + expect(page).to have_content("updated the Participatory processes help section") end it "destroys the section when it is empty" do
decidim-admin/spec/system/admin_manages_newsletters_spec.rb+11 −8 modified@@ -7,6 +7,7 @@ describe "Admin manages newsletters" do let(:organization) { create(:organization) } + let!(:attributes) { attributes_for(:newsletter, organization:) } let(:user) { create(:user, :admin, :confirmed, name: "Sarah Kerrigan", organization:) } let!(:deliverable_users) { create_list(:user, 5, :confirmed, newsletter_notifications_at: Time.current, organization:) } @@ -41,9 +42,7 @@ fill_in_i18n( :newsletter_subject, "#newsletter-subject-tabs", - en: "A fancy newsletter for %{name}", - es: "Un correo electrónico muy chulo para %{name}", - ca: "Un correu electrònic flipant per a %{name}" + **attributes[:subject].except("machine_translations") ) fill_in_i18n_editor( @@ -82,7 +81,10 @@ end expect(page).to have_content("Preview") - expect(page).to have_content("A fancy newsletter for #{user.name}") + expect(page).to have_content(translated(attributes[:subject])) + + visit decidim_admin.root_path + expect(page).to have_content("created the #{translated(attributes[:subject])} newsletter") end end @@ -148,9 +150,7 @@ fill_in_i18n( :newsletter_subject, "#newsletter-subject-tabs", - en: "A fancy newsletter", - es: "Un correo electrónico muy chulo", - ca: "Un correu electrònic flipant" + **attributes[:subject].except("machine_translations") ) fill_in_i18n_editor( @@ -165,7 +165,10 @@ end expect(page).to have_content("Preview") - expect(page).to have_content("A fancy newsletter") + expect(page).to have_content(translated(attributes[:subject])) + + visit decidim_admin.root_path + expect(page).to have_content("updated the #{translated(attributes[:subject])} newsletter") end end
decidim-admin/spec/system/admin_manages_organization_areas_spec.rb+12 −8 modified@@ -7,6 +7,7 @@ let(:admin) { create(:user, :admin, :confirmed) } let(:organization) { admin.organization } + let(:attributes) { attributes_for(:area) } before do switch_to_host(organization.host) @@ -26,9 +27,8 @@ click_link "Add" within ".item__edit-form" do - fill_in_i18n :area_name, "#area-name-tabs", en: "My area", - es: "Mi area", - ca: "La meva area" + fill_in_i18n :area_name, "#area-name-tabs", **attributes[:name].except("machine_translations") + select area_type.name["en"], from: :area_area_type_id find("*[type=submit]").click @@ -37,8 +37,11 @@ expect(page).to have_admin_callout("successfully") within "table" do - expect(page).to have_content("My area") + expect(page).to have_content(translated(attributes[:name])) end + + visit decidim_admin.root_path + expect(page).to have_content("created the #{translated(attributes[:name])} area") end context "with existing areas" do @@ -61,17 +64,18 @@ end within ".item__edit-form" do - fill_in_i18n :area_name, "#area-name-tabs", en: "Another area", - es: "Otra area", - ca: "Una altra area" + fill_in_i18n :area_name, "#area-name-tabs", **attributes[:name].except("machine_translations") find("*[type=submit]").click end expect(page).to have_admin_callout("successfully") within "table" do - expect(page).to have_content("Another area") + expect(page).to have_content(translated(attributes[:name])) end + + visit decidim_admin.root_path + expect(page).to have_content("updated the #{translated(attributes[:name])} area") end it "can delete them" do
decidim-admin/spec/system/admin_manages_organization_area_types_spec.rb+13 −10 modified@@ -5,6 +5,7 @@ describe "Admin manages area types" do let(:admin) { create(:user, :admin, :confirmed) } let(:organization) { admin.organization } + let(:attributes) { attributes_for(:area_type) } before do switch_to_host(organization.host) @@ -24,17 +25,13 @@ fill_in_i18n( :area_type_name, "#area_type-name-tabs", - en: "Sectorial en", - es: "Sectorial es", - ca: "Sectorial ca" + **attributes[:name].except("machine_translations") ) fill_in_i18n( :area_type_plural, "#area_type-plural-tabs", - en: "Sectorials en", - es: "Sectoriales es", - ca: "Sectorials ca" + **attributes[:plural].except("machine_translations") ) find("*[type=submit]").click @@ -43,8 +40,11 @@ expect(page).to have_admin_callout("successfully") within "table" do - expect(page).to have_content("Sectorial en") + expect(page).to have_content(translated(attributes[:name])) end + + visit decidim_admin.root_path + expect(page).to have_content("created the #{translated(attributes[:name])} area type") end context "with existing area_types" do @@ -69,22 +69,25 @@ fill_in_i18n( :area_type_name, "#area_type-name-tabs", - en: "Not Sectorial en" + **attributes[:name].except("machine_translations") ) fill_in_i18n( :area_type_plural, "#area_type-plural-tabs", - en: "This is the new pluarl" + **attributes[:plural].except("machine_translations") ) find("*[type=submit]").click end expect(page).to have_admin_callout("successfully") within "table" do - expect(page).to have_content("Not Sectorial en") + expect(page).to have_content(translated(attributes[:name])) end + + visit decidim_admin.root_path + expect(page).to have_content("updated the #{translated(attributes[:name])} area type") end it "can delete them" do
decidim-admin/spec/system/admin_manages_organization_scopes_spec.rb+11 −8 modified@@ -7,6 +7,7 @@ let(:admin) { create(:user, :admin, :confirmed) } let(:organization) { admin.organization } + let!(:attributes) { attributes_for(:scope) } before do switch_to_host(organization.host) @@ -26,9 +27,7 @@ click_link "Add" within ".new_scope" do - fill_in_i18n :scope_name, "#scope-name-tabs", en: "My nice district", - es: "Mi lindo distrito", - ca: "El meu bonic barri" + fill_in_i18n :scope_name, "#scope-name-tabs", **attributes[:name].except("machine_translations") fill_in "Code", with: "MY-DISTRICT" select scope_type.name["en"], from: :scope_scope_type_id @@ -38,8 +37,11 @@ expect(page).to have_admin_callout("successfully") within "table" do - expect(page).to have_content("My nice district") + expect(page).to have_content(translated(attributes[:name])) end + + visit decidim_admin.root_path + expect(page).to have_content("created the #{translated(attributes[:name])} scope") end context "with existing scopes" do @@ -55,17 +57,18 @@ end within ".edit_scope" do - fill_in_i18n :scope_name, "#scope-name-tabs", en: "Another district", - es: "Otro distrito", - ca: "Un altre districte" + fill_in_i18n :scope_name, "#scope-name-tabs", **attributes[:name].except("machine_translations") find("*[type=submit]").click end expect(page).to have_admin_callout("successfully") within "table" do - expect(page).to have_content("Another district") + expect(page).to have_content(translated(attributes[:name])) end + + visit decidim_admin.root_path + expect(page).to have_content("updated the #{translated(attributes[:name])} scope") end it "can delete them" do
decidim-admin/spec/system/admin_manages_organization_scope_types_spec.rb+13 −10 modified@@ -5,6 +5,7 @@ describe "Admin manages scope types" do let(:admin) { create(:user, :admin, :confirmed) } let(:organization) { admin.organization } + let!(:attributes) { attributes_for(:scope_type) } before do switch_to_host(organization.host) @@ -24,17 +25,13 @@ fill_in_i18n( :scope_type_name, "#scope_type-name-tabs", - en: "Territorial en", - es: "Territorial es", - ca: "Territorial ca" + **attributes[:name].except("machine_translations") ) fill_in_i18n( :scope_type_plural, "#scope_type-plural-tabs", - en: "Territorials en", - es: "Territoriales es", - ca: "Territorials ca" + **attributes[:plural].except("machine_translations") ) find("*[type=submit]").click @@ -43,8 +40,11 @@ expect(page).to have_admin_callout("successfully") within "table" do - expect(page).to have_content("Territorial en") + expect(page).to have_content(translated(attributes[:name])) end + + visit decidim_admin.root_path + expect(page).to have_content("created the #{translated(attributes[:name])} scope type") end context "with existing scope_types" do @@ -69,22 +69,25 @@ fill_in_i18n( :scope_type_name, "#scope_type-name-tabs", - en: "Not Territorial en" + **attributes[:name].except("machine_translations") ) fill_in_i18n( :scope_type_plural, "#scope_type-plural-tabs", - en: "This is the new pluarl" + **attributes[:plural].except("machine_translations") ) find("*[type=submit]").click end expect(page).to have_admin_callout("successfully") within "table" do - expect(page).to have_content("Not Territorial en") + expect(page).to have_content(translated(attributes[:name])) end + + visit decidim_admin.root_path + expect(page).to have_content("updated the #{translated(attributes[:name])} scope type") end it "can delete them" do
decidim-admin/spec/system/admin_manages_organization_spec.rb+5 −1 modified@@ -6,6 +6,7 @@ include ActionView::Helpers::SanitizeHelper let(:organization) { create(:organization) } + let(:attributes) { attributes_for(:organization) } let(:user) { create(:user, :admin, :confirmed, organization:) } before do @@ -17,7 +18,7 @@ it "updates the values from the form" do visit decidim_admin.edit_organization_path - fill_in "Name", with: "My super-uber organization" + fill_in :organization_name, with: attributes[:name] %w(X Facebook Instagram YouTube GitHub).each do |network| within "#organization_social_handlers" do @@ -38,6 +39,9 @@ click_button "Update" expect(page).to have_content("updated successfully") + + visit decidim_admin.root_path + expect(page).to have_content("updated the organization settings") end it "marks the comments_max_length as required" do
decidim-admin/spec/system/static_pages_spec.rb+13 −10 modified@@ -148,6 +148,7 @@ describe "Managing pages" do let!(:topic) { create(:static_page_topic, organization:) } + let(:attributes) { attributes_for(:static_page) } before do login_as admin, scope: :user @@ -172,17 +173,13 @@ fill_in_i18n( :static_page_title, "#static_page-title-tabs", - en: "Welcome to Decidim", - es: "Te damos la bienvendida a Decidim", - ca: "Et donem la benvinguda a Decidim" + **attributes[:title].except("machine_translations") ) fill_in_i18n_editor( :static_page_content, "#static_page-content-tabs", - en: "<p>Some HTML content</p>", - es: "<p>Contenido HTML</p>", - ca: "<p>Contingut HTML</p>" + **attributes[:content].except("machine_translations") ) select topic.title[I18n.locale.to_s], from: :static_page_topic_id @@ -192,8 +189,11 @@ expect(page).to have_admin_callout("successfully") within find(".card", text: topic.title[I18n.locale.to_s]) do - expect(page).to have_css("tr", text: "Welcome to Decidim") + expect(page).to have_css("tr", text: translated(attributes[:title])) end + + visit decidim_admin.root_path + expect(page).to have_content("created the #{translated(attributes[:title])} static page") end context "with existing pages" do @@ -223,12 +223,12 @@ fill_in_i18n( :static_page_title, "#static_page-title-tabs", - en: "Not welcomed anymore" + **attributes[:title].except("machine_translations") ) fill_in_i18n_editor( :static_page_content, "#static_page-content-tabs", - en: "This is the new <strong>content</strong>" + **attributes[:content].except("machine_translations") ) select topic.title[I18n.locale.to_s], from: :static_page_topic_id find("*[type=submit]").click @@ -237,8 +237,11 @@ expect(page).to have_admin_callout("successfully") within find(".card", text: topic.title[I18n.locale.to_s]) do - expect(page).to have_css("tr", text: "Not welcomed anymore") + expect(page).to have_css("tr", text: translated(attributes[:title])) end + + visit decidim_admin.root_path + expect(page).to have_content("updated the #{translated(attributes[:title])} static page") end it "can delete them" do
decidim-assemblies/spec/shared/manage_assembly_components_examples.rb+16 −10 modified@@ -1,6 +1,8 @@ # frozen_string_literal: true shared_examples "manage assembly components" do + let!(:attributes) { attributes_for(:component, participatory_space: assembly) } + before do switch_to_host(organization.host) login_as user, scope: :user @@ -20,9 +22,7 @@ fill_in_i18n( :component_name, "#component-name-tabs", - en: "My component", - ca: "La meva funcionalitat", - es: "Mi funcionalitat" + **attributes[:name].except("machine_translations") ) within ".global-settings" do @@ -49,12 +49,17 @@ it "is successfully created" do expect(page).to have_admin_callout("successfully") - expect(page).to have_content("My component") + expect(page).to have_content(translated(attributes[:name])) + end + + it "has a successful admin log" do + visit decidim_admin.root_path + expect(page).to have_content("created #{translated(attributes[:name])} in #{translated(assembly.title)}") end context "and then edit it" do before do - within find("tr", text: "My component") do + within "tr", text: translated(attributes[:name]) do click_link "Configure" end end @@ -103,9 +108,7 @@ fill_in_i18n( :component_name, "#component-name-tabs", - en: "My updated component", - ca: "La meva funcionalitat actualitzada", - es: "Mi funcionalidad actualizada" + **attributes[:name].except("machine_translations") ) within ".global-settings" do @@ -120,9 +123,9 @@ end expect(page).to have_admin_callout("successfully") - expect(page).to have_content("My updated component") + expect(page).to have_content(translated(attributes[:name])) - within find("tr", text: "My updated component") do + within "tr", text: translated(attributes[:name]) do click_link "Configure" end @@ -133,6 +136,9 @@ within ".default-step-settings" do expect(all("input[type=checkbox]").first).to be_checked end + + visit decidim_admin.root_path + expect(page).to have_content("updated #{translated(attributes[:name])} in #{translated(assembly.title)}") end end
decidim-assemblies/spec/shared/manage_assembly_private_users_examples.rb+3 −0 modified@@ -35,6 +35,9 @@ within "#private_users table" do expect(page).to have_content(other_user.email) end + + visit decidim_admin.root_path + expect(page).to have_content("invited #{other_user.name} to be a private participant") end describe "when import a batch of private users from csv" do
decidim-conferences/spec/shared/manage_conference_components_examples.rb+16 −10 modified@@ -1,6 +1,8 @@ # frozen_string_literal: true shared_examples "manage conference components" do + let!(:attributes) { attributes_for(:component, participatory_space: conference) } + before do switch_to_host(organization.host) login_as user, scope: :user @@ -20,9 +22,7 @@ fill_in_i18n( :component_name, "#component-name-tabs", - en: "My component", - ca: "La meva funcionalitat", - es: "Mi funcionalitat" + **attributes[:name].except("machine_translations") ) within ".global-settings" do @@ -49,12 +49,17 @@ it "is successfully created" do expect(page).to have_admin_callout("successfully") - expect(page).to have_content("My component") + expect(page).to have_content(translated(attributes[:name])) + end + + it "has a successful admin log" do + visit decidim_admin.root_path + expect(page).to have_content("created #{translated(attributes[:name])} in #{translated(conference.title)}") end context "and then edit it" do before do - within find("tr", text: "My component") do + within "tr", text: translated(attributes[:name]) do click_link "Configure" end end @@ -103,9 +108,7 @@ fill_in_i18n( :component_name, "#component-name-tabs", - en: "My updated component", - ca: "La meva funcionalitat actualitzada", - es: "Mi funcionalidad actualizada" + **attributes[:name].except("machine_translations") ) within ".global-settings" do @@ -120,9 +123,9 @@ end expect(page).to have_admin_callout("successfully") - expect(page).to have_content("My updated component") + expect(page).to have_content(translated(attributes[:name])) - within find("tr", text: "My updated component") do + within "tr", text: translated(attributes[:name]) do click_link "Configure" end @@ -133,6 +136,9 @@ within ".default-step-settings" do expect(all("input[type=checkbox]").first).to be_checked end + + visit decidim_admin.root_path + expect(page).to have_content("updated #{translated(attributes[:name])} in #{translated(conference.title)}") end end
decidim-core/app/presenters/decidim/admin_log/organization_presenter.rb+1 −1 modified@@ -26,7 +26,7 @@ def diff_fields_mapping def settings_attributes_mapping { - name: :string, + name: :i18n, default_locale: :locale, reference_prefix: :string, twitter_handler: :string,
decidim-initiatives/spec/system/admin/admin_manages_initiative_components_spec.rb+15 −10 modified@@ -7,6 +7,7 @@ let(:user) { create(:user, :admin, :confirmed, organization:) } let!(:initiative) { create(:initiative, organization:) } + let!(:attributes) { attributes_for(:component, participatory_space: initiative) } before do switch_to_host(organization.host) @@ -28,9 +29,7 @@ fill_in_i18n( :component_name, "#component-name-tabs", - en: "My component", - ca: "El meu component", - es: "Mi componente" + **attributes[:name].except("machine_translations") ) within ".global-settings" do @@ -57,12 +56,17 @@ it "is successfully created" do expect(page).to have_admin_callout("Component created successfully.") - expect(page).to have_content("My component") + expect(page).to have_content(translated(attributes[:name])) + end + + it "has a successful admin log" do + visit decidim_admin.root_path + expect(page).to have_content("created #{translated(attributes[:name])} in #{translated(initiative.title)}") end context "and then edit it" do before do - within find("tr", text: "My component") do + within "tr", text: translated(attributes[:name]) do page.find(".action-icon--configure").click end end @@ -111,9 +115,7 @@ fill_in_i18n( :component_name, "#component-name-tabs", - en: "My updated component", - ca: "El meu component actualitzat", - es: "Mi componente actualizado" + **attributes[:name].except("machine_translations") ) within ".global-settings" do @@ -128,9 +130,9 @@ end expect(page).to have_admin_callout("The component was updated successfully.") - expect(page).to have_content("My updated component") + expect(page).to have_content(translated(attributes[:name])) - within find("tr", text: "My updated component") do + within "tr", text: translated(attributes[:name]) do page.find(".action-icon--configure").click end @@ -141,6 +143,9 @@ within ".default-step-settings" do expect(all("input[type=checkbox]").first).to be_checked end + + visit decidim_admin.root_path + expect(page).to have_content("updated #{translated(attributes[:name])} in #{translated(initiative.title)}") end end
decidim-initiatives/spec/system/admin/admin_manages_initiatives_types_spec.rb+15 −3 modified@@ -6,6 +6,7 @@ let(:organization) { create(:organization) } let(:user) { create(:user, :admin, :confirmed, organization:) } let!(:initiatives_type) { create(:initiatives_type, organization:) } + let(:attributes) { attributes_for(:initiatives_type) } before do switch_to_host(organization.host) @@ -26,13 +27,13 @@ fill_in_i18n( :initiatives_type_title, "#initiatives_type-title-tabs", - en: "My initiative type" + **attributes[:title].except("machine_translations") ) fill_in_i18n_editor( :initiatives_type_description, "#initiatives_type-description-tabs", - en: "A longer description" + **attributes[:description].except("machine_translations") ) select("Online", from: "Signature type") @@ -42,6 +43,9 @@ click_button "Create" expect(page).to have_admin_callout("A new initiative type has been successfully created") + + visit decidim_admin.root_path + expect(page).to have_content("created the #{translated(attributes[:title])} initiatives type") end end @@ -54,7 +58,12 @@ fill_in_i18n( :initiatives_type_title, "#initiatives_type-title-tabs", - en: "My updated initiative type" + **attributes[:title].except("machine_translations") + ) + fill_in_i18n_editor( + :initiatives_type_description, + "#initiatives_type-description-tabs", + **attributes[:description].except("machine_translations") ) select("Mixed", from: "Signature type") @@ -67,6 +76,9 @@ click_button "Update" expect(page).to have_admin_callout("The initiative type has been successfully updated") + + visit decidim_admin.root_path + expect(page).to have_content("updated the #{translated(attributes[:title])} initiatives type") end end
decidim-initiatives/spec/system/admin/update_initiative_spec.rb+21 −0 modified@@ -15,6 +15,8 @@ def submit_and_validate context "when initiative update" do context "and user is admin" do + let(:attributes) { attributes_for(:initiative, organization:) } + before do switch_to_host(organization.host) login_as user, scope: :user @@ -29,6 +31,25 @@ def submit_and_validate submit_and_validate end + it "updates the initiative" do + page.find(".action-icon--edit").click + + fill_in_i18n( + :initiative_title, + "#initiative-title-tabs", + **attributes[:title].except("machine_translations") + ) + fill_in_i18n_editor( + :initiative_description, + "#initiative-description-tabs", + **attributes[:description].except("machine_translations") + ) + submit_and_validate + + visit decidim_admin.root_path + expect(page).to have_content("updated the #{translated(attributes[:title])} initiative") + end + context "when initiative is in created state" do before do initiative.created!
decidim-participatory_processes/spec/shared/manage_participatory_process_private_users_examples.rb+3 −0 modified@@ -35,6 +35,9 @@ within "#private_users table" do expect(page).to have_content(other_user.email) end + + visit decidim_admin.root_path + expect(page).to have_content("invited #{other_user.name} to be a private participant") end describe "when import a batch of private users from csv" do
decidim-participatory_processes/spec/shared/manage_process_components_examples.rb+16 −10 modified@@ -4,6 +4,8 @@ let!(:participatory_process) do create(:participatory_process, :with_steps, organization:) end + let!(:attributes) { attributes_for(:component, participatory_space: participatory_process) } + let(:step_id) { participatory_process.steps.first.id } before do @@ -30,9 +32,7 @@ fill_in_i18n( :component_name, "#component-name-tabs", - en: "My component", - ca: "La meva funcionalitat", - es: "Mi funcionalitat" + **attributes[:name].except("machine_translations") ) within ".global-settings" do @@ -59,12 +59,17 @@ it "is successfully created" do expect(page).to have_admin_callout("successfully") - expect(page).to have_content("My component") + expect(page).to have_content(translated(attributes[:name])) + end + + it "has a successful admin log" do + visit decidim_admin.root_path + expect(page).to have_content("created #{translated(attributes[:name])} in #{translated(participatory_process.title)}") end context "and then edit it" do before do - within find("tr", text: "My component") do + within "tr", text: translated(attributes[:name]) do click_link "Configure" end end @@ -194,9 +199,7 @@ fill_in_i18n( :component_name, "#component-name-tabs", - en: "My updated component", - ca: "La meva funcionalitat actualitzada", - es: "Mi funcionalidad actualizada" + **attributes[:name].except("machine_translations") ) within ".global-settings" do @@ -211,9 +214,9 @@ end expect(page).to have_admin_callout("successfully") - expect(page).to have_content("My updated component") + expect(page).to have_content(translated(attributes[:name])) - within find("tr", text: "My updated component") do + within "tr", text: translated(attributes[:name]) do click_link "Configure" end @@ -224,6 +227,9 @@ within ".step-settings" do expect(all("input[type=checkbox]").first).to be_checked end + + visit decidim_admin.root_path + expect(page).to have_content("updated #{translated(attributes[:name])} in #{translated(participatory_process.title)}") end context "when the process does not have active steps" do
e494235d559bBackport 'Refactor malformed titles in admin logs (part 1)' to v0.28 (#13082)
54 files changed · +627 −690
decidim-accountability/spec/shared/manage_results_examples.rb+14 −23 modified@@ -31,20 +31,15 @@ context "when having existing proposals" do let!(:proposal_component) { create(:proposal_component, participatory_space:) } let!(:proposals) { create_list(:proposal, 5, component: proposal_component) } + let(:attributes) { attributes_for(:result, component: current_component) } 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" - ) + fill_in_i18n(:result_title, "#result-title-tabs", **attributes[:title].except("machine_translations")) tom_select("#proposals_list", option_id: proposals.first(2).map(&:id)) @@ -54,28 +49,20 @@ expect(page).to have_admin_callout("successfully") within "table" do - expect(page).to have_content("My new title") + expect(page).to have_content(translated(attributes[:title])) end + + visit decidim_admin.root_path + expect(page).to have_content("updated result") + expect(page).to have_content(translated(attributes[:title])) 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" - ) + fill_in_i18n(:result_title, "#result-title-tabs", **attributes[:title].except("machine_translations")) + fill_in_i18n_editor(:result_description, "#result-description-tabs", **attributes[:description].except("machine_translations")) tom_select("#proposals_list", option_id: proposals.first(2).map(&:id)) @@ -88,8 +75,12 @@ expect(page).to have_admin_callout("successfully") within "table" do - expect(page).to have_content("My result") + expect(page).to have_content(translated(attributes[:title])) end + + visit decidim_admin.root_path + expect(page).to have_content("created result") + expect(page).to have_content(attributes[:title]["en"]) end end
decidim-accountability/spec/shared/manage_statuses_examples.rb+13 −20 modified@@ -1,6 +1,8 @@ # frozen_string_literal: true RSpec.shared_examples "manage statuses" do + let(:attributes) { attributes_for(:status) } + it "updates a status" do within find("tr", text: status.key) do click_link "Edit" @@ -10,9 +12,7 @@ fill_in_i18n( :status_name, "#status-name-tabs", - en: "My new name", - es: "Mi nuevo nombre", - ca: "El meu nou nom" + **attributes[:name].except("machine_translations") ) find("*[type=submit]").click @@ -21,8 +21,11 @@ expect(page).to have_admin_callout("successfully") within "table" do - expect(page).to have_content("My new name") + expect(page).to have_content(translated(attributes[:name])) end + + visit decidim_admin.root_path + expect(page).to have_content("updated the #{translated(attributes[:name])} status") end it "creates a new status" do @@ -31,21 +34,8 @@ within ".new_status" do fill_in :status_key, with: "status_key_1" - fill_in_i18n( - :status_name, - "#status-name-tabs", - en: "A longer name", - es: "Nombre más larga", - ca: "Nom més llarga" - ) - - fill_in_i18n( - :status_description, - "#status-description-tabs", - en: "A longer description", - es: "Descripción más larga", - ca: "Descripció més llarga" - ) + fill_in_i18n(:status_name, "#status-name-tabs", **attributes[:name].except("machine_translations")) + fill_in_i18n(:status_description, "#status-description-tabs", **attributes[:description].except("machine_translations")) fill_in :status_progress, with: 75 @@ -56,8 +46,11 @@ within "table" do expect(page).to have_content("status_key_1") - expect(page).to have_content("A longer name") + expect(page).to have_content(translated(attributes[:name])) end + + visit decidim_admin.root_path + expect(page).to have_content("created the #{translated(attributes[:name])} status") end describe "deleting a result" do
decidim-accountability/spec/shared/manage_timeline_examples.rb+48 −0 added@@ -0,0 +1,48 @@ +# frozen_string_literal: true + +RSpec.shared_examples "manage timeline" do + let(:attributes) { attributes_for(:timeline_entry, result:) } + + it "updates a timeline entry", versioning: true do + visit current_path + click_on "Edit", match: :first + + within ".edit_timeline_entry" do + fill_in :timeline_entry_entry_date, with: Date.current.strftime("%d/%m/%Y") + fill_in_i18n(:timeline_entry_title, "#timeline_entry-title-tabs", **attributes[:title].except("machine_translations")) + fill_in_i18n_editor(:timeline_entry_description, "#timeline_entry-description-tabs", **attributes[:description].except("machine_translations")) + + find("*[type=submit]").click + end + + expect(page).to have_admin_callout("successfully") + + within "table" do + expect(page).to have_content(translated(attributes[:title])) + end + + visit decidim_admin.root_path + expect(page).to have_content("updated the #{translated(attributes[:title])} timeline entry") + end + + it "creates a timeline entry", versioning: true do + click_on "New timeline entry", match: :first + + within ".new_timeline_entry" do + fill_in :timeline_entry_entry_date, with: Date.current.strftime("%d/%m/%Y") + fill_in_i18n(:timeline_entry_title, "#timeline_entry-title-tabs", **attributes[:title].except("machine_translations")) + fill_in_i18n_editor(:timeline_entry_description, "#timeline_entry-description-tabs", **attributes[:description].except("machine_translations")) + + find("*[type=submit]").click + end + + expect(page).to have_admin_callout("successfully") + + within "table" do + expect(page).to have_content(translated(attributes[:title])) + end + + visit decidim_admin.root_path + expect(page).to have_content("created the #{translated(attributes[:title])} timeline entry") + end +end
decidim-accountability/spec/system/admin/admin_manages_accountability_spec.rb+13 −0 modified@@ -35,4 +35,17 @@ it_behaves_like "manage statuses" end + + describe "timeline" do + before do + visit_component_admin + within "tr", text: translated(result.title) do + click_on "Project evolution" + end + end + + let!(:timeline_entry) { create(:timeline_entry, result:) } + + it_behaves_like "manage timeline" + end end
decidim-assemblies/spec/shared/manage_assemblies_examples.rb+28 −15 modified@@ -6,40 +6,53 @@ let(:image3_path) { Decidim::Dev.asset(image3_filename) } let(:assembly_parent_id_options) { page.find("#assembly_parent_id").find_all("option").map(&:value) } + let(:attributes) { attributes_for(:assembly, :with_content_blocks, organization:, blocks_manifests: [:announcement]) } before do click_link "Configure" end it "updates an assembly" do - fill_in_i18n( - :assembly_title, - "#assembly-title-tabs", - en: "My new title", - es: "Mi nuevo título", - ca: "El meu nou títol" - ) + fill_in_i18n(:assembly_title, "#assembly-title-tabs", **attributes[:title].except("machine_translations")) dynamically_attach_file(:assembly_banner_image, image3_path, remove_before: true) within ".edit_assembly" do expect(assembly_parent_id_options).not_to include(assembly.id) - fill_in "assembly[creation_date]", with: Date.yesterday - fill_in "assembly[included_at]", with: Date.current - fill_in "assembly[duration]", with: Date.tomorrow - fill_in "assembly[closing_date]", with: Date.tomorrow + fill_in_i18n(:assembly_subtitle, "#assembly-subtitle-tabs", **attributes[:subtitle].except("machine_translations")) + fill_in_i18n_editor(:assembly_short_description, "#assembly-short_description-tabs", **attributes[:short_description].except("machine_translations")) + fill_in_i18n_editor(:assembly_description, "#assembly-description-tabs", **attributes[:description].except("machine_translations")) + fill_in_i18n_editor(:assembly_purpose_of_action, "#assembly-purpose_of_action-tabs", **attributes[:purpose_of_action].except("machine_translations")) + fill_in_i18n_editor(:assembly_composition, "#assembly-composition-tabs", **attributes[:composition].except("machine_translations")) + fill_in_i18n_editor(:assembly_internal_organisation, "#assembly-internal_organisation-tabs", **attributes[:internal_organisation].except("machine_translations")) + fill_in_i18n_editor(:assembly_announcement, "#assembly-announcement-tabs", **attributes[:announcement].except("machine_translations")) + fill_in_i18n_editor(:assembly_closing_date_reason, "#assembly-closing_date_reason-tabs", **attributes[:closing_date_reason].except("machine_translations")) + + fill_in_i18n(:assembly_participatory_scope, "#assembly-participatory_scope-tabs", **attributes[:participatory_scope].except("machine_translations")) + fill_in_i18n(:assembly_participatory_structure, "#assembly-participatory_structure-tabs", **attributes[:participatory_structure].except("machine_translations")) + fill_in_i18n(:assembly_meta_scope, "#assembly-meta_scope-tabs", **attributes[:meta_scope].except("machine_translations")) + fill_in_i18n(:assembly_local_area, "#assembly-local_area-tabs", **attributes[:local_area].except("machine_translations")) + fill_in_i18n(:assembly_target, "#assembly-target-tabs", **attributes[:target].except("machine_translations")) + + fill_in :assembly_creation_date, with: Date.yesterday.strftime("%d/%m/%Y"), fill_options: { clear: :backspace } + fill_in :assembly_included_at, with: Date.current.strftime("%d/%m/%Y"), fill_options: { clear: :backspace } + fill_in :assembly_duration, with: Date.tomorrow.strftime("%d/%m/%Y"), fill_options: { clear: :backspace } + fill_in :assembly_closing_date, with: Date.tomorrow.strftime("%d/%m/%Y"), fill_options: { clear: :backspace } find("*[type=submit]").click end expect(page).to have_admin_callout("successfully") within "[data-content]" do - expect(page).to have_selector("input[value='My new title']") + expect(page).to have_selector("input[value='#{translated(attributes[:title])}']") expect(page).to have_css("img[src*='#{image3_filename}']") - expect(page).to have_css("input[value='#{Date.yesterday}']") - expect(page).to have_css("input[value='#{Date.current}']") - expect(page).to have_css("input[value='#{Date.tomorrow}']", count: 2) + expect(page).to have_css("input[value='#{Date.yesterday.strftime("%Y-%d-%m")}']") + expect(page).to have_css("input[value='#{Date.current.strftime("%Y-%d-%m")}']") + expect(page).to have_css("input[value='#{Date.tomorrow.strftime("%Y-%d-%m")}']", count: 2) end + + visit decidim_admin.root_path + expect(page).to have_content("updated the #{translated(attributes[:title])} assembly") end end
decidim-assemblies/spec/shared/manage_assembly_admins_examples.rb+9 −3 modified@@ -2,6 +2,7 @@ shared_examples "manage assembly admins examples" do let(:other_user) { create(:user, organization:, email: "my_email@example.org") } + let(:attributes) { attributes_for(:user, organization:) } let!(:assembly_admin) do create(:assembly_admin, @@ -25,12 +26,12 @@ end end - it "creates a new assembly admin" do + it "creates a new assembly admin", versioning: true do click_link "New assembly admin" within ".new_assembly_user_role" do fill_in :assembly_user_role_email, with: other_user.email - fill_in :assembly_user_role_name, with: "John Doe" + fill_in :assembly_user_role_name, with: attributes[:name] select "Administrator", from: :assembly_user_role_role find("*[type=submit]").click @@ -41,6 +42,9 @@ within "#assembly_admins table" do expect(page).to have_content(other_user.email) end + + visit decidim_admin.root_path + expect(page).to have_content("invited #{other_user.name} to the #{translated(assembly.title)} assembly") end describe "when managing different users" do @@ -49,7 +53,7 @@ visit current_path end - it "updates an assembly admin" do + it "updates an assembly admin", versioning: true do within "#assembly_admins" do within find("#assembly_admins tr", text: other_user.email) do click_link "Edit" @@ -67,6 +71,8 @@ within "#assembly_admins table" do expect(page).to have_content("Collaborator") end + visit decidim_admin.root_path + expect(page).to have_content("changed the role of #{other_user.name} in the #{translated(assembly.title)} assembly") end it "deletes an assembly_user_role" do
decidim-assemblies/spec/shared/manage_assembly_members_examples.rb+18 −12 modified@@ -12,17 +12,17 @@ context "without existing user" do let!(:assembly_member) { create(:assembly_member, assembly:) } + let(:attributes) { attributes_for(:assembly_member, assembly:) } - it "creates a new assembly member" do + it "creates a new assembly member", versioning: true do click_link "New assembly member" fill_in :assembly_member_designation_date, with: Time.current within ".new_assembly_member" do - fill_in( - :assembly_member_full_name, - with: "Daisy O'connor" - ) + fill_in(:assembly_member_full_name, with: attributes[:full_name]) + fill_in(:assembly_member_gender, with: attributes[:gender]) + fill_in(:assembly_member_birthplace, with: attributes[:birthplace]) end dynamically_attach_file(:assembly_member_non_user_avatar, Decidim::Dev.asset("avatar.jpg")) do @@ -39,8 +39,11 @@ expect(page).to have_current_path decidim_admin_assemblies.assembly_members_path(assembly) within "#assembly_members table" do - expect(page).to have_content("Daisy O'connor") + expect(page).to have_content(attributes[:full_name]) end + + visit decidim_admin.root_path + expect(page).to have_content("created the #{attributes[:full_name]} member") end end @@ -98,6 +101,7 @@ describe "when managing other assembly members" do let!(:assembly_member) { create(:assembly_member, assembly:) } + let(:attributes) { attributes_for(:assembly_member, assembly:) } before do visit current_path @@ -109,16 +113,15 @@ end end - it "updates an assembly member" do + it "updates an assembly member", versioning: true do within find("#assembly_members tr", text: assembly_member.full_name) do click_link "Edit" end within ".edit_assembly_member" do - fill_in( - :assembly_member_full_name, - with: "Alicia O'connor" - ) + fill_in(:assembly_member_full_name, with: attributes[:full_name]) + fill_in(:assembly_member_gender, with: attributes[:gender]) + fill_in(:assembly_member_birthplace, with: attributes[:birthplace]) find("*[type=submit]").click end @@ -127,8 +130,11 @@ expect(page).to have_current_path decidim_admin_assemblies.assembly_members_path(assembly) within "#assembly_members table" do - expect(page).to have_content("Alicia O'connor") + expect(page).to have_content(attributes[:full_name]) end + + visit decidim_admin.root_path + expect(page).to have_content("updated the #{assembly_member.full_name} member") end it "deletes the assembly member" do
decidim-assemblies/spec/system/admin/admin_manages_assemblies_spec.rb+21 −30 modified@@ -45,6 +45,7 @@ let(:image2_filename) { "city2.jpeg" } let(:image2_path) { Decidim::Dev.asset(image2_filename) } + let(:attributes) { attributes_for(:assembly, :with_content_blocks, organization:, blocks_manifests: [:announcement]) } before do click_link "New assembly" @@ -56,36 +57,23 @@ it_behaves_like "having a rich text editor for field", "#closing_date_reason_div", "content" - it "creates a new assembly" do + it "creates a new assembly", versioning: true do within ".new_assembly" do - fill_in_i18n( - :assembly_title, - "#assembly-title-tabs", - en: "My assembly", - es: "Mi proceso participativo", - ca: "El meu procés participatiu" - ) - fill_in_i18n( - :assembly_subtitle, - "#assembly-subtitle-tabs", - en: "Subtitle", - es: "Subtítulo", - ca: "Subtítol" - ) - fill_in_i18n_editor( - :assembly_short_description, - "#assembly-short_description-tabs", - en: "Short description", - es: "Descripción corta", - ca: "Descripció curta" - ) - fill_in_i18n_editor( - :assembly_description, - "#assembly-description-tabs", - en: "A longer description", - es: "Descripción más larga", - ca: "Descripció més llarga" - ) + fill_in_i18n(:assembly_title, "#assembly-title-tabs", **attributes[:title].except("machine_translations")) + fill_in_i18n(:assembly_subtitle, "#assembly-subtitle-tabs", **attributes[:subtitle].except("machine_translations")) + fill_in_i18n_editor(:assembly_short_description, "#assembly-short_description-tabs", **attributes[:short_description].except("machine_translations")) + fill_in_i18n_editor(:assembly_description, "#assembly-description-tabs", **attributes[:description].except("machine_translations")) + fill_in_i18n_editor(:assembly_purpose_of_action, "#assembly-purpose_of_action-tabs", **attributes[:purpose_of_action].except("machine_translations")) + fill_in_i18n_editor(:assembly_composition, "#assembly-composition-tabs", **attributes[:composition].except("machine_translations")) + fill_in_i18n_editor(:assembly_internal_organisation, "#assembly-internal_organisation-tabs", **attributes[:internal_organisation].except("machine_translations")) + fill_in_i18n_editor(:assembly_announcement, "#assembly-announcement-tabs", **attributes[:announcement].except("machine_translations")) + fill_in_i18n_editor(:assembly_closing_date_reason, "#assembly-closing_date_reason-tabs", **attributes[:closing_date_reason].except("machine_translations")) + + fill_in_i18n(:assembly_participatory_scope, "#assembly-participatory_scope-tabs", **attributes[:participatory_scope].except("machine_translations")) + fill_in_i18n(:assembly_participatory_structure, "#assembly-participatory_structure-tabs", **attributes[:participatory_structure].except("machine_translations")) + fill_in_i18n(:assembly_meta_scope, "#assembly-meta_scope-tabs", **attributes[:meta_scope].except("machine_translations")) + fill_in_i18n(:assembly_local_area, "#assembly-local_area-tabs", **attributes[:local_area].except("machine_translations")) + fill_in_i18n(:assembly_target, "#assembly-target-tabs", **attributes[:target].except("machine_translations")) fill_in :assembly_slug, with: "slug" fill_in :assembly_hashtag, with: "#hashtag" @@ -103,8 +91,11 @@ within "[data-content]" do expect(page).to have_current_path decidim_admin_assemblies.assemblies_path(q: { parent_id_eq: parent_assembly&.id }) - expect(page).to have_content("My assembly") + expect(page).to have_content(translated(attributes[:title])) end + + visit decidim_admin.root_path + expect(page).to have_content("created the #{translated(attributes[:title])} assembly") end end
decidim-assemblies/spec/system/admin/admin_manages_assemblies_types_spec.rb+16 −18 modified@@ -2,11 +2,10 @@ require "spec_helper" -describe "Admin manages assemblies" do - include Decidim::SanitizeHelper - +describe "Admin manages assemblies types" do let(:admin) { create(:user, :admin, :confirmed) } let(:organization) { admin.organization } + let(:attributes) { attributes_for(:assemblies_type) } describe "Managing assemblies types" do before do @@ -15,27 +14,25 @@ visit decidim_admin_assemblies.assemblies_types_path end - it "can create new assemblies types" do + it "can create new assemblies types", versioning: true do within "[data-content]" do click_link "New assembly type" within ".new_assembly_type" do - fill_in_i18n( - :assemblies_type_title, - "#assemblies_type-title-tabs", - en: "My assembly type", - es: "Mi assembly type", - ca: "La meva assembly type" - ) + fill_in_i18n(:assemblies_type_title, "#assemblies_type-title-tabs", **attributes[:title].except("machine_translations")) + find("*[type=submit]").click end end expect(page).to have_admin_callout("successfully") within "table" do - expect(page).to have_content("My assembly type") + expect(page).to have_content(translated(attributes[:title])) end + + visit decidim_admin.root_path + expect(page).to have_content("created the #{translated(attributes[:title])} assembly type") end context "with existing assemblies types" do @@ -51,23 +48,24 @@ end end - it "can edit them" do - within find("tr", text: translated(assembly_type.title)) do + it "can edit them", versioning: true do + within "tr", text: translated(assembly_type.title) do click_link "Edit" end within ".edit_assembly_type" do - fill_in_i18n :assemblies_type_title, "#assemblies_type-title-tabs", en: "Another assembly type", - es: "Otra assembly type", - ca: "Una altra assembly type" + fill_in_i18n :assemblies_type_title, "#assemblies_type-title-tabs", **attributes[:title].except("machine_translations") find("*[type=submit]").click end expect(page).to have_admin_callout("successfully") within "table" do - expect(page).to have_content("Another assembly type") + expect(page).to have_content(translated(attributes[:title])) end + + visit decidim_admin.root_path + expect(page).to have_content("updated the #{translated(attributes[:title])} assembly type") end it "can delete them" do
decidim-blogs/spec/shared/manage_posts_examples.rb+22 −34 modified@@ -1,67 +1,50 @@ # frozen_string_literal: true -shared_examples "manage posts" do +# we really need the audit_check variable, as it seems that a process admin should not be able to see the admin logs +# Therefore, as long we do have the logs checks in this shared example, we need to have the config flag. +shared_examples "manage posts" do |audit_check: true| it_behaves_like "having a rich text editor for field", ".tabs-content[data-tabs-content='post-body-tabs']", "full" do before do within find("tr", text: translated(post1.title)) do click_link "Edit" end end end + let(:attributes) { attributes_for(:post) } - it "updates a post" do + it "updates a post", versioning: true do within find("tr", text: translated(post1.title)) do click_link "Edit" end within ".edit_post" do expect(page).to have_select("post_decidim_author_id", selected: author.name) - fill_in_i18n( - :post_title, - "#post-title-tabs", - en: "My new title", - es: "Mi nuevo título", - ca: "El meu nou títol" - ) - fill_in_i18n_editor( - :post_body, - "#post-body-tabs", - en: "A longer description", - es: "Descripción más larga", - ca: "Descripció més llarga" - ) + fill_in_i18n(:post_title, "#post-title-tabs", **attributes[:title].except("machine_translations")) + fill_in_i18n_editor(:post_body, "#post-body-tabs", **attributes[:body].except("machine_translations")) find("*[type=submit]").click end expect(page).to have_admin_callout("successfully") within "table" do - expect(page).to have_content("My new title") + expect(page).to have_content(translated(attributes[:title])) expect(page).to have_content("Post title 2") expect(page).to have_content(author.name) end + + if audit_check == true + visit decidim_admin.root_path + expect(page).to have_content("updated the #{translated(attributes[:title])} blog post") + end end - it "creates a new post" do + it "creates a new post", versioning: true do click_link "New post" - fill_in_i18n( - :post_title, - "#post-title-tabs", - en: "My post", - es: "Mi post", - ca: "El meu post" - ) - - fill_in_i18n_editor( - :post_body, - "#post-body-tabs", - en: "A description", - es: "Descripción", - ca: "Descripció" - ) + fill_in_i18n(:post_title, "#post-title-tabs", **attributes[:title].except("machine_translations")) + fill_in_i18n_editor(:post_body, "#post-body-tabs", **attributes[:body].except("machine_translations")) within ".new_post" do find("*[type=submit]").click @@ -70,10 +53,15 @@ expect(page).to have_admin_callout("successfully") within "table" do - expect(page).to have_content("My post") + expect(page).to have_content(translated(attributes[:title])) expect(page).to have_content("Post title 1") expect(page).to have_content("Post title 2") end + + if audit_check == true + visit decidim_admin.root_path + expect(page).to have_content("created the #{translated(attributes[:title])} blog post") + end end describe "deleting a post" do
decidim-blogs/spec/system/process_admin_manages_post_spec.rb+1 −1 modified@@ -10,5 +10,5 @@ include_context "when managing a component as a process admin" - it_behaves_like "manage posts" + it_behaves_like "manage posts", audit_check: false end
decidim-budgets/spec/shared/manage_projects_examples.rb+16 −25 modified@@ -140,26 +140,16 @@ end end - it "creates a new project", :slow do + let(:attributes) { attributes_for(:project) } + + it "creates a new project", versioning: true do within ".bulk-actions-budgets" do click_link "New project" end 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_i18n(:project_title, "#project-title-tabs", **attributes[:title].except("machine_translations")) + fill_in_i18n_editor(:project_description, "#project-description-tabs", **attributes[:description].except("machine_translations")) fill_in :project_budget_amount, with: 22_000_000 select translated(scope.name), from: :project_decidim_scope_id @@ -171,8 +161,10 @@ expect(page).to have_admin_callout("successfully") within "table" do - expect(page).to have_content("My project") + expect(page).to have_content(translated(attributes[:title])) end + visit decidim_admin.root_path + expect(page).to have_content("created the #{translated(attributes[:title])} project") end context "when deleting a project" do @@ -198,20 +190,16 @@ context "when having existing proposals" do let!(:proposal_component) { create(:proposal_component, participatory_space:) } let!(:proposals) { create_list(:proposal, 5, component: proposal_component) } + let(:attributes) { attributes_for(:project) } - it "updates a project" do + it "updates a project", versioning: true 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" - ) + fill_in_i18n(:project_title, "#project-title-tabs", **attributes[:title].except("machine_translations")) + fill_in_i18n_editor(:project_description, "#project-description-tabs", **attributes[:description].except("machine_translations")) tom_select("#proposals_list", option_id: proposals.last(2).map(&:id)) @@ -221,8 +209,11 @@ expect(page).to have_admin_callout("successfully") within "table" do - expect(page).to have_content("My new title") + expect(page).to have_content(translated(attributes[:title])) end + + visit decidim_admin.root_path + expect(page).to have_content("updated the #{translated(attributes[:title])} project") end it "removes proposals from project", :slow do
decidim-budgets/spec/system/admin_manages_budgets_spec.rb+17 −27 modified@@ -3,12 +3,12 @@ require "spec_helper" describe "Admin manages budgets" do - let(:budget) { create(:budget, component: current_component) } + let!(:budget) { create(:budget, component: current_component) } let(:manifest_name) { "budgets" } + let(:attributes) { attributes_for(:budget) } include_context "when managing a component as an admin" before do - budget switch_to_host(organization.host) login_as user, scope: :user visit_component_admin @@ -20,24 +20,13 @@ it_behaves_like "having a rich text editor", "new_budget", "content" end - it "creates a new budget" do + it "creates a new budget", versioning: true do click_link "New budget" within ".new_budget" do - fill_in_i18n( - :budget_title, - "#budget-title-tabs", - en: "My Budget", - es: "Mi Presupuesto", - ca: "El meu Pressupost" - ) - fill_in_i18n_editor( - :budget_description, - "#budget-description-tabs", - en: "Long description", - es: "Descripción más larga", - ca: "Descripció més llarga" - ) + fill_in_i18n(:budget_title, "#budget-title-tabs", **attributes[:title].except("machine_translations")) + fill_in_i18n_editor(:budget_description, "#budget-description-tabs", **attributes[:description].except("machine_translations")) + fill_in :budget_weight, with: 1 fill_in :budget_total_budget, with: 100_000_00 select translated(scope.name), from: :budget_decidim_scope_id @@ -48,33 +37,34 @@ expect(page).to have_admin_callout("Budget successfully created.") within "table" do - expect(page).to have_content("My Budget") + expect(page).to have_content(translated(attributes[:title])) end + + visit decidim_admin.root_path + expect(page).to have_content("created the #{translated(attributes[:title])} budget") end - describe "updating a budget" do + describe "updating a budget", versioning: true do it "updates a budget" do within find("tr", text: translated(budget.title)) do page.find(".action-icon--edit").click end within ".edit_budget" do - fill_in_i18n( - :budget_title, - "#budget-title-tabs", - en: "My new title", - es: "Mi nuevo título", - ca: "El meu nou títol" - ) + fill_in_i18n(:budget_title, "#budget-title-tabs", **attributes[:title].except("machine_translations")) + fill_in_i18n_editor(:budget_description, "#budget-description-tabs", **attributes[:description].except("machine_translations")) end click_button "Update budget" expect(page).to have_admin_callout("Budget successfully updated.") within "table" do - expect(page).to have_content("My new title") + expect(page).to have_content(translated(attributes[:title])) end + + visit decidim_admin.root_path + expect(page).to have_content("updated the #{translated(attributes[:title])} budget") end end
decidim-budgets/spec/system/admin_manages_projects_spec.rb+1 −2 modified@@ -4,14 +4,13 @@ describe "Admin manages projects" do let(:manifest_name) { "budgets" } - let(:budget) { create(:budget, component: current_component) } + let!(:budget) { create(:budget, component: current_component) } let!(:project) { create(:project, budget:) } let!(:destination_budget) { create(:budget, component: current_component) } include_context "when managing a component as an admin" before do - budget switch_to_host(organization.host) login_as user, scope: :user visit_component_admin
decidim-conferences/spec/shared/manage_conference_admins_examples.rb+8 −3 modified@@ -2,6 +2,7 @@ shared_examples "manage conference admins examples" do let(:other_user) { create(:user, organization:, email: "my_email@example.org") } + let(:attributes) { attributes_for(:user, organization:) } let!(:conference_admin) do create(:conference_admin, @@ -25,12 +26,12 @@ end end - it "creates a new conference admin" do + it "creates a new conference admin", versioning: true do click_link "New conference admin" within ".new_conference_user_role" do fill_in :conference_user_role_email, with: other_user.email - fill_in :conference_user_role_name, with: "John Doe" + fill_in :conference_user_role_name, with: attributes[:name] select "Administrator", from: :conference_user_role_role find("*[type=submit]").click @@ -41,6 +42,8 @@ within "#conference_admins table" do expect(page).to have_content(other_user.email) end + visit decidim_admin.root_path + expect(page).to have_content("invited #{other_user.name} to the #{translated(conference.title)} conference") end describe "when managing different users" do @@ -49,7 +52,7 @@ visit current_path end - it "updates a conference admin" do + it "updates a conference admin", versioning: true do within "#conference_admins" do within find("#conference_admins tr", text: other_user.email) do click_link "Edit" @@ -67,6 +70,8 @@ within "#conference_admins table" do expect(page).to have_content("Collaborator") end + visit decidim_admin.root_path + expect(page).to have_content("changed the role of #{other_user.name} in the #{translated(conference.title)} conference") end it "deletes a conference_user_role" do
decidim-conferences/spec/shared/manage_conferences_examples.rb+22 −39 modified@@ -7,6 +7,7 @@ let(:image2_filename) { "city2.jpeg" } let(:image2_path) { Decidim::Dev.asset(image2_filename) } + let(:attributes) { attributes_for(:conference) } before do click_link "New conference" @@ -17,36 +18,13 @@ end it_behaves_like "having a rich text editor for field", "#conference_registrations_terms", "content" - it "creates a new conference" do + it "creates a new conference", versioning: true do within ".new_conference" do - fill_in_i18n( - :conference_title, - "#conference-title-tabs", - en: "My conference", - es: "Mi proceso participativo", - ca: "El meu procés participatiu" - ) - fill_in_i18n( - :conference_slogan, - "#conference-slogan-tabs", - en: "Slogan", - es: "Eslogan", - ca: "Eslógan" - ) - fill_in_i18n_editor( - :conference_short_description, - "#conference-short_description-tabs", - en: "Short description", - es: "Descripción corta", - ca: "Descripció curta" - ) - fill_in_i18n_editor( - :conference_description, - "#conference-description-tabs", - en: "A longer description", - es: "Descripción más larga", - ca: "Descripció més llarga" - ) + fill_in_i18n(:conference_title, "#conference-title-tabs", **attributes[:title].except("machine_translations")) + fill_in_i18n(:conference_slogan, "#conference-slogan-tabs", **attributes[:slogan].except("machine_translations")) + fill_in_i18n_editor(:conference_short_description, "#conference-short_description-tabs", **attributes[:short_description].except("machine_translations")) + fill_in_i18n_editor(:conference_description, "#conference-description-tabs", **attributes[:description].except("machine_translations")) + fill_in_i18n_editor(:conference_objectives, "#conference-objectives-tabs", **attributes[:objectives].except("machine_translations")) fill_in :conference_weight, with: 1 fill_in :conference_slug, with: "slug" @@ -67,41 +45,46 @@ within "[data-content]" do expect(page).to have_current_path decidim_admin_conferences.conferences_path - expect(page).to have_content("My conference") + expect(page).to have_content(translated(attributes[:title])) end + + visit decidim_admin.root_path + expect(page).to have_content("created the #{translated(attributes[:title])} conference") end end describe "updating a conference" do let(:image3_filename) { "city3.jpeg" } let(:image3_path) { Decidim::Dev.asset(image3_filename) } + let(:attributes) { attributes_for(:conference) } before do within find("tr", text: translated(conference.title)) do click_link "Configure" end end - it "updates a conference" do - fill_in_i18n( - :conference_title, - "#conference-title-tabs", - en: "My new title", - es: "Mi nuevo título", - ca: "El meu nou títol" - ) + it "updates a conference", versioning: true do dynamically_attach_file(:conference_banner_image, image3_path, remove_before: true) within ".edit_conference" do + fill_in_i18n(:conference_title, "#conference-title-tabs", **attributes[:title].except("machine_translations")) + fill_in_i18n(:conference_slogan, "#conference-slogan-tabs", **attributes[:slogan].except("machine_translations")) + fill_in_i18n_editor(:conference_short_description, "#conference-short_description-tabs", **attributes[:short_description].except("machine_translations")) + fill_in_i18n_editor(:conference_description, "#conference-description-tabs", **attributes[:description].except("machine_translations")) + fill_in_i18n_editor(:conference_objectives, "#conference-objectives-tabs", **attributes[:objectives].except("machine_translations")) find("*[type=submit]").click end expect(page).to have_admin_callout("successfully") within "[data-content]" do - expect(page).to have_selector("input[value='My new title']") + expect(page).to have_selector("input[value='#{translated(attributes[:title])}']") expect(page).to have_css("img[src*='#{image3_filename}']") end + + visit decidim_admin.root_path + expect(page).to have_content("updated the #{translated(attributes[:title])} conference") end end
decidim-conferences/spec/shared/manage_conference_speakers_examples.rb+17 −12 modified@@ -2,6 +2,7 @@ shared_examples "manage conference speakers examples" do let!(:conference_speaker) { create(:conference_speaker, conference:) } + let(:attributes) { attributes_for(:conference_speaker, conference:) } before do switch_to_host(organization.host) @@ -19,14 +20,14 @@ end context "without existing user" do - it "creates a new conference speaker" do + it "creates a new conference speaker", versioning: true do click_link "New speaker" within ".new_conference_speaker" do - fill_in( - :conference_speaker_full_name, - with: "Daisy O'connor" - ) + fill_in(:conference_speaker_full_name, with: attributes[:full_name]) + fill_in_i18n(:conference_speaker_position, "#conference_speaker-position-tabs", **attributes[:position].except("machine_translations")) + fill_in_i18n(:conference_speaker_affiliation, "#conference_speaker-affiliation-tabs", **attributes[:affiliation].except("machine_translations")) + fill_in_i18n_editor(:conference_speaker_short_bio, "#conference_speaker-short_bio-tabs", **attributes[:short_bio].except("machine_translations")) find("*[type=submit]").click end @@ -35,8 +36,10 @@ expect(page).to have_current_path decidim_admin_conferences.conference_speakers_path(conference) within "#conference_speakers table" do - expect(page).to have_content("Daisy O'connor") + expect(page).to have_content(attributes[:full_name]) end + visit decidim_admin.root_path + expect(page).to have_content("created the #{attributes[:full_name]} speaker in the") end end @@ -67,16 +70,16 @@ visit current_path end - it "updates a conference speaker" do + it "updates a conference speaker", versioning: true do within find("#conference_speakers tr", text: conference_speaker.full_name) do click_link "Edit" end within ".edit_conference_speaker" do - fill_in( - :conference_speaker_full_name, - with: "Alicia O'connor" - ) + fill_in(:conference_speaker_full_name, with: attributes[:full_name]) + fill_in_i18n(:conference_speaker_position, "#conference_speaker-position-tabs", **attributes[:position].except("machine_translations")) + fill_in_i18n(:conference_speaker_affiliation, "#conference_speaker-affiliation-tabs", **attributes[:affiliation].except("machine_translations")) + fill_in_i18n_editor(:conference_speaker_short_bio, "#conference_speaker-short_bio-tabs", **attributes[:short_bio].except("machine_translations")) find("*[type=submit]").click end @@ -85,8 +88,10 @@ expect(page).to have_current_path decidim_admin_conferences.conference_speakers_path(conference) within "#conference_speakers table" do - expect(page).to have_content("Alicia O'connor") + expect(page).to have_content(attributes[:full_name]) end + visit decidim_admin.root_path + expect(page).to have_content("updated the #{conference_speaker.full_name} speaker in the") end it "deletes the conference speaker" do
decidim-conferences/spec/shared/manage_media_links_examples.rb+13 −18 modified@@ -1,6 +1,8 @@ # frozen_string_literal: true shared_examples "manage media links examples" do + let!(:attributes) { attributes_for(:media_link, conference:) } + before do switch_to_host(organization.host) login_as user, scope: :user @@ -15,16 +17,10 @@ click_link "New media link" end - it "creates a new media link" do + it "creates a new media link", versioning: true do within "[data-content]" do within ".new_media_link" do - fill_in_i18n( - :conference_media_link_title, - "#conference_media_link-title-tabs", - en: "Media Link en", - es: "Media Link es", - ca: "Media Link ca" - ) + fill_in_i18n(:conference_media_link_title, "#conference_media_link-title-tabs", **attributes[:title].except("machine_translations")) fill_in :conference_media_link_link, with: "https://decidim.org" fill_in :conference_media_link_weight, with: 2 @@ -38,8 +34,11 @@ within "[data-content]" do expect(page).to have_current_path decidim_admin_conferences.conference_media_links_path(conference) - expect(page).to have_content("Media Link en") + expect(page).to have_content(translated(attributes[:title])) end + + visit decidim_admin.root_path + expect(page).to have_content("created the #{translated(attributes[:title])} media link") end end @@ -56,19 +55,13 @@ end end - it "updates a conference media links" do + it "updates a conference media links", versioning: true do within find("#media_links tr", text: translated(media_link.title)) do click_link "Edit" end within ".edit_media_link" do - fill_in_i18n( - :conference_media_link_title, - "#conference_media_link-title-tabs", - en: "Media Link update en", - es: "Media Link update es", - ca: "Media Link update ca" - ) + fill_in_i18n(:conference_media_link_title, "#conference_media_link-title-tabs", **attributes[:title].except("machine_translations")) fill_in :conference_media_link_link, with: "https://decidim.org" fill_in :conference_media_link_weight, with: 2 @@ -81,8 +74,10 @@ expect(page).to have_current_path decidim_admin_conferences.conference_media_links_path(conference) within "#media_links table" do - expect(page).to have_content("Media Link update en") + expect(page).to have_content(translated(attributes[:title])) end + visit decidim_admin.root_path + expect(page).to have_content("updated the #{translated(media_link.title)} media link") end it "deletes the conference media link" do
decidim-conferences/spec/shared/manage_partners_examples.rb+31 −6 modified@@ -2,6 +2,7 @@ shared_examples "manage partners examples" do let!(:conference_partner) { create(:partner, conference:) } + let!(:attributes) { attributes_for(:partner, conference:) } before do switch_to_host(organization.host) @@ -19,20 +20,42 @@ end describe "when managing other conference partners" do + let(:image1_filename) { "city.jpeg" } + let(:image1_path) { Decidim::Dev.asset(image1_filename) } + before do visit current_path end - it "updates a conference partners" do + it "creates a conference partner", versioning: true do + click_on "New partner" + dynamically_attach_file(:conference_partner_logo, image1_path) + + within ".new_partner" do + fill_in(:conference_partner_name, with: attributes[:name]) + + select("Collaborator", from: :conference_partner_partner_type) + + find("*[type=submit]").click + end + expect(page).to have_admin_callout("successfully") + expect(page).to have_current_path decidim_admin_conferences.conference_partners_path(conference) + + within "#partners table" do + expect(page).to have_content(attributes[:name]) + expect(page).to have_content("Collaborator") + end + visit decidim_admin.root_path + expect(page).to have_content("created the partner #{attributes[:name]}") + end + + it "updates a conference partners", versioning: true do within find("#partners tr", text: conference_partner.name) do click_link "Edit" end within ".edit_partner" do - fill_in( - :conference_partner_name, - with: "Partner name" - ) + fill_in(:conference_partner_name, with: attributes[:name]) select( "Collaborator", @@ -46,9 +69,11 @@ expect(page).to have_current_path decidim_admin_conferences.conference_partners_path(conference) within "#partners table" do - expect(page).to have_content("Partner name") + expect(page).to have_content(attributes[:name]) expect(page).to have_content("Collaborator") end + visit decidim_admin.root_path + expect(page).to have_content("updated the partner #{conference_partner.name}") end context "when the partner type is already a Collaborator" do
decidim-conferences/spec/shared/manage_registration_types_examples.rb+30 −8 modified@@ -2,6 +2,7 @@ shared_examples "manage registration types examples" do let!(:registration_type) { create(:registration_type, conference:) } + let(:attributes) { attributes_for(:registration_type, conference:) } before do switch_to_host(organization.host) @@ -23,19 +24,37 @@ visit current_path end + it "creates a conference registration types", versioning: true do + click_on "New registration type" + + within ".new_registration_type" do + fill_in_i18n(:conference_registration_type_title, "#conference_registration_type-title-tabs", **attributes[:title].except("machine_translations")) + fill_in_i18n_editor(:conference_registration_type_description, "#conference_registration_type-description-tabs", **attributes[:description].except("machine_translations")) + + fill_in(:conference_registration_type_weight, with: 4) + + find("*[type=submit]").click + end + + expect(page).to have_admin_callout("successfully") + expect(page).to have_current_path decidim_admin_conferences.conference_registration_types_path(conference) + + within "#registration_types table" do + expect(page).to have_content(translated(attributes[:title])) + end + + visit decidim_admin.root_path + expect(page).to have_content("created the #{translated(attributes[:title])} registration type") + end + it "updates a conference registration types" do within find("#registration_types tr", text: translated(registration_type.title)) do click_link "Edit" end within ".edit_registration_type" do - fill_in_i18n( - :conference_registration_type_title, - "#conference_registration_type-title-tabs", - en: "Registration type title", - es: "Registration type title es", - ca: "Registration type title ca" - ) + fill_in_i18n(:conference_registration_type_title, "#conference_registration_type-title-tabs", **attributes[:title].except("machine_translations")) + fill_in_i18n_editor(:conference_registration_type_description, "#conference_registration_type-description-tabs", **attributes[:description].except("machine_translations")) find("*[type=submit]").click end @@ -44,8 +63,11 @@ expect(page).to have_current_path decidim_admin_conferences.conference_registration_types_path(conference) within "#registration_types table" do - expect(page).to have_content("Registration type title") + expect(page).to have_content(translated(attributes[:title])) end + + visit decidim_admin.root_path + expect(page).to have_content("updated the #{translated(registration_type.title)} registration type") end it "deletes the conference registration type" do
decidim-core/app/presenters/decidim/log/resource_presenter.rb+7 −1 modified@@ -10,6 +10,8 @@ module Log # overwrite `BasePresenter#resource_presenter` to return your custom resource presenter. # The only requirement for custom renderers is that they should respond to `present`. class ResourcePresenter + include Decidim::SanitizeHelper + # Public: Initializes the presenter. # # resource - An instance of a model that can be located by @@ -65,7 +67,11 @@ def resource_path # # Returns an HTML-safe String. def present_resource_name - h.translated_attribute extra["title"] + if resource.present? && resource.respond_to?(:presenter) && resource.presenter.respond_to?(:title) + resource.presenter.title(html_escape: true) + else + decidim_escape_translated(extra["title"]).html_safe + end end end end
decidim-core/app/services/decidim/log/diff_changeset_calculator.rb+1 −1 modified@@ -86,7 +86,7 @@ def generate_i18n_changeset(attribute, values, type) locales.flat_map do |locale| previous_value = values.first.try(:[], locale) new_value = values.last.try(:[], locale) - if previous_value == new_value + if previous_value == new_value || (previous_value.nil? && new_value.blank?) nil else label = generate_label(attribute, locale)
decidim-debates/app/models/decidim/debates/debate.rb+6 −0 modified@@ -56,6 +56,12 @@ class Debate < Debates::ApplicationRecord } scope_search_multi :with_any_state, [:open, :closed] + # Returns the presenter for this debate, to be used in the views. + # Required by ResourceRenderer. + def presenter + Decidim::Debates::DebatePresenter.new(self) + end + def self.log_presenter_class_for(_log) Decidim::Debates::AdminLog::DebatePresenter end
decidim-debates/app/presenters/decidim/debates/admin_log/debate_presenter.rb+0 −4 modified@@ -15,10 +15,6 @@ module AdminLog class DebatePresenter < Decidim::Log::BasePresenter private - def resource_presenter - @resource_presenter ||= Decidim::Debates::Log::ResourcePresenter.new(action_log.resource, h, action_log.extra["resource"]) - end - def diff_fields_mapping { description: "Decidim::Debates::AdminLog::ValueTypes::DebateTitleDescriptionPresenter",
decidim-debates/app/presenters/decidim/debates/admin_log/value_types/debate_title_description_presenter.rb+1 −1 modified@@ -10,7 +10,7 @@ class DebateTitleDescriptionPresenter < Decidim::Log::ValueTypes::DefaultPresent def present return unless value - renderer = Decidim::ContentRenderers::HashtagRenderer.new(h.translated_attribute(value)) + renderer = Decidim::ContentRenderers::HashtagRenderer.new(h.decidim_escape_translated(value)) renderer.render(links: false).html_safe end end
decidim-debates/app/presenters/decidim/debates/log/resource_presenter.rb+0 −18 removed@@ -1,18 +0,0 @@ -# frozen_string_literal: true - -module Decidim - module Debates - module Log - class ResourcePresenter < Decidim::Log::ResourcePresenter - private - - # Private: Presents resource name. - # - # Returns an HTML-safe String. - def present_resource_name - Decidim::Debates::DebatePresenter.new(resource).title - end - end - end - end -end
decidim-debates/spec/shared/manage_debates_examples.rb+30 −63 modified@@ -2,6 +2,7 @@ RSpec.shared_examples "manage debates" do let!(:debate) { create(:debate, category:, component: current_component) } + let(:attributes) { attributes_for(:debate, :closed, component: current_component) } before { visit_component_admin } @@ -39,28 +40,27 @@ end describe "updating a debate" do - it "updates a debate" do + it "updates a debate", versioning: true do within find("tr", text: translated(debate.title)) do page.find(".action-icon--edit").click end within ".edit_debate" do - fill_in_i18n( - :debate_title, - "#debate-title-tabs", - en: "My new title", - es: "Mi nuevo título", - ca: "El meu nou títol" - ) + fill_in_i18n(:debate_title, "#debate-title-tabs", **attributes[:title].except("machine_translations")) + fill_in_i18n_editor(:debate_description, "#debate-description-tabs", **attributes[:description].except("machine_translations")) + fill_in_i18n_editor(:debate_instructions, "#debate-instructions-tabs", **attributes[:instructions].except("machine_translations")) find("*[type=submit]").click end expect(page).to have_admin_callout "Debate successfully updated" within "table" do - expect(page).to have_content("My new title") + expect(page).to have_content(translated(attributes[:title])) end + + visit decidim_admin.root_path + expect(page).to have_content("updated the #{translated(attributes[:title])} debate on the") end context "when the debate has an author" do @@ -88,31 +88,13 @@ end end - it "creates a new finite debate" do + it "creates a new finite debate", versioning: true do click_link "New debate" within ".new_debate" do - fill_in_i18n( - :debate_title, - "#debate-title-tabs", - en: "My debate", - es: "Mi debate", - ca: "El meu debat" - ) - fill_in_i18n_editor( - :debate_description, - "#debate-description-tabs", - en: "Long description", - es: "Descripción más larga", - ca: "Descripció més llarga" - ) - fill_in_i18n_editor( - :debate_instructions, - "#debate-instructions-tabs", - en: "Long instructions", - es: "Instrucciones más largas", - ca: "Instruccions més llargues" - ) + fill_in_i18n(:debate_title, "#debate-title-tabs", **attributes[:title].except("machine_translations")) + fill_in_i18n_editor(:debate_description, "#debate-description-tabs", **attributes[:description].except("machine_translations")) + fill_in_i18n_editor(:debate_instructions, "#debate-instructions-tabs", **attributes[:instructions].except("machine_translations")) choose "Finite" end @@ -129,35 +111,20 @@ expect(page).to have_admin_callout "Debate successfully created" within "table" do - expect(page).to have_content("My debate") + expect(page).to have_content(translated(attributes[:title])) end + + visit decidim_admin.root_path + expect(page).to have_content("created the #{translated(attributes[:title])} debate on the") end it "creates a new open debate" do click_link "New debate" within ".new_debate" do - fill_in_i18n( - :debate_title, - "#debate-title-tabs", - en: "My debate", - es: "Mi debate", - ca: "El meu debat" - ) - fill_in_i18n_editor( - :debate_description, - "#debate-description-tabs", - en: "Long description", - es: "Descripción más larga", - ca: "Descripció més llarga" - ) - fill_in_i18n_editor( - :debate_instructions, - "#debate-instructions-tabs", - en: "Long instructions", - es: "Instrucciones más largas", - ca: "Instruccions més llargues" - ) + fill_in_i18n(:debate_title, "#debate-title-tabs", **attributes[:title].except("machine_translations")) + fill_in_i18n_editor(:debate_description, "#debate-description-tabs", **attributes[:description].except("machine_translations")) + fill_in_i18n_editor(:debate_instructions, "#debate-instructions-tabs", **attributes[:instructions].except("machine_translations")) choose "Open" end @@ -174,8 +141,11 @@ expect(page).to have_admin_callout "Debate successfully created" within "table" do - expect(page).to have_content("My debate") + expect(page).to have_content(translated(attributes[:title])) end + + visit decidim_admin.root_path + expect(page).to have_content("created the #{translated(attributes[:title])} debate on the") end describe "deleting a debate" do @@ -210,20 +180,14 @@ end end - describe "closing a debate" do + describe "closing a debate", versioning: true do it "closes a debate" do within find("tr", text: translated(debate.title)) do page.find(".action-icon--close").click end within ".edit_close_debate" do - fill_in_i18n_editor( - :debate_conclusions, - "#debate-conclusions-tabs", - en: "The debate was great", - es: "El debate fué genial", - ca: "El debat ha anat molt bé" - ) + fill_in_i18n_editor(:debate_conclusions, "#debate-conclusions-tabs", **attributes[:conclusions].except("machine_translations")) find("*[type=submit]").click end @@ -237,7 +201,10 @@ end end - expect(page).to have_content("The debate was great") + expect(page).to have_content(strip_tags(translated(attributes[:conclusions])).strip) + + visit decidim_admin.root_path + expect(page).to have_content("performed some action on #{translated(debate.title)} in") end context "when the debate has an author" do
decidim-meetings/app/presenters/decidim/meetings/admin_log/meeting_presenter.rb+0 −4 modified@@ -15,10 +15,6 @@ module AdminLog class MeetingPresenter < Decidim::Log::BasePresenter private - def resource_presenter - @resource_presenter ||= Decidim::Meetings::Log::ResourcePresenter.new(action_log.resource, h, action_log.extra["resource"]) - end - def diff_fields_mapping { address: :string,
decidim-meetings/app/presenters/decidim/meetings/admin_log/value_types/meeting_title_description_presenter.rb+1 −1 modified@@ -10,7 +10,7 @@ class MeetingTitleDescriptionPresenter < Decidim::Log::ValueTypes::DefaultPresen def present return unless value - renderer = Decidim::ContentRenderers::HashtagRenderer.new(h.translated_attribute(value)) + renderer = Decidim::ContentRenderers::HashtagRenderer.new(h.decidim_escape_translated(value)) renderer.render(links: false).html_safe end end
decidim-meetings/app/presenters/decidim/meetings/log/resource_presenter.rb+0 −18 removed@@ -1,18 +0,0 @@ -# frozen_string_literal: true - -module Decidim - module Meetings - module Log - class ResourcePresenter < Decidim::Log::ResourcePresenter - private - - # Private: Presents resource name. - # - # Returns an HTML-safe String. - def present_resource_name - Decidim::Meetings::MeetingPresenter.new(resource).title - end - end - end - end -end
decidim-meetings/spec/system/admin/admin_manages_meetings_spec.rb+24 −37 modified@@ -10,6 +10,12 @@ let(:latitude) { 40.1234 } let(:longitude) { 2.1234 } let(:service_titles) { ["This is the first service", "This is the second service"] } + let(:base_date) { Time.new.utc } + let(:meeting_start_date) { base_date.strftime("%d/%m/%Y") } + let(:meeting_start_time) { base_date.utc.strftime("%H:%M") } + let(:meeting_end_date) { ((base_date + 2.days) + 1.month).strftime("%d/%m/%Y") } + let(:meeting_end_time) { (base_date + 4.hours).strftime("%H:%M") } + let(:attributes) { attributes_for(:meeting, component: current_component) } include_context "when managing a component as an admin" @@ -153,13 +159,12 @@ end within ".edit_meeting" do - fill_in_i18n( - :meeting_title, - "#meeting-title-tabs", - en: "My new title", - es: "Mi nuevo título", - ca: "El meu nou títol" - ) + fill_in_i18n(:meeting_title, "#meeting-title-tabs", **attributes[:title].except("machine_translations")) + + fill_in_i18n(:meeting_location, "#meeting-location-tabs", **attributes[:location].except("machine_translations")) + fill_in_i18n(:meeting_location_hints, "#meeting-location_hints-tabs", **attributes[:location_hints].except("machine_translations")) + fill_in_i18n_editor(:meeting_description, "#meeting-description-tabs", **attributes[:description].except("machine_translations")) + fill_in_geocoding :meeting_address, with: address find("*[type=submit]").click @@ -168,8 +173,11 @@ expect(page).to have_admin_callout("successfully") within "table" do - expect(page).to have_content("My new title") + expect(page).to have_content(translated(attributes[:title])) end + + visit decidim_admin.root_path + expect(page).to have_content("updated the #{translated(attributes[:title])} meeting on the") end it "sets registration enabled to true when registration type is on this platform" do @@ -268,37 +276,13 @@ it "creates a new meeting", :serves_geocoding_autocomplete do click_link "New meeting" - fill_in_i18n( - :meeting_title, - "#meeting-title-tabs", - en: "My meeting", - es: "Mi meeting", - ca: "El meu meeting" - ) + fill_in_i18n(:meeting_title, "#meeting-title-tabs", **attributes[:title].except("machine_translations")) select "In person", from: :meeting_type_of_meeting - fill_in_i18n( - :meeting_location, - "#meeting-location-tabs", - en: "Location", - es: "Location", - ca: "Location" - ) - fill_in_i18n( - :meeting_location_hints, - "#meeting-location_hints-tabs", - en: "Location hints", - es: "Location hints", - ca: "Location hints" - ) - fill_in_i18n_editor( - :meeting_description, - "#meeting-description-tabs", - en: "A longer description", - es: "Descripción más larga", - ca: "Descripció més llarga" - ) + fill_in_i18n(:meeting_location, "#meeting-location-tabs", **attributes[:location].except("machine_translations")) + fill_in_i18n(:meeting_location_hints, "#meeting-location_hints-tabs", **attributes[:location_hints].except("machine_translations")) + fill_in_i18n_editor(:meeting_description, "#meeting-description-tabs", **attributes[:description].except("machine_translations")) fill_in_geocoding :meeting_address, with: address fill_in_services @@ -318,8 +302,11 @@ expect(page).to have_admin_callout("successfully") within "table" do - expect(page).to have_content("My meeting") + expect(page).to have_content(translated(attributes[:title])) end + + visit decidim_admin.root_path + expect(page).to have_content("created the #{translated(attributes[:title])} meeting on the") end context "when using the front-end geocoder", :serves_geocoding_autocomplete do
decidim-pages/spec/system/admin_spec.rb+8 −9 modified@@ -21,25 +21,24 @@ visit_component_admin end - it_behaves_like "having a rich text editor for field", ".tabs-content[data-tabs-content='page-body-tabs']", "full" + let!(:attributes) { attributes_for(:static_page) } - it "updates the page" do - new_body = { - en: "<p>New body</p>", - ca: "<p>Nou cos</p>", - es: "<p>Nuevo cuerpo</p>" - } + it_behaves_like "having a rich text editor for field", ".tabs-content[data-tabs-content='page-body-tabs']", "full" + it "updates the page", versioning: true do within "form.edit_page" do - fill_in_i18n_editor(:page_body, "#page-body-tabs", new_body) + fill_in_i18n_editor(:page_body, "#page-body-tabs", **attributes[:content].except("machine_translations")) find("*[type=submit]").click end expect(page).to have_admin_callout("successfully") visit_component - expect(page).to have_content("New body") + expect(page).to have_content(translated(component.name)) + + visit decidim_admin.root_path + expect(page).to have_content("updated the #{translated(component.name)} page") end end
decidim-participatory_processes/lib/decidim/participatory_processes/test/factories.rb+1 −0 modified@@ -141,6 +141,7 @@ end title { generate_localized_title(:participatory_process_step_title, skip_injection:) } description { generate_localized_description(:participatory_process_step_description, skip_injection:) } + cta_text { generate_localized_description(:participatory_process_step_cta_text, skip_injection:) } start_date { 1.month.ago } end_date { 2.months.from_now } position { nil }
decidim-participatory_processes/spec/shared/manage_process_admins_examples.rb+10 −3 modified@@ -2,6 +2,7 @@ shared_examples "manage process admins examples" do let(:other_user) { create(:user, organization:, email: "my_email@example.org") } + let(:attributes) { attributes_for(:user, organization:) } let!(:process_admin) do create(:process_admin, @@ -25,12 +26,12 @@ end end - it "creates a new process admin" do + it "creates a new process admin", versioning: true do click_link "New process admin" within ".new_participatory_process_user_role" do fill_in :participatory_process_user_role_email, with: other_user.email - fill_in :participatory_process_user_role_name, with: "John Doe" + fill_in :participatory_process_user_role_name, with: attributes[:name] select "Administrator", from: :participatory_process_user_role_role find("*[type=submit]").click @@ -41,6 +42,9 @@ within "#process_admins table" do expect(page).to have_content(other_user.email) end + + visit decidim_admin.root_path + expect(page).to have_content("invited the participant #{other_user.name} to the #{translated(participatory_process.title)} participatory process") end describe "when managing different users" do @@ -50,7 +54,7 @@ visit current_path end - it "updates a process admin" do + it "updates a process admin", versioning: true do within "#process_admins" do within find("#process_admins tr", text: other_user.email) do click_link "Edit" @@ -68,6 +72,9 @@ within "#process_admins table" do expect(page).to have_content("Administrator") end + + visit decidim_admin.root_path + expect(page).to have_content("changed the role of the participant #{other_user.name} in the #{translated(participatory_process.title)} participatory process") end it "deletes a participatory_process_user_role" do
decidim-participatory_processes/spec/shared/manage_processes_examples.rb+17 −8 modified@@ -85,6 +85,7 @@ def filter_by_group(group_title) context "when updating a participatory process" do let(:image3_filename) { "city3.jpeg" } let(:image3_path) { Decidim::Dev.asset(image3_filename) } + let(:attributes) { attributes_for(:participatory_process, organization:) } before do within find("tr", text: translated(participatory_process.title)) do @@ -97,13 +98,18 @@ def filter_by_group(group_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" - ) + fill_in_i18n(:participatory_process_title, "#participatory_process-title-tabs", **attributes[:title].except("machine_translations")) + fill_in_i18n(:participatory_process_subtitle, "#participatory_process-subtitle-tabs", **attributes[:subtitle].except("machine_translations")) + fill_in_i18n_editor(:participatory_process_short_description, "#participatory_process-short_description-tabs", **attributes[:short_description].except("machine_translations")) + fill_in_i18n_editor(:participatory_process_description, "#participatory_process-description-tabs", **attributes[:description].except("machine_translations")) + fill_in_i18n_editor(:participatory_process_announcement, "#participatory_process-announcement-tabs", **attributes[:announcement].except("machine_translations")) + fill_in_i18n(:participatory_process_developer_group, "#participatory_process-developer_group-tabs", **attributes[:developer_group].except("machine_translations")) + fill_in_i18n(:participatory_process_local_area, "#participatory_process-local_area-tabs", **attributes[:local_area].except("machine_translations")) + fill_in_i18n(:participatory_process_meta_scope, "#participatory_process-meta_scope-tabs", **attributes[:meta_scope].except("machine_translations")) + fill_in_i18n(:participatory_process_target, "#participatory_process-target-tabs", **attributes[:target].except("machine_translations")) + fill_in_i18n(:participatory_process_participatory_scope, "#participatory_process-participatory_scope-tabs", **attributes[:participatory_scope].except("machine_translations")) + fill_in_i18n(:participatory_process_participatory_structure, "#participatory_process-participatory_structure-tabs", **attributes[:participatory_structure].except("machine_translations")) + dynamically_attach_file(:participatory_process_banner_image, image3_path, remove_before: true) fill_in :participatory_process_end_date, with: Time.current.change(day: 22) @@ -115,9 +121,12 @@ def filter_by_group(group_title) expect(page).to have_admin_callout("successfully") within "[data-content]" do - expect(page).to have_selector("input[value='My new title']") + expect(page).to have_selector("input[value='#{translated(attributes[:title])}']") expect(page).to have_css("img[src*='#{image3_filename}']") end + + visit decidim_admin.root_path + expect(page).to have_content("updated the #{translated(attributes[:title])} participatory process") end end
decidim-participatory_processes/spec/shared/manage_process_steps_examples.rb+17 −18 modified@@ -9,6 +9,7 @@ active: ) end + let(:attributes) { attributes_for(:participatory_process_step, participatory_process:) } before do switch_to_host(organization.host) @@ -23,23 +24,20 @@ before { click_link "New phase" } end - it "creates a new participatory_process" do + it "creates a new participatory_process", versioning: true do click_link "New phase" fill_in_i18n( :participatory_process_step_title, "#participatory_process_step-title-tabs", - en: "My participatory process step", - es: "Mi fase de proceso participativo", - ca: "La meva fase de procés participatiu" + **attributes[:title].except("machine_translations") ) fill_in_i18n_editor( :participatory_process_step_description, "#participatory_process_step-description-tabs", - en: "A longer description", - es: "Descripción más larga", - ca: "Descripció més llarga" + **attributes[:description].except("machine_translations") ) + fill_in_i18n(:participatory_process_step_cta_text, "#participatory_process_step-cta_text-tabs", **attributes[:cta_text].except("machine_translations")) fill_in :participatory_process_step_start_date, with: Time.current.change(day: 12) fill_in :participatory_process_step_end_date, with: Time.current.change(day: 22) @@ -51,37 +49,38 @@ expect(page).to have_admin_callout("successfully") within "#steps table" do - expect(page).to have_content("My participatory process step") + expect(page).to have_content(translated(attributes[:title])) expect(page).to have_content("12,") expect(page).to have_content("22,") end + visit decidim_admin.root_path + expect(page).to have_content("created the #{translated(attributes[:title])} phase in") end - it "updates a participatory_process_step" do + it "updates a participatory_process_step", versioning: true do within "#steps" do within find("tr", text: translated(process_step.title)) do click_link "Edit" end end within ".edit_participatory_process_step" do - fill_in_i18n( - :participatory_process_step_title, - "#participatory_process_step-title-tabs", - en: "My new title", - es: "Mi nuevo título", - ca: "El meu nou títol" - ) + fill_in_i18n(:participatory_process_step_title, "#participatory_process_step-title-tabs", **attributes[:title].except("machine_translations")) + fill_in_i18n_editor(:participatory_process_step_description, "#participatory_process_step-description-tabs", **attributes[:description].except("machine_translations")) + fill_in_i18n(:participatory_process_step_cta_text, "#participatory_process_step-cta_text-tabs", **attributes[:cta_text].except("machine_translations")) find("*[type=submit]").click end expect(page).to have_admin_callout("successfully") within "#steps table" do - expect(page).to have_content("My new title") - click_link("My new title") + expect(page).to have_content(translated(attributes[:title])) + click_link(translated(attributes[:title])) end + + visit decidim_admin.root_path + expect(page).to have_content("updated the #{translated(attributes[:title])} phase in") end context "when deleting a participatory process step" do
decidim-participatory_processes/spec/system/admin/admin_manages_participatory_processes_spec.rb+16 −28 modified@@ -55,6 +55,7 @@ let(:image2_filename) { "city2.jpeg" } let(:image2_path) { Decidim::Dev.asset(image2_filename) } + let(:attributes) { attributes_for(:participatory_process, organization:) } before do click_link "New process" @@ -66,34 +67,18 @@ it "creates a new participatory process" do within ".new_participatory_process" do - fill_in_i18n( - :participatory_process_title, - "#participatory_process-title-tabs", - en: "My participatory process", - es: "Mi proceso participativo", - ca: "El meu procés participatiu" - ) - fill_in_i18n( - :participatory_process_subtitle, - "#participatory_process-subtitle-tabs", - en: "Subtitle", - es: "Subtítulo", - ca: "Subtítol" - ) - fill_in_i18n_editor( - :participatory_process_short_description, - "#participatory_process-short_description-tabs", - en: "Short description", - es: "Descripción corta", - ca: "Descripció curta" - ) - fill_in_i18n_editor( - :participatory_process_description, - "#participatory_process-description-tabs", - en: "A longer description", - es: "Descripción más larga", - ca: "Descripció més llarga" - ) + fill_in_i18n(:participatory_process_title, "#participatory_process-title-tabs", **attributes[:title].except("machine_translations")) + fill_in_i18n(:participatory_process_subtitle, "#participatory_process-subtitle-tabs", **attributes[:subtitle].except("machine_translations")) + fill_in_i18n_editor(:participatory_process_short_description, "#participatory_process-short_description-tabs", **attributes[:short_description].except("machine_translations")) + fill_in_i18n_editor(:participatory_process_description, "#participatory_process-description-tabs", **attributes[:description].except("machine_translations")) + fill_in_i18n_editor(:participatory_process_announcement, "#participatory_process-announcement-tabs", **attributes[:announcement].except("machine_translations")) + + fill_in_i18n(:participatory_process_developer_group, "#participatory_process-developer_group-tabs", **attributes[:developer_group].except("machine_translations")) + fill_in_i18n(:participatory_process_local_area, "#participatory_process-local_area-tabs", **attributes[:local_area].except("machine_translations")) + fill_in_i18n(:participatory_process_meta_scope, "#participatory_process-meta_scope-tabs", **attributes[:meta_scope].except("machine_translations")) + fill_in_i18n(:participatory_process_target, "#participatory_process-target-tabs", **attributes[:target].except("machine_translations")) + fill_in_i18n(:participatory_process_participatory_scope, "#participatory_process-participatory_scope-tabs", **attributes[:participatory_scope].except("machine_translations")) + fill_in_i18n(:participatory_process_participatory_structure, "#participatory_process-participatory_structure-tabs", **attributes[:participatory_structure].except("machine_translations")) group_title = participatory_process_groups.first.title["en"] select group_title, from: :participatory_process_participatory_process_group_id @@ -117,6 +102,9 @@ expect(page).to have_content("Phases") expect(page).to have_content("Introduction") end + + visit decidim_admin.root_path + expect(page).to have_content("created the #{translated(attributes[:title])} participatory process") end end
decidim-participatory_processes/spec/system/admin/admin_manages_participatory_process_groups_spec.rb+24 −49 modified@@ -8,7 +8,7 @@ let!(:participatory_processes) do create_list(:participatory_process, 3, organization:) end - + let(:attributes) { attributes_for(:participatory_process_group, organization:) } let(:image1_filename) { "city.jpeg" } let(:image1_path) { Decidim::Dev.asset(image1_filename) } @@ -26,35 +26,18 @@ end end - it "creates a new participatory process group" do + it "creates a new participatory process group", versioning: true do within "div.process-title" do click_link "New process group" end within ".new_participatory_process_group" do - fill_in_i18n( - :participatory_process_group_title, - "#participatory_process_group-title-tabs", - en: "My group", - es: "Mi grupo", - ca: "El meu grup" - ) - fill_in_i18n_editor( - :participatory_process_group_description, - "#participatory_process_group-description-tabs", - en: "A longer description", - es: "Descripción más larga", - ca: "Descripció més llarga" - ) + fill_in_i18n(:participatory_process_group_title, "#participatory_process_group-title-tabs", **attributes[:title].except("machine_translations")) + fill_in_i18n(:participatory_process_group_developer_group, "#participatory_process_group-developer_group-tabs", **attributes[:developer_group].except("machine_translations")) + fill_in_i18n_editor(:participatory_process_group_description, "#participatory_process_group-description-tabs", **attributes[:description].except("machine_translations")) + fill_in :participatory_process_group_hashtag, with: "hashtag" fill_in :participatory_process_group_group_url, with: "http://example.org" - fill_in_i18n( - :participatory_process_group_developer_group, - "#participatory_process_group-developer_group-tabs", - en: "X corporation", - es: "La corporación X", - ca: "La corporació X" - ) select participatory_processes.first.title["en"], from: :participatory_process_group_participatory_process_ids end @@ -65,12 +48,17 @@ end expect(page).to have_admin_callout("successfully") - expect(page).to have_field(:participatory_process_group_title_en, with: "My group") + expect(page).to have_field(:participatory_process_group_title_en, with: translated(attributes[:title])) expect(page).to have_field(:participatory_process_group_hashtag, with: "hashtag") expect(page).to have_field(:participatory_process_group_group_url, with: "http://example.org") - expect(page).to have_field(:participatory_process_group_developer_group_en, with: "X corporation") + expect(page).to have_field(:participatory_process_group_developer_group_en, with: translated(attributes[:developer_group])) expect(page).to have_select("Related processes", selected: participatory_processes.first.title["en"]) expect(page).to have_css("img[src*='#{image1_filename}']") + + expect(page).to have_admin_callout("successfully") + + visit decidim_admin.root_path + expect(page).to have_content("created the #{translated(attributes[:title])} participatory process group") end context "with existing groups" do @@ -90,29 +78,13 @@ end within ".edit_participatory_process_group" do - fill_in_i18n( - :participatory_process_group_title, - "#participatory_process_group-title-tabs", - en: "My old group", - es: "Mi grupo antiguo", - ca: "El meu grup antic" - ) - fill_in_i18n_editor( - :participatory_process_group_description, - "#participatory_process_group-description-tabs", - en: "New description", - es: "Nueva descripción", - ca: "Nova descripció" - ) + fill_in_i18n(:participatory_process_group_title, "#participatory_process_group-title-tabs", **attributes[:title].except("machine_translations")) + fill_in_i18n_editor(:participatory_process_group_description, "#participatory_process_group-description-tabs", **attributes[:description].except("machine_translations")) + fill_in :participatory_process_group_hashtag, with: "new_hashtag" fill_in :participatory_process_group_group_url, with: "http://new-example.org" - fill_in_i18n( - :participatory_process_group_developer_group, - "#participatory_process_group-developer_group-tabs", - en: "Z corporation", - es: "La corporación Z", - ca: "La corporació Z" - ) + fill_in_i18n(:participatory_process_group_developer_group, "#participatory_process_group-developer_group-tabs", **attributes[:developer_group].except("machine_translations")) + select participatory_processes.last.title["en"], from: :participatory_process_group_participatory_process_ids end @@ -123,13 +95,16 @@ end expect(page).to have_admin_callout("successfully") - expect(page).to have_field(:participatory_process_group_title_en, with: "My old group") - expect(page).to have_content("New description") + expect(page).to have_field(:participatory_process_group_title_en, with: translated(attributes[:title])) + expect(page).to have_content(strip_tags(translated(attributes[:description])).strip) expect(page).to have_field(:participatory_process_group_hashtag, with: "new_hashtag") expect(page).to have_field(:participatory_process_group_group_url, with: "http://new-example.org") - expect(page).to have_field(:participatory_process_group_developer_group_en, with: "Z corporation") + expect(page).to have_field(:participatory_process_group_developer_group_en, with: translated(attributes[:developer_group])) expect(page).to have_select("Related processes", selected: participatory_processes.last.title["en"]) expect(page).to have_css("img[src*='#{image2_filename}']") + + visit decidim_admin.root_path + expect(page).to have_content("updated the #{translated(attributes[:title])} participatory process group") end it "validates the group attributes" do
decidim-participatory_processes/spec/system/admin/admin_manages_participatory_process_types_spec.rb+14 −17 modified@@ -8,6 +8,7 @@ let!(:participatory_processes) do create_list(:participatory_process, 3, organization:) end + let(:attributes) { attributes_for(:participatory_process_type, organization:) } describe "Managing participatory process types" do before do @@ -16,25 +17,23 @@ visit decidim_admin_participatory_processes.participatory_process_types_path end - it "can create new participatory process types" do + it "can create new participatory process types", versioning: true do click_link "New process type" within ".new_participatory_process_type" do - fill_in_i18n( - :participatory_process_type_title, - "#participatory_process_type-title-tabs", - en: "My participatory process type", - es: "Mi tipo de proceso participativo", - ca: "El meu tipus de procés participatiu " - ) + fill_in_i18n(:participatory_process_type_title, "#participatory_process_type-title-tabs", **attributes[:title].except("machine_translations")) + find("*[type=submit]").click end expect(page).to have_admin_callout("successfully") within "table" do - expect(page).to have_content("My participatory process type") + expect(page).to have_content(translated(attributes[:title])) end + + visit decidim_admin.root_path + expect(page).to have_content("created the #{translated(attributes[:title])} participatory process type") end context "with existing participatory process types" do @@ -56,21 +55,19 @@ end within ".edit_participatory_process_type" do - fill_in_i18n( - :participatory_process_type_title, - "#participatory_process_type-title-tabs", - en: "Another participatory process type", - es: "Otro tipo de proceso participativo", - ca: "Un altre tipus de procés participatiu" - ) + fill_in_i18n(:participatory_process_type_title, "#participatory_process_type-title-tabs", **attributes[:title].except("machine_translations")) + find("*[type=submit]").click end expect(page).to have_admin_callout("successfully") within "table" do - expect(page).to have_content("Another participatory process type") + expect(page).to have_content(translated(attributes[:title])) end + + visit decidim_admin.root_path + expect(page).to have_content("updated the #{translated(attributes[:title])} participatory process type") end it "can delete them" do
decidim-participatory_processes/spec/types/participatory_process_step_type_spec.rb+1 −1 modified@@ -80,7 +80,7 @@ module ParticipatoryProcesses let(:query) { '{ callToActionText { locales translation(locale:"en") } }' } it "returns the step's call to action text" do - expect(response["callToActionText"]["locales"]).to include(*model.cta_text.keys) + expect(response["callToActionText"]["locales"]).to include(*model.cta_text.except("machine_translations").keys) expect(response["callToActionText"]["translation"]).to eq(model.cta_text["en"]) end end
decidim-proposals/app/presenters/decidim/proposals/admin_log/proposal_presenter.rb+1 −5 modified@@ -15,13 +15,9 @@ module AdminLog class ProposalPresenter < Decidim::Log::BasePresenter private - def resource_presenter - @resource_presenter ||= Decidim::Proposals::Log::ResourcePresenter.new(action_log.resource, h, action_log.extra["resource"]) - end - def diff_fields_mapping { - title: "Decidim::Proposals::AdminLog::ValueTypes::ProposalTitleBodyPresenter", + title: :i18n, body: "Decidim::Proposals::AdminLog::ValueTypes::ProposalTitleBodyPresenter", state: "Decidim::Proposals::AdminLog::ValueTypes::ProposalStatePresenter", answered_at: :date,
decidim-proposals/app/presenters/decidim/proposals/admin_log/value_types/proposal_title_body_presenter.rb+1 −3 modified@@ -5,12 +5,10 @@ module Proposals module AdminLog module ValueTypes class ProposalTitleBodyPresenter < Decidim::Log::ValueTypes::DefaultPresenter - include Decidim::TranslatableAttributes - def present return unless value - translated_value = translated_attribute(value) + translated_value = h.decidim_escape_translated(value) return if translated_value.blank? renderer = Decidim::ContentRenderers::HashtagRenderer.new(translated_value)
decidim-proposals/app/presenters/decidim/proposals/log/resource_presenter.rb+0 −22 removed@@ -1,22 +0,0 @@ -# frozen_string_literal: true - -module Decidim - module Proposals - module Log - class ResourcePresenter < Decidim::Log::ResourcePresenter - private - - # Private: Presents resource name. - # - # Returns an HTML-safe String. - def present_resource_name - if resource.present? - Decidim::Proposals::ProposalPresenter.new(resource).title - else - super - end - end - end - end - end -end
decidim-proposals/app/presenters/decidim/proposals/log/valuation_assignment_presenter.rb+1 −1 modified@@ -11,7 +11,7 @@ class ValuationAssignmentPresenter < Decidim::Log::ResourcePresenter # Returns an HTML-safe String. def present_resource_name if resource.present? - Decidim::Proposals::ProposalPresenter.new(resource.proposal).title + resource.proposal.presenter.title(html_escape: true) else super end
decidim-proposals/lib/decidim/proposals/test/factories.rb+7 −1 modified@@ -441,7 +441,13 @@ transient do skip_injection { false } end - body { Faker::Lorem.sentences(number: 3).join("\n") } + body do + if skip_injection + generate(:title) + else + "<script>alert(\"proposal_note_body\");</script> #{generate(:title)}" + end + end proposal { build(:proposal, skip_injection:) } author { build(:user, organization: proposal.organization, skip_injection:) } end
decidim-proposals/spec/presenters/decidim/log/resource_presenter_spec.rb+1 −6 renamed@@ -2,7 +2,7 @@ require "spec_helper" -describe Decidim::Proposals::Log::ResourcePresenter, type: :helper do +describe Decidim::Log::ResourcePresenter, type: :helper do let(:presenter) { described_class.new(resource, helper, extra) } let(:resource) { create(:proposal, title: Faker::Book.unique.title) } let(:extra) do @@ -12,11 +12,6 @@ end let(:resource_path) { Decidim::ResourceLocatorPresenter.new(resource).path } - before do - helper.extend(Decidim::ApplicationHelper) - helper.extend(Decidim::TranslationsHelper) - end - context "when the resource exists" do it "links to its public page with the name of the proposal" do html = presenter.present
decidim-proposals/spec/presenters/decidim/proposals/admin_log/value_types/proposal_title_body_presenter_spec.rb+10 −3 modified@@ -2,16 +2,23 @@ require "spec_helper" -describe Decidim::Proposals::AdminLog::ValueTypes::ProposalTitleBodyPresenter do - subject { described_class.new(value, _helpers) } +describe Decidim::Proposals::AdminLog::ValueTypes::ProposalTitleBodyPresenter, type: :helper do + subject { described_class.new(value, helper) } + + before do + module FooBar + include Decidim::SanitizeHelper + end + + helper.extend FooBar + end let(:value) do { "en" => "My value", "es" => "My title in Spanish" } end - let(:_helpers) { nil } describe "#present" do it "handles i18n fields" do
decidim-proposals/spec/shared/manage_proposals_examples.rb+9 −5 modified@@ -66,6 +66,8 @@ end context "when process is not related to any scope" do + let(:attributes) { attributes_for(:proposal, component: current_component) } + it "can be related to a scope" do click_link "New proposal" @@ -74,12 +76,12 @@ end end - it "creates a new proposal", :slow do + it "creates a new proposal", versioning: true do click_link "New proposal" within ".new_proposal" do - fill_in_i18n :proposal_title, "#proposal-title-tabs", en: "Make decidim great again" - fill_in_i18n_editor :proposal_body, "#proposal-body-tabs", en: "Decidim is great but it can be better" + fill_in_i18n :proposal_title, "#proposal-title-tabs", **attributes[:title].except("machine_translations") + fill_in_i18n_editor :proposal_body, "#proposal-body-tabs", **attributes[:body].except("machine_translations") select translated(category.name), from: :proposal_category_id select translated(scope.name), from: :proposal_scope_id find("*[type=submit]").click @@ -90,11 +92,13 @@ within "table" do proposal = Decidim::Proposals::Proposal.last - expect(page).to have_content("Make decidim great again") - expect(translated(proposal.body)).to eq("<p>Decidim is great but it can be better</p>") + expect(page).to have_content(translated(attributes[:title])) + expect(translated(proposal.body)).to eq("<p>#{strip_tags(translated(attributes[:body]))}</p>") expect(proposal.category).to eq(category) expect(proposal.scope).to eq(scope) end + visit decidim_admin.root_path + expect(page).to have_content("created the #{translated(attributes[:title])} proposal") end end
decidim-proposals/spec/system/admin/admin_edits_proposal_spec.rb+10 −6 modified@@ -22,25 +22,29 @@ end describe "editing an official proposal" do - let(:new_title) { "This is my proposal new title" } - let(:new_body) { "This is my proposal new body" } + let(:attributes) { attributes_for(:proposal, component: current_component) } it "can be updated" do visit_component_admin find("a.action-icon--edit-proposal").click expect(page).to have_content "Update proposal" - fill_in_i18n :proposal_title, "#proposal-title-tabs", en: new_title - fill_in_i18n_editor :proposal_body, "#proposal-body-tabs", en: new_body + fill_in_i18n :proposal_title, "#proposal-title-tabs", **attributes[:title].except("machine_translations") + fill_in_i18n_editor :proposal_body, "#proposal-body-tabs", **attributes[:body].except("machine_translations") click_button "Update" preview_window = window_opened_by { find("a.action-icon--preview").click } within_window preview_window do - expect(page).to have_content(new_title) - expect(page).to have_content(new_body) + expect(page).to have_content(translated(attributes[:title])) + expect(page).to have_content(strip_tags(translated(attributes[:body])).strip) end + + expect(page).to have_admin_callout("successfully") + + visit decidim_admin.root_path + expect(page).to have_content("updated the #{translated(attributes[:title])} official proposal") end context "when the proposal has some votes" do
decidim-proposals/spec/system/admin/admin_manages_proposal_valuators_spec.rb+5 −0 modified@@ -52,6 +52,11 @@ expect(page).to have_selector("td.valuators-count", text: 1) end end + + it "displays log" do + visit decidim_admin.root_path + expect(page).to have_content("assigned the #{translated(proposal.title)} proposal to a valuator") + end end end
decidim-proposals/spec/system/admin/index_proposal_notes_spec.rb+8 −4 modified@@ -9,6 +9,7 @@ let(:manifest_name) { "proposals" } let(:proposal) { create(:proposal, component:) } let(:participatory_space) { component.participatory_space } + let(:attributes) { attributes_for(:proposal_note) } let(:body) { "New awesome body" } let(:proposal_notes_count) { 5 } @@ -33,15 +34,15 @@ it "shows proposal notes for the current proposal" do proposal_notes.each do |proposal_note| expect(page).to have_content(proposal_note.author.name) - expect(page).to have_content(proposal_note.body) + expect(page).to have_content(decidim_sanitize_translated(proposal_note.body)) end expect(page).to have_selector("form") end context "when the form has a text inside body" do - it "creates a proposal note", :slow do + it "creates a proposal note", versioning: true do within ".new_proposal_note" do - fill_in :proposal_note_body, with: body + fill_in :proposal_note_body, with: attributes[:body] find("*[type=submit]").click end @@ -50,8 +51,11 @@ click_button "Private notes" within ".component__show_notes-grid .comment:last-child" do - expect(page).to have_content("New awesome body") + expect(page).to have_content(decidim_sanitize_translated(attributes[:body])) end + + visit decidim_admin.root_path + expect(page).to have_content("left a private note on the #{translated(proposal.title)} proposal") end end
decidim-sortitions/spec/shared/manage_sortitions_examples.rb+9 −23 modified@@ -56,37 +56,20 @@ 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) } + let(:attributes) { attributes_for(:sortition, component: current_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 + it "shows the sortition details", versioning: true 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" - ) + + fill_in_i18n_editor(:sortition_witnesses, "#sortition-witnesses-tabs", **attributes[:witnesses].except("machine_translations")) + fill_in_i18n_editor(:sortition_additional_info, "#sortition-additional_info-tabs", **attributes[:additional_info].except("machine_translations")) + fill_in_i18n(:sortition_title, "#sortition-title-tabs", **attributes[:title].except("machine_translations")) accept_confirm { find("*[type=submit]").click } end @@ -114,6 +97,9 @@ expect(page).to have_content(translated(p.title)) end end + + visit decidim_admin.root_path + expect(page).to have_content("created the #{translated(attributes[:title])} sortition") end end end
decidim-sortitions/spec/shared/update_sortitions_examples.rb+7 −16 modified@@ -3,6 +3,7 @@ shared_examples "update sortitions" do describe "update sortition data" do let!(:sortition) { create(:sortition, component: current_component) } + let(:attributes) { attributes_for(:sortition, component: current_component) } before do visit_component_admin @@ -24,28 +25,18 @@ end context "when updates a sortition" do - it "Redirects to sortitions view" do + it "Redirects to sortitions view", versioning: true do within ".edit_sortition" do - 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" - ) + fill_in_i18n_editor(:sortition_additional_info, "#sortition-additional_info-tabs", **attributes[:additional_info].except("machine_translations")) + fill_in_i18n(:sortition_title, "#sortition-title-tabs", **attributes[:title].except("machine_translations")) find("*[type=submit]").click end expect(page).to have_admin_callout("successfully") + + visit decidim_admin.root_path + expect(page).to have_content("updated the #{translated(attributes[:title])} sortition") end end end
decidim-templates/spec/system/admin/admin_manages_proposal_answer_templates_spec.rb+22 −18 modified@@ -3,8 +3,14 @@ require "spec_helper" describe "Admin manages proposal answer templates" do + let(:description) { "A component" } let!(:organization) { create(:organization) } let!(:user) { create(:user, :admin, :confirmed, organization:) } + let(:participatory_space) { create(:participatory_process, title: { en: "A participatory process" }, organization:) } + let!(:templatable) { create(:proposal_component, name: { en: description }, participatory_space:) } + let(:field_values) { { internal_state: "not_answered" } } + let!(:template) { create(:template, target: :proposal_answer, organization:, templatable:, field_values:) } + let(:attributes) { attributes_for(:template, target: :proposal_answer, organization:, templatable:, field_values:) } before do switch_to_host(organization.host) @@ -39,31 +45,24 @@ end describe "creating a proposal_answer_template" do - let(:participatory_process) { create(:participatory_process, title: { en: "A participatory process" }, organization:) } - let!(:proposals_component) { create(:component, manifest_name: :proposals, name: { en: "A component" }, participatory_space: participatory_process) } - before do within ".layout-content" do click_link("New") end end - shared_examples "creates a new template with scopes" do |scope_name| + shared_examples "creates a new template with scopes", versioning: true do |scope_name| it "creates a new template" do within ".new_proposal_answer_template" do fill_in_i18n( :proposal_answer_template_name, "#proposal_answer_template-name-tabs", - en: "My template", - es: "Mi plantilla", - ca: "La meva plantilla" + **attributes[:name].except("machine_translations") ) fill_in_i18n_editor( :proposal_answer_template_description, "#proposal_answer_template-description-tabs", - en: "Description", - es: "Descripción", - ca: "Descripció" + **attributes[:description].except("machine_translations") ) choose "Not answered" @@ -76,8 +75,12 @@ expect(page).to have_current_path decidim_admin_templates.proposal_answer_templates_path within ".table-list" do expect(page).to have_i18n_content(scope_name) - expect(page).to have_content("My template") + expect(page).to have_content(translated(attributes[:name])) end + expect(page).to have_admin_callout("successfully") + + visit decidim_admin.root_path + expect(page).to have_content("created the #{translated(attributes[:name])} questionnaire template") end end @@ -87,23 +90,20 @@ describe "updating a template" do let!(:template) { create(:template, :proposal_answer, organization:) } - let(:participatory_process) { create(:participatory_process, title: { en: "A participatory process" }, organization:) } - let!(:proposals_component) { create(:component, manifest_name: :proposals, name: { en: "A component" }, participatory_space: participatory_process) } before do visit decidim_admin_templates.proposal_answer_templates_path click_link translated(template.name) end shared_examples "updates a template with scopes" do |scope_name| - it "updates a template" do + it "updates a template", versioning: true do fill_in_i18n( :proposal_answer_template_name, "#proposal_answer_template-name-tabs", - en: "My new name", - es: "Mi nuevo nombre", - ca: "El meu nou nom" + **attributes[:name].except("machine_translations") ) + fill_in_i18n_editor(:proposal_answer_template_description, "#proposal_answer_template-description-tabs", **attributes[:description].except("machine_translations")) select scope_name, from: :proposal_answer_template_component_constraint @@ -115,8 +115,12 @@ expect(page).to have_current_path decidim_admin_templates.proposal_answer_templates_path within ".table-list" do expect(page).to have_i18n_content(scope_name) - expect(page).to have_content("My new name") + expect(page).to have_content(translated(attributes[:name])) end + expect(page).to have_admin_callout("successfully") + + visit decidim_admin.root_path + expect(page).to have_content("updated the #{translated(attributes[:name])} questionnaire template") end end
Vulnerability mechanics
Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
8- github.com/advisories/GHSA-rx9f-5ggv-5rh6ghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2024-32034ghsaADVISORY
- github.com/decidim/decidim/commit/23fc8d702a4976727f78617f5e42353d67931645ghsax_refsource_MISCWEB
- github.com/decidim/decidim/commit/9d79f09a2d38c87feb28725670d6cc1f55c22072ghsax_refsource_MISCWEB
- github.com/decidim/decidim/commit/e494235d559be13dd1f8694345e6f6bba762d1c0ghsax_refsource_MISCWEB
- github.com/decidim/decidim/commit/ff755e23814aeb56e9089fc08006a5d3faee47b6ghsax_refsource_MISCWEB
- github.com/decidim/decidim/security/advisories/GHSA-rx9f-5ggv-5rh6ghsax_refsource_CONFIRMWEB
- github.com/rubysec/ruby-advisory-db/blob/master/gems/decidim-admin/CVE-2024-32034.ymlghsaWEB
News mentions
0No linked articles in our index yet.