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.
- checksums.yaml +4 -4
- data/app/assets/config/decidim_core_manifest.js +1 -0
- data/app/assets/javascripts/decidim/notifications.js.es6 +33 -0
- data/app/assets/stylesheets/decidim/extras/_meeting-registrations.scss +11 -0
- data/app/assets/stylesheets/decidim/modules/_extra.scss +4 -0
- data/app/assets/stylesheets/decidim/modules/_process-nav.scss +14 -0
- data/app/commands/decidim/create_follow.rb +40 -0
- data/app/commands/decidim/create_omniauth_registration.rb +0 -2
- data/app/commands/decidim/create_registration.rb +1 -3
- data/app/commands/decidim/create_report.rb +7 -7
- data/app/commands/decidim/delete_follow.rb +37 -0
- data/app/commands/decidim/invite_user.rb +1 -3
- data/app/commands/decidim/update_notifications_settings.rb +1 -2
- data/app/constraints/decidim/current_feature.rb +3 -4
- data/app/controllers/concerns/decidim/settings.rb +1 -1
- data/app/controllers/decidim/features/base_controller.rb +5 -6
- data/app/controllers/decidim/follows_controller.rb +45 -0
- data/app/controllers/decidim/notifications_controller.rb +39 -0
- data/app/controllers/decidim/pages_controller.rb +2 -2
- data/app/controllers/decidim/scopes_controller.rb +2 -0
- data/app/controllers/decidim/widgets_controller.rb +3 -3
- data/app/forms/decidim/follow_form.rb +20 -0
- data/app/forms/decidim/invite_user_form.rb +1 -1
- data/app/forms/decidim/notifications_settings_form.rb +2 -4
- data/app/helpers/decidim/action_authorization_helper.rb +2 -1
- data/app/helpers/decidim/decidim_form_helper.rb +4 -0
- data/app/helpers/decidim/feature_path_helper.rb +2 -13
- data/app/helpers/decidim/icon_helper.rb +26 -8
- data/app/helpers/decidim/paginate_helper.rb +1 -1
- data/app/helpers/decidim/scopes_helper.rb +1 -1
- data/app/jobs/decidim/email_notification_generator_job.rb +12 -0
- data/app/jobs/decidim/export_job.rb +1 -3
- data/app/jobs/decidim/notification_generator_for_recipient_job.rb +14 -0
- data/app/jobs/decidim/notification_generator_job.rb +12 -0
- data/app/mailers/decidim/export_mailer.rb +6 -7
- data/app/mailers/decidim/notification_mailer.rb +20 -0
- data/app/mailers/decidim/reported_mailer.rb +3 -3
- data/app/models/decidim/abilities/admin_ability.rb +0 -1
- data/app/models/decidim/abilities/base_ability.rb +8 -0
- data/app/models/decidim/abilities/everyone_ability.rb +0 -2
- data/app/models/decidim/abilities/participatory_process_admin_ability.rb +1 -1
- data/app/models/decidim/abilities/participatory_process_collaborator_ability.rb +1 -1
- data/app/models/decidim/category.rb +4 -4
- data/app/models/decidim/feature.rb +29 -4
- data/app/models/decidim/follow.rb +10 -0
- data/app/models/decidim/moderation.rb +1 -1
- data/app/models/decidim/notification.rb +12 -0
- data/app/models/decidim/scope.rb +8 -8
- data/app/models/decidim/user.rb +11 -1
- data/app/presenters/decidim/home_stats_presenter.rb +1 -1
- data/app/presenters/decidim/resource_locator_presenter.rb +3 -18
- data/app/queries/decidim/participatory_processes_with_user_role.rb +1 -1
- data/app/services/decidim/email_notification_generator.rb +63 -0
- data/app/services/decidim/events_manager.rb +41 -0
- data/app/services/decidim/notification_generator.rb +51 -0
- data/app/services/decidim/notification_generator_for_recipient.rb +50 -0
- data/app/uploaders/decidim/attachment_uploader.rb +1 -1
- data/app/views/decidim/authorizations/first_login.html.erb +2 -2
- data/app/views/decidim/follows/update_button.js.erb +3 -0
- data/app/views/decidim/notification_mailer/event_received.html.erb +9 -0
- data/app/views/decidim/notifications/_notification.html.erb +18 -0
- data/app/views/decidim/notifications/index.html.erb +32 -0
- data/app/views/decidim/notifications_settings/show.html.erb +3 -10
- data/app/views/decidim/shared/_follow_button.html.erb +19 -0
- data/app/views/layouts/decidim/_head.html.erb +1 -0
- data/app/views/layouts/decidim/_head_extra.html.erb +7 -0
- data/app/views/layouts/decidim/_user_menu.html.erb +1 -0
- data/app/views/layouts/decidim/_wrapper.html.erb +3 -0
- data/app/views/layouts/decidim/widget.html.erb +3 -3
- data/app/views/pages/home/_hero.html.erb +1 -1
- data/app/views/pages/home/_highlighted_processes.html.erb +3 -3
- data/config/locales/ca.yml +29 -74
- data/config/locales/en.yml +23 -71
- data/config/locales/es.yml +31 -78
- data/config/locales/eu.yml +61 -65
- data/config/locales/fi.yml +91 -51
- data/config/locales/fr.yml +40 -83
- data/config/locales/it.yml +129 -54
- data/config/locales/nl.yml +90 -51
- data/config/locales/pl.yml +319 -10
- data/config/locales/uk.yml +400 -0
- data/config/routes.rb +8 -14
- data/db/migrate/20170720120231_make_moderations_polymorphic.rb +29 -0
- data/db/migrate/20170726145242_make_categories_polymorphic.rb +27 -0
- data/db/migrate/20170807123535_create_decidim_follows.rb +20 -0
- data/db/migrate/20170808071019_create_decidim_notifications.rb +13 -0
- data/db/migrate/20170906091718_add_extra_to_notifications.rb +7 -0
- data/db/migrate/20170912082054_add_emails_on_notifications_flag_to_user.rb +7 -0
- data/db/migrate/20170913092351_add_header_snippets_to_organizations.rb +7 -0
- data/db/migrate/20170914075721_remove_followable_index_from_follows.rb +7 -0
- data/db/migrate/20170914092116_remove_comment_and_replies_notifications_from_users.rb +8 -0
- data/db/seeds.rb +2 -108
- data/lib/decidim/core.rb +46 -8
- data/lib/decidim/core/engine.rb +20 -6
- data/lib/decidim/core/test.rb +3 -0
- data/lib/decidim/core/test/factories.rb +37 -75
- data/lib/decidim/core/test/shared_examples/comments_examples.rb +0 -26
- data/lib/decidim/core/test/shared_examples/follows_examples.rb +37 -0
- data/lib/decidim/core/test/shared_examples/manage_moderations_examples.rb +1 -1
- data/lib/decidim/core/test/shared_examples/process_announcements_examples.rb +1 -1
- data/lib/decidim/core/test/shared_examples/reportable.rb +4 -4
- data/lib/decidim/core/test/shared_examples/reports_examples.rb +1 -1
- data/lib/decidim/core/test/shared_examples/scope_helper_examples.rb +41 -0
- data/lib/decidim/core/test/shared_examples/user_localised_email_examples.rb +25 -0
- data/lib/decidim/core/version.rb +1 -1
- data/lib/decidim/engine_router.rb +54 -0
- data/lib/decidim/events.rb +9 -0
- data/lib/decidim/events/base_event.rb +70 -0
- data/lib/decidim/events/email_event.rb +39 -0
- data/lib/decidim/events/notification_event.rb +32 -0
- data/lib/decidim/exporters.rb +7 -0
- data/lib/decidim/exporters/export_data.rb +14 -0
- data/lib/decidim/feature_manifest.rb +2 -2
- data/lib/decidim/features/namer.rb +1 -1
- data/lib/decidim/followable.rb +13 -0
- data/lib/decidim/form_builder.rb +1 -1
- data/lib/decidim/has_feature.rb +1 -1
- data/lib/decidim/has_settings.rb +19 -15
- data/lib/decidim/manifest_registry.rb +1 -3
- data/lib/decidim/participable.rb +80 -0
- data/lib/decidim/participatory_space_manifest.rb +40 -0
- data/lib/decidim/query_extensions.rb +1 -1
- data/lib/decidim/resource_manifest.rb +1 -1
- data/lib/decidim/settings_manifest.rb +0 -4
- data/vendor/assets/javascripts/datepicker-locales/foundation-datepicker.uk.js +14 -0
- data/vendor/assets/javascripts/morphdom.js +14 -5
- metadata +70 -79
- data/app/assets/images/decidim/process.svg +0 -10
- data/app/constraints/decidim/current_participatory_process.rb +0 -35
- data/app/controllers/concerns/decidim/needs_participatory_process.rb +0 -46
- data/app/controllers/decidim/participatory_process_groups_controller.rb +0 -26
- data/app/controllers/decidim/participatory_process_steps_controller.rb +0 -18
- data/app/controllers/decidim/participatory_process_widgets_controller.rb +0 -19
- data/app/controllers/decidim/participatory_processes_controller.rb +0 -49
- data/app/helpers/decidim/participatory_process_helper.rb +0 -17
- data/app/helpers/decidim/participatory_process_steps_helper.rb +0 -18
- data/app/models/decidim/participatory_process.rb +0 -61
- data/app/models/decidim/participatory_process_group.rb +0 -15
- data/app/models/decidim/participatory_process_step.rb +0 -39
- data/app/presenters/decidim/participatory_process_stats_presenter.rb +0 -50
- data/app/queries/decidim/highlighted_participatory_processes.rb +0 -10
- data/app/queries/decidim/organization_participatory_process_groups.rb +0 -14
- data/app/queries/decidim/organization_participatory_processes.rb +0 -14
- data/app/queries/decidim/organization_prioritized_participatory_processes.rb +0 -18
- data/app/queries/decidim/organization_published_participatory_processes.rb +0 -17
- data/app/queries/decidim/prioritized_participatory_processes.rb +0 -11
- data/app/queries/decidim/promoted_participatory_processes.rb +0 -10
- data/app/queries/decidim/published_participatory_processes.rb +0 -10
- data/app/views/decidim/participatory_process_groups/_participatory_process_group.html.erb +0 -22
- data/app/views/decidim/participatory_process_groups/show.html.erb +0 -11
- data/app/views/decidim/participatory_process_steps/_participatory_process_step.html.erb +0 -16
- data/app/views/decidim/participatory_process_steps/_timeline.html.erb +0 -7
- data/app/views/decidim/participatory_process_steps/index.html.erb +0 -14
- data/app/views/decidim/participatory_process_widgets/show.html.erb +0 -17
- data/app/views/decidim/participatory_processes/_no_processes_yet.html.erb +0 -3
- data/app/views/decidim/participatory_processes/_order_by_processes.html.erb +0 -3
- data/app/views/decidim/participatory_processes/_participatory_process.html.erb +0 -28
- data/app/views/decidim/participatory_processes/_promoted_process.html.erb +0 -32
- data/app/views/decidim/participatory_processes/_statistics.html.erb +0 -10
- data/app/views/decidim/participatory_processes/index.html.erb +0 -17
- data/app/views/decidim/participatory_processes/show.html.erb +0 -85
- data/app/views/layouts/decidim/_process_header.html.erb +0 -65
- data/app/views/layouts/decidim/_process_header_steps.html.erb +0 -27
- data/app/views/layouts/decidim/participatory_process.html.erb +0 -30
- data/config/i18n-tasks.yml +0 -138
- data/db/migrate/20161005130108_add_participatory_processes.rb +0 -19
- data/db/migrate/20161010102356_translate_processes.rb +0 -17
- data/db/migrate/20161011125616_add_hero_image_to_processes.rb +0 -7
- data/db/migrate/20161011141033_add_banner_image_to_processes.rb +0 -7
- data/db/migrate/20161013134732_add_promoted_flag_to_processes.rb +0 -7
- data/db/migrate/20161017085822_add_participatory_process_steps.rb +0 -18
- data/db/migrate/20161019072016_add_active_flag_to_step.rb +0 -13
- data/db/migrate/20161020080756_add_position_to_steps.rb +0 -9
- data/db/migrate/20161025125300_add_published_at_to_processes.rb +0 -7
- data/db/migrate/20161107152228_remove_not_null_on_step_position.rb +0 -7
- data/db/migrate/20161110092735_add_index_for_process_slug_organization.rb +0 -10
- data/db/migrate/20161116115156_create_attachments.rb +0 -18
- data/db/migrate/20170116135237_loosen_step_requirements.rb +0 -8
- data/db/migrate/20170123134023_make_attachments_polymorphic.rb +0 -20
- data/db/migrate/20170125135937_rename_attachable_to_attached_to.rb +0 -13
- data/db/migrate/20170126151123_add_extra_info_to_processes.rb +0 -10
- data/db/migrate/20170206083118_rename_extra_info_on_processes.rb +0 -14
- data/db/migrate/20170220110740_remove_steps_short_description.rb +0 -23
- data/db/migrate/20170221094835_add_scopes_to_processes.rb +0 -8
- data/db/migrate/20170228142440_add_participatory_process_groups.rb +0 -17
- data/db/migrate/20170404132616_change_steps_end_and_start_date_to_date.rb +0 -8
- data/db/migrate/20170725085104_add_show_statistics_to_participatory_processes.rb +0 -7
- data/db/migrate/20170804125402_attachment_description_nullable.rb +0 -7
- data/db/migrate/20170808080905_add_announcement_to_participatory_processes.rb +0 -7
- data/db/migrate/20170809084005_add_scopes_enabled_to_participatory_processes.rb +0 -7
- data/db/seeds/Exampledocument.pdf +0 -0
- data/db/seeds/city.jpeg +0 -0
- data/db/seeds/city2.jpeg +0 -0
- data/lib/decidim/notifiable.rb +0 -22
data/lib/decidim/core/test.rb
CHANGED
@@ -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
|
-
|
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
|
-
|
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
|
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
|
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(:
|
8
|
-
let(:moderation) { create(:moderation, reportable: subject,
|
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,
|
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,
|
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,
|
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
|
data/lib/decidim/core/version.rb
CHANGED
@@ -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,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
|