decidim 0.0.4 → 0.0.5

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of decidim might be problematic. Click here for more details.

Files changed (216) hide show
  1. checksums.yaml +4 -4
  2. data/.eslintrc.json +2 -5
  3. data/.mention-bot +2 -1
  4. data/.yardopts +8 -0
  5. data/Gemfile.lock +64 -62
  6. data/README.md +11 -9
  7. data/decidim-admin/app/assets/javascripts/decidim/admin/sort_steps.js.es6 +3 -3
  8. data/decidim-admin/app/assets/stylesheets/decidim/admin/_email_preview.scss +5 -0
  9. data/decidim-admin/app/assets/stylesheets/decidim/admin/application.scss +1 -0
  10. data/decidim-admin/app/commands/decidim/admin/create_newsletter.rb +30 -0
  11. data/decidim-admin/app/commands/decidim/admin/deliver_newsletter.rb +29 -0
  12. data/decidim-admin/app/commands/decidim/admin/destroy_participatory_process_step.rb +9 -0
  13. data/decidim-admin/app/commands/decidim/admin/update_newsletter.rb +33 -0
  14. data/decidim-admin/app/constraints/decidim/admin/organization_dashboard_constraint.rb +1 -1
  15. data/decidim-admin/app/controllers/decidim/admin/features_controller.rb +2 -2
  16. data/decidim-admin/app/controllers/decidim/admin/newsletters_controller.rb +115 -0
  17. data/decidim-admin/app/controllers/decidim/admin/participatory_processes_controller.rb +4 -4
  18. data/decidim-admin/app/forms/decidim/admin/newsletter_form.rb +15 -0
  19. data/decidim-admin/app/jobs/decidim/admin/newsletter_delivery_job.rb +18 -0
  20. data/decidim-admin/app/jobs/decidim/admin/newsletter_job.rb +32 -0
  21. data/decidim-admin/app/models/decidim/admin/abilities/admin_user.rb +4 -0
  22. data/decidim-admin/app/models/decidim/admin/abilities/base.rb +4 -0
  23. data/decidim-admin/app/models/decidim/admin/abilities/collaborator_user.rb +19 -0
  24. data/decidim-admin/app/models/decidim/admin/abilities/participatory_process_admin.rb +1 -1
  25. data/decidim-admin/app/queries/decidim/admin/manageable_participatory_processes_for_user.rb +1 -1
  26. data/decidim-admin/app/views/decidim/admin/newsletters/_form.html.erb +5 -0
  27. data/decidim-admin/app/views/decidim/admin/newsletters/edit.html.erb +11 -0
  28. data/decidim-admin/app/views/decidim/admin/newsletters/index.html.erb +47 -0
  29. data/decidim-admin/app/views/decidim/admin/newsletters/new.html.erb +11 -0
  30. data/decidim-admin/app/views/decidim/admin/newsletters/show.html.erb +14 -0
  31. data/decidim-admin/app/views/decidim/admin/participatory_process_steps/_form.html.erb +1 -1
  32. data/decidim-admin/app/views/decidim/admin/participatory_processes/_form.html.erb +1 -1
  33. data/decidim-admin/app/views/decidim/admin/static_pages/_form.html.erb +1 -1
  34. data/decidim-admin/app/views/layouts/decidim/admin/_sidebar.html.erb +1 -0
  35. data/decidim-admin/config/locales/ca.yml +40 -0
  36. data/decidim-admin/config/locales/en.yml +40 -0
  37. data/decidim-admin/config/locales/es.yml +40 -0
  38. data/decidim-admin/config/routes.rb +7 -0
  39. data/decidim-admin/decidim-admin.gemspec +0 -1
  40. data/decidim-admin/lib/decidim/admin/engine.rb +1 -0
  41. data/decidim-admin/lib/decidim/admin/features/base_controller.rb +5 -1
  42. data/decidim-admin/spec/commands/create_newsletter_spec.rb +62 -0
  43. data/decidim-admin/spec/commands/deliver_newsletter_spec.rb +45 -0
  44. data/decidim-admin/spec/commands/destroy_participatory_process_step_spec.rb +12 -0
  45. data/decidim-admin/spec/commands/update_newsletter_spec.rb +64 -0
  46. data/decidim-admin/spec/features/admin_manages_newsletters_spec.rb +147 -0
  47. data/decidim-admin/spec/features/admin_manages_participatory_processes_spec.rb +1 -5
  48. data/decidim-admin/spec/features/static_pages_spec.rb +16 -0
  49. data/decidim-admin/spec/forms/newsletter_form_spec.rb +47 -0
  50. data/decidim-admin/spec/jobs/newsletter_delivery_job_spec.rb +25 -0
  51. data/decidim-admin/spec/jobs/newsletter_job_spec.rb +29 -0
  52. data/decidim-admin/spec/models/abilities/collaborator_user_spec.rb +66 -0
  53. data/decidim-admin/spec/organization_dashboard_constraint_spec.rb +55 -0
  54. data/decidim-admin/spec/queries/manageable_participatory_processes_for_user_spec.rb +8 -0
  55. data/decidim-admin/spec/shared/manage_processes_examples.rb +1 -5
  56. data/decidim-api/lib/decidim/api.rb +2 -7
  57. data/decidim-api/lib/decidim/api/{types/mutation.rb → mutation_type.rb} +0 -0
  58. data/decidim-api/lib/decidim/api/{types/query.rb → query_type.rb} +0 -0
  59. data/decidim-budgets/app/assets/javascripts/decidim/budgets/projects.js.es6 +4 -4
  60. data/decidim-budgets/app/commands/decidim/budgets/add_line_item.rb +4 -2
  61. data/decidim-budgets/app/commands/decidim/budgets/checkout.rb +7 -3
  62. data/decidim-budgets/app/models/decidim/budgets/order.rb +16 -1
  63. data/decidim-budgets/app/models/decidim/budgets/project.rb +16 -0
  64. data/decidim-budgets/app/views/decidim/budgets/line_items/update_budget.js.erb +7 -7
  65. data/decidim-budgets/app/views/decidim/budgets/projects/_budget_confirm.html.erb +27 -25
  66. data/decidim-budgets/app/views/decidim/budgets/projects/_budget_summary.html.erb +4 -13
  67. data/decidim-budgets/app/views/decidim/budgets/projects/_order_progress.html.erb +23 -21
  68. data/decidim-budgets/app/views/decidim/budgets/projects/_order_selected_projects.html.erb +25 -23
  69. data/decidim-budgets/app/views/decidim/budgets/projects/_order_total_budget.html.erb +3 -1
  70. data/decidim-budgets/app/views/decidim/budgets/projects/_project.html.erb +32 -30
  71. data/decidim-budgets/app/views/decidim/budgets/projects/_projects.html.erb +1 -3
  72. data/decidim-budgets/app/views/decidim/budgets/projects/index.html.erb +0 -4
  73. data/decidim-budgets/app/views/decidim/budgets/projects/show.html.erb +5 -6
  74. data/decidim-budgets/config/i18n-tasks.yml +1 -0
  75. data/decidim-budgets/config/locales/ca.yml +7 -2
  76. data/decidim-budgets/config/locales/en.yml +17 -6
  77. data/decidim-budgets/config/locales/es.yml +7 -2
  78. data/decidim-budgets/lib/decidim/budgets/feature.rb +2 -2
  79. data/decidim-budgets/spec/commands/add_line_item_spec.rb +16 -3
  80. data/decidim-budgets/spec/commands/cancel_order_spec.rb +7 -1
  81. data/decidim-budgets/spec/commands/checkout_spec.rb +9 -2
  82. data/decidim-budgets/spec/commands/remove_line_item_spec.rb +16 -5
  83. data/decidim-budgets/spec/features/orders_spec.rb +8 -2
  84. data/decidim-budgets/spec/models/order_spec.rb +31 -2
  85. data/decidim-budgets/spec/shared/admin_shared_context.rb +1 -1
  86. data/decidim-comments/README.md +1 -1
  87. data/decidim-comments/app/assets/javascripts/decidim/comments/bundle.js +0 -0
  88. data/decidim-comments/app/frontend/comments/add_comment_form.component.jsx +156 -93
  89. data/decidim-comments/app/frontend/comments/add_comment_form.component.test.jsx +36 -23
  90. data/decidim-comments/app/frontend/comments/add_comment_form.mutation.graphql +5 -3
  91. data/decidim-comments/app/frontend/comments/add_comment_form_commentable.fragment.graphql +4 -0
  92. data/decidim-comments/app/frontend/comments/add_comment_form_session.fragment.graphql +6 -0
  93. data/decidim-comments/app/frontend/comments/comment.component.jsx +11 -13
  94. data/decidim-comments/app/frontend/comments/comment.component.test.jsx +22 -21
  95. data/decidim-comments/app/frontend/comments/comment.fragment.graphql +4 -4
  96. data/decidim-comments/app/frontend/comments/comment_data.fragment.graphql +4 -3
  97. data/decidim-comments/app/frontend/comments/comment_order_selector.component.jsx +1 -1
  98. data/decidim-comments/app/frontend/comments/comment_thread.component.jsx +3 -3
  99. data/decidim-comments/app/frontend/comments/comment_thread.component.test.jsx +3 -3
  100. data/decidim-comments/app/frontend/comments/comment_thread.fragment.graphql +1 -1
  101. data/decidim-comments/app/frontend/comments/comments.component.jsx +47 -39
  102. data/decidim-comments/app/frontend/comments/comments.component.test.jsx +51 -38
  103. data/decidim-comments/app/frontend/comments/comments.query.graphql +10 -4
  104. data/decidim-comments/app/frontend/comments/down_vote_button.component.jsx +6 -3
  105. data/decidim-comments/app/frontend/comments/up_vote_button.component.jsx +7 -4
  106. data/decidim-comments/app/frontend/support/generate_comments_data.js +4 -4
  107. data/decidim-comments/app/models/decidim/comments/comment.rb +7 -9
  108. data/decidim-comments/app/queries/decidim/comments/{comments_with_replies.rb → sorted_comments.rb} +3 -8
  109. data/decidim-comments/app/types/decidim/comments/commentable_interface.rb +44 -0
  110. data/decidim-comments/app/types/decidim/comments/commentable_mutation_type.rb +29 -0
  111. data/decidim-comments/app/types/decidim/comments/commentable_type.rb +14 -0
  112. data/decidim-comments/config/locales/ca.yml +3 -1
  113. data/decidim-comments/config/locales/en.yml +5 -2
  114. data/decidim-comments/config/locales/es.yml +3 -1
  115. data/decidim-comments/lib/decidim/comments.rb +4 -0
  116. data/decidim-comments/{app/types/decidim/comments → lib/decidim/comments/api}/add_comment_type.rb +0 -0
  117. data/decidim-comments/{app/types/decidim/comments → lib/decidim/comments/api}/comment_mutation_type.rb +0 -0
  118. data/decidim-comments/{app/types/decidim/comments → lib/decidim/comments/api}/comment_type.rb +11 -17
  119. data/decidim-comments/lib/decidim/comments/commentable.rb +45 -0
  120. data/decidim-comments/lib/decidim/comments/comments_helper.rb +15 -10
  121. data/decidim-comments/lib/decidim/comments/mutation_extensions.rb +8 -16
  122. data/decidim-comments/lib/decidim/comments/query_extensions.rb +5 -8
  123. data/decidim-comments/lib/decidim/comments/test/factories.rb +3 -3
  124. data/decidim-comments/spec/commands/vote_comment_spec.rb +3 -1
  125. data/decidim-comments/spec/features/comments_spec.rb +28 -14
  126. data/decidim-comments/spec/features/notifications_spec.rb +1 -1
  127. data/decidim-comments/spec/helpers/comments_helper_spec.rb +4 -27
  128. data/decidim-comments/spec/models/comment_spec.rb +7 -11
  129. data/decidim-comments/spec/models/comment_vote_spec.rb +3 -1
  130. data/decidim-comments/spec/models/seed_spec.rb +3 -4
  131. data/decidim-comments/spec/queries/{comments_with_replies_spec.rb → sorted_comments_spec.rb} +12 -29
  132. data/decidim-comments/spec/types/comment_type_spec.rb +23 -17
  133. data/decidim-comments/spec/types/commentable_mutation_type_spec.rb +34 -0
  134. data/decidim-comments/spec/types/commentable_type_spec.rb +48 -0
  135. data/decidim-comments/spec/types/mutation_type_spec.rb +5 -22
  136. data/decidim-comments/spec/types/query_type_spec.rb +0 -24
  137. data/decidim-dev/config/i18n-tasks.yml +4 -0
  138. data/decidim-dev/decidim-dev.gemspec +1 -1
  139. data/decidim-dev/lib/decidim/dev/test/rspec_support/action_mailer.rb +10 -4
  140. data/decidim-dev/lib/decidim/dev/test/rspec_support/feature.rb +6 -5
  141. data/decidim-dev/lib/decidim/dev/test/rspec_support/i18n.rb +0 -1
  142. data/decidim-meetings/app/assets/javascripts/decidim/meetings/map.js.es6.erb +8 -3
  143. data/decidim-meetings/app/assets/stylesheets/decidim/meetings/map.css +3 -1
  144. data/decidim-meetings/app/controllers/decidim/meetings/meetings_controller.rb +2 -2
  145. data/decidim-meetings/app/forms/decidim/meetings/admin/close_meeting_form.rb +2 -1
  146. data/decidim-meetings/app/helpers/decidim/meetings/map_helper.rb +1 -0
  147. data/decidim-meetings/app/services/decidim/meetings/meeting_search.rb +7 -3
  148. data/decidim-meetings/app/views/decidim/meetings/meetings/_datetime.html.erb +1 -1
  149. data/decidim-meetings/app/views/decidim/meetings/meetings/_filters.html.erb +5 -5
  150. data/decidim-meetings/app/views/decidim/meetings/meetings/_linked_meetings.html.erb +1 -1
  151. data/decidim-meetings/app/views/decidim/meetings/meetings/index.html.erb +1 -5
  152. data/decidim-meetings/app/views/decidim/meetings/meetings/show.html.erb +16 -9
  153. data/decidim-meetings/config/locales/ca.yml +2 -3
  154. data/decidim-meetings/config/locales/en.yml +2 -3
  155. data/decidim-meetings/config/locales/es.yml +2 -3
  156. data/decidim-meetings/spec/features/explore_meetings_spec.rb +75 -24
  157. data/decidim-meetings/spec/forms/close_meeting_form_spec.rb +1 -1
  158. data/decidim-meetings/spec/services/meeting_search_spec.rb +15 -12
  159. data/decidim-meetings/vendor/assets/javascripts/leaflet.markercluster.js +7 -0
  160. data/decidim-meetings/vendor/assets/stylesheets/MarkerCluster.Default.css +60 -0
  161. data/decidim-meetings/vendor/assets/stylesheets/MarkerCluster.css +14 -0
  162. data/decidim-pages/app/models/decidim/pages/page.rb +22 -0
  163. data/decidim-pages/app/views/decidim/pages/application/show.html.erb +2 -6
  164. data/decidim-pages/config/locales/ca.yml +2 -2
  165. data/decidim-pages/config/locales/en.yml +2 -2
  166. data/decidim-pages/config/locales/es.yml +2 -2
  167. data/decidim-pages/lib/decidim/pages/feature.rb +2 -2
  168. data/decidim-pages/spec/features/page_show_spec.rb +0 -33
  169. data/decidim-proposals/app/controllers/decidim/proposals/admin/proposal_answers_controller.rb +2 -0
  170. data/decidim-proposals/app/controllers/decidim/proposals/admin/proposals_controller.rb +2 -0
  171. data/decidim-proposals/app/models/decidim/proposals/abilities/admin_user.rb +45 -0
  172. data/decidim-proposals/app/models/decidim/proposals/abilities/process_admin_user.rb +57 -0
  173. data/decidim-proposals/app/models/decidim/proposals/proposal.rb +21 -0
  174. data/decidim-proposals/app/views/decidim/proposals/admin/proposals/_form.html.erb +1 -1
  175. data/decidim-proposals/app/views/decidim/proposals/admin/proposals/index.html.erb +16 -10
  176. data/decidim-proposals/app/views/decidim/proposals/proposal_votes/update_buttons_and_counters.js.erb +4 -4
  177. data/decidim-proposals/app/views/decidim/proposals/proposals/_filters.html.erb +7 -3
  178. data/decidim-proposals/app/views/decidim/proposals/proposals/_proposal.html.erb +2 -6
  179. data/decidim-proposals/app/views/decidim/proposals/proposals/_remaining_votes_count.html.erb +3 -1
  180. data/decidim-proposals/app/views/decidim/proposals/proposals/_tags.html.erb +1 -1
  181. data/decidim-proposals/app/views/decidim/proposals/proposals/_vote_button.html.erb +23 -21
  182. data/decidim-proposals/app/views/decidim/proposals/proposals/_votes_count.html.erb +9 -6
  183. data/decidim-proposals/app/views/decidim/proposals/proposals/_votes_limit.html.erb +1 -3
  184. data/decidim-proposals/app/views/decidim/proposals/proposals/index.html.erb +0 -4
  185. data/decidim-proposals/app/views/decidim/proposals/proposals/new.html.erb +1 -1
  186. data/decidim-proposals/app/views/decidim/proposals/proposals/show.html.erb +2 -6
  187. data/decidim-proposals/config/locales/ca.yml +8 -1
  188. data/decidim-proposals/config/locales/en.yml +8 -1
  189. data/decidim-proposals/config/locales/es.yml +8 -1
  190. data/decidim-proposals/lib/decidim/proposals/admin_engine.rb +7 -0
  191. data/decidim-proposals/lib/decidim/proposals/feature.rb +6 -2
  192. data/decidim-proposals/spec/features/proposals_spec.rb +226 -40
  193. data/decidim-proposals/spec/models/decidim/proposals/abilities/admin_user_spec.rb +62 -0
  194. data/decidim-proposals/spec/models/decidim/proposals/abilities/process_admin_user_spec.rb +63 -0
  195. data/decidim-proposals/spec/shared/manage_proposals_examples.rb +161 -50
  196. data/decidim-results/app/models/decidim/results/result.rb +21 -0
  197. data/decidim-results/app/views/decidim/results/results/index.html.erb +0 -4
  198. data/decidim-results/app/views/decidim/results/results/show.html.erb +2 -8
  199. data/decidim-results/config/i18n-tasks.yml +1 -0
  200. data/decidim-results/config/locales/ca.yml +5 -2
  201. data/decidim-results/config/locales/en.yml +5 -2
  202. data/decidim-results/config/locales/es.yml +5 -2
  203. data/decidim-results/lib/decidim/results/feature.rb +2 -2
  204. data/decidim-results/spec/services/result_stats_calculator_spec.rb +2 -2
  205. data/decidim-results/spec/shared/admin_shared_context.rb +1 -1
  206. data/decidim-system/config/i18n-tasks.yml +1 -1
  207. data/package.json +50 -51
  208. data/yarn.lock +198 -151
  209. metadata +69 -36
  210. data/decidim-admin/spec/features/admin_access_control.rb +0 -52
  211. data/decidim-api/lib/decidim/api/types/author_interface.rb +0 -13
  212. data/decidim-api/lib/decidim/api/types/localized_string.rb +0 -13
  213. data/decidim-api/lib/decidim/api/types/translated_field.rb +0 -44
  214. data/decidim-api/spec/types/localized_string_type_spec.rb +0 -31
  215. data/decidim-api/spec/types/translated_field_type_spec.rb +0 -69
  216. data/decidim-comments/app/frontend/comments/add_comment_form.fragment.graphql +0 -6
