decidim-action_delegator 0.8.1 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +104 -58
- data/Rakefile +2 -2
- data/app/commands/decidim/action_delegator/admin/create_delegation.rb +1 -3
- data/app/commands/decidim/action_delegator/admin/create_setting.rb +5 -2
- data/app/commands/decidim/action_delegator/admin/update_setting.rb +4 -2
- data/app/controllers/concerns/decidim/action_delegator/devise/sessions_controller_override.rb +1 -1
- data/app/controllers/concerns/decidim/action_delegator/election_per_question_votes_controller_override.rb +65 -0
- data/app/controllers/concerns/decidim/action_delegator/election_votes_controller_override.rb +38 -0
- data/app/controllers/concerns/decidim/action_delegator/votes_controller_methods.rb +46 -0
- data/app/controllers/decidim/action_delegator/admin/application_controller.rb +11 -5
- data/app/controllers/decidim/action_delegator/admin/delegations_controller.rb +3 -11
- data/app/controllers/decidim/action_delegator/admin/invite_participants_controller.rb +0 -8
- data/app/controllers/decidim/action_delegator/admin/manage_delegations_controller.rb +13 -21
- data/app/controllers/decidim/action_delegator/admin/manage_participants_controller.rb +11 -20
- data/app/controllers/decidim/action_delegator/admin/participants_controller.rb +1 -9
- data/app/controllers/decidim/action_delegator/admin/permissions_controller.rb +1 -24
- data/app/controllers/decidim/action_delegator/admin/ponderations_controller.rb +0 -8
- data/app/controllers/decidim/action_delegator/admin/settings_controller.rb +12 -12
- data/app/controllers/decidim/action_delegator/application_controller.rb +3 -3
- data/app/controllers/decidim/action_delegator/elections/admin/results_controller.rb +58 -0
- data/app/controllers/decidim/action_delegator/elections/results_controller.rb +36 -0
- data/app/controllers/decidim/action_delegator/user_delegations_controller.rb +1 -1
- data/app/controllers/decidim/action_delegator/verifications/delegations_verifier/authorizations_controller.rb +14 -18
- data/app/forms/decidim/action_delegator/admin/action_delegator_census_form.rb +44 -0
- data/app/forms/decidim/action_delegator/admin/csv_import_form.rb +17 -0
- data/app/forms/decidim/action_delegator/admin/delegation_form.rb +6 -2
- data/app/forms/decidim/action_delegator/admin/ponderation_form.rb +2 -1
- data/app/forms/decidim/action_delegator/admin/setting_form.rb +16 -10
- data/app/forms/decidim/action_delegator/censuses/internal_users_form.rb +32 -0
- data/app/forms/decidim/action_delegator/verifications/delegations_verifier_form.rb +41 -25
- data/app/helpers/decidim/action_delegator/admin/{delegation_helper.rb → settings_helper.rb} +3 -16
- data/app/helpers/decidim/action_delegator/settings_helper.rb +124 -0
- data/app/jobs/decidim/action_delegator/admin/invite_participants_job.rb +1 -1
- data/app/jobs/decidim/action_delegator/send_sms_job.rb +2 -2
- data/app/jobs/decidim/action_delegator/twilio_send_sms_job.rb +2 -2
- data/app/models/decidim/action_delegator/delegation.rb +35 -9
- data/app/models/decidim/action_delegator/participant.rb +15 -9
- data/app/models/decidim/action_delegator/ponderation.rb +0 -2
- data/app/models/decidim/action_delegator/setting.rb +14 -32
- data/app/overrides/decidim/elections/admin/dashboard/_results/_add_results_contents.html.erb.deface +10 -0
- data/app/overrides/decidim/elections/admin/dashboard/_results/_add_results_tabs.html.erb.deface +3 -0
- data/app/overrides/decidim/elections/elections/_election_aside/add_delegation_buttons.html.erb.deface +3 -0
- data/app/overrides/decidim/elections/elections/_vote_results/replace_results_div.html.erb.deface +8 -0
- data/app/overrides/decidim/elections/per_question_votes/show/add_delegation_hidden_input.html.erb.deface +3 -0
- data/app/overrides/decidim/elections/per_question_votes/show/add_delegation_id_to_links.html.erb.deface +3 -0
- data/app/overrides/decidim/elections/per_question_votes/waiting/add_delegation_buttons.html.erb.deface +3 -0
- data/app/overrides/decidim/elections/votes/receipt/add_delegation_buttons.html.erb.deface +3 -0
- data/app/packs/entrypoints/decidim_action_delegator_elections.js +1 -0
- data/app/packs/src/decidim/action_delegator/elections_live_results.js +160 -0
- data/app/permissions/decidim/action_delegator/admin/permissions.rb +29 -0
- data/app/permissions/decidim/action_delegator/permissions.rb +6 -30
- data/app/presenters/decidim/action_delegator/setting_presenter.rb +33 -0
- data/app/queries/decidim/action_delegator/action_delegator_census_users.rb +51 -0
- data/app/queries/decidim/action_delegator/authorized_resources.rb +28 -0
- data/app/queries/decidim/action_delegator/election_settings.rb +23 -0
- data/app/queries/decidim/action_delegator/{delegated_votes_versions.rb → elections_delegated_votes_versions.rb} +8 -8
- data/app/queries/decidim/action_delegator/elections_question_responses_by_type.rb +33 -0
- data/app/queries/decidim/action_delegator/elections_question_weighted_responses.rb +28 -0
- data/app/queries/decidim/action_delegator/elections_votes_with_ponderations.rb +62 -0
- data/app/services/decidim/action_delegator/delegations_csv_importer.rb +3 -3
- data/app/services/decidim/action_delegator/participants_csv_importer.rb +1 -1
- data/app/services/decidim/action_delegator/sms_gateway.rb +2 -2
- data/app/views/decidim/action_delegator/admin/censuses/_action_delegator_census_form.html.erb +44 -0
- data/app/views/decidim/action_delegator/admin/censuses/_action_delegator_census_options_form.html.erb +25 -0
- data/app/views/decidim/action_delegator/admin/delegations/index.html.erb +12 -13
- data/app/views/decidim/action_delegator/admin/delegations/new.html.erb +29 -27
- data/app/views/decidim/action_delegator/admin/manage_delegations/new.html.erb +36 -24
- data/app/views/decidim/action_delegator/admin/manage_participants/new.html.erb +47 -33
- data/app/views/decidim/action_delegator/admin/participants/_form.html.erb +14 -8
- data/app/views/decidim/action_delegator/admin/participants/edit.html.erb +11 -13
- data/app/views/decidim/action_delegator/admin/participants/index.html.erb +20 -25
- data/app/views/decidim/action_delegator/admin/participants/new.html.erb +11 -13
- data/app/views/decidim/action_delegator/admin/ponderations/_form.html.erb +13 -7
- data/app/views/decidim/action_delegator/admin/ponderations/edit.html.erb +11 -13
- data/app/views/decidim/action_delegator/admin/ponderations/index.html.erb +8 -11
- data/app/views/decidim/action_delegator/admin/ponderations/new.html.erb +11 -13
- data/app/views/decidim/action_delegator/admin/settings/_form.html.erb +26 -12
- data/app/views/decidim/action_delegator/admin/settings/_participants_sync_check.html.erb +1 -1
- data/app/views/decidim/action_delegator/admin/settings/_setting_checks.html.erb +11 -16
- data/app/views/decidim/action_delegator/admin/settings/edit.html.erb +11 -12
- data/app/views/decidim/action_delegator/admin/settings/index.html.erb +22 -19
- data/app/views/decidim/action_delegator/admin/settings/new.html.erb +11 -12
- data/app/views/decidim/action_delegator/admin/shared/_tabs_menu.html.erb +15 -0
- data/app/views/decidim/action_delegator/censuses/_internal_users_form.html.erb +61 -0
- data/app/views/decidim/action_delegator/elections/_delegation_buttons.html.erb +10 -0
- data/app/views/decidim/action_delegator/elections/_normal_election_buttons.html.erb +13 -0
- data/app/views/decidim/action_delegator/elections/_per_question_buttons.html.erb +9 -0
- data/app/views/decidim/action_delegator/elections/_per_question_waiting_buttons.html.erb +19 -0
- data/app/views/decidim/action_delegator/elections/_vote_results.html.erb +10 -0
- data/app/views/decidim/action_delegator/elections/_vote_results_question.html.erb +13 -0
- data/app/views/decidim/action_delegator/elections/admin/dashboard/_by_type_and_weight.html.erb +45 -0
- data/app/views/decidim/action_delegator/elections/admin/dashboard/_results_tabs.html.erb +5 -0
- data/app/views/decidim/action_delegator/elections/admin/dashboard/_results_type_info.html.erb +4 -0
- data/app/views/decidim/action_delegator/elections/admin/dashboard/_sum_of_weights.html.erb +43 -0
- data/app/views/decidim/action_delegator/elections/admin/dashboard/_totals.html.erb +27 -0
- data/app/views/decidim/action_delegator/user_delegations/index.html.erb +13 -14
- data/app/views/decidim/action_delegator/verifications/delegations_verifier/authorizations/edit.html.erb +19 -29
- data/app/views/decidim/action_delegator/verifications/delegations_verifier/authorizations/new.html.erb +42 -40
- data/config/assets.rb +3 -35
- data/config/i18n-tasks.yml +27 -5
- data/config/locales/ca.yml +70 -56
- data/config/locales/cs.yml +161 -145
- data/config/locales/en.yml +110 -67
- data/config/locales/es.yml +70 -56
- data/db/migrate/20200824113801_create_settings.rb +1 -1
- data/db/migrate/20250729104037_add_title_to_action_delegator_settings.rb +31 -0
- data/lib/decidim/action_delegator/admin_engine.rb +72 -45
- data/lib/decidim/action_delegator/common_rake.rb +13 -0
- data/lib/decidim/action_delegator/engine.rb +49 -19
- data/lib/decidim/action_delegator/test/delegation_examples.rb +144 -0
- data/lib/decidim/action_delegator/test/factories.rb +11 -6
- data/lib/decidim/action_delegator/verifications/delegations_authorizer.rb +80 -47
- data/lib/decidim/action_delegator/version.rb +3 -3
- data/lib/decidim/action_delegator.rb +8 -26
- data/lib/tasks/migrate_consultations.rake +382 -0
- data/lib/tasks/upgrade_tasks.rake +5 -0
- data/package.json +10 -27
- metadata +72 -112
- data/app/commands/concerns/decidim/action_delegator/consultations/multiple_vote_question_override.rb +0 -31
- data/app/commands/concerns/decidim/action_delegator/consultations/vote_question_override.rb +0 -44
- data/app/commands/decidim/action_delegator/admin/fix_resource_permissions.rb +0 -46
- data/app/commands/decidim/action_delegator/vote_delegation.rb +0 -28
- data/app/controllers/concerns/decidim/action_delegator/consultations/consultations_controller_override.rb +0 -16
- data/app/controllers/concerns/decidim/action_delegator/consultations/question_multiple_votes_controller_override.rb +0 -29
- data/app/controllers/concerns/decidim/action_delegator/consultations/question_votes_controller_override.rb +0 -57
- data/app/controllers/concerns/decidim/action_delegator/consultations/questions_controller_override.rb +0 -16
- data/app/controllers/concerns/decidim/action_delegator/needs_consultation_styles.rb +0 -24
- data/app/controllers/decidim/action_delegator/admin/consultations/exports_controller.rb +0 -27
- data/app/controllers/decidim/action_delegator/admin/consultations_controller.rb +0 -47
- data/app/controllers/decidim/action_delegator/admin/exports/_sum_of_weights_controller.rb +0 -15
- data/app/forms/concerns/decidim/action_delegator/consultations/vote_form_override.rb +0 -15
- data/app/helpers/decidim/action_delegator/delegation_helper.rb +0 -13
- data/app/jobs/decidim/action_delegator/export_consultation_results_job.rb +0 -51
- data/app/models/concerns/decidim/action_delegator/consultations/question_override.rb +0 -18
- data/app/models/concerns/decidim/action_delegator/consultations/vote_override.rb +0 -15
- data/app/models/decidim/action_delegator/unversioned_vote.rb +0 -19
- data/app/models/decidim/action_delegator/whodunnit_vote.rb +0 -28
- data/app/overrides/decidim/consultations/admin/consultations/results/add_ongoing_warning.html.erb.deface +0 -3
- data/app/overrides/decidim/consultations/consultations/_question/add_delegation_link.html.erb.deface +0 -3
- data/app/overrides/decidim/consultations/consultations/_regular_questions/prevent_empty_questions.html.erb.deface +0 -10
- data/app/overrides/decidim/consultations/consultations/_regular_questions/remove_highlighted_scopes.html.erb.deface +0 -5
- data/app/overrides/decidim/consultations/question_multiple_votes/_form/add_delegation_notice.html.erb.deface +0 -8
- data/app/overrides/decidim/consultations/questions/_vote_button/add_delegations_link.html.erb.deface +0 -3
- data/app/overrides/decidim/consultations/questions/_vote_button/add_modal.html.erb.deface +0 -3
- data/app/overrides/decidim/consultations/questions/_vote_button/add_modal_javascript.html.erb.deface +0 -4
- data/app/overrides/decidim/consultations/questions/_vote_button/replace_delegation_to_multivote_link.html.erb.deface +0 -8
- data/app/overrides/decidim/consultations/questions/_vote_modal/add_delegation_callout.html.erb.deface +0 -3
- data/app/overrides/decidim/consultations/questions/_vote_modal_confirm/add_delegation_callout.html.erb.deface +0 -3
- data/app/overrides/decidim/consultations/questions/_vote_modal_confirm/add_hidden_field.html.erb.deface +0 -3
- data/app/overrides/layouts/decidim/admin/remove_deprecation.rb +0 -10
- data/app/packs/entrypoints/decidim_action_delegator.scss +0 -1
- data/app/packs/entrypoints/decidim_action_delegator_questions.js +0 -5
- data/app/packs/src/decidim/action_delegator/questions.js +0 -33
- data/app/packs/stylesheets/decidim/action_delegator/questions.scss +0 -26
- data/app/permissions/concerns/decidim/action_delegator/consultations/permissions_override.rb +0 -35
- data/app/presenters/decidim/action_delegator/question_with_totals.rb +0 -24
- data/app/queries/decidim/action_delegator/consultation_delegations.rb +0 -25
- data/app/queries/decidim/action_delegator/delegates_votes_by_consultation.rb +0 -24
- data/app/queries/decidim/action_delegator/delegates_votes_by_question.rb +0 -26
- data/app/queries/decidim/action_delegator/delegation_votes.rb +0 -30
- data/app/queries/decidim/action_delegator/grantee_delegations.rb +0 -24
- data/app/queries/decidim/action_delegator/organization_delegations.rb +0 -26
- data/app/queries/decidim/action_delegator/organization_settings.rb +0 -31
- data/app/queries/decidim/action_delegator/responses.rb +0 -24
- data/app/queries/decidim/action_delegator/responses_by_membership.rb +0 -58
- data/app/queries/decidim/action_delegator/scrutiny.rb +0 -87
- data/app/queries/decidim/action_delegator/setting_delegations.rb +0 -19
- data/app/queries/decidim/action_delegator/sum_of_membership_weight.rb +0 -44
- data/app/queries/decidim/action_delegator/sum_of_weights.rb +0 -25
- data/app/queries/decidim/action_delegator/type_and_weight.rb +0 -26
- data/app/queries/decidim/action_delegator/voted_with_ponderations.rb +0 -30
- data/app/queries/decidim/action_delegator/votes_count_aggregation.rb +0 -34
- data/app/serializers/decidim/action_delegator/consultation_results_serializer.rb +0 -19
- data/app/views/decidim/action_delegator/admin/consultations/_ongoing_consultation_warning.html.erb +0 -3
- data/app/views/decidim/action_delegator/admin/consultations/results.html.erb +0 -65
- data/app/views/decidim/action_delegator/admin/consultations/weighted_results.html.erb +0 -66
- data/app/views/decidim/action_delegator/consultations/_link_to_question.html.erb +0 -11
- data/app/views/decidim/action_delegator/consultations/questions/_callout.html.erb +0 -5
- data/app/views/decidim/action_delegator/consultations/questions/_delegations_modal.html.erb +0 -34
- data/app/views/decidim/action_delegator/consultations/questions/_link_to_delegations.html.erb +0 -11
- data/app/views/decidim/action_delegator/consultations/questions/_vote_delegated_active.html.erb +0 -32
- data/app/views/decidim/action_delegator/consultations/questions/_vote_delegated_finished.html.erb +0 -9
- data/app/views/decidim/action_delegator/consultations/questions/_vote_delegated_upcoming.html.erb +0 -8
- data/app/views/decidim/consultations/question_votes/update_vote_button.js.erb +0 -82
- data/lib/tasks/import_direct_verification.rake +0 -30
@@ -3,7 +3,7 @@
|
|
3
3
|
require "savon"
|
4
4
|
require "rails"
|
5
5
|
require "decidim/core"
|
6
|
-
require "decidim/
|
6
|
+
require "decidim/elections"
|
7
7
|
require "deface"
|
8
8
|
|
9
9
|
module Decidim
|
@@ -12,33 +12,33 @@ module Decidim
|
|
12
12
|
# Handles all the logic related to delegation except verifications
|
13
13
|
class Engine < ::Rails::Engine
|
14
14
|
isolate_namespace Decidim::ActionDelegator
|
15
|
+
include Decidim::TranslatableAttributes
|
15
16
|
|
16
17
|
routes do
|
17
|
-
|
18
|
+
namespace :elections do
|
19
|
+
get ":id/sum_of_weights", to: "results#sum_of_weights", as: :results_sum_of_weights
|
20
|
+
namespace :admin do
|
21
|
+
get ":id/by_type_and_weight", to: "results#by_type_and_weight", as: :results_by_type_and_weight
|
22
|
+
get ":id/sum_of_weights", to: "results#sum_of_weights", as: :results_sum_of_weights
|
23
|
+
get ":id/totals", to: "results#totals", as: :results_totals
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
18
27
|
authenticate(:user) do
|
19
|
-
resources :user_delegations, controller: :user_delegations
|
28
|
+
resources :user_delegations, controller: :user_delegations, only: [:index]
|
20
29
|
root to: "user_delegations#index"
|
21
30
|
end
|
22
31
|
end
|
23
32
|
|
24
|
-
config.to_prepare do
|
25
|
-
# override votes questions
|
26
|
-
Decidim::Consultations::Question.include(Decidim::ActionDelegator::Consultations::QuestionOverride)
|
27
|
-
Decidim::Consultations::VoteQuestion.include(Decidim::ActionDelegator::Consultations::VoteQuestionOverride)
|
28
|
-
Decidim::Consultations::MultipleVoteQuestion.include(Decidim::ActionDelegator::Consultations::MultipleVoteQuestionOverride)
|
29
|
-
Decidim::Consultations::VoteForm.include(Decidim::ActionDelegator::Consultations::VoteFormOverride)
|
30
|
-
Decidim::Consultations::MultiVoteForm.include(Decidim::ActionDelegator::Consultations::VoteFormOverride)
|
31
|
-
Decidim::Consultations::Vote.include(Decidim::ActionDelegator::Consultations::VoteOverride)
|
32
|
-
Decidim::Consultations::Permissions.include(Decidim::ActionDelegator::Consultations::PermissionsOverride)
|
33
|
-
end
|
34
|
-
|
35
33
|
initializer "decidim_action_delegator.overrides", after: "decidim.action_controller" do
|
36
34
|
config.to_prepare do
|
37
35
|
Decidim::Devise::SessionsController.include(Decidim::ActionDelegator::Devise::SessionsControllerOverride)
|
38
|
-
Decidim
|
39
|
-
|
40
|
-
|
41
|
-
|
36
|
+
if Decidim.module_installed?(:elections)
|
37
|
+
Decidim::Elections::VotesController.include(Decidim::ActionDelegator::ElectionVotesControllerOverride)
|
38
|
+
Decidim::Elections::PerQuestionVotesController.include(Decidim::ActionDelegator::ElectionPerQuestionVotesControllerOverride)
|
39
|
+
Decidim::Elections::ElectionsController.helper(SettingsHelper)
|
40
|
+
Decidim::Elections::Admin::ElectionsController.helper(SettingsHelper)
|
41
|
+
end
|
42
42
|
end
|
43
43
|
end
|
44
44
|
|
@@ -50,6 +50,13 @@ module Decidim
|
|
50
50
|
workflow.engine = Decidim::ActionDelegator::Verifications::DelegationsVerifier::Engine
|
51
51
|
workflow.expires_in = Decidim::ActionDelegator.authorization_expiration_time
|
52
52
|
workflow.time_between_renewals = 1.minute
|
53
|
+
workflow.options do |options|
|
54
|
+
options.attribute :setting, type: :select, raw_choices: true, choices: lambda { |context|
|
55
|
+
Decidim::ActionDelegator::Setting.where(organization: context[:component]&.organization).active.map do |setting|
|
56
|
+
[translated_attribute(setting.title), setting.id]
|
57
|
+
end
|
58
|
+
}
|
59
|
+
end
|
53
60
|
end
|
54
61
|
end
|
55
62
|
|
@@ -57,7 +64,7 @@ module Decidim
|
|
57
64
|
Decidim.register_assets_path File.expand_path("app/packs", root)
|
58
65
|
end
|
59
66
|
|
60
|
-
initializer "
|
67
|
+
initializer "decidim_action_delegator.user_menu" do
|
61
68
|
Decidim.menu :user_menu do |menu|
|
62
69
|
menu.add_item :vote_delegations,
|
63
70
|
t("vote_delegations", scope: "layouts.decidim.user_profile"),
|
@@ -66,6 +73,29 @@ module Decidim
|
|
66
73
|
active: :exact
|
67
74
|
end
|
68
75
|
end
|
76
|
+
|
77
|
+
initializer "decidim_action_delegator.census_registry" do
|
78
|
+
next unless Decidim.module_installed?(:elections)
|
79
|
+
|
80
|
+
Decidim::Elections.census_registry.register(:action_delegator_census) do |manifest|
|
81
|
+
manifest.admin_form = "Decidim::ActionDelegator::Admin::ActionDelegatorCensusForm"
|
82
|
+
manifest.admin_form_partial = "decidim/action_delegator/admin/censuses/action_delegator_census_form"
|
83
|
+
manifest.voter_form = "Decidim::ActionDelegator::Censuses::InternalUsersForm"
|
84
|
+
manifest.voter_form_partial = "decidim/action_delegator/censuses/internal_users_form"
|
85
|
+
|
86
|
+
manifest.user_query do |election|
|
87
|
+
Decidim::ActionDelegator::ActionDelegatorCensusUsers.new(election).query
|
88
|
+
end
|
89
|
+
|
90
|
+
manifest.census_ready_validator { |election| election.census_settings["setting_id"].present? }
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
initializer "decidim_action_delegator.icons" do
|
95
|
+
Decidim.icons.register(name: "weight-line", icon: "weight-line", category: "system", description: "", engine: :action_delegator)
|
96
|
+
Decidim.icons.register(name: "user-shared-line", icon: "user-shared-line", category: "system", description: "", engine: :action_delegator)
|
97
|
+
Decidim.icons.register(name: "arrow-go-forward-line", icon: "arrow-go-forward-line", category: "system", description: "", engine: :action_delegator)
|
98
|
+
end
|
69
99
|
end
|
70
100
|
end
|
71
101
|
end
|
@@ -0,0 +1,144 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
shared_examples "voting in a per question election" do
|
4
|
+
it "shows delegation and allows the user vote for himself and the granter" do
|
5
|
+
expect(page).to have_css(".election__aside-voted")
|
6
|
+
expect(page).to have_content("You have delegated votes.")
|
7
|
+
expect(page).to have_content("You can vote on behalf of the following participants in this election:")
|
8
|
+
|
9
|
+
within ".election__aside-voted" do
|
10
|
+
expect(page).to have_content(user.name.to_s)
|
11
|
+
end
|
12
|
+
|
13
|
+
click_on "Vote"
|
14
|
+
expect(page).to have_content("You are voting for yourself (#{delegate_user.name})")
|
15
|
+
|
16
|
+
first("input[value=\"#{response_option1.id}\"]").click
|
17
|
+
click_on "Cast vote"
|
18
|
+
|
19
|
+
expect(page).to have_content("Waiting for the next question")
|
20
|
+
|
21
|
+
expect(page).to have_css(".waiting-buttons")
|
22
|
+
expect(page).to have_content("You have delegated votes.")
|
23
|
+
expect(page).to have_link(
|
24
|
+
"Continue voting on behalf of #{user.name}",
|
25
|
+
href: election_per_question_vote_path(current_question.id, delegation.id)
|
26
|
+
)
|
27
|
+
click_on "Continue voting on behalf of #{user.name}"
|
28
|
+
expect(page).to have_content("You are voting on behalf of #{user.name}")
|
29
|
+
|
30
|
+
first("input[value=\"#{response_option2.id}\"]").click
|
31
|
+
click_on "Cast vote"
|
32
|
+
|
33
|
+
expect(page).to have_content("Your vote has been successfully cast")
|
34
|
+
expect(page).to have_link("Edit your vote", href: election_per_question_vote_path(current_question))
|
35
|
+
expect(page).to have_link("Edit vote for #{user.name}", href: election_per_question_vote_path(current_question) + "?delegation=#{delegation.id}")
|
36
|
+
|
37
|
+
expect(last_vote(delegate_user).response_option).to eq(response_option1)
|
38
|
+
expect(last_vote(user).response_option).to eq(response_option2)
|
39
|
+
|
40
|
+
click_on "Edit vote for #{user.name}"
|
41
|
+
first("input[value=\"#{response_option1.id}\"]").click
|
42
|
+
click_on "Cast vote"
|
43
|
+
|
44
|
+
expect(page).to have_content("Your vote has been successfully cast")
|
45
|
+
expect(last_vote(user).response_option.reload).to eq(response_option1)
|
46
|
+
|
47
|
+
click_on "Edit your vote"
|
48
|
+
first("input[value=\"#{response_option2.id}\"]").click
|
49
|
+
click_on "Cast vote"
|
50
|
+
|
51
|
+
sleep 0.1 # Wait for the versioning to be saved
|
52
|
+
expect(last_vote(delegate_user).response_option.reload).to eq(response_option2)
|
53
|
+
expect(last_vote(delegate_user).versions.first.whodunnit).to eq(delegate_user.id.to_s)
|
54
|
+
expect(last_vote(delegate_user).versions.first.decidim_action_delegator_delegation_id).to be_blank
|
55
|
+
expect(last_vote(user).versions.first.whodunnit).to eq(delegate_user.id.to_s)
|
56
|
+
expect(last_vote(user).versions.first.decidim_action_delegator_delegation_id).to eq(delegation.id)
|
57
|
+
end
|
58
|
+
|
59
|
+
context "when delegate has voted for delegated user" do
|
60
|
+
let!(:next_question) { create(:election_question, :voting_enabled, :with_response_options, election:) }
|
61
|
+
let!(:vote1) { create(:election_vote, question: current_question, response_option: current_question.response_options.first, voter_uid: user.to_global_id.to_s) }
|
62
|
+
let!(:vote2) { create(:election_vote, question: next_question, response_option: next_question.response_options.first, voter_uid: user.to_global_id.to_s) }
|
63
|
+
|
64
|
+
it "shows voted status on election page" do
|
65
|
+
visit election_path
|
66
|
+
expect(page).to have_content("You have delegated votes.")
|
67
|
+
expect(page).to have_content("You can vote on behalf of the following participants in this election:")
|
68
|
+
|
69
|
+
within all(".election__aside-voted").last do
|
70
|
+
expect(page).to have_content("✔ #{user.name}")
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
shared_examples "voting in a normal election" do
|
77
|
+
it "shows delegation and allows the user vote for himself and the granter" do
|
78
|
+
expect(page).to have_css(".election__aside-voted")
|
79
|
+
expect(page).to have_content("You have delegated votes.")
|
80
|
+
expect(page).to have_content("Vote on behalf of #{user.name}")
|
81
|
+
|
82
|
+
click_on "Vote"
|
83
|
+
|
84
|
+
first("input[value=\"#{response_option1.id}\"]").click
|
85
|
+
click_on "Next"
|
86
|
+
sleep 0.1
|
87
|
+
first('input[type="radio"], input[type="checkbox"]').click
|
88
|
+
click_on "Next"
|
89
|
+
click_on "Cast vote"
|
90
|
+
|
91
|
+
expect(page).to have_content("Your vote has been successfully cast")
|
92
|
+
click_on "Exit the voting booth"
|
93
|
+
|
94
|
+
expect(page).to have_content("You have already voted.")
|
95
|
+
expect(last_vote(delegate_user).response_option).to eq(response_option1)
|
96
|
+
|
97
|
+
click_on "Vote on behalf of #{user.name}"
|
98
|
+
expect(page).to have_content("You are voting on behalf of #{user.name}")
|
99
|
+
|
100
|
+
first("input[value=\"#{response_option2.id}\"]").click
|
101
|
+
click_on "Next"
|
102
|
+
sleep 0.1
|
103
|
+
first('input[type="radio"], input[type="checkbox"]').click
|
104
|
+
click_on "Next"
|
105
|
+
click_on "Cast vote"
|
106
|
+
|
107
|
+
expect(page).to have_content("Your vote has been successfully cast")
|
108
|
+
click_on "Exit the voting booth"
|
109
|
+
expect(page).to have_content("You have already voted.")
|
110
|
+
|
111
|
+
expect(last_vote(user).response_option.reload).to eq(response_option2)
|
112
|
+
|
113
|
+
click_on "Vote"
|
114
|
+
first("input[value=\"#{response_option2.id}\"]").click
|
115
|
+
click_on "Next"
|
116
|
+
sleep 0.1
|
117
|
+
click_on "Next"
|
118
|
+
click_on "Cast vote"
|
119
|
+
click_on "Exit the voting booth"
|
120
|
+
|
121
|
+
expect(last_vote(delegate_user).reload.response_option).to eq(response_option2)
|
122
|
+
|
123
|
+
click_on "Vote on behalf of #{user.name}"
|
124
|
+
first("input[value=\"#{response_option1.id}\"]").click
|
125
|
+
click_on "Next"
|
126
|
+
sleep 0.1
|
127
|
+
click_on "Next"
|
128
|
+
click_on "Cast vote"
|
129
|
+
click_on "Exit the voting booth"
|
130
|
+
|
131
|
+
expect(last_vote(user).reload.response_option).to eq(response_option1)
|
132
|
+
expect(last_vote(delegate_user).versions.first.whodunnit).to eq(delegate_user.id.to_s)
|
133
|
+
expect(last_vote(delegate_user).versions.first.decidim_action_delegator_delegation_id).to be_blank
|
134
|
+
expect(last_vote(user).versions.first.whodunnit).to eq(delegate_user.id.to_s)
|
135
|
+
expect(last_vote(user).versions.first.decidim_action_delegator_delegation_id).to eq(delegation.id)
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
shared_examples "no delegations available" do
|
140
|
+
it "does not show delegation buttons" do
|
141
|
+
expect(page).to have_no_css(".election__aside-voted")
|
142
|
+
expect(page).to have_no_content("You have delegated votes.")
|
143
|
+
end
|
144
|
+
end
|
@@ -1,13 +1,10 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "decidim/core/test/factories"
|
4
|
-
require "decidim/consultations/test/factories"
|
5
|
-
|
6
3
|
FactoryBot.define do
|
7
4
|
factory :delegation, class: "Decidim::ActionDelegator::Delegation" do
|
8
5
|
setting
|
9
|
-
granter { association :user, organization: setting.
|
10
|
-
grantee { association :user, organization: setting.
|
6
|
+
granter { association :user, organization: setting.organization }
|
7
|
+
grantee { association :user, organization: setting.organization }
|
11
8
|
end
|
12
9
|
|
13
10
|
factory :ponderation, class: "Decidim::ActionDelegator::Ponderation" do
|
@@ -24,13 +21,21 @@ FactoryBot.define do
|
|
24
21
|
end
|
25
22
|
|
26
23
|
factory :setting, class: "Decidim::ActionDelegator::Setting" do
|
24
|
+
organization { create(:organization) }
|
25
|
+
transient do
|
26
|
+
skip_injection { false }
|
27
|
+
end
|
28
|
+
|
29
|
+
title { generate_localized_title(:title, skip_injection:) }
|
30
|
+
description { generate_localized_description(:description, skip_injection:) }
|
27
31
|
max_grants { 3 }
|
28
|
-
|
32
|
+
|
29
33
|
trait :with_ponderations do
|
30
34
|
after(:create) do |setting|
|
31
35
|
create_list(:ponderation, 3, setting: setting)
|
32
36
|
end
|
33
37
|
end
|
38
|
+
|
34
39
|
trait :with_participants do
|
35
40
|
after(:create) do |setting|
|
36
41
|
create_list(:participant, 3, setting: setting)
|
@@ -5,77 +5,110 @@ module Decidim
|
|
5
5
|
module Verifications
|
6
6
|
class DelegationsAuthorizer < Decidim::Verifications::DefaultActionAuthorizer
|
7
7
|
def authorize
|
8
|
-
|
9
|
-
|
8
|
+
if !authorization
|
9
|
+
[:missing, { action: :authorize }]
|
10
|
+
elsif authorization_expired?
|
11
|
+
[:expired, { action: :authorize }]
|
12
|
+
elsif !authorization.granted?
|
13
|
+
[:pending, { action: :resume }]
|
14
|
+
elsif invalid_setting?
|
15
|
+
return [:unauthorized, { extra_explanation: extra_explanations }]
|
16
|
+
else
|
17
|
+
[:ok, {}]
|
18
|
+
end
|
19
|
+
end
|
10
20
|
|
11
|
-
|
12
|
-
return
|
13
|
-
return
|
21
|
+
def invalid_setting?
|
22
|
+
return true unless setting
|
23
|
+
return true unless user_is_a_participant?
|
14
24
|
|
15
|
-
|
25
|
+
false
|
16
26
|
end
|
17
27
|
|
18
28
|
private
|
19
29
|
|
20
|
-
def
|
21
|
-
return unless setting
|
30
|
+
def user_is_a_participant?
|
31
|
+
return false unless setting && setting.active?
|
22
32
|
|
23
|
-
setting.
|
33
|
+
setting.participants.exists?(participant_params(setting))
|
24
34
|
end
|
25
35
|
|
26
|
-
def
|
27
|
-
|
28
|
-
|
29
|
-
|
36
|
+
def participant_params(setting)
|
37
|
+
params = {}
|
38
|
+
params[:email] = authorization.user.email if setting.email_required?
|
39
|
+
params[:phone] = authorization.metadata["phone"] if setting.phone_required?
|
40
|
+
params
|
30
41
|
end
|
31
42
|
|
32
|
-
def
|
33
|
-
|
34
|
-
|
35
|
-
@census_params = { email: authorization.user.email }
|
36
|
-
@census_params[:phone] = authorization.metadata["phone"] if setting.phone_required?
|
37
|
-
@census_params
|
43
|
+
def authorizations_path
|
44
|
+
Decidim::Verifications::Engine.routes.url_helpers.authorizations_path
|
38
45
|
end
|
39
46
|
|
40
47
|
def extra_explanations
|
41
48
|
return @extra_explanations if @extra_explanations
|
42
49
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
50
|
+
@extra_explanations = []
|
51
|
+
|
52
|
+
if setting
|
53
|
+
if setting.active?
|
54
|
+
@extra_explanations << {
|
55
|
+
key: "not_in_census_html",
|
56
|
+
params: {
|
57
|
+
scope: "decidim.action_delegator.delegations_authorizer",
|
58
|
+
census: translated_attribute(setting.title),
|
59
|
+
renew_path: authorizations_path
|
60
|
+
}
|
61
|
+
}
|
62
|
+
if setting.email_required?
|
63
|
+
@extra_explanations << {
|
64
|
+
key: "email",
|
65
|
+
params: { scope: "decidim.action_delegator.delegations_authorizer", email: authorization.user.email }
|
66
|
+
}
|
67
|
+
end
|
68
|
+
if setting.phone_required?
|
69
|
+
@extra_explanations << {
|
70
|
+
key: "phone",
|
71
|
+
params: { scope: "decidim.action_delegator.delegations_authorizer", phone: authorization.metadata["phone"] || "---" }
|
72
|
+
}
|
73
|
+
end
|
74
|
+
else
|
75
|
+
@extra_explanations << {
|
76
|
+
key: "inactive_setting_html",
|
77
|
+
params: {
|
78
|
+
scope: "decidim.action_delegator.delegations_authorizer",
|
79
|
+
census: translated_attribute(setting.title),
|
80
|
+
renew_path: authorizations_path
|
81
|
+
}
|
82
|
+
}
|
83
|
+
end
|
84
|
+
else
|
61
85
|
@extra_explanations << {
|
62
|
-
key: "
|
63
|
-
params: {
|
86
|
+
key: "no_setting_html",
|
87
|
+
params: {
|
88
|
+
scope: "decidim.action_delegator.delegations_authorizer",
|
89
|
+
renew_path: authorizations_path
|
90
|
+
}
|
64
91
|
}
|
65
92
|
end
|
66
|
-
@extra_explanations
|
67
|
-
end
|
68
93
|
|
69
|
-
|
70
|
-
@setting ||= Decidim::ActionDelegator::Setting.find_by(consultation: consultation)
|
94
|
+
@extra_explanations
|
71
95
|
end
|
72
96
|
|
73
|
-
|
74
|
-
|
97
|
+
# Obtain the setting from the resource (in case is an election) or from the standard options (coming from the component/resource permissions hash) otherwise
|
98
|
+
def setting_id
|
99
|
+
@setting_id ||= if resource && resource.respond_to?(:census_settings) && resource.respond_to?(:census_manifest)
|
100
|
+
if resource.census_manifest == "action_delegator_census"
|
101
|
+
resource.census_settings["setting_id"]
|
102
|
+
else
|
103
|
+
resource.census_settings.dig("authorization_handlers", "delegations_verifier", "options", "setting")
|
104
|
+
end
|
105
|
+
else
|
106
|
+
options["setting"]
|
107
|
+
end
|
75
108
|
end
|
76
109
|
|
77
|
-
def
|
78
|
-
@
|
110
|
+
def setting
|
111
|
+
@setting ||= Decidim::ActionDelegator::Setting.find_by(id: setting_id)
|
79
112
|
end
|
80
113
|
end
|
81
114
|
end
|
@@ -3,8 +3,8 @@
|
|
3
3
|
module Decidim
|
4
4
|
# This holds the decidim-action_delegator version.
|
5
5
|
module ActionDelegator
|
6
|
-
VERSION = "0.
|
7
|
-
DECIDIM_VERSION = "
|
8
|
-
COMPAT_DECIDIM_VERSION = [">= 0.
|
6
|
+
VERSION = "0.9.0"
|
7
|
+
DECIDIM_VERSION = { github: "decidim/decidim", branch: "develop" }.freeze
|
8
|
+
COMPAT_DECIDIM_VERSION = [">= 0.31.0.dev", "< 0.32"].freeze
|
9
9
|
end
|
10
10
|
end
|
@@ -14,25 +14,25 @@ module Decidim
|
|
14
14
|
# this is the SmsGateway provided by this module
|
15
15
|
# Note that it will be ignored if you provide your own SmsGateway in Decidim.sms_gateway_service
|
16
16
|
config_accessor :sms_gateway_service do
|
17
|
-
"Decidim::ActionDelegator::SmsGateway"
|
17
|
+
Decidim::Env.new("AD_SMS_GATEWAY_SERVICE", "Decidim::ActionDelegator::SmsGateway").to_s
|
18
18
|
end
|
19
19
|
|
20
20
|
# The default expiration time for the integrated authorization
|
21
21
|
# if zero, the authorization won't be registered
|
22
22
|
config_accessor :authorization_expiration_time do
|
23
|
-
3.months
|
23
|
+
Decidim::Env.new("AD_AUTHORIZATION_EXPIRATION_TIME").presence&.to_i || 3.months
|
24
24
|
end
|
25
25
|
|
26
26
|
# Put this to false if you don't want to allow administrators to invite users not registered
|
27
27
|
# in the platform when uploading a census (inviting users without permission can be a GDPR offense).
|
28
28
|
config_accessor :allow_to_invite_users do
|
29
|
-
true
|
29
|
+
Decidim::Env.new("AD_ALLOW_TO_INVITE_USERS", true).present?
|
30
30
|
end
|
31
31
|
|
32
32
|
# If true, tries to automatically authorize users when they log in with the "Corporate Governance Verifier"
|
33
33
|
# Note that this is only possible when the verifier is configured to use only the email (if SMS is required, the user will have to do the standard verification process)
|
34
34
|
config_accessor :authorize_on_login do
|
35
|
-
true
|
35
|
+
Decidim::Env.new("AD_AUTHORIZE_ON_LOGIN", true).present?
|
36
36
|
end
|
37
37
|
|
38
38
|
# used for comparing phone numbers from a census list and the ones introduced by the user
|
@@ -40,30 +40,12 @@ module Decidim
|
|
40
40
|
# if you have a census list with +34 666 666 666 and the user introduces 0034666666666 or 666666666, they will be considered the same
|
41
41
|
# can be empty or null if yo don't want to check different combinations of prefixes
|
42
42
|
config_accessor :phone_prefixes do
|
43
|
-
|
43
|
+
Decidim::Env.new("AD_PHONE_PREFIXES", "+34,0034,34").to_array
|
44
44
|
end
|
45
45
|
|
46
46
|
# The regex for validating phone numbers
|
47
47
|
config_accessor :phone_regex do
|
48
|
-
|
49
|
-
end
|
50
|
-
|
51
|
-
# Consultations has an annoying and totally useless deprecation warning
|
52
|
-
# This plugin removes it by default.
|
53
|
-
# If you want to keep it, you can set this config to false
|
54
|
-
config_accessor :remove_consultation_deprecation_warning do
|
55
|
-
true
|
56
|
-
end
|
57
|
-
|
58
|
-
# In a consultation the highlighted questions are duplicated in the list of regular questions
|
59
|
-
# this maintains the highlighted questions in the highlighted list and removes them from the regular list
|
60
|
-
config_accessor :remove_duplicated_highlighted_questions do
|
61
|
-
true
|
62
|
-
end
|
63
|
-
|
64
|
-
# If true, admins can view the result of a consultation even if the consultation is ongoing
|
65
|
-
config_accessor :admin_preview_results do
|
66
|
-
true
|
48
|
+
Decidim::Env.new("AD_PHONE_REGEX", '^\d{6,15}$').to_s # 6 to 15 digits
|
67
49
|
end
|
68
50
|
end
|
69
51
|
end
|
@@ -74,7 +56,7 @@ end
|
|
74
56
|
# manage their delegations
|
75
57
|
Decidim.register_global_engine(
|
76
58
|
:decidim_action_delegator, # this is the name of the global method to access engine routes
|
77
|
-
|
59
|
+
Decidim::ActionDelegator::Engine,
|
78
60
|
at: "/action_delegator"
|
79
61
|
)
|
80
62
|
|
@@ -82,6 +64,6 @@ Decidim.register_global_engine(
|
|
82
64
|
# create their own
|
83
65
|
Decidim.register_global_engine(
|
84
66
|
:decidim_admin_action_delegator,
|
85
|
-
|
67
|
+
Decidim::ActionDelegator::AdminEngine,
|
86
68
|
at: "/admin/action_delegator"
|
87
69
|
)
|