From 4bcfd82618f3a25c75a36bdcf2a1e35344adf5b2 Mon Sep 17 00:00:00 2001 From: Anna Topalidi Date: Fri, 25 Aug 2023 15:08:59 +0200 Subject: [PATCH 01/11] add allow_to_edit_proposals_after_import config --- .../decidim_awesome/admin/config_form.rb | 1 + .../admin/permissions_override.rb | 37 +++++++++++++++++++ .../admin/config/_form_proposals.html.erb | 7 ++++ config/locales/en.yml | 5 +++ lib/decidim/decidim_awesome/awesome.rb | 4 ++ lib/decidim/decidim_awesome/engine.rb | 3 ++ .../decidim_awesome/test/initializer.rb | 1 + 7 files changed, 58 insertions(+) create mode 100644 app/permissions/concerns/decidim/decidim_awesome/admin/permissions_override.rb diff --git a/app/forms/decidim/decidim_awesome/admin/config_form.rb b/app/forms/decidim/decidim_awesome/admin/config_form.rb index 57ed59307..634e33325 100644 --- a/app/forms/decidim/decidim_awesome/admin/config_form.rb +++ b/app/forms/decidim/decidim_awesome/admin/config_form.rb @@ -11,6 +11,7 @@ class ConfigForm < Decidim::Form attribute :allow_images_in_full_editor, Boolean attribute :allow_images_in_small_editor, Boolean attribute :allow_images_in_proposals, Boolean + attribute :allow_to_edit_proposals_after_import, Boolean attribute :use_markdown_editor, Boolean attribute :allow_images_in_markdown_editor, Boolean attribute :auto_save_forms, Boolean diff --git a/app/permissions/concerns/decidim/decidim_awesome/admin/permissions_override.rb b/app/permissions/concerns/decidim/decidim_awesome/admin/permissions_override.rb new file mode 100644 index 000000000..c3b417021 --- /dev/null +++ b/app/permissions/concerns/decidim/decidim_awesome/admin/permissions_override.rb @@ -0,0 +1,37 @@ +# frozen_string_literal: true + +module Decidim + module DecidimAwesome + module Admin + module PermissionsOverride + extend ActiveSupport::Concern + + included do + private + + def admin_edition_is_available? + return unless proposal + + if proposal_imported? && allow_to_edit_proposals_after_import_enabled? + true + else + (proposal.official? || proposal.official_meeting?) && proposal.votes.empty? + end + end + + def proposal_imported? + Decidim::ResourceLink.exists?( + name: "copied_from_component", + to_type: "Decidim::Proposals::Proposal", + to_id: proposal.id + ) + end + + def allow_to_edit_proposals_after_import_enabled? + Decidim::DecidimAwesome::AwesomeConfig.find_by(var: :allow_to_edit_proposals_after_import)&.value == true + end + end + end + end + end +end diff --git a/app/views/decidim/decidim_awesome/admin/config/_form_proposals.html.erb b/app/views/decidim/decidim_awesome/admin/config/_form_proposals.html.erb index b563aca1f..bdce07d42 100644 --- a/app/views/decidim/decidim_awesome/admin/config/_form_proposals.html.erb +++ b/app/views/decidim/decidim_awesome/admin/config/_form_proposals.html.erb @@ -11,6 +11,13 @@ <% end %> +<% if config_enabled? :allow_to_edit_proposals_after_import %> +

<%= t("edit_proposals_after_import", scope: "decidim.decidim_awesome.admin.config") %>

+ + <%= form.check_box :allow_to_edit_proposals_after_import %> +

<%= t("help.allow_to_edit_proposals_after_import", scope: "decidim.decidim_awesome.admin.config.form") %>