@@ -0,0 +1,64 @@
1
+ # frozen_string_literal: true
2
+ require "spec_helper"
3
+
4
+ module Decidim
5
+ module Admin
6
+ describe UpdateNewsletter, :db do
7
+ describe "call" do
8
+ let(:user) { create(:user, organization: organization) }
9
+ let(:organization) { create(:organization) }
10
+ let(:newsletter) { create(:newsletter, organization: organization) }
11
+
12
+ let(:form) do
13
+ double(
14
+ subject: Decidim::Faker::Localized.paragraph(3),
15
+ body: Decidim::Faker::Localized.paragraph(3),
16
+ valid?: true
17
+ )
18
+ end
19
+
20
+ let(:command) { described_class.new(newsletter, form, user) }
21
+
22
+ describe "when the form is not valid" do
23
+ before do
24
+ expect(form).to receive(:valid?).and_return(false)
25
+ end
26
+
27
+ it "broadcasts invalid" do
28
+ expect { command.call }.to broadcast(:invalid)
29
+ end
30
+
31
+ it "doesn't create a newsletter" do
32
+ expect do
33
+ command.call
34
+ end.not_to change { newsletter.reload.updated_at }
35
+ end
36
+ end
37
+
38
+ describe "when the newsletter can't be edited by this user" do
39
+ let(:user) { create(:user) }
40
+
41
+ it "broadcasts invalid" do
42
+ expect { command.call }.to broadcast(:invalid)
43
+ end
44
+ end
45
+
46
+ describe "when the form is valid" do
47
+ it "broadcasts ok" do
48
+ expect { command.call }.to broadcast(:ok)
49
+ end
50
+
51
+ it "updates the newsletter" do
52
+ command.call
53
+ newsletter.reload
54
+
55
+ expect(newsletter.author).to eq(user)
56
+ expect(newsletter.subject).to eq(form.subject.stringify_keys)
57
+ expect(newsletter.sent?).to eq(false)
58
+ expect(newsletter.body).to eq(form.body.stringify_keys)
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,147 @@
1
+ # coding: utf-8
2
+ # frozen_string_literal: true
3
+
4
+ require "spec_helper"
5
+
6
+ describe "Admin manages newsletters", type: :feature do
7
+ let(:organization) { create(:organization) }
8
+ let(:user) { create(:user, :admin, :confirmed, name: "Sarah Kerrigan", organization: organization) }
9
+ let!(:deliverable_users) { create_list(:user, 5, newsletter_notifications: true, organization: organization) }
10
+
11
+ before do
12
+ switch_to_host(organization.host)
13
+ login_as user, scope: :user
14
+ end
15
+
16
+ around do |example|
17
+ perform_enqueued_jobs do
18
+ example.run
19
+ end
20
+ end
21
+
22
+ describe "creates and previews a newsletter" do
23
+ it "allows a newsletter to be created" do
24
+ visit decidim_admin.newsletters_path
25
+
26
+ find("#newsletters .actions .new").click
27
+
28
+ within ".new_newsletter" do
29
+ fill_in_i18n(
30
+ :newsletter_subject,
31
+ "#subject-tabs",
32
+ en: "A fancy newsletter for %{name}",
33
+ es: "Un correo electrónico muy chulo para %{name}",
34
+ ca: "Un correu electrònic flipant per a %{name}"
35
+ )
36
+
37
+ fill_in_i18n_editor(
38
+ :newsletter_body,
39
+ "#body-tabs",
40
+ en: "Hello %{name}! Relevant content.",
41
+ es: "Hola, %{name}! Contenido relevante.",
42
+ ca: "Hola, %{name}! Contingut rellevant."
43
+ )
44
+
45
+ find("*[type=submit]").click
46
+ end
47
+
48
+ expect(page).to have_content("Preview")
49
+ expect(page).to have_content("A fancy newsletter for #{user.name}")
50
+ end
51
+ end
52
+
53
+ describe "previews a newsletter" do
54
+ let!(:newsletter) do
55
+ create(:newsletter,
56
+ organization: organization,
57
+ subject: {
58
+ en: "A fancy newsletter for %{name}",
59
+ es: "Un correo electrónico muy chulo para %{name}",
60
+ ca: "Un correu electrònic flipant per a %{name}"
61
+ },
62
+ body: {
63
+ en: "Hello %{name}! Relevant content.",
64
+ es: "Hola, %{name}! Contenido relevante.",
65
+ ca: "Hola, %{name}! Contingut rellevant."
66
+ })
67
+ end
68
+
69
+ it "previews a newsletter" do
70
+ visit decidim_admin.newsletter_path(newsletter)
71
+
72
+ expect(page).to have_content("A fancy newsletter for Sarah Kerrigan")
73
+ expect(page).to have_css("iframe.email-preview[src=\"#{decidim_admin.preview_newsletter_path(newsletter)}\"]")
74
+
75
+ visit decidim_admin.preview_newsletter_path(newsletter)
76
+ expect(page).to have_content("Hello Sarah Kerrigan! Relevant content.")
77
+ end
78
+ end
79
+
80
+ describe "update newsletter" do
81
+ let!(:newsletter) { create(:newsletter, organization: organization)}
82
+
83
+ it "allows a newsletter to be updated" do
84
+ visit decidim_admin.newsletters_path
85
+ within("tr[data-newsletter-id=\"#{newsletter.id}\"]") do
86
+ click_link "Edit"
87
+ end
88
+
89
+ within ".edit_newsletter" do
90
+ fill_in_i18n(
91
+ :newsletter_subject,
92
+ "#subject-tabs",
93
+ en: "A fancy newsletter",
94
+ es: "Un correo electrónico muy chulo",
95
+ ca: "Un correu electrònic flipant"
96
+ )
97
+
98
+ fill_in_i18n_editor(
99
+ :newsletter_body,
100
+ "#body-tabs",
101
+ en: "Relevant content.",
102
+ es: "Contenido relevante.",
103
+ ca: "Contingut rellevant."
104
+ )
105
+
106
+ find("*[type=submit]").click
107
+ end
108
+
109
+ expect(page).to have_content("Preview")
110
+ expect(page).to have_content("A fancy newsletter")
111
+ end
112
+ end
113
+
114
+ describe "deliver a newsletter" do
115
+ let!(:newsletter) { create(:newsletter, organization: organization)}
116
+
117
+ it "allows a newsletter to be created" do
118
+ visit decidim_admin.newsletter_path(newsletter)
119
+
120
+ within ".actions" do
121
+ find("*", text: "Deliver").click
122
+ end
123
+
124
+ expect(page).to have_content("Newsletters")
125
+ expect(page).to have_content("successfully")
126
+
127
+ within ".newsletters tbody" do
128
+ expect(page).to have_content("5 / 5")
129
+ end
130
+ end
131
+ end
132
+
133
+ describe "destroy a newsletter" do
134
+ let!(:newsletter) { create(:newsletter, organization: organization)}
135
+
136
+ it "destroys a newsletter" do
137
+ visit decidim_admin.newsletters_path
138
+
139
+ within("tr[data-newsletter-id=\"#{newsletter.id}\"]") do
140
+ click_link "Destroy"
141
+ end
142
+
143
+ expect(page).to have_content("successfully")
144
+ expect(page).to have_no_css("tr[data-newsletter-id=\"#{newsletter.id}\"]")
145
+ end
146
+ end
147
+ end
@@ -58,12 +58,8 @@ describe "Admin manage participatory processes", type: :feature do
58
58
  expect(page).to have_content("successfully")
