decidim-core 0.5.1 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (194) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/config/decidim_core_manifest.js +1 -0
  3. data/app/assets/javascripts/decidim/notifications.js.es6 +33 -0
  4. data/app/assets/stylesheets/decidim/extras/_meeting-registrations.scss +11 -0
  5. data/app/assets/stylesheets/decidim/modules/_extra.scss +4 -0
  6. data/app/assets/stylesheets/decidim/modules/_process-nav.scss +14 -0
  7. data/app/commands/decidim/create_follow.rb +40 -0
  8. data/app/commands/decidim/create_omniauth_registration.rb +0 -2
  9. data/app/commands/decidim/create_registration.rb +1 -3
  10. data/app/commands/decidim/create_report.rb +7 -7
  11. data/app/commands/decidim/delete_follow.rb +37 -0
  12. data/app/commands/decidim/invite_user.rb +1 -3
  13. data/app/commands/decidim/update_notifications_settings.rb +1 -2
  14. data/app/constraints/decidim/current_feature.rb +3 -4
  15. data/app/controllers/concerns/decidim/settings.rb +1 -1
  16. data/app/controllers/decidim/features/base_controller.rb +5 -6
  17. data/app/controllers/decidim/follows_controller.rb +45 -0
  18. data/app/controllers/decidim/notifications_controller.rb +39 -0
  19. data/app/controllers/decidim/pages_controller.rb +2 -2
  20. data/app/controllers/decidim/scopes_controller.rb +2 -0
  21. data/app/controllers/decidim/widgets_controller.rb +3 -3
  22. data/app/forms/decidim/follow_form.rb +20 -0
  23. data/app/forms/decidim/invite_user_form.rb +1 -1
  24. data/app/forms/decidim/notifications_settings_form.rb +2 -4
  25. data/app/helpers/decidim/action_authorization_helper.rb +2 -1
  26. data/app/helpers/decidim/decidim_form_helper.rb +4 -0
  27. data/app/helpers/decidim/feature_path_helper.rb +2 -13
  28. data/app/helpers/decidim/icon_helper.rb +26 -8
  29. data/app/helpers/decidim/paginate_helper.rb +1 -1
  30. data/app/helpers/decidim/scopes_helper.rb +1 -1
  31. data/app/jobs/decidim/email_notification_generator_job.rb +12 -0
  32. data/app/jobs/decidim/export_job.rb +1 -3
  33. data/app/jobs/decidim/notification_generator_for_recipient_job.rb +14 -0
  34. data/app/jobs/decidim/notification_generator_job.rb +12 -0
  35. data/app/mailers/decidim/export_mailer.rb +6 -7
  36. data/app/mailers/decidim/notification_mailer.rb +20 -0
  37. data/app/mailers/decidim/reported_mailer.rb +3 -3
  38. data/app/models/decidim/abilities/admin_ability.rb +0 -1
  39. data/app/models/decidim/abilities/base_ability.rb +8 -0
  40. data/app/models/decidim/abilities/everyone_ability.rb +0 -2
  41. data/app/models/decidim/abilities/participatory_process_admin_ability.rb +1 -1
  42. data/app/models/decidim/abilities/participatory_process_collaborator_ability.rb +1 -1
  43. data/app/models/decidim/category.rb +4 -4
  44. data/app/models/decidim/feature.rb +29 -4
  45. data/app/models/decidim/follow.rb +10 -0
  46. data/app/models/decidim/moderation.rb +1 -1
  47. data/app/models/decidim/notification.rb +12 -0
  48. data/app/models/decidim/scope.rb +8 -8
  49. data/app/models/decidim/user.rb +11 -1
  50. data/app/presenters/decidim/home_stats_presenter.rb +1 -1
  51. data/app/presenters/decidim/resource_locator_presenter.rb +3 -18
  52. data/app/queries/decidim/participatory_processes_with_user_role.rb +1 -1
  53. data/app/services/decidim/email_notification_generator.rb +63 -0
  54. data/app/services/decidim/events_manager.rb +41 -0
  55. data/app/services/decidim/notification_generator.rb +51 -0
  56. data/app/services/decidim/notification_generator_for_recipient.rb +50 -0
  57. data/app/uploaders/decidim/attachment_uploader.rb +1 -1
  58. data/app/views/decidim/authorizations/first_login.html.erb +2 -2
  59. data/app/views/decidim/follows/update_button.js.erb +3 -0
  60. data/app/views/decidim/notification_mailer/event_received.html.erb +9 -0
  61. data/app/views/decidim/notifications/_notification.html.erb +18 -0
  62. data/app/views/decidim/notifications/index.html.erb +32 -0
  63. data/app/views/decidim/notifications_settings/show.html.erb +3 -10
  64. data/app/views/decidim/shared/_follow_button.html.erb +19 -0
  65. data/app/views/layouts/decidim/_head.html.erb +1 -0
  66. data/app/views/layouts/decidim/_head_extra.html.erb +7 -0
  67. data/app/views/layouts/decidim/_user_menu.html.erb +1 -0
  68. data/app/views/layouts/decidim/_wrapper.html.erb +3 -0
  69. data/app/views/layouts/decidim/widget.html.erb +3 -3
  70. data/app/views/pages/home/_hero.html.erb +1 -1
  71. data/app/views/pages/home/_highlighted_processes.html.erb +3 -3
  72. data/config/locales/ca.yml +29 -74
  73. data/config/locales/en.yml +23 -71
  74. data/config/locales/es.yml +31 -78
  75. data/config/locales/eu.yml +61 -65
  76. data/config/locales/fi.yml +91 -51
  77. data/config/locales/fr.yml +40 -83
  78. data/config/locales/it.yml +129 -54
  79. data/config/locales/nl.yml +90 -51
  80. data/config/locales/pl.yml +319 -10
  81. data/config/locales/uk.yml +400 -0
  82. data/config/routes.rb +8 -14
  83. data/db/migrate/20170720120231_make_moderations_polymorphic.rb +29 -0
  84. data/db/migrate/20170726145242_make_categories_polymorphic.rb +27 -0
  85. data/db/migrate/20170807123535_create_decidim_follows.rb +20 -0
  86. data/db/migrate/20170808071019_create_decidim_notifications.rb +13 -0
  87. data/db/migrate/20170906091718_add_extra_to_notifications.rb +7 -0
  88. data/db/migrate/20170912082054_add_emails_on_notifications_flag_to_user.rb +7 -0
  89. data/db/migrate/20170913092351_add_header_snippets_to_organizations.rb +7 -0
  90. data/db/migrate/20170914075721_remove_followable_index_from_follows.rb +7 -0
  91. data/db/migrate/20170914092116_remove_comment_and_replies_notifications_from_users.rb +8 -0
  92. data/db/seeds.rb +2 -108
  93. data/lib/decidim/core.rb +46 -8
  94. data/lib/decidim/core/engine.rb +20 -6
  95. data/lib/decidim/core/test.rb +3 -0
  96. data/lib/decidim/core/test/factories.rb +37 -75
  97. data/lib/decidim/core/test/shared_examples/comments_examples.rb +0 -26
  98. data/lib/decidim/core/test/shared_examples/follows_examples.rb +37 -0
  99. data/lib/decidim/core/test/shared_examples/manage_moderations_examples.rb +1 -1
  100. data/lib/decidim/core/test/shared_examples/process_announcements_examples.rb +1 -1
  101. data/lib/decidim/core/test/shared_examples/reportable.rb +4 -4
  102. data/lib/decidim/core/test/shared_examples/reports_examples.rb +1 -1
  103. data/lib/decidim/core/test/shared_examples/scope_helper_examples.rb +41 -0
  104. data/lib/decidim/core/test/shared_examples/user_localised_email_examples.rb +25 -0
  105. data/lib/decidim/core/version.rb +1 -1
  106. data/lib/decidim/engine_router.rb +54 -0
  107. data/lib/decidim/events.rb +9 -0
  108. data/lib/decidim/events/base_event.rb +70 -0
  109. data/lib/decidim/events/email_event.rb +39 -0
  110. data/lib/decidim/events/notification_event.rb +32 -0
  111. data/lib/decidim/exporters.rb +7 -0
  112. data/lib/decidim/exporters/export_data.rb +14 -0
  113. data/lib/decidim/feature_manifest.rb +2 -2
  114. data/lib/decidim/features/namer.rb +1 -1
  115. data/lib/decidim/followable.rb +13 -0
  116. data/lib/decidim/form_builder.rb +1 -1
  117. data/lib/decidim/has_feature.rb +1 -1
  118. data/lib/decidim/has_settings.rb +19 -15
  119. data/lib/decidim/manifest_registry.rb +1 -3
  120. data/lib/decidim/participable.rb +80 -0
  121. data/lib/decidim/participatory_space_manifest.rb +40 -0
  122. data/lib/decidim/query_extensions.rb +1 -1
  123. data/lib/decidim/resource_manifest.rb +1 -1
  124. data/lib/decidim/settings_manifest.rb +0 -4
  125. data/vendor/assets/javascripts/datepicker-locales/foundation-datepicker.uk.js +14 -0
  126. data/vendor/assets/javascripts/morphdom.js +14 -5
  127. metadata +70 -79
  128. data/app/assets/images/decidim/process.svg +0 -10
  129. data/app/constraints/decidim/current_participatory_process.rb +0 -35
  130. data/app/controllers/concerns/decidim/needs_participatory_process.rb +0 -46
  131. data/app/controllers/decidim/participatory_process_groups_controller.rb +0 -26
  132. data/app/controllers/decidim/participatory_process_steps_controller.rb +0 -18
  133. data/app/controllers/decidim/participatory_process_widgets_controller.rb +0 -19
  134. data/app/controllers/decidim/participatory_processes_controller.rb +0 -49
  135. data/app/helpers/decidim/participatory_process_helper.rb +0 -17
  136. data/app/helpers/decidim/participatory_process_steps_helper.rb +0 -18
  137. data/app/models/decidim/participatory_process.rb +0 -61
  138. data/app/models/decidim/participatory_process_group.rb +0 -15
  139. data/app/models/decidim/participatory_process_step.rb +0 -39
  140. data/app/presenters/decidim/participatory_process_stats_presenter.rb +0 -50
  141. data/app/queries/decidim/highlighted_participatory_processes.rb +0 -10
  142. data/app/queries/decidim/organization_participatory_process_groups.rb +0 -14
  143. data/app/queries/decidim/organization_participatory_processes.rb +0 -14
  144. data/app/queries/decidim/organization_prioritized_participatory_processes.rb +0 -18
  145. data/app/queries/decidim/organization_published_participatory_processes.rb +0 -17
  146. data/app/queries/decidim/prioritized_participatory_processes.rb +0 -11
  147. data/app/queries/decidim/promoted_participatory_processes.rb +0 -10
  148. data/app/queries/decidim/published_participatory_processes.rb +0 -10
  149. data/app/views/decidim/participatory_process_groups/_participatory_process_group.html.erb +0 -22
  150. data/app/views/decidim/participatory_process_groups/show.html.erb +0 -11
  151. data/app/views/decidim/participatory_process_steps/_participatory_process_step.html.erb +0 -16
  152. data/app/views/decidim/participatory_process_steps/_timeline.html.erb +0 -7
  153. data/app/views/decidim/participatory_process_steps/index.html.erb +0 -14
  154. data/app/views/decidim/participatory_process_widgets/show.html.erb +0 -17
  155. data/app/views/decidim/participatory_processes/_no_processes_yet.html.erb +0 -3
  156. data/app/views/decidim/participatory_processes/_order_by_processes.html.erb +0 -3
  157. data/app/views/decidim/participatory_processes/_participatory_process.html.erb +0 -28
  158. data/app/views/decidim/participatory_processes/_promoted_process.html.erb +0 -32
  159. data/app/views/decidim/participatory_processes/_statistics.html.erb +0 -10
  160. data/app/views/decidim/participatory_processes/index.html.erb +0 -17
  161. data/app/views/decidim/participatory_processes/show.html.erb +0 -85
  162. data/app/views/layouts/decidim/_process_header.html.erb +0 -65
  163. data/app/views/layouts/decidim/_process_header_steps.html.erb +0 -27
  164. data/app/views/layouts/decidim/participatory_process.html.erb +0 -30
  165. data/config/i18n-tasks.yml +0 -138
  166. data/db/migrate/20161005130108_add_participatory_processes.rb +0 -19
  167. data/db/migrate/20161010102356_translate_processes.rb +0 -17
  168. data/db/migrate/20161011125616_add_hero_image_to_processes.rb +0 -7
  169. data/db/migrate/20161011141033_add_banner_image_to_processes.rb +0 -7
  170. data/db/migrate/20161013134732_add_promoted_flag_to_processes.rb +0 -7
  171. data/db/migrate/20161017085822_add_participatory_process_steps.rb +0 -18
  172. data/db/migrate/20161019072016_add_active_flag_to_step.rb +0 -13
  173. data/db/migrate/20161020080756_add_position_to_steps.rb +0 -9
  174. data/db/migrate/20161025125300_add_published_at_to_processes.rb +0 -7
  175. data/db/migrate/20161107152228_remove_not_null_on_step_position.rb +0 -7
  176. data/db/migrate/20161110092735_add_index_for_process_slug_organization.rb +0 -10
  177. data/db/migrate/20161116115156_create_attachments.rb +0 -18
  178. data/db/migrate/20170116135237_loosen_step_requirements.rb +0 -8
  179. data/db/migrate/20170123134023_make_attachments_polymorphic.rb +0 -20
  180. data/db/migrate/20170125135937_rename_attachable_to_attached_to.rb +0 -13
  181. data/db/migrate/20170126151123_add_extra_info_to_processes.rb +0 -10
  182. data/db/migrate/20170206083118_rename_extra_info_on_processes.rb +0 -14
  183. data/db/migrate/20170220110740_remove_steps_short_description.rb +0 -23
  184. data/db/migrate/20170221094835_add_scopes_to_processes.rb +0 -8
  185. data/db/migrate/20170228142440_add_participatory_process_groups.rb +0 -17
  186. data/db/migrate/20170404132616_change_steps_end_and_start_date_to_date.rb +0 -8
  187. data/db/migrate/20170725085104_add_show_statistics_to_participatory_processes.rb +0 -7
  188. data/db/migrate/20170804125402_attachment_description_nullable.rb +0 -7
  189. data/db/migrate/20170808080905_add_announcement_to_participatory_processes.rb +0 -7
  190. data/db/migrate/20170809084005_add_scopes_enabled_to_participatory_processes.rb +0 -7
  191. data/db/seeds/Exampledocument.pdf +0 -0
  192. data/db/seeds/city.jpeg +0 -0
  193. data/db/seeds/city2.jpeg +0 -0
  194. data/lib/decidim/notifiable.rb +0 -22
