VYPR
Moderate severityNVD Advisory· Published Sep 16, 2024· Updated Sep 16, 2024

Cross-site scripting (XSS) in the decidim admin activity log

CVE-2024-32034

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.

PackageAffected versionsPatched versions
decidim-adminRubyGems
< 0.27.70.27.7
decidim-adminRubyGems
>= 0.28.0, < 0.28.20.28.2

Affected products

1

Patches

4
9d79f09a2d38

Backport 'Refactor malformed titles in admin logs (part 2)' to v0.27 (#13085)

https://github.com/decidim/decidimAlexandru Emil LupuJul 11, 2024via ghsa
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
    
ff755e23814a

Backport 'Refactor malformed titles in admin logs (part 1)' to v0.27 (#13084)

https://github.com/decidim/decidimAlexandru Emil LupuJul 9, 2024via ghsa
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 %> &gt;
    +        <%= link_to decidim_escape_translated(budget.title).html_safe, budgets_path %> &gt;
             <%= 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("&quot;", "\"")).to appear_before(decidim_escape_translated(last_document.title).gsub("&quot;", "\""))
    +        expect(decidim_escape_translated(first_document.title).gsub("&#39;", "\'")).to appear_before(decidim_escape_translated(last_document.title).gsub("&#39;", "\'"))
           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("&quot;",
    -                                                                                "\"")).to appear_before(decidim_escape_translated(last_attachment_collection.name).gsub("&quot;",
    -                                                                                                                                                                        "\""))
    +        expect(decidim_escape_translated(first_attachment_collection.name).gsub("&#39;",
    +                                                                                "\'")).to appear_before(decidim_escape_translated(last_attachment_collection.name).gsub("&#39;",
    +                                                                                                                                                                        "\'"))
           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("&quot;", "\"")).to appear_before(decidim_escape_translated(last_document.title).gsub("&quot;", "\""))
    +        expect(decidim_escape_translated(first_document.title).gsub("&#39;", "\'")).to appear_before(decidim_escape_translated(last_document.title).gsub("&#39;", "\'"))
           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("&quot;", "\""))
    +        expect(subject.to_s).to include(decidim_escape_translated(meeting.title).gsub("&#39;", "\'"))
           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("&quot;", "\""))
    +        expect(subject.to_s).to include(decidim_escape_translated(meeting.title).gsub("&#39;", "\'"))
           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
    
23fc8d702a49

Backport 'Refactor malformed titles in admin logs (part 2)' to v0.28 (#13083)

https://github.com/decidim/decidimAlexandru Emil LupuJul 8, 2024via ghsa
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
    
e494235d559b

Backport 'Refactor malformed titles in admin logs (part 1)' to v0.28 (#13082)

https://github.com/decidim/decidimAlexandru Emil LupuJul 8, 2024via ghsa
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

News mentions

0

No linked articles in our index yet.