+<% end %> + <% if config_enabled? %i(validate_title_min_length validate_title_max_caps_percent validate_title_max_marks_together validate_title_start_with_caps) %> diff --git a/config/locales/en.yml b/config/locales/en.yml index 5366e42e7..77b2de9a9 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -213,6 +213,9 @@ en: destroy_scoped_style: error: Error removing CSS box! %{error} success: CSS box %{key} removed successfully + edit_proposals_after_import: When proposals are imported between components, + not the original or the duplciated can be edited by the owners. This setting + changes that form: edit_label: Rename label errors: @@ -227,6 +230,8 @@ en: editor, available to any user allow_images_in_small_editor: This will add an image uploader icon in all the editors WYSIWYG with minimal options in the toolbar enabled. + allow_to_edit_proposals_after_import: Other component settings still + apply (time limit, owner only, etc) auto_save_forms: This will use LocalStorage to automatically save data introduced by users in surveys and other forms while they are filling it. Data will be restored in a future visit with the same browser diff --git a/lib/decidim/decidim_awesome/awesome.rb b/lib/decidim/decidim_awesome/awesome.rb index c76505043..afa61b2e1 100644 --- a/lib/decidim/decidim_awesome/awesome.rb +++ b/lib/decidim/decidim_awesome/awesome.rb @@ -43,6 +43,10 @@ module DecidimAwesome false end + config_accessor :allow_to_edit_proposals_after_import do + true + end + config_accessor :use_markdown_editor do false end diff --git a/lib/decidim/decidim_awesome/engine.rb b/lib/decidim/decidim_awesome/engine.rb index d62874a18..894b51388 100644 --- a/lib/decidim/decidim_awesome/engine.rb +++ b/lib/decidim/decidim_awesome/engine.rb @@ -48,6 +48,9 @@ class Engine < ::Rails::Engine Decidim::Proposals::ProposalWizardCreateStepForm.include(Decidim::DecidimAwesome::Proposals::ProposalWizardCreateStepFormOverride) end + # override admin's permissions to edit proposals after import + Decidim::Proposals::Admin::Permissions.include(Decidim::DecidimAwesome::Admin::PermissionsOverride) if DecidimAwesome.enabled?(:allow_to_edit_proposals_after_import) + # override user's admin property Decidim::User.include(Decidim::DecidimAwesome::UserOverride) if DecidimAwesome.enabled?(:scoped_admins) diff --git a/lib/decidim/decidim_awesome/test/initializer.rb b/lib/decidim/decidim_awesome/test/initializer.rb index 44a4296e9..20aaacffb 100644 --- a/lib/decidim/decidim_awesome/test/initializer.rb +++ b/lib/decidim/decidim_awesome/test/initializer.rb @@ -6,6 +6,7 @@ :allow_images_in_full_editor, :allow_images_in_small_editor, :allow_images_in_proposals, + :allow_to_edit_proposals_after_import, :use_markdown_editor, :allow_images_in_markdown_editor, :auto_save_forms, From 46ca3a90b2a34c706b5d90aedc4387ee0177dd35 Mon Sep 17 00:00:00 2001 From: Anna Topalidi Date: Fri, 25 Aug 2023 16:18:36 +0200 Subject: [PATCH 02/11] add spec system checker --- lib/decidim/decidim_awesome/checksums.yml | 2 ++ spec/lib/system_checker_spec.rb | 2 +- spec/system/admin/admin_spec.rb | 4 ++-- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/lib/decidim/decidim_awesome/checksums.yml b/lib/decidim/decidim_awesome/checksums.yml index 306ac7118..45dcf0856 100644 --- a/lib/decidim/decidim_awesome/checksums.yml +++ b/lib/decidim/decidim_awesome/checksums.yml @@ -33,6 +33,8 @@ decidim-proposals: decidim-0.27: c0ebeac39ebe4926bf0e5fc585a384d7 decidim-0.27.1: a4f902d1c4829a7f7f62299686f8604e decidim-0.27.3: a9c9ed5eedaf7bf80afaf9ff5a89c254 + /app/permissions/decidim/proposals/admin/permissions.rb: + decidim-0.27.3: 751b15ced553b17b7203f66a0152fb75 /app/views/decidim/proposals/collaborative_drafts/_edit_form_fields.html.erb: # this file is not overriden anymore but it needs to be the last version decidim-0.26: 519a0d34a9ffbd8b9c26d9b68ff4e2a3 diff --git a/spec/lib/system_checker_spec.rb b/spec/lib/system_checker_spec.rb index ef6e000fa..b5d5a91eb 100644 --- a/spec/lib/system_checker_spec.rb +++ b/spec/lib/system_checker_spec.rb @@ -21,7 +21,7 @@ module Decidim::DecidimAwesome end it "has 5 modified files in proposals" do - expect(subject.overrides["decidim-proposals"].files.length).to eq(5) + expect(subject.overrides["decidim-proposals"].files.length).to eq(6) end context "when file" do diff --git a/spec/system/admin/admin_spec.rb b/spec/system/admin/admin_spec.rb index 2781ea6cd..5423eeedb 100644 --- a/spec/system/admin/admin_spec.rb +++ b/spec/system/admin/admin_spec.rb @@ -138,7 +138,7 @@ end context "when some proposals hacks are disabled" do - [:allow_images_in_proposals, :validate_title_min_length, :validate_title_max_caps_percent, :validate_title_max_marks_together, :validate_title_start_with_caps, :validate_body_min_length, :validate_body_max_caps_percent, :validate_body_max_marks_together, :validate_body_start_with_caps].each do |var| + [:allow_images_in_proposals, :allow_to_edit_proposals_after_import, :validate_title_min_length, :validate_title_max_caps_percent, :validate_title_max_marks_together, :validate_title_start_with_caps, :validate_body_min_length, :validate_body_max_caps_percent, :validate_body_max_marks_together, :validate_body_start_with_caps].each do |var| let(:disabled_features) { [var] } it_behaves_like "has menu link", "proposals" @@ -146,7 +146,7 @@ end context "when all proposals hacks are disabled" do - let(:disabled_features) { [:allow_images_in_proposals, :validate_title_min_length, :validate_title_max_caps_percent, :validate_title_max_marks_together, :validate_title_start_with_caps, :validate_body_min_length, :validate_body_max_caps_percent, :validate_body_max_marks_together, :validate_body_start_with_caps] } + let(:disabled_features) { [:allow_images_in_proposals, :allow_to_edit_proposals_after_import, :validate_title_min_length, :validate_title_max_caps_percent, :validate_title_max_marks_together, :validate_title_start_with_caps, :validate_body_min_length, :validate_body_max_caps_percent, :validate_body_max_marks_together, :validate_body_start_with_caps] } it_behaves_like "do not have menu link", "proposals" end From 3e8b724329c38c2e75ad2a311fcb0c4fbadc7827 Mon Sep 17 00:00:00 2001 From: Anna Topalidi Date: Fri, 25 Aug 2023 18:51:22 +0200 Subject: [PATCH 03/11] add system tests --- .../admin/config_constraints_helpers.rb | 2 +- spec/awesome_summary_spec.rb | 1 + .../admin/edit_proposal_after_import_spec.rb | 60 +++++++++++++++++++ 3 files changed, 62 insertions(+), 1 deletion(-) create mode 100644 spec/system/admin/edit_proposal_after_import_spec.rb diff --git a/app/helpers/decidim/decidim_awesome/admin/config_constraints_helpers.rb b/app/helpers/decidim/decidim_awesome/admin/config_constraints_helpers.rb index d372fc4ab..b86b38d67 100644 --- a/app/helpers/decidim/decidim_awesome/admin/config_constraints_helpers.rb +++ b/app/helpers/decidim/decidim_awesome/admin/config_constraints_helpers.rb @@ -15,7 +15,7 @@ def check(status) def menus @menus ||= { editors: config_enabled?([:allow_images_in_full_editor, :allow_images_in_small_editor, :use_markdown_editor, :allow_images_in_markdown_editor]), - proposals: config_enabled?([:allow_images_in_proposals, + proposals: config_enabled?([:allow_images_in_proposals, :allow_to_edit_proposals_after_import, :validate_title_min_length, :validate_title_max_caps_percent, :validate_title_max_marks_together, :validate_title_start_with_caps, :validate_body_min_length, :validate_body_max_caps_percent, diff --git a/spec/awesome_summary_spec.rb b/spec/awesome_summary_spec.rb index a1c40b8f2..0f3ea33fd 100644 --- a/spec/awesome_summary_spec.rb +++ b/spec/awesome_summary_spec.rb @@ -27,6 +27,7 @@ let!(:allow_images_in_proposals) { create(:awesome_config, organization: organization, var: :allow_images_in_proposals, value: true) } let!(:allow_images_in_small_editor) { create(:awesome_config, organization: organization, var: :allow_images_in_small_editor, value: true) } let!(:allow_images_in_full_editor) { create(:awesome_config, organization: organization, var: :allow_images_in_full_editor, value: true) } + let!(:allow_to_edit_proposals_after_import) { create(:awesome_config, organization: organization, var: :allow_to_edit_proposals_after_import, value: true) } let!(:use_markdown_editor) { create(:awesome_config, organization: organization, var: :use_markdown_editor, value: true) } let!(:allow_images_in_markdown_editor) { create(:awesome_config, organization: organization, var: :allow_images_in_markdown_editor, value: true) } let!(:auto_save_forms) { create(:awesome_config, organization: organization, var: :auto_save_forms, value: true) } diff --git a/spec/system/admin/edit_proposal_after_import_spec.rb b/spec/system/admin/edit_proposal_after_import_spec.rb new file mode 100644 index 000000000..efe50ff89 --- /dev/null +++ b/spec/system/admin/edit_proposal_after_import_spec.rb @@ -0,0 +1,60 @@ +# frozen_string_literal: true + +require "spec_helper" + +describe "Edit proposal after import", type: :system do + let!(:organization) { create(:organization) } + let(:manifest_name) { "proposals" } + let(:participatory_space) { create(:participatory_process, organization: organization) } + let!(:component) { create(:proposal_component, organization: organization, participatory_space: participatory_space) } + let!(:original_component) { create(:proposal_component, organization: organization, participatory_space: participatory_space) } + let!(:proposals) { create_list(:proposal, 3, :accepted, component: component) } + let(:user) { create :user, organization: organization } + let!(:allow_to_edit_proposals_after_import) { create(:awesome_config, organization: organization, var: :allow_to_edit_proposals_after_import, value: config_value) } + + include_context "when managing a component as an admin" + + before do + page.find("a", text: original_component.name["en"]).click + page.find(".imports").click + click_link "Import proposals from another component" + + within ".import_proposals" do + select component.name["en"], from: "Origin component" + check "Accepted" + check "Keep original authors" + check "Import proposals" + end + + click_button "Import proposals" + end + + context "when config is set to true" do + let(:config_value) { true } + + it "allows the user to edit all 3 imported proposals" do + page.find("a", text: component.name["en"]).click + + proposals.each do |proposal| + expect(page).to have_content(proposal.title["en"]) + end + + expect(page).to have_css('a[title="Edit proposal"]', count: 3) + expect(Decidim::Proposals::Proposal.count).to eq(6) + end + end + + context "when config is set to false" do + let(:config_value) { false } + + it "allows the user to edit all 3 imported proposals" do + page.find("a", text: component.name["en"]).click + + proposals.each do |proposal| + expect(page).to have_content(proposal.title["en"]) + end + + expect(page).not_to have_css('a[title="Edit proposal"]') + end + end +end From 65b55da0ffed8e93a03eb868cd1c17edbc3b7294 Mon Sep 17 00:00:00 2001 From: Anna Topalidi Date: Mon, 28 Aug 2023 11:20:20 +0200 Subject: [PATCH 04/11] fix test --- spec/controllers/admin/config_controller_spec.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/spec/controllers/admin/config_controller_spec.rb b/spec/controllers/admin/config_controller_spec.rb index 1dc0f70cc..2cb2d136f 100644 --- a/spec/controllers/admin/config_controller_spec.rb +++ b/spec/controllers/admin/config_controller_spec.rb @@ -64,6 +64,7 @@ module Admin context "and proposals is disabled" do let(:disabled) do editors + [:allow_images_in_proposals, + :allow_to_edit_proposals_after_import, :validate_title_min_length, :validate_title_max_caps_percent, :validate_title_max_marks_together, From 996eb59d6cf473fc83f53ca11ab7cd38963ab88c Mon Sep 17 00:00:00 2001 From: Anna Topalidi Date: Tue, 29 Aug 2023 23:15:44 +0200 Subject: [PATCH 05/11] fix the constraints bug --- .../admin/config/_form_proposals.html.erb | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/app/views/decidim/decidim_awesome/admin/config/_form_proposals.html.erb b/app/views/decidim/decidim_awesome/admin/config/_form_proposals.html.erb index bdce07d42..5a16225b9 100644 --- a/app/views/decidim/decidim_awesome/admin/config/_form_proposals.html.erb +++ b/app/views/decidim/decidim_awesome/admin/config/_form_proposals.html.erb @@ -11,12 +11,16 @@ <% end %> -<% if config_enabled? :allow_to_edit_proposals_after_import %> -