@@ -16,3 +16,6 @@ require "decidim/core/test/shared_examples/reports_examples"
16
16
  require "decidim/core/test/shared_examples/manage_moderations_examples"
17
17
  require "decidim/core/test/shared_examples/paginated_resource_examples"
18
18
  require "decidim/core/test/shared_examples/errors"
19
+ require "decidim/core/test/shared_examples/scope_helper_examples"
20
+ require "decidim/core/test/shared_examples/user_localised_email_examples"
21
+ require "decidim/core/test/shared_examples/follows_examples"
@@ -27,11 +27,14 @@ FactoryGirl.define do
27
27
  factory :category, class: Decidim::Category do
28
28
  name { Decidim::Faker::Localized.sentence(3) }
29
29
  description { Decidim::Faker::Localized.wrapped("<p>", "</p>") { Decidim::Faker::Localized.sentence(2) } }
30
- participatory_process
30
+
31
+ association :participatory_space, factory: :participatory_process
31
32
  end
32
33
 
33
34
  factory :subcategory, parent: :category do
34
35
  parent { build(:category) }
36
+
37
+ participatory_space { parent.participatory_space }
35
38
  end
36
39
 
37
40
  factory :organization, class: Decidim::Organization do
@@ -54,76 +57,6 @@ FactoryGirl.define do
54
57
  official_url { Faker::Internet.url }
