decidim-department_admin 0.7.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (96) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE-AGPLv3.txt +661 -0
  3. data/README.md +132 -0
  4. data/Rakefile +9 -0
  5. data/app/controllers/decidim/department_admin/admin/application_controller.rb +15 -0
  6. data/app/controllers/decidim/department_admin/application_controller.rb +13 -0
  7. data/app/decorators/decidim/admin/newsletters_controller_decorator.rb +30 -0
  8. data/app/decorators/decidim/admin/users_controller_decorator.rb +128 -0
  9. data/app/decorators/decidim/area_decorator.rb +44 -0
  10. data/app/decorators/decidim/assemblies/admin/assemblies_controller_decorator.rb +25 -0
  11. data/app/decorators/decidim/assemblies/admin/assemblies_helper_decorator.rb +24 -0
  12. data/app/decorators/decidim/assemblies/create_assembly_decorator.rb +19 -0
  13. data/app/decorators/decidim/assemblies/parent_assemblies_for_select_decorator.rb +38 -0
  14. data/app/decorators/decidim/assemblies/permissions_decorator.rb +22 -0
  15. data/app/decorators/decidim/assemblies/update_assembly_decorator.rb +19 -0
  16. data/app/decorators/decidim/assemblies_decorator.rb +21 -0
  17. data/app/decorators/decidim/assemblies_with_user_role_decorator.rb +27 -0
  18. data/app/decorators/decidim/conference_form_decorator.rb +23 -0
  19. data/app/decorators/decidim/conferences/admin/conferences_controller_decorator.rb +27 -0
  20. data/app/decorators/decidim/conferences/create_conference_decorator.rb +51 -0
  21. data/app/decorators/decidim/conferences/permissions_decorator.rb +24 -0
  22. data/app/decorators/decidim/conferences/update_conference_decorator.rb +21 -0
  23. data/app/decorators/decidim/conferences_decorator.rb +27 -0
  24. data/app/decorators/decidim/conferences_with_user_role_decorator.rb +29 -0
  25. data/app/decorators/decidim/decidim_form_helper_decorator.rb +23 -0
  26. data/app/decorators/decidim/invite_user_decorator.rb +56 -0
  27. data/app/decorators/decidim/invite_user_form_decorator.rb +45 -0
  28. data/app/decorators/decidim/newsletter_decorator.rb +20 -0
  29. data/app/decorators/decidim/newsletters_helper_decorator.rb +44 -0
  30. data/app/decorators/decidim/participatory_process_decorator.rb +21 -0
  31. data/app/decorators/decidim/participatory_process_group_decorator.rb +17 -0
  32. data/app/decorators/decidim/participatory_processes/admin/participatory_processes_controller_decorator.rb +25 -0
  33. data/app/decorators/decidim/participatory_processes/create_participatory_process_decorator.rb +19 -0
  34. data/app/decorators/decidim/participatory_processes/permissions_decorator.rb +22 -0
  35. data/app/decorators/decidim/participatory_processes/update_participatory_process_decorator.rb +19 -0
  36. data/app/decorators/decidim/participatory_processes_with_user_role_decorator.rb +27 -0
  37. data/app/decorators/decidim/user_decorator.rb +59 -0
  38. data/app/decorators/lib/decidim/participatory_space_resourceable_decorator.rb +36 -0
  39. data/app/helpers/decidim/admin/user_roles_helper.rb +25 -0
  40. data/app/helpers/decidim/department_admin/application_helper.rb +54 -0
  41. data/app/models/decidim/participatory_space_role_config/department_admin.rb +8 -0
  42. data/app/overrides/decidim/admin/shared/add_radio_buttons_to_filters.rb +6 -0
  43. data/app/packs/entrypoints/decidim_department_admin.js +4 -0
  44. data/app/packs/entrypoints/decidim_department_admin.scss +1 -0
  45. data/app/packs/images/decidim/department_admin/icon.svg +1 -0
  46. data/app/packs/stylesheets/decidim/admin/department_admin.scss +5 -0
  47. data/app/permissions/decidim/assemblies/participatory_space_permissions.rb +14 -0
  48. data/app/permissions/decidim/conferences/participatory_space_permissions.rb +17 -0
  49. data/app/permissions/decidim/department_admin/permissions.rb +240 -0
  50. data/app/permissions/decidim/participatory_processes/participatory_space_permissions.rb +14 -0
  51. data/app/queries/decidim/admin/user_admin_by_space_name_filter.rb +67 -0
  52. data/app/queries/decidim/admin/user_admin_filter.rb +50 -0
  53. data/app/views/decidim/admin/users/_filters.html.erb +28 -0
  54. data/app/views/decidim/admin/users/_form.html.erb +30 -0
  55. data/app/views/decidim/admin/users/index.html.erb +93 -0
  56. data/app/views/decidim/admin/users/show.html.erb +99 -0
  57. data/app/views/decidim/assemblies/admin/assemblies/index.html.erb +147 -0
  58. data/app/views/decidim/conferences/admin/conferences/_form.html.erb +127 -0
  59. data/app/views/decidim/conferences/admin/conferences/index.html.erb +85 -0
  60. data/app/views/decidim/participatory_processes/admin/participatory_processes/index.html.erb +160 -0
  61. data/config/assets.rb +27 -0
  62. data/config/i18n-tasks.yml +148 -0
  63. data/config/initializers/user_roles.rb +4 -0
  64. data/config/locales/ca.yml +61 -0
  65. data/config/locales/cs.yml +46 -0
  66. data/config/locales/en.yml +61 -0
  67. data/config/locales/es.yml +61 -0
  68. data/db/migrate/20190328130102_create_department_admin_areas.rb +10 -0
  69. data/db/migrate/20210420143021_add_area_to_conferences.rb +7 -0
  70. data/lib/decidim/department_admin/admin.rb +10 -0
  71. data/lib/decidim/department_admin/admin_engine.rb +27 -0
  72. data/lib/decidim/department_admin/engine.rb +137 -0
  73. data/lib/decidim/department_admin/test/factories.rb +17 -0
  74. data/lib/decidim/department_admin/version.rb +11 -0
  75. data/lib/decidim/department_admin.rb +15 -0
  76. data/spec/commands/decidim/admin/deliver_newsletter_spec.rb +175 -0
  77. data/spec/commands/decidim/invite_user_spec.rb +42 -0
  78. data/spec/controllers/decidim/admin/users_controller_spec.rb +119 -0
  79. data/spec/factories.rb +4 -0
  80. data/spec/features/check_overrides_spec.rb +11 -0
  81. data/spec/i18n_spec.rb +29 -0
  82. data/spec/models/decidim/area_spec.rb +23 -0
  83. data/spec/permissions/decidim/department_admin/department_admin_permissions_spec.rb +120 -0
  84. data/spec/queries/parent_assemblies_for_select_spec.rb +52 -0
  85. data/spec/spec_helper.rb +47 -0
  86. data/spec/system/admin_explores_processes_spec.rb +53 -0
  87. data/spec/system/admin_invite_department_admin_spec.rb +118 -0
  88. data/spec/system/department_admin_manages_newsletters_spec.rb +237 -0
  89. data/spec/system/department_admin_should_be_able_to_access_admin_dashboard_spec.rb +75 -0
  90. data/spec/system/department_admin_should_be_able_to_manage_assemblies_spec.rb +99 -0
  91. data/spec/system/department_admin_should_be_able_to_manage_conferences_spec.rb +74 -0
  92. data/spec/system/department_admin_should_be_able_to_manage_processes_spec.rb +117 -0
  93. data/spec/system/department_admin_should_be_able_to_see_only_assemblies_from_her_area_spec.rb +46 -0
  94. data/spec/system/department_admin_should_be_able_to_see_only_newsletters_from_her_area_spec.rb +53 -0
  95. data/spec/system/department_admin_should_be_able_to_see_only_processes_from_her_area_spec.rb +50 -0
  96. metadata +229 -0