59
59
  end
60
60
 
61
- within "table" do
61
+ within ".tabs-content" do
62
62
  expect(page).to have_content("My participatory process")
63
- click_link("My participatory process")
64
- end
65
-
66
- within "dl" do
67
63
  expect(page).to have_css("img[src*='#{image1_filename}']")
68
64
  expect(page).to have_css("img[src*='#{image2_filename}']")
69
65
  end
@@ -11,6 +11,22 @@ describe "Content pages", type: :feature do
11
11
  switch_to_host(organization.host)
12
12
  end
13
13
 
14
+ describe "Showing pages" do
15
+ let!(:decidim_pages) { create_list(:static_page, 5, organization: organization) }
16
+
17
+ before do
18
+ visit decidim.pages_path
19
+ end
20
+
21
+ it "shows the list of all the pages" do
22
+ decidim_pages.each do |decidim_page|
23
+ expect(page).to have_css(
24
+ "a[href=\"#{decidim.page_path(decidim_page)}\"]",
25
+ text: decidim_page.title[I18n.locale.to_s].upcase)
26
+ end
27
+ end
28
+ end
29
+
14
30
  describe "Managing pages" do
15
31
  before do
16
32
  login_as admin, scope: :user
@@ -0,0 +1,47 @@
1
+ # coding: utf-8
2
+ # frozen_string_literal: true
3
+ require "spec_helper"
4
+
5
+ module Decidim
6
+ module Admin
7
+ describe NewsletterForm do
8
+ let(:organization) { create(:organization) }
9
+ let(:newsletter_subject) do
10
+ {
11
+ en: "Subject",
12
+ es: "Asunto",
13
+ ca: "Assumpte"
14
+ }
15
+ end
16
+
17
+ let(:body) do
18
+ {
19
+ en: "Body",
20
+ es: "Cuerpo",
21
+ ca: "Cos"
22
+ }
23
+ end
24
+
25
+ subject do
26
+ described_class.new(subject: newsletter_subject, body: body).
27
+ with_context(current_organization: organization)
28
+ end
29
+
30
+ context "when everything is OK" do
31
+ it { is_expected.to be_valid }
32
+ end
33
+
34
+ context "when there's no subject" do
35
+ let(:newsletter_subject) { nil }
36
+
37
+ it { is_expected.to be_invalid }
38
+ end
39
+
40
+ context "when there's no body" do
41
+ let(:body) { nil }
42
+
43
+ it { is_expected.to be_invalid }
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+ require "spec_helper"
3
+
4
+ module Decidim
5
+ module Admin
6
+ describe NewsletterDeliveryJob do
7
+ let(:user) { create(:user) }
8
+ let(:organization) { create(:organization) }
9
+ let(:newsletter) { create(:newsletter, organization: organization, total_deliveries: 0) }
10
+
11
+ it "delivers a newsletter to a single user" do
12
+ NewsletterDeliveryJob.perform_now(user, newsletter)
13
+
14
+ expect(last_email.subject).to include(newsletter.subject[I18n.locale.to_s])
15
+ expect(last_email.to).to include(user.email)
16
+ end
17
+
18
+ it "increments the delivery count" do
19
+ expect {
20
+ NewsletterDeliveryJob.perform_now(user, newsletter)
21
+ }.to change { newsletter.reload.total_deliveries }.by(1)
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+ require "spec_helper"
3
+
4
+ module Decidim
5
+ module Admin
6
+ describe NewsletterJob do
7
+ let!(:newsletter) { create(:newsletter, organization: organization, total_deliveries: 0) }
8
+ let!(:organization) { create(:organization) }
9
+ let!(:deliverable_user) { create(:user, :confirmed, newsletter_notifications: true, organization: organization) }
10
+ let!(:non_deliverable_user) { create(:user, :confirmed, newsletter_notifications: false, organization: organization) }
11
+
12
+ it "delivers a newsletter to a the eligible users" do
13
+ expect(NewsletterDeliveryJob).to receive(:perform_later).with(deliverable_user, newsletter)
14
+
15
+ NewsletterJob.perform_now(newsletter)
16
+ end
17
+
18
+ it "updates the recipients count" do
19
+ NewsletterJob.perform_now(newsletter)
20
+ expect(newsletter.reload.total_recipients).to eq(1)
21
+ end
22
+
23
+ it "updates the deliveries count" do
24
+ NewsletterJob.perform_now(newsletter)
25
+ expect(newsletter.reload.total_deliveries).to eq(0)
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,66 @@
1
+ # frozen_string_literal: true
2
+ require "spec_helper"
3
+
4
+ describe Decidim::Admin::Abilities::CollaboratorUser do
5
+ let(:user) { build(:user, :collaborator) }
6
+
7
+ subject { described_class.new(user, {}) }
8
+
9
+ context "when the user is not a collaborator" do
10
+ let(:user) { build(:user) }
11
+
12
+ it "doesn't have any permission" do
13
+ expect(subject.permissions[:can]).to be_empty
14
+ expect(subject.permissions[:cannot]).to be_empty
15
+ end
16
+ end
17
+
18
+ it { is_expected.to be_able_to(:preview, Decidim::ParticipatoryProcess) }
19
+
20
+ context "when a page is a default one" do
21
+ let(:page) { build(:static_page, :default) }
22
+ let(:form) { Decidim::Admin::StaticPageForm.new(slug: page.slug) }
23
+
24
+ it { is_expected.not_to be_able_to(:update_slug, page) }
25
+ it { is_expected.not_to be_able_to(:update_slug, form) }
26
+ it { is_expected.not_to be_able_to(:destroy, page) }
27
+ it { is_expected.not_to be_able_to(:destroy, form) }
28
+ end
29
+
30
+ context "when a page is not default one" do
31
+ let(:page) { build(:static_page) }
32
+ let(:form) { Decidim::Admin::StaticPageForm.new(slug: page.slug) }
33
+
34
+ it { is_expected.not_to be_able_to(:update_slug, page) }
35
+ it { is_expected.not_to be_able_to(:update_slug, form) }
36
+ it { is_expected.not_to be_able_to(:destroy, page) }
37
+ it { is_expected.not_to be_able_to(:destroy, form) }
38
+ end
39
+
40
+ context "when the organization is the one they belong to" do
41
+ let(:organization) { user.organization }
42
+
43
+ it { is_expected.not_to be_able_to(:update, organization) }
44
+ it { is_expected.not_to be_able_to(:read, organization) }
45
+ end
46
+
47
+ context "when the organization is different form the one they belong to" do
48
+ let(:organization) { build(:organization) }
49
+
50
+ it { is_expected.not_to be_able_to(:update, organization) }
51
+ it { is_expected.not_to be_able_to(:read, organization) }
52
+ end
53
+
54
+ context "when destroying a user" do
55
+ context "when the user is themselves" do
56
+ let(:user_to_destroy) { user }
57
+ it { is_expected.not_to be_able_to(:destroy, user_to_destroy) }
58
+ end
59
+
60
+ context "when it is another user" do
61
+ let(:user_to_destroy) { build(:user) }
62
+
63
+ it { is_expected.not_to be_able_to(:destroy, user_to_destroy) }
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,55 @@
1
+ # frozen_string_literal: true
2
+ require "spec_helper"
3
+
4
+ module Decidim
5
+ module Admin
6
+ describe OrganizationDashboardConstraint do
7
+ let(:organization) { create(:organization) }
8
+ let(:request) do
9
+ double(
10
+ env: {
11
+ "decidim.current_organization" => organization,
12
+ "warden" => warden
13
+ }
14
+ )
15
+ end
16
+ let(:warden) do
17
+ double(
18
+ authenticate!: authenticated,
19
+ user: user
20
+ )
21
+ end
22
+
23
+ subject { described_class.new(request).matches? }
24
+
25
+ context "when authenticated" do
26
+ let(:authenticated) { true }
27
+
28
+ context "a regular user" do
29
+ let(:user) { create(:user, :confirmed, organization: organization) }
30
+
31
+ it { is_expected.to be_falsey }
32
+ end
33
+
34
+ context "an organization admin" do
35
+ let(:user) { create(:user, :confirmed, :admin, organization: organization) }
36
+ it { is_expected.to be_truthy }
37
+ end
38
+
39
+ context "an admin from another organization" do
40
+ let(:other_organization) { create(:organization) }
41
+ let(:user) { create(:user, :confirmed, :admin, organization: other_organization) }
42
+
43
+ it { is_expected.to be_falsey }
44
+ end
45
+ end
46
+
47
+ describe "when unauthenticated" do
48
+ let(:authenticated) { false }
49
+ let(:user) { nil }
50
+
51
+ it { is_expected.to be_falsey }
52
+ end
53
+ end
54
+ end
55
+ end