55
58
  end
56
59
 
57
- factory :participatory_process, class: Decidim::ParticipatoryProcess do
58
- title { Decidim::Faker::Localized.sentence(3) }
59
- slug { generate(:slug) }
60
- subtitle { Decidim::Faker::Localized.sentence(1) }
61
- short_description { Decidim::Faker::Localized.wrapped("<p>", "</p>") { Decidim::Faker::Localized.sentence(2) } }
62
- description { Decidim::Faker::Localized.wrapped("<p>", "</p>") { Decidim::Faker::Localized.sentence(4) } }
63
- hero_image { Decidim::Dev.test_file("city.jpeg", "image/jpeg") }
64
- banner_image { Decidim::Dev.test_file("city2.jpeg", "image/jpeg") }
65
- published_at { Time.current }
66
- organization
67
- meta_scope { Decidim::Faker::Localized.word }
68
- developer_group { Decidim::Faker::Localized.sentence(1) }
69
- local_area { Decidim::Faker::Localized.sentence(2) }
70
- target { Decidim::Faker::Localized.sentence(3) }
71
- participatory_scope { Decidim::Faker::Localized.sentence(1) }
72
- participatory_structure { Decidim::Faker::Localized.sentence(2) }
73
- end_date 2.month.from_now.at_midnight
74
- show_statistics true
75
-
76
- trait :promoted do
77
- promoted true
78
- end
79
-
80
- trait :unpublished do
81
- published_at nil
82
- end
83
-
84
- trait :published do
85
- published_at { Time.current }
86
- end
87
-
88
- trait :with_steps do
89
- transient { current_step_ends 1.month.from_now }
90
-
91
- after(:create) do |participatory_process, evaluator|
92
- create(:participatory_process_step,
93
- active: true,
94
- end_date: evaluator.current_step_ends,
95
- participatory_process: participatory_process)
96
- participatory_process.reload
97
- participatory_process.steps.reload
98
- end
99
- end
100
- end
101
-
102
- factory :participatory_process_group, class: Decidim::ParticipatoryProcessGroup do
103
- name { Decidim::Faker::Localized.sentence(3) }
104
- description { Decidim::Faker::Localized.wrapped("<p>", "</p>") { Decidim::Faker::Localized.sentence(4) } }
105
- hero_image { Decidim::Dev.test_file("city.jpeg", "image/jpeg") }
106
- organization
107
- end
108
-
109
- factory :participatory_process_step, class: Decidim::ParticipatoryProcessStep do
110
- title { Decidim::Faker::Localized.sentence(3) }
111
- description { Decidim::Faker::Localized.wrapped("<p>", "</p>") { Decidim::Faker::Localized.sentence(4) } }
112
- start_date 1.month.ago.at_midnight
113
- end_date 2.month.from_now.at_midnight
114
- position nil
115
- participatory_process
116
-
117
- after(:create) do |step, _evaluator|
118
- step.participatory_process.reload
119
- step.participatory_process.steps.reload
120
- end
121
-
122
- trait :active do
123
- active true
124
- end
125
- end
126
-
127
60
  factory :user, class: Decidim::User do