<%= t("edit_proposals_after_import", scope: "decidim.decidim_awesome.admin.config") %>

+
+ <% if config_enabled? :allow_to_edit_proposals_after_import %> +

<%= t("edit_proposals_after_import", scope: "decidim.decidim_awesome.admin.config") %>

- <%= form.check_box :allow_to_edit_proposals_after_import %> -

<%= t("help.allow_to_edit_proposals_after_import", scope: "decidim.decidim_awesome.admin.config.form") %>

-<% end %> + <%= form.check_box :allow_to_edit_proposals_after_import %> +

<%= t("help.allow_to_edit_proposals_after_import", scope: "decidim.decidim_awesome.admin.config.form") %>

+ + <%= render(partial: "decidim/decidim_awesome/admin/config/constraints", locals: { key: :allow_to_edit_proposals_after_import, constraints: constraints_for(:allow_to_edit_proposals_after_import) }) %> + <% end %> +
<% if config_enabled? %i(validate_title_min_length validate_title_max_caps_percent validate_title_max_marks_together validate_title_start_with_caps) %> @@ -67,6 +71,7 @@

<%= t("validators.body", scope: "decidim.decidim_awesome.admin.config.form") %>

+
<% if config_enabled? :validate_body_start_with_caps %> <%= form.check_box :validate_body_start_with_caps %> @@ -94,4 +99,5 @@ <%= render(partial: "decidim/decidim_awesome/admin/config/constraints", locals: { key: :validate_body_max_marks_together, constraints: constraints_for(:validate_body_max_marks_together) }) %> <% end %>
+
<% end %> From ae41fb934683a2766b4089de7183896cbe5a4e09 Mon Sep 17 00:00:00 2001 From: Anna Topalidi Date: Wed, 30 Aug 2023 14:53:17 +0200 Subject: [PATCH 06/11] proposal override --- Gemfile.lock | 3 ++ .../proposals/proposal_override.rb | 42 +++++++++++++++++++ .../admin/permissions_override.rb | 37 ---------------- lib/decidim/decidim_awesome/engine.rb | 4 +- 4 files changed, 47 insertions(+), 39 deletions(-) create mode 100644 app/models/concerns/decidim/decidim_awesome/proposals/proposal_override.rb delete mode 100644 app/permissions/concerns/decidim/decidim_awesome/admin/permissions_override.rb diff --git a/Gemfile.lock b/Gemfile.lock index 58fadac34..697f3b73b 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -512,6 +512,8 @@ GEM nio4r (2.5.9) nokogiri (1.14.5-arm64-darwin) racc (~> 1.4) + nokogiri (1.14.5-x86_64-darwin) + racc (~> 1.4) nokogiri (1.14.5-x86_64-linux) racc (~> 1.4) oauth (1.1.0) @@ -801,6 +803,7 @@ GEM PLATFORMS arm64-darwin-22 + x86_64-darwin-22 x86_64-linux DEPENDENCIES diff --git a/app/models/concerns/decidim/decidim_awesome/proposals/proposal_override.rb b/app/models/concerns/decidim/decidim_awesome/proposals/proposal_override.rb new file mode 100644 index 000000000..27112cc47 --- /dev/null +++ b/app/models/concerns/decidim/decidim_awesome/proposals/proposal_override.rb @@ -0,0 +1,42 @@ +# frozen_string_literal: true + +module Decidim + module DecidimAwesome + module Proposals + module ProposalOverride + extend ActiveSupport::Concern + + included do + def editable_by?(user) + return true if draft? && created_by?(user) + return true if awesome_config_allows_editing?(user) + + !published_state? && within_edit_time_limit? && !copied_from_other_component? && created_by?(user) + end + + private + + def awesome_config_allows_editing?(user) + awesome_config = allow_to_edit_proposals_after_import + + return false unless awesome_config.value && created_by?(user) + return true if awesome_config.constraints.blank? + + constraints_to_check = manifest_to_check(awesome_config) + + participatory_space.manifest.name.to_s == constraints_to_check + end + + def allow_to_edit_proposals_after_import + Decidim::DecidimAwesome::AwesomeConfig.find_or_initialize_by(var: :allow_to_edit_proposals_after_import) + end + + def manifest_to_check(awesome_config) + constraint = awesome_config.constraints.detect { |c| c.settings["participatory_space_manifest"] } + constraint&.settings ? constraint.settings["participatory_space_manifest"] : nil + end + end + end + end + end +end diff --git a/app/permissions/concerns/decidim/decidim_awesome/admin/permissions_override.rb b/app/permissions/concerns/decidim/decidim_awesome/admin/permissions_override.rb deleted file mode 100644 index c3b417021..000000000 --- a/app/permissions/concerns/decidim/decidim_awesome/admin/permissions_override.rb +++ /dev/null @@ -1,37 +0,0 @@ -# frozen_string_literal: true - -module Decidim - module DecidimAwesome - module Admin - module PermissionsOverride - extend ActiveSupport::Concern - - included do - private - - def admin_edition_is_available? - return unless proposal - - if proposal_imported? && allow_to_edit_proposals_after_import_enabled? - true - else - (proposal.official? || proposal.official_meeting?) && proposal.votes.empty? - end - end - - def proposal_imported? - Decidim::ResourceLink.exists?( - name: "copied_from_component", - to_type: "Decidim::Proposals::Proposal", - to_id: proposal.id - ) - end - - def allow_to_edit_proposals_after_import_enabled? - Decidim::DecidimAwesome::AwesomeConfig.find_by(var: :allow_to_edit_proposals_after_import)&.value == true - end - end - end - end - end -end diff --git a/lib/decidim/decidim_awesome/engine.rb b/lib/decidim/decidim_awesome/engine.rb index 894b51388..82cbd081e 100644 --- a/lib/decidim/decidim_awesome/engine.rb +++ b/lib/decidim/decidim_awesome/engine.rb @@ -48,8 +48,8 @@ class Engine < ::Rails::Engine Decidim::Proposals::ProposalWizardCreateStepForm.include(Decidim::DecidimAwesome::Proposals::ProposalWizardCreateStepFormOverride) end - # override admin's permissions to edit proposals after import - Decidim::Proposals::Admin::Permissions.include(Decidim::DecidimAwesome::Admin::PermissionsOverride) if DecidimAwesome.enabled?(:allow_to_edit_proposals_after_import) + # override Proposal to edit proposals after import + Decidim::Proposals::Proposal.include(Decidim::DecidimAwesome::Proposals::ProposalOverride) if DecidimAwesome.enabled?(:allow_to_edit_proposals_after_import) # override user's admin property Decidim::User.include(Decidim::DecidimAwesome::UserOverride) if DecidimAwesome.enabled?(:scoped_admins) From f6abad3ebb9b497190e216751ab7bbfe723c89fd Mon Sep 17 00:00:00 2001 From: Anna Topalidi Date: Thu, 31 Aug 2023 12:32:34 +0200 Subject: [PATCH 07/11] refactoring, add tests --- .../proposals/proposal_override.rb | 14 +++-- .../admin/edit_proposal_after_import_spec.rb | 60 ------------------- .../system/edit_proposal_after_import_spec.rb | 60 +++++++++++++++++++ 3 files changed, 70 insertions(+), 64 deletions(-) delete mode 100644 spec/system/admin/edit_proposal_after_import_spec.rb create mode 100644 spec/system/edit_proposal_after_import_spec.rb diff --git a/app/models/concerns/decidim/decidim_awesome/proposals/proposal_override.rb b/app/models/concerns/decidim/decidim_awesome/proposals/proposal_override.rb index 27112cc47..8ec85edb0 100644 --- a/app/models/concerns/decidim/decidim_awesome/proposals/proposal_override.rb +++ b/app/models/concerns/decidim/decidim_awesome/proposals/proposal_override.rb @@ -9,17 +9,23 @@ module ProposalOverride included do def editable_by?(user) return true if draft? && created_by?(user) - return true if awesome_config_allows_editing?(user) + return false unless default_edit_permissions(user) - !published_state? && within_edit_time_limit? && !copied_from_other_component? && created_by?(user) + allow_to_edit_proposals_after_import ? awesome_config_allows_editing? : true end private - def awesome_config_allows_editing?(user) + def default_edit_permissions(user) + return true if !published_state? && within_edit_time_limit? && + !copied_from_other_component? && created_by?(user) + + false + end + + def awesome_config_allows_editing? awesome_config = allow_to_edit_proposals_after_import - return false unless awesome_config.value && created_by?(user) return true if awesome_config.constraints.blank? constraints_to_check = manifest_to_check(awesome_config) diff --git a/spec/system/admin/edit_proposal_after_import_spec.rb b/spec/system/admin/edit_proposal_after_import_spec.rb deleted file mode 100644 index efe50ff89..000000000 --- a/spec/system/admin/edit_proposal_after_import_spec.rb +++ /dev/null @@ -1,60 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" - -describe "Edit proposal after import", type: :system do - let!(:organization) { create(:organization) } - let(:manifest_name) { "proposals" } - let(:participatory_space) { create(:participatory_process, organization: organization) } - let!(:component) { create(:proposal_component, organization: organization, participatory_space: participatory_space) } - let!(:original_component) { create(:proposal_component, organization: organization, participatory_space: participatory_space) } - let!(:proposals) { create_list(:proposal, 3, :accepted, component: component) } - let(:user) { create :user, organization: organization } - let!(:allow_to_edit_proposals_after_import) { create(:awesome_config, organization: organization, var: :allow_to_edit_proposals_after_import, value: config_value) } - - include_context "when managing a component as an admin" - - before do - page.find("a", text: original_component.name["en"]).click - page.find(".imports").click - click_link "Import proposals from another component" - - within ".import_proposals" do - select component.name["en"], from: "Origin component" - check "Accepted" - check "Keep original authors" - check "Import proposals" - end - - click_button "Import proposals" - end - - context "when config is set to true" do - let(:config_value) { true } - - it "allows the user to edit all 3 imported proposals" do - page.find("a", text: component.name["en"]).click - - proposals.each do |proposal| - expect(page).to have_content(proposal.title["en"]) - end - - expect(page).to have_css('a[title="Edit proposal"]', count: 3) - expect(Decidim::Proposals::Proposal.count).to eq(6) - end - end - - context "when config is set to false" do - let(:config_value) { false } - - it "allows the user to edit all 3 imported proposals" do - page.find("a", text: component.name["en"]).click - - proposals.each do |proposal| - expect(page).to have_content(proposal.title["en"]) - end - - expect(page).not_to have_css('a[title="Edit proposal"]') - end - end -end diff --git a/spec/system/edit_proposal_after_import_spec.rb b/spec/system/edit_proposal_after_import_spec.rb new file mode 100644 index 000000000..c4fbad429 --- /dev/null +++ b/spec/system/edit_proposal_after_import_spec.rb @@ -0,0 +1,60 @@ +# frozen_string_literal: true + +require "spec_helper" + +describe "Edit proposals after import", type: :system do + include_context "with a component" + let(:organization) { create :organization } + let(:user) { create :user, :confirmed, organization: organization } + let(:manifest_name) { "proposals" } + let!(:proposal) { create(:proposal, users: [user], component: component) } + let(:proposal_title) { translated(proposal.title) } + let!(:assembly) { create(:assembly, organization: organization) } + let!(:assembly_proposal_component) { create :component, participatory_space: assembly, manifest: manifest } + let!(:assembly_proposal) { create(:proposal, :published, :official, component: assembly_proposal_component, users: [user]) } + let!(:allow_to_edit_proposals_after_import) { create(:awesome_config, organization: organization, var: :allow_to_edit_proposals_after_import, value: edit_proposal) } + let(:edit_proposal) { true } + + context "when editing proposal after import is enabled" do + before do + switch_to_host(organization.host) + login_as user, scope: :user + assembly_proposal.coauthorships.first.update!(author: user) + visit decidim_assemblies.decidim_assembly_proposals_path(assembly_slug: assembly.slug, component_id: assembly_proposal_component.id) + end + + context "when constrains are not present" do + it "allows editing the proposal" do + click_link assembly_proposal.title["en"] + expect(page).to have_content("EDIT PROPOSAL") + end + end + + context "when constrains are present" do + let!(:constraint) { create(:config_constraint, awesome_config: allow_to_edit_proposals_after_import, settings: settings) } + let(:settings) do + { "participatory_space_manifest" => "participatory_processes" } + end + + context "when participatory space is not the same" do + it "does not allows editing the proposal" do + puts "allow_to_edit_proposals_after_import #{allow_to_edit_proposals_after_import.inspect}" + puts "allow_to_edit_proposals_after_import.constraints #{allow_to_edit_proposals_after_import.constraints.inspect}" + click_link assembly_proposal.title["en"] + expect(page).not_to have_content("EDIT PROPOSAL") + end + end + + context "when participatory space is the same" do + before do + visit_component + click_link proposal_title + end + + it "allows editing the proposal" do + expect(page).to have_content("EDIT PROPOSAL") + end + end + end + end +end From 6d01fc5d7bd0387437db6207b4cb321f11c59905 Mon Sep 17 00:00:00 2001 From: Anna Topalidi <60363870+antopalidi@users.noreply.github.com> Date: Thu, 31 Aug 2023 13:04:39 +0200 Subject: [PATCH 08/11] Update lib/decidim/decidim_awesome/awesome.rb MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Ivan Vergés --- lib/decidim/decidim_awesome/awesome.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/decidim/decidim_awesome/awesome.rb b/lib/decidim/decidim_awesome/awesome.rb index afa61b2e1..5b69ada53 100644 --- a/lib/decidim/decidim_awesome/awesome.rb +++ b/lib/decidim/decidim_awesome/awesome.rb @@ -44,7 +44,7 @@ module DecidimAwesome end config_accessor :allow_to_edit_proposals_after_import do - true + false end config_accessor :use_markdown_editor do From 08938a32b4cf2f56486eb1bd35361b43bb8ebffc Mon Sep 17 00:00:00 2001 From: Anna Topalidi Date: Thu, 31 Aug 2023 22:53:14 +0200 Subject: [PATCH 09/11] fix --- .../proposals/proposal_override.rb | 46 +++++++++---- .../system/edit_proposal_after_import_spec.rb | 69 ++++++++++++++----- 2 files changed, 84 insertions(+), 31 deletions(-) diff --git a/app/models/concerns/decidim/decidim_awesome/proposals/proposal_override.rb b/app/models/concerns/decidim/decidim_awesome/proposals/proposal_override.rb index 8ec85edb0..329163298 100644 --- a/app/models/concerns/decidim/decidim_awesome/proposals/proposal_override.rb +++ b/app/models/concerns/decidim/decidim_awesome/proposals/proposal_override.rb @@ -9,37 +9,53 @@ module ProposalOverride included do def editable_by?(user) return true if draft? && created_by?(user) - return false unless default_edit_permissions(user) - allow_to_edit_proposals_after_import ? awesome_config_allows_editing? : true + if allow_to_edit_proposals_after_import.value && copied_from_other_component? + can_edit_copied_component?(user) + else + default_edit_permissions(user) + end end private - def default_edit_permissions(user) - return true if !published_state? && within_edit_time_limit? && - !copied_from_other_component? && created_by?(user) + def can_edit_copied_component?(user) + return false unless within_edit_time_limit? && created_by?(user) - false + awesome_config_allows_editing? end - def awesome_config_allows_editing? - awesome_config = allow_to_edit_proposals_after_import - - return true if awesome_config.constraints.blank? + def default_edit_permissions(user) + !published_state? && within_edit_time_limit? && !copied_from_other_component? && created_by?(user) + end - constraints_to_check = manifest_to_check(awesome_config) + def awesome_config_allows_editing? + return true if allow_to_edit_proposals_after_import.constraints.blank? - participatory_space.manifest.name.to_s == constraints_to_check + allow_to_edit_proposals_after_import.constraints.any? do |constraint| + check_constraint(constraint) + end end def allow_to_edit_proposals_after_import Decidim::DecidimAwesome::AwesomeConfig.find_or_initialize_by(var: :allow_to_edit_proposals_after_import) end - def manifest_to_check(awesome_config) - constraint = awesome_config.constraints.detect { |c| c.settings["participatory_space_manifest"] } - constraint&.settings ? constraint.settings["participatory_space_manifest"] : nil + def check_constraint(constraint) + constraint.settings.all? do |key, value| + case key + when "participatory_space_manifest" + value == participatory_space.manifest.name.to_s + when "participatory_space_slug" + value == participatory_space.slug + when "component_manifest" + value == component.manifest.name.to_s + when "component_id" + value == component.id + else + false + end + end end end end diff --git a/spec/system/edit_proposal_after_import_spec.rb b/spec/system/edit_proposal_after_import_spec.rb index c4fbad429..0dd58f446 100644 --- a/spec/system/edit_proposal_after_import_spec.rb +++ b/spec/system/edit_proposal_after_import_spec.rb @@ -7,54 +7,91 @@ let(:organization) { create :organization } let(:user) { create :user, :confirmed, organization: organization } let(:manifest_name) { "proposals" } + let!(:component) { create(:proposal_component, manifest: manifest, participatory_space: participatory_process) } let!(:proposal) { create(:proposal, users: [user], component: component) } let(:proposal_title) { translated(proposal.title) } - let!(:assembly) { create(:assembly, organization: organization) } - let!(:assembly_proposal_component) { create :component, participatory_space: assembly, manifest: manifest } - let!(:assembly_proposal) { create(:proposal, :published, :official, component: assembly_proposal_component, users: [user]) } let!(:allow_to_edit_proposals_after_import) { create(:awesome_config, organization: organization, var: :allow_to_edit_proposals_after_import, value: edit_proposal) } - let(:edit_proposal) { true } + let(:copied_component) { create(:proposal_component, manifest: manifest, participatory_space: participatory_process) } + let!(:copied_proposal) { create :proposal, component: copied_component, users: [user] } context "when editing proposal after import is enabled" do + let(:edit_proposal) { true } + before do switch_to_host(organization.host) login_as user, scope: :user - assembly_proposal.coauthorships.first.update!(author: user) - visit decidim_assemblies.decidim_assembly_proposals_path(assembly_slug: assembly.slug, component_id: assembly_proposal_component.id) + proposal.coauthorships.first.update!(author: user) + copied_proposal.link_resources([proposal], "copied_from_component") + visit_component end context "when constrains are not present" do it "allows editing the proposal" do - click_link assembly_proposal.title["en"] + click_link proposal_title expect(page).to have_content("EDIT PROPOSAL") end end context "when constrains are present" do let!(:constraint) { create(:config_constraint, awesome_config: allow_to_edit_proposals_after_import, settings: settings) } - let(:settings) do - { "participatory_space_manifest" => "participatory_processes" } - end context "when participatory space is not the same" do + let(:settings) do + { "participatory_space_manifest" => "assemblies" } + end + it "does not allows editing the proposal" do - puts "allow_to_edit_proposals_after_import #{allow_to_edit_proposals_after_import.inspect}" - puts "allow_to_edit_proposals_after_import.constraints #{allow_to_edit_proposals_after_import.constraints.inspect}" - click_link assembly_proposal.title["en"] + click_link proposal_title expect(page).not_to have_content("EDIT PROPOSAL") end end context "when participatory space is the same" do - before do - visit_component - click_link proposal_title + let(:settings) do + { "participatory_space_manifest" => "participatory_processes" } end it "allows editing the proposal" do + click_link proposal_title expect(page).to have_content("EDIT PROPOSAL") end end end end + + context "when editing a proposal after import is disabled" do + let(:edit_proposal) { false } + + before do + switch_to_host(organization.host) + login_as user, scope: :user + proposal.coauthorships.first.update!(author: user) + copied_proposal.link_resources([proposal], "copied_from_component") + allow_to_edit_proposals_after_import.reload + visit_component + end + + it "does not allow editing the proposal" do + click_link proposal_title + expect(page).not_to have_content("EDIT PROPOSAL") + end + end + + context "when editing a proposal after import by another user" do + let(:another_user) { create :user, :confirmed, organization: organization } + let(:edit_proposal) { true } + + before do + switch_to_host(organization.host) + login_as another_user, scope: :user + proposal.coauthorships.first.update!(author: user) + copied_proposal.link_resources([proposal], "copied_from_component") + visit_component + end + + it "does not allow editing the proposal" do + click_link proposal_title + expect(page).not_to have_content("EDIT PROPOSAL") + end + end end From a78eea75c7d62372cfb045ac906ab9cfa45f9871 Mon Sep 17 00:00:00 2001 From: Anna Topalidi Date: Fri, 1 Sep 2023 08:24:46 +0200 Subject: [PATCH 10/11] refactoring --- .../system/edit_proposal_after_import_spec.rb | 27 ++++++++----------- 1 file changed, 11 insertions(+), 16 deletions(-) diff --git a/spec/system/edit_proposal_after_import_spec.rb b/spec/system/edit_proposal_after_import_spec.rb index 0dd58f446..77a37b914 100644 --- a/spec/system/edit_proposal_after_import_spec.rb +++ b/spec/system/edit_proposal_after_import_spec.rb @@ -18,11 +18,7 @@ let(:edit_proposal) { true } before do - switch_to_host(organization.host) - login_as user, scope: :user - proposal.coauthorships.first.update!(author: user) - copied_proposal.link_resources([proposal], "copied_from_component") - visit_component + visit_proposal(user) end context "when constrains are not present" do @@ -63,12 +59,7 @@ let(:edit_proposal) { false } before do - switch_to_host(organization.host) - login_as user, scope: :user - proposal.coauthorships.first.update!(author: user) - copied_proposal.link_resources([proposal], "copied_from_component") - allow_to_edit_proposals_after_import.reload - visit_component + visit_proposal(user) end it "does not allow editing the proposal" do @@ -82,11 +73,7 @@ let(:edit_proposal) { true } before do - switch_to_host(organization.host) - login_as another_user, scope: :user - proposal.coauthorships.first.update!(author: user) - copied_proposal.link_resources([proposal], "copied_from_component") - visit_component + visit_proposal(another_user) end it "does not allow editing the proposal" do @@ -94,4 +81,12 @@ expect(page).not_to have_content("EDIT PROPOSAL") end end + + private + + def visit_proposal(user) + login_as user, scope: :user + copied_proposal.link_resources([proposal], "copied_from_component") + visit_component + end end From 5ab5ebbfe6463971d8fbd1cb8884511158c39bd4 Mon Sep 17 00:00:00 2001 From: Anna Topalidi Date: Mon, 4 Sep 2023 12:04:20 +0200 Subject: [PATCH 11/11] change checksums --- lib/decidim/decidim_awesome/checksums.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/decidim/decidim_awesome/checksums.yml b/lib/decidim/decidim_awesome/checksums.yml index 45dcf0856..40d8a97f8 100644 --- a/lib/decidim/decidim_awesome/checksums.yml +++ b/lib/decidim/decidim_awesome/checksums.yml @@ -33,8 +33,9 @@ decidim-proposals: decidim-0.27: c0ebeac39ebe4926bf0e5fc585a384d7 decidim-0.27.1: a4f902d1c4829a7f7f62299686f8604e decidim-0.27.3: a9c9ed5eedaf7bf80afaf9ff5a89c254 - /app/permissions/decidim/proposals/admin/permissions.rb: - decidim-0.27.3: 751b15ced553b17b7203f66a0152fb75 + /app/models/decidim/proposals/proposal.rb: + decidim-0.26.8: 7aba8a3b12b2fa0214ad6d83f5e6e0ce + decidim-0.27.4: 079dbce3c0d567b1f0feb75fe7f88919 /app/views/decidim/proposals/collaborative_drafts/_edit_form_fields.html.erb: # this file is not overriden anymore but it needs to be the last version decidim-0.26: 519a0d34a9ffbd8b9c26d9b68ff4e2a3