@@ -0,0 +1,175 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
4
+
5
+ module Decidim::Admin
6
+ describe DeliverNewsletter do
7
+ describe "call" do
8
+ let(:organization) { create(:organization) }
9
+ let(:newsletter) do
10
+ create(:newsletter,
11
+ organization: organization,
12
+ author: current_user)
13
+ end
14
+ let(:area) { create(:area, organization: organization) }
15
+ let(:current_user) { create(:department_admin, :confirmed, organization: organization, area: area) }
16
+ let(:send_to_all_users) { false }
17
+ let(:send_to_followers) { false }
18
+ let(:send_to_participants) { false }
19
+ let(:participatory_space_types) { [] }
20
+ let(:scope_ids) { [] }
21
+
22
+ let(:form_params) do
23
+ {
24
+ send_to_all_users: send_to_all_users,
25
+ send_to_followers: send_to_followers,
26
+ send_to_participants: send_to_participants,
27
+ participatory_space_types: participatory_space_types,
28
+ scope_ids: scope_ids,
29
+ }
30
+ end
31
+
32
+ let(:form) do
33
+ SelectiveNewsletterForm.from_params(
34
+ form_params
35
+ ).with_context(
36
+ current_organization: organization,
37
+ current_user: current_user
38
+ )
39
+ end
40
+
41
+ let(:command) { described_class.new(newsletter, form, current_user) }
42
+
43
+ shared_examples_for "selective newsletter" do
44
+ context "when everything is ok" do
45
+ it "updates the counters and delivers to the right users" do
46
+ clear_emails
47
+ expect(emails.length).to eq(0)
48
+
49
+ perform_enqueued_jobs { command.call }
50
+
51
+ expect(emails.length).to eq(deliverable_users.count)
52
+
53
+ newsletter.reload
54
+ expect(newsletter.total_deliveries).to eq(deliverable_users.count)
55
+ expect(newsletter.total_recipients).to eq(deliverable_users.count)
56
+ end
57
+
58
+ it "logs the action", versioning: true do
59
+ expect(Decidim.traceability)
60
+ .to receive(:perform_action!)
61
+ .with("deliver", newsletter, current_user)
62
+ .and_call_original
63
+
64
+ expect do
65
+ perform_enqueued_jobs { command.call }
66
+ end.to change(Decidim::ActionLog, :count)
67
+
68
+ action_log = Decidim::ActionLog.last
69
+ expect(action_log.version).to be_present
70
+ expect(action_log.version.event).to eq "update"
71
+ end
72
+ end
73
+ end
74
+
75
+ context "when the user is a department admin" do
76
+ let!(:participatory_process) { create(:participatory_process, organization: organization, area: area) }
77
+ let!(:component) { create(:dummy_component, organization: newsletter.organization, participatory_space: participatory_process) }
78
+
79
+ context "when no spaces selected" do
80
+ it "is not valid" do
81
+ expect { command.call }.to broadcast(:invalid)
82
+ end
83
+ end
84
+
85
+ context "when spaces selected" do
86
+ let(:participatory_space_types) do
87
+ [
88
+ { "id" => nil,
89
+ "manifest_name" => "participatory_processes",
90
+ "ids" => [component.participatory_space.id.to_s] },
91
+ { "id" => nil,
92
+ "manifest_name" => "assemblies",
93
+ "ids" => [] },
94
+ { "id" => nil,
95
+ "manifest_name" => "conferences",
96
+ "ids" => [] },
97
+ { "id" => nil,
98
+ "manifest_name" => "consultations",
99
+ "ids" => [] },
100
+ { "id" => nil,
101
+ "manifest_name" => "initiatives",
102
+ "ids" => [] },
103
+ ]
104
+ end
105
+
106
+ context "when sending to followers" do
107
+ let(:send_to_followers) { true }
108
+
109
+ let!(:deliverable_users) do
110
+ create_list(:user, rand(2..9), :confirmed, organization: organization, newsletter_notifications_at: Time.current)
111
+ end
112
+
113
+ let!(:undeliverable_users) do
114
+ create_list(:user, rand(2..9), :confirmed, organization: organization, newsletter_notifications_at: Time.current)
115
+ end
116
+
117
+ before do
118
+ deliverable_users.each do |follower|
119
+ create(:follow, followable: participatory_process, user: follower)
120
+ end
121
+ end
122
+
123
+ it_behaves_like "selective newsletter"
124
+ end
125
+
126
+ context "when sending to all space participants" do
127
+ let(:send_to_participants) { true }
128
+ let!(:deliverable_users) do
129
+ create_list(:user, rand(2..9), :confirmed, organization: organization, newsletter_notifications_at: Time.current)
130
+ end
131
+
132
+ before do
133
+ deliverable_users.each do |participant|
134
+ create(:dummy_resource, component: component, author: participant, published_at: Time.current)
135
+ end
136
+ end
137
+
138
+ it_behaves_like "selective newsletter"
139
+ end
140
+
141
+ context "when sending to followers and participants" do
142
+ let(:send_to_participants) { true }
143
+ let(:send_to_followers) { true }
144
+
145
+ let!(:participant_users) do
146
+ create_list(:user, rand(2..9), :confirmed, organization: organization, newsletter_notifications_at: Time.current)
147
+ end
148
+
149
+ let!(:follower_users) do
150
+ create_list(:user, rand(2..9), :confirmed, organization: organization, newsletter_notifications_at: Time.current)
151
+ end
152
+
153
+ let!(:deliverable_users) { participant_users + follower_users }
154
+
155
+ let!(:undeliverable_users) do
156
+ create_list(:user, rand(2..9), :confirmed, organization: organization, newsletter_notifications_at: Time.current)
157
+ end
158
+
159
+ before do
160
+ participant_users.each do |participant|
161
+ create(:dummy_resource, component: component, author: participant, published_at: Time.current)
162
+ end
163
+
164
+ follower_users.each do |follower|
165
+ create(:follow, followable: component.participatory_space, user: follower)
166
+ end
167
+ end
168
+
169
+ it_behaves_like "selective newsletter"
170
+ end
171
+ end
172
+ end
173
+ end
174
+ end
175
+ end
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
4
+
5
+ module Decidim
6
+ describe InviteUser do
7
+ describe "call" do
8
+ let(:organization) { create(:organization) }
9
+
10
+ let(:current_user) { create(:admin, :confirmed, organization: organization) }
11
+
12
+ let(:form_params) do
13
+ {
14
+ name: "user_name",
15
+ email: "user_name@example.org",
16
+ organization: organization,
17
+ }
18
+ end
19
+
20
+ let(:form) do
21
+ InviteUserForm.from_params(
22
+ form_params
23
+ ).with_context(
24
+ current_organization: organization,
25
+ current_user: current_user
26
+ )
27
+ end
28
+
29
+ let(:command) { described_class.new(form, current_user) }
30
+
31
+ shared_examples_for "inviting_users" do
32
+ context "when everything is ok" do
33
+ it "invites the user with no area" do
34
+ invite_user
35
+ user = Decidim::User.find_by(email: "user_name@example.org")
36
+ expect(user).to exist
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,119 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
4
+
5
+ module Decidim::Admin
6
+ describe UsersController, type: :controller do
7
+ # routes { Decidim::Core::Engine.routes }
8
+ routes { Decidim::Admin::Engine.routes }
9
+
10
+ let!(:admin_user) { create(:user, :admin, :confirmed) }
11
+ let!(:current_user) { admin_user }
12
+ let(:organization) { admin_user.organization }
13
+
14
+ before do
15
+ request.env["decidim.current_organization"] = organization
16
+ sign_in current_user, scope: :user
17
+ end
18
+
19
+ describe "role filter" do
20
+ let!(:participant) { create(:user, :confirmed, organization: organization) }
21
+ let!(:department_admin_user) { create(:department_admin, :confirmed, organization: organization) }
22
+ let!(:user_manager) { create(:user, :confirmed, organization: organization, roles: ["user_manager"]) }
23
+ let!(:process_admin) { create(:user, :confirmed, organization: organization) }
24
+ let!(:participatory_process) { create(:participatory_process, organization: organization, title: { en: "A Process space" }) }
25
+ let!(:process_admin_rel) { Decidim::ParticipatoryProcessUserRole.create(role: "admin", user: process_admin, participatory_process: participatory_process) }
26
+ let!(:assembly_admin) { create(:user, :confirmed, organization: organization) }
27
+ let!(:assembly) { create(:assembly, organization: organization, title: { en: "An Assembly space" }) }
28
+ let!(:assembly_admin_rel) { Decidim::AssemblyUserRole.create(role: "admin", user: assembly_admin, assembly: assembly) }
29
+
30
+ subject { controller.filtered_collection }
31
+
32
+ context "when not filtering" do
33
+ it "lists all kind of admin users" do
34
+ get :index, params: {}
35
+
36
+ expect(subject).to include(admin_user, department_admin_user, user_manager, assembly_admin, process_admin)
37
+ expect(subject).not_to include(participant)
38
+ expect(response).to render_template(:index)
39
+ end
40
+ end
41
+
42
+ context "when filtering by process admin email in user term" do
43
+ it "lists the process admin user" do
44
+ get :index, params: { q: { name_or_nickname_or_email_cont: process_admin.email.split("@").first } }
45
+
46
+ expect(subject).to include(process_admin)
47
+ expect(subject).not_to include(admin_user, department_admin_user, user_manager, assembly_admin, participant)
48
+ expect(response).to render_template(:index)
49
+ end
50
+ end
51
+
52
+ context "when filtering by space name" do
53
+ it "lists the space_admins in spaces matching the given term" do
54
+ get :index, params: { q: { name_or_nickname_or_email_cont: "space" }, filter_search: "by_process_name" }
55
+
56
+ expect(subject).to include(process_admin, assembly_admin)
57
+ expect(subject).not_to include(admin_user, department_admin_user, user_manager, participant)
58
+ expect(response).to render_template(:index)
59
+ end
60
+ end
61
+
62
+ context "when filtering by admin role" do
63
+ let(:params) do
64
+ { role: "admin" }
65
+ end
66
+
67
+ it "lists only users with role admin" do
68
+ get :index, params: params
69
+
70
+ expect(subject).to include(admin_user)
71
+ expect(subject).not_to include(department_admin_user, user_manager, process_admin, assembly_admin, participant)
72
+ expect(response).to render_template(:index)
73
+ end
74
+ end
75
+
76
+ context "when filtering by department_admin role" do
77
+ let(:params) do
78
+ { role: "department_admin" }
79
+ end
80
+
81
+ it "lists only users with role department_admin" do
82
+ get :index, params: params
83
+
84
+ expect(subject).to include(department_admin_user)
85
+ expect(subject).not_to include(admin_user, user_manager, process_admin, assembly_admin, participant)
86
+ expect(response).to render_template(:index)
87
+ end
88
+ end
89
+
90
+ context "when filtering by user_manager role" do
91
+ let(:params) do
92
+ { role: "user_manager" }
93
+ end
94
+
95
+ it "lists only users with role user_manager" do
96
+ get :index, params: params
97
+
98
+ expect(subject).to include(user_manager)
99
+ expect(subject).not_to include(admin_user, department_admin_user, process_admin, assembly_admin, participant)
100
+ expect(response).to render_template(:index)
101
+ end
102
+ end
103
+
104
+ context "when filtering by space_admin role" do
105
+ let(:params) do
106
+ { role: "space_admin" }
107
+ end
108
+
109
+ it "lists only users with role space_admin" do
110
+ get :index, params: params
111
+
112
+ expect(subject).to include(process_admin, assembly_admin)
113
+ expect(subject).not_to include(admin_user, department_admin_user, user_manager, participant)
114
+ expect(response).to render_template(:index)
115
+ end
116
+ end
117
+ end
118
+ end
119
+ end
data/spec/factories.rb ADDED
@@ -0,0 +1,4 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "decidim/department_admin/test/factories"
4
+ require "decidim/conferences/test/factories"
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
4
+
5
+ RSpec.describe "Overrides" do
6
+ it "check failing tests in Decidim v0.28" do
7
+ # Make test succeed spec/system/department_admin_should_be_able_to_manage_assemblies_spec.rbL73
8
+ # expect(page).to have_current_path decidim_admin_assemblies.assemblies_path(q: { parent_id_eq: parent_assembly&.id })
9
+ expect(Decidim.version).to be < "0.28"
10
+ end
11
+ end
data/spec/i18n_spec.rb ADDED
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "i18n/tasks"
4
+
5
+ RSpec.describe "I18n" do
6
+ let(:i18n) { I18n::Tasks::BaseTask.new }
7
+ let(:missing_keys) { i18n.missing_keys }
8
+ let(:unused_keys) { i18n.unused_keys }
9
+
10
+ # All keys from overriding templates come from Decidim so we're having many false positives
11
+ # Probably it will be best tot remove this spec rather than having all keys ignored.
12
+ # it "does not have missing keys" do
13
+ # expect(missing_keys).to be_empty,
14
+ # "Missing #{missing_keys.leaves.count} i18n keys, run `i18n-tasks missing' to show them"
15
+ # end
16
+
17
+ it "does not have unused keys" do
18
+ expect(unused_keys).to be_empty,
19
+ "#{unused_keys.leaves.count} unused i18n keys, run `i18n-tasks unused' to show them"
20
+ end
21
+
22
+ it "files are normalized" do
23
+ non_normalized = i18n.non_normalized_paths
24
+ error_message = "The following files need to be normalized:\n" \
25
+ "#{non_normalized.map { |path| " #{path}" }.join("\n")}\n" \
26
+ "Please run `i18n-tasks normalize` to fix"
27
+ expect(non_normalized).to be_empty, error_message
28
+ end
29
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
4
+
5
+ module Decidim
6
+ describe Area do
7
+ subject(:area) { create(:area) }
8
+
9
+ context "when depending participatory process exist" do
10
+ let!(:department_admin) do
11
+ user = create(:user, :confirmed, organization: area.organization)
12
+ user.roles << "department_admin"
13
+ user.areas << area
14
+ user.save!
15
+ user
16
+ end
17
+
18
+ it "can not be deleted" do
19
+ expect(area.destroy).to be false
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,120 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
4
+
5
+ module Decidim
6
+ module DepartmentAdmin
7
+ describe Permissions do
8
+ let(:area) { create(:area) }
9
+ let!(:user) do
10
+ create(:department_admin, :confirmed, organization: area.organization, area: area)
11
+ end
12
+
13
+ def should_allow_action(scope, action, subject)
14
+ action = PermissionAction.new(scope: scope, action: action, subject: subject)
15
+ permissions = DepartmentAdmin::Permissions.new(user, action)
16
+ expect(permissions.permissions).to be_allowed
17
+ end
18
+
19
+ def should_allow_action_with_ctx(scope, action, subject, ctx)
20
+ action = PermissionAction.new(scope: scope, action: action, subject: subject)
21
+ permissions = DepartmentAdmin::Permissions.new(user, action, ctx)
22
+ expect(permissions.permissions).to be_allowed
23
+ end
24
+
25
+ context "when user role is department_admin" do
26
+ context "with simple permission actions" do
27
+ it "allows accepted actions" do
28
+ should_allow_action(:admin, :read, :admin_dashboard)
29
+ should_allow_action(:admin, :read, :process_list)
30
+ should_allow_action(:admin, :create, :process)
31
+ should_allow_action(:admin, :read, :process_step)
32
+ should_allow_action(:admin, :create, :process_step)
33
+ should_allow_action(:admin, :read, :assembly_list)
34
+ should_allow_action(:admin, :read, :assembly_user_role)
35
+ should_allow_action(:admin, :create, :assembly)
36
+ should_allow_action(:admin, :index, :newsletter)
37
+ should_allow_action(:admin, :create, :newsletter)
38
+ should_allow_action(:admin, :create, :attachment_collection)
39
+ should_allow_action(:admin, :read, :conference_list)
40
+ should_allow_action(:admin, :read, :conference_user_role)
41
+ should_allow_action(:admin, :create, :conference)
42
+ end
43
+
44
+ it "does not allow non accepted actions" do
45
+ action = PermissionAction.new(scope: :admin, action: :write, subject: :admin_dashboard)
46
+ permissions = DepartmentAdmin::Permissions.new(user, action)
47
+ expect { permissions.permissions.allowed? }.to raise_error(Decidim::PermissionAction::PermissionNotSetError)
48
+ end
49
+ end
50
+
51
+ context "with permission actions with context" do
52
+ context "when acction is allowed and context is space_name" do
53
+ it "allows accepted actions with expected context" do
54
+ should_allow_action_with_ctx(:admin, :enter, :space_area, space_name: :processes)
55
+ should_allow_action_with_ctx(:admin, :enter, :space_area, space_name: :assemblies)
56
+ should_allow_action_with_ctx(:admin, :enter, :space_area, space_name: :conferences)
57
+ end
58
+
59
+ it "does not allow accepted actions with unexpected context" do
60
+ action = PermissionAction.new(scope: :admin, action: :enter, subject: :space_area)
61
+ permissions = DepartmentAdmin::Permissions.new(user, action, space_name: :custom_module)
62
+ expect { permissions.permissions.allowed? }.to raise_error(Decidim::PermissionAction::PermissionNotSetError)
63
+ end
64
+ end
65
+
66
+ context "when acction is allowed and context is process" do
67
+ context "when process has same area as department_admin" do
68
+ let(:process) { create(:participatory_process, organization: area.organization, area: area) }
69
+ let(:assembly) { create(:assembly, organization: area.organization, area: area) }
70
+ let(:conference) { create(:conference, organization: area.organization, area: area) }
71
+
72
+ it "allows accepted actions with expected context" do
73
+ should_allow_action_with_ctx(:admin, :read, :participatory_space, current_participatory_space: process)
74
+ should_allow_action_with_ctx(:admin, :update, :process, process: process)
75
+ pps = ParticipatoryProcessStep.new(participatory_process: process)
76
+ should_allow_action_with_ctx(:admin, :update, :process_step, process_step: pps)
77
+ should_allow_action_with_ctx(:admin, :destroy, :process_step, process_step: pps)
78
+ should_allow_action_with_ctx(:admin, :update, :assembly, assembly: assembly)
79
+ should_allow_action_with_ctx(:admin, :update, :conference, conference: conference)
80
+ # -> {permission_for?(requested_action, :admin, :read, :newsletter, restricted_rsrc: context[:newsletter])},
81
+ end
82
+
83
+ context "when meeting has same area as department_admin" do
84
+ let(:meeting) { create(:meeing, participatory_space: process, area: area) }
85
+
86
+ it "allows accepted actions with expected context" do
87
+ should_allow_action(:admin, :create, :attachment)
88
+ end
89
+ end
90
+ end
91
+
92
+ context "when process has different area as department_admin" do
93
+ let(:process) { create(:participatory_process, organization: area.organization) }
94
+
95
+ it "does not allow accepted actions with unexpected context" do
96
+ action = PermissionAction.new(scope: :admin, action: :update, subject: :process)
97
+ permissions = DepartmentAdmin::Permissions.new(user, action, process: process)
98
+ expect { permissions.permissions.allowed? }.to raise_error(Decidim::PermissionAction::PermissionNotSetError)
99
+ end
100
+ end
101
+ end
102
+
103
+ # context "when acction is allowed and context is component" do
104
+ # context "when component has same area as department_admin" do
105
+ # TODO: complete the test implementation
106
+ # let(:process) { create(:participatory_process, organization: area.organization, area: area) }
107
+ # let(:component) { create(:survey, participatory_space: process) }
108
+
109
+ # it "should allow accepted actions" # do
110
+ # should_allow_action(:admin, :read, :component)
111
+ # should_allow_action(:admin, :create, :component)
112
+ # should_allow_action_with_ctx(:admin, :export, :component_data, current_participatory_space: process)
113
+ # end
114
+ # end
115
+ # end
116
+ end
117
+ end
118
+ end
119
+ end
120
+ end
@@ -0,0 +1,52 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
4
+
5
+ module Decidim::Assemblies
6
+ describe ParentAssembliesForSelect do
7
+ subject { described_class.for(organization, assembly) }
8
+
9
+ let(:organization) { create(:organization) }
10
+ let!(:assembly) { create(:assembly, organization: organization) }
11
+ let!(:assemblies) { create_list(:assembly, 3, organization: organization) }
12
+ let!(:child_assembly) { create(:assembly, :with_parent, parent: assembly, organization: organization) }
13
+ let!(:grand_child_assembly) { create(:assembly, :with_parent, parent: child_assembly, organization: organization) }
14
+
15
+ describe "query" do
16
+ context "when current_user is nil" do
17
+ it "returns assemblies that can be parent" do
18
+ expect(subject.count).to eq(3)
19
+ expect(subject).to match_array(assemblies)
20
+ end
21
+ end
22
+
23
+ context "when current_user is present" do
24
+ subject { described_class.for(organization, assembly, current_user) }
25
+
26
+ let!(:current_user) do
27
+ create(:department_admin, :confirmed, organization: area.organization, area: area)
28
+ end
29
+ let(:area) { create(:area) }
30
+ let!(:assemblies_with_area) { create_list(:assembly, 3, organization: organization, area: area) }
31
+
32
+ it "returns assemblies that can be parent with same current user area" do
33
+ expect(subject.count).to eq(3)
34
+ expect(subject).to match_array(assemblies_with_area)
35
+ end
36
+ end
37
+
38
+ context "when assembly is nil" do
39
+ let(:assembly) { nil }
40
+
41
+ it "returns all assemblies" do
42
+ expected = assemblies
43
+ expected << child_assembly
44
+ expected << grand_child_assembly
45
+
46
+ expect(subject.count).to eq(5)
47
+ expect(subject).to match_array(expected)
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "decidim/dev"
4
+
5
+ ENV["ENGINE_ROOT"] = File.dirname(__dir__)
6
+
7
+ # require "decidim/admin"
8
+ # require "decidim/core"
9
+ # require "decidim/core/test"
10
+
11
+ Decidim::Dev.dummy_app_path = File.expand_path(File.join("spec", "decidim_dummy_app"))
12
+
13
+ require "decidim/dev/test/base_spec_helper"
14
+
15
+ require "decidim/department_admin"
16
+
17
+ if ENV["SIMPLECOV"]
18
+ require "simplecov"
19
+ SimpleCov.start do
20
+ # `ENGINE_ROOT` holds the name of the engine we're testing.
21
+ # This brings us to the main Decidim folder.
22
+ root File.expand_path(".", ENV.fetch("ENGINE_ROOT", nil))
23
+
24
+ # We make sure we track all Ruby files, to avoid skipping unrequired files
25
+ # We need to include the `../` section, otherwise it only tracks files from the
26
+ # `ENGINE_ROOT` folder for some reason.
27
+ # track_files "../**/*.rb"
28
+
29
+ # We ignore some of the files because they are never tested
30
+ add_filter "/config/"
31
+ add_filter "/db/"
32
+ add_filter "/vendor/"
33
+ add_filter "/spec/"
34
+ add_filter "/test/"
35
+ add_filter %r{^/decidim-[^/]*/lib/decidim/[^/]*/engine.rb}
36
+ add_filter %r{^/decidim-[^/]*/lib/decidim/[^/]*/admin-engine.rb}
37
+ add_filter %r{^/decidim-[^/]*/lib/decidim/[^/]*/component.rb}
38
+ add_filter %r{^/decidim-[^/]*/lib/decidim/[^/]*/participatory_space.rb}
39
+ end
40
+
41
+ SimpleCov.merge_timeout 1800
42
+
43
+ if ENV["CI"]
44
+ require "simplecov-cobertura"
45
+ SimpleCov.formatter = SimpleCov::Formatter::CoberturaFormatter
46
+ end
47
+ end
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
4
+
5
+ describe "Admin explores processes", type: :system do
6
+ let(:organization) { create(:organization) }
7
+ let!(:area) { create(:area, organization: organization) }
8
+ let!(:process) { create(:participatory_process, organization: organization, area: area) }
9
+
10
+ let!(:admin) { create(:user, :admin, :confirmed, organization: organization) }
11
+
12
+ before do
13
+ switch_to_host(organization.host)
14
+ login_as admin, scope: :user
15
+ end
16
+
17
+ describe "when there are admins of all types" do
18
+ let!(:department_admin) do
19
+ user = create(:user, :confirmed, organization: organization)
20
+ user.roles << "department_admin"
21
+ user.areas << area
22
+ user.save!
23
+ user
24
+ end
25
+
26
+ context "when visiting the list of participatory processes" do
27
+ before do
28
+ visit decidim_admin_participatory_processes.participatory_processes_path
29
+ end
30
+
31
+ it "renders a new column for the process department (aka area)" do
32
+ check_column_header_exists(position: 2, content: "Department/Area")
33
+ check_column_data_exists(position: 2, content: area.name["en"])
34
+ check_column_data_exists(position: 3, content: department_admin.name)
35
+ end
36
+
37
+ it "renders a new column for the department admins in the process"
38
+ it "renders a new column for the process admins in the process"
39
+ end
40
+ end
41
+
42
+ def check_column_header_exists(position: 1, content: "")
43
+ within "#processes .card-section .table-scroll table thead th:nth-child(#{position})" do
44
+ expect(page).to have_content(content)
45
+ end
46
+ end
47
+
48
+ def check_column_data_exists(position: 1, content: "")
49
+ within "#processes .card-section .table-scroll table tbody td:nth-child(#{position})" do
50
+ expect(page).to have_content(content)
51
+ end
52
+ end
53
+ end