128
61
  email { generate(:email) }
129
62
  password "password1234"
@@ -133,8 +66,6 @@ FactoryGirl.define do
133
66
  locale { organization.default_locale }
134
67
  tos_agreement "1"
135
68
  avatar { Decidim::Dev.test_file("avatar.jpg", "image/jpeg") }
136
- comments_notifications true
137
- replies_notifications true
138
69
 
139
70
  trait :confirmed do
140
71
  confirmed_at { Time.current }
@@ -286,8 +217,12 @@ FactoryGirl.define do
286
217
  end
287
218
 
288
219
  factory :feature, class: Decidim::Feature do
220
+ transient do
221
+ organization { create(:organization) }
222
+ end
223
+
289
224
  name { Decidim::Faker::Localized.sentence(3) }
290
- participatory_process
225
+ participatory_space { create(:participatory_process, organization: organization) }
291
226
  manifest_name "dummy"
292
227
  published_at { Time.now }
293
228
 
@@ -343,7 +278,7 @@ FactoryGirl.define do
343
278
 
344
279
  factory :moderation, class: Decidim::Moderation do
345
280
  reportable { build(:dummy_resource) }
346
- participatory_process { reportable.feature.participatory_process }
281
+ participatory_space { reportable.feature.participatory_space }
347
282
  end
348
283
 
349
284
  factory :report, class: Decidim::Report do
@@ -357,4 +292,31 @@ FactoryGirl.define do
357
292
  user { build(:user, :managed, organization: admin.organization) }
358
293
  started_at Time.current
359
294
  end
295
+
296
+ factory :follow, class: "Decidim::Follow" do
297
+ user do
298
+ build(
299
+ :user,
300
+ organization: followable.try(:organization) || build(:organization)
301
+ )
302
+ end
303
+ followable { build(:dummy_resource) }
304
+ end
305
+
306
+ factory :notification, class: "Decidim::Notification" do
307
+ user do
308
+ build(
309
+ :user,
310
+ organization: resource.try(:organization) || build(:organization)
311
+ )
312
+ end
313
+ resource { build(:dummy_resource) }
314
+ event_name { resource.class.name.underscore.tr("/", ".") }
315
+ event_class { "Decidim::DummyResourceEvent" }
316
+ extra do
317
+ {
318
+ some_extra_data: "1"
319
+ }
320
+ end
321
+ end
360
322
  end
@@ -68,22 +68,6 @@ shared_examples "comments" do
68
68
  it "shows comment to the user" do
69
69
  expect(page).to have_comment_from(user, "This is a new comment")
70
70
  end
71
-
72
- it "send notifications" do
73
- expect(page).to have_comment_from(user, "This is a new comment")
74
-
75
- if commentable.notifiable?(author: user)
76
- wait_for_email subject: "new comment"
77
- relogin_as commentable.users_to_notify.first, scope: :user
78
- visit last_email_first_link
79
-
80
- expect(page).to have_comment_from(user, "This is a new comment")
81
- else
82
- expect do
83
- wait_for_email subject: "new comment"
84
- end.to raise_error StandardError
85
- end
86
- end
87
71
  end
88
72
 
89
73
  context "when the user has verified organizations" do
@@ -127,16 +111,6 @@ shared_examples "comments" do
127
111
  it "shows reply to the user" do
128
112
  expect(page).to have_reply_to(comment, "This is a reply")
129
113
  end
130
-
131
- it "sends notifications received by commentable's author" do
132
- expect(page).to have_reply_to(comment, "This is a reply")
133
-
134
- wait_for_email subject: "new reply"
135
- relogin_as comment.author, scope: :user
136
- visit last_email_first_link
137
-
138
- expect(page).to have_reply_to(comment, "This is a reply")
139
- end
140
114
  end
141
115
 
142
116
  describe "arguable option" do
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ shared_examples "follows" do
4
+ include_context "feature"
5
+
6
+ before do
7
+ login_as user, scope: :user
8
+ end
9
+
10
+ context "when not following the followable" do
11
+ context "when user clicks the Follow button" do
12
+ it "makes the user follow the followable" do
13
+ visit resource_locator(followable).path
14
+ expect do
15
+ click_button "Follow"
16
+ expect(page).to have_content "Stop following"
17
+ end.to change(Decidim::Follow, :count).by(1)
18
+ end
19
+ end
20
+ end
21
+
22
+ context "when the user is following the followable" do
23
+ before do
24
+ create(:follow, followable: followable, user: user)
25
+ end
26
+
27
+ context "when user clicks the Follow button" do
28
+ it "makes the user follow the followable" do
29
+ visit resource_locator(followable).path
30
+ expect do
31
+ click_button "Stop following"
32
+ expect(page).to have_content "Follow"
33
+ end.to change(Decidim::Follow, :count).by(-1)
34
+ end
35
+ end
36
+ end
37
+ end
@@ -18,7 +18,7 @@ shared_examples "manage moderations" do
18
18
  end
19
19
 
20
20
  before do
21
- visit decidim_admin.edit_participatory_process_path(participatory_process)
21
+ visit decidim_admin_participatory_processes.edit_participatory_process_path(participatory_process)
22
22
  click_link "Moderations"
23
23
  end
24
24
 
@@ -22,7 +22,7 @@ shared_examples "manage processes announcements" do
22
22
  expect(page).to have_content("successfully")
23
23
  end
24
24
 
25
- visit decidim_admin.participatory_processes_path
25
+ visit decidim_admin_participatory_processes.participatory_processes_path
26
26
 
27
27
  within "tr", text: translated(participatory_process.title) do
28
28
  page.find("a.action-icon--preview").click
@@ -4,8 +4,8 @@ require "spec_helper"
4
4
 
5
5
  shared_examples_for "reportable" do
6
6
  let(:user) { create(:user, organization: subject.organization) }
7
- let(:participatory_process) { subject.feature.participatory_process }
8
- let(:moderation) { create(:moderation, reportable: subject, participatory_process: participatory_process, report_count: 1) }
7
+ let(:participatory_space) { subject.feature.participatory_space }
8
+ let(:moderation) { create(:moderation, reportable: subject, participatory_space: participatory_space, report_count: 1) }
9
9
  let!(:report) { create(:report, moderation: moderation, user: user) }
10
10
 
11
11
  describe "#reported_by?" do
@@ -26,14 +26,14 @@ shared_examples_for "reportable" do
26
26
  end
27
27
 
28
28
  context "when the resource has been hidden" do
29
- let(:moderation) { create(:moderation, reportable: subject, participatory_process: participatory_process, report_count: 1, hidden_at: Time.current) }
29
+ let(:moderation) { create(:moderation, reportable: subject, participatory_space: participatory_space, report_count: 1, hidden_at: Time.current) }
30
30
  it { expect(subject).to be_hidden }
31
31
  end
32
32
  end
33
33
 
34
34
  context "#reported?" do
35
35
  context "when the report count is equal to 0" do
36
- let(:moderation) { create(:moderation, reportable: subject, participatory_process: participatory_process, report_count: 0) }
36
+ let(:moderation) { create(:moderation, reportable: subject, participatory_space: participatory_space, report_count: 0) }
37
37
  let!(:report) { nil }
38
38
  it { expect(subject).not_to be_reported }
39
39
  end
@@ -42,7 +42,7 @@ shared_examples "reports" do
42
42
 
43
43
  context "and the user has reported the resource previously" do
44
44
  before do
45
- moderation = create(:moderation, reportable: reportable, participatory_process: participatory_process)
45
+ moderation = create(:moderation, reportable: reportable, participatory_space: participatory_process)
46
46
  create(:report, moderation: moderation, user: user, reason: "spam")
47
47
  end
48
48
 
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
4
+
5
+ shared_examples "scope helpers" do
6
+ describe Decidim::ScopesHelper do
7
+ let(:organization) { create(:organization) }
8
+ let(:scopes_enabled) { true }
9
+ let(:participatory_space_scope) { nil }
10
+ let(:feature) { create(:feature, manifest_name: "dummy", participatory_space: participatory_space) }
11
+ let(:scope) { create(:scope, organization: organization) }
12
+ let(:resource) { create(:dummy_resource, feature: feature, scope: scope) }
13
+
14
+ subject { helper.has_visible_scopes?(resource) }
15
+
16
+ before do
17
+ allow(helper).to receive(:current_participatory_space).and_return(participatory_space)
18
+ end
19
+
20
+ describe "has_visible_scopes?" do
21
+ context "when all conditions are met" do
22
+ it { is_expected.to be_truthy }
23
+ end
24
+
25
+ context "when the process has not scope enabled" do
26
+ let(:scopes_enabled) { false }
27
+ it { is_expected.to be_falsey }
28
+ end
29
+
30
+ context "when the process has a scope" do
31
+ let(:participatory_space_scope) { create(:scope, organization: organization) }
32
+ it { is_expected.to be_falsey }
33
+ end
34
+
35
+ context "when the resource has not a scope" do
36
+ let(:scope) { nil }
37
+ it { is_expected.to be_falsey }
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
4
+
5
+ shared_examples "user localised email" do
6
+ let(:user) { create(:user, locale: locale, organization: organization) }
7
+
8
+ context "when the user has a custom locale" do
9
+ let(:locale) { "ca" }
10
+
11
+ it "uses the user's locale" do
12
+ expect(mail.subject).to eq(subject)
13
+ expect(mail.body.encoded).to match(body)
14
+ end
15
+ end
16
+
17
+ context "otherwise" do
18
+ let(:locale) { nil }
19
+
20
+ it "uses the default locale" do
21
+ expect(mail.subject).to eq(default_subject)
22
+ expect(mail.body.encoded).to match(default_body)
23
+ end
24
+ end
25
+ end
@@ -3,7 +3,7 @@
3
3
  # This holds Decidim's version and the Rails version on which it depends.
4
4
  module Decidim
5
5
  def self.version
6
- "0.5.1"
6
+ "0.6.0"
7
7
  end
8
8
 
9
9
  def self.rails_version
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ #
5
+ # This class is responsible for sending route helper methods to the correct
6
+ # mounted engine. To do that, it needs to know the name of the mounted helper
7
+ # for the engine, and the contextual parameters to identify the mount point
8
+ # for it, which are added to the parameters passed to the route helper.
9
+ #
10
+ class EngineRouter
11
+ include Rails.application.routes.mounted_helpers
12
+
13
+ # Instantiates a router to the frontend engine for an object.
14
+ #
15
+ # @param target [#mounted_engine, #mounted_params] Object to be routed
16
+ #
17
+ # @return [EngineRouter] The new engine router
18
+ def self.main_proxy(target)
19
+ new(target.mounted_engine, target.mounted_params)
20
+ end
21
+
22
+ # Instantiates a router to the backend engine for an object.
23
+ #
24
+ # @param target [#mounted_admin_engine, #mounted_params] Object to be routed
25
+ #
26
+ # @return [EngineRouter] The new engine router
27
+ def self.admin_proxy(target)
28
+ new(target.mounted_admin_engine, target.mounted_params)
29
+ end
30
+
31
+ attr_reader :default_url_options
32
+
33
+ def initialize(engine, default_url_options)
34
+ @engine = engine
35
+ @default_url_options = default_url_options
36
+ end
37
+
38
+ def respond_to_missing?(method_name, include_private = false)
39
+ route_helper?(method_name) || super
40
+ end
41
+
42
+ def method_missing(method_name, *args)
43
+ return super unless route_helper?(method_name)
44
+
45
+ send(@engine).send(method_name, *args)
46
+ end
47
+
48
+ private
49
+
50
+ def route_helper?(method_name)
51
+ method_name.to_s.match?(/_(url|path)$/)
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Events
5
+ autoload :BaseEvent, "decidim/events/base_event"
6
+ autoload :EmailEvent, "decidim/events/email_event"
7
+ autoload :NotificationEvent, "decidim/events/notification_event"
8
+ end
9
+ end
@@ -0,0 +1,70 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Events
5
+ # This class serves as a base for all event classes. Event classes are intended to
6
+ # add more logic to a `Decidim::Notification` and are used to render them in the
7
+ # notifications dashboard and to generate other notifications (emails, for example).
8
+ class BaseEvent
9
+ # Public: Stores all the notification types this event can create. Please, do not
10
+ # overwrite this method, consider it final. Instead, add values to the array via
11
+ # modules, take the `NotificationEvent` module as an example:
12
+ #
13
+ # Example:
14
+ #
15
+ # module WebPushNotificationEvent
16
+ # extend ActiveSupport::Concern
17
+ #
18
+ # included do
19
+ # types << :web_push_notifications
20
+ # end
21
+ # end
22
+ #
23
+ # class MyEvent < Decidim::Events::BaseEvent
24
+ # include WebPushNotificationEvent
25
+ # end
26
+ #
27
+ # MyEvent.types # => [:web_push_notifications]
28
+ def self.types
29
+ @types ||= []
30
+ end
31
+
32
+ # Initializes the class.
33
+ #
34
+ # event_name - a String with the name of the event.
35
+ # resource - the resource that received the event
36
+ # user - the User that receives the event
37
+ # extra - a Hash with extra information of the event.
38
+ def initialize(resource:, event_name:, user:, extra:)
39
+ @event_name = event_name
40
+ @resource = resource
41
+ @user = user
42
+ @extra = extra
43
+ end
44
+
45
+ # Caches the locator for the given resource, so that
46
+ # we can find the resource URL.
47
+ def resource_locator
48
+ @resource_locator ||= Decidim::ResourceLocatorPresenter.new(resource)
49
+ end
50
+
51
+ # Caches the path for the given resource.
52
+ def resource_path
53
+ @resource_path ||= resource_locator.path
54
+ end
55
+
56
+ # Caches the URL for the given resource.
57
+ def resource_url
58
+ @resource_url ||= resource_locator.url
59
+ end
60
+
61
+ private
62
+
63
+ attr_reader :event_name, :resource, :user, :extra
64
+
65
+ def resource_title
66
+ resource.title.is_a?(Hash) ? resource.title[I18n.locale.to_s] : resource.title
67
+ end
68
+ end
69
+ end
70
+ end