decidim-core 0.9.3 → 0.10.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (192) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/decidim/append_redirect_url_to_modals.js.es6 +1 -1
  3. data/app/assets/javascripts/decidim/data_picker.js.es6 +32 -28
  4. data/app/assets/javascripts/decidim/form_filter.component.js.es6 +2 -2
  5. data/app/assets/javascripts/decidim/foundation.js.es6 +1 -2
  6. data/app/assets/stylesheets/decidim/_decidim.scss +6 -1
  7. data/app/assets/stylesheets/decidim/modules/_address.scss +4 -0
  8. data/app/assets/stylesheets/decidim/modules/_block-banner.scss +39 -0
  9. data/app/assets/stylesheets/decidim/modules/_buttons.scss +76 -1
  10. data/app/assets/stylesheets/decidim/modules/_callout.scss +4 -0
  11. data/app/assets/stylesheets/decidim/modules/_cards.scss +117 -16
  12. data/app/assets/stylesheets/decidim/modules/_collapsible-list.scss +19 -0
  13. data/app/assets/stylesheets/decidim/modules/_data-picker.scss +0 -1
  14. data/app/assets/stylesheets/decidim/modules/_docs-manager.scss +16 -0
  15. data/app/assets/stylesheets/decidim/modules/_icons.scss +13 -4
  16. data/app/assets/stylesheets/decidim/modules/_margins.scss +39 -0
  17. data/app/assets/stylesheets/decidim/modules/_modules.scss +4 -0
  18. data/app/assets/stylesheets/decidim/modules/_navbar.scss +26 -0
  19. data/app/assets/stylesheets/decidim/modules/_process-phase.scss +49 -0
  20. data/app/assets/stylesheets/decidim/modules/_reveal.scss +39 -0
  21. data/app/assets/stylesheets/decidim/modules/_typography.scss +45 -0
  22. data/app/assets/stylesheets/decidim/modules/_wizard-steps.scss +45 -0
  23. data/app/assets/stylesheets/decidim/utils/_helpers.scss +14 -0
  24. data/app/assets/stylesheets/decidim/utils/_mixins.scss +34 -0
  25. data/app/assets/stylesheets/decidim/utils/_settings.scss +6 -3
  26. data/app/commands/decidim/create_report.rb +2 -2
  27. data/app/controllers/decidim/devise/invitations_controller.rb +1 -1
  28. data/app/controllers/decidim/features/base_controller.rb +1 -1
  29. data/app/controllers/decidim/locales_controller.rb +1 -1
  30. data/app/forms/decidim/registration_form.rb +1 -1
  31. data/app/helpers/decidim/decidim_form_helper.rb +26 -1
  32. data/app/helpers/decidim/meta_tags_helper.rb +2 -0
  33. data/app/helpers/decidim/resource_reference_helper.rb +24 -0
  34. data/app/helpers/decidim/scopes_helper.rb +22 -4
  35. data/app/helpers/decidim/view_hooks_helper.rb +6 -3
  36. data/app/mailers/decidim/messaging/conversation_mailer.rb +2 -0
  37. data/app/models/decidim/abilities/base_ability.rb +1 -1
  38. data/app/models/decidim/action_log.rb +57 -0
  39. data/app/models/decidim/area.rb +25 -0
  40. data/app/models/decidim/area_type.rb +20 -0
  41. data/app/models/decidim/attachment.rb +3 -0
  42. data/app/models/decidim/attachment_collection.rb +16 -0
  43. data/app/models/decidim/authorization.rb +1 -0
  44. data/app/models/decidim/categorization.rb +2 -0
  45. data/app/models/decidim/category.rb +8 -0
  46. data/app/models/decidim/feature.rb +6 -1
  47. data/app/models/decidim/moderation.rb +7 -0
  48. data/app/models/decidim/newsletter.rb +7 -0
  49. data/app/models/decidim/organization.rb +9 -0
  50. data/app/models/decidim/participatory_process_user_role.rb +9 -0
  51. data/app/models/decidim/resource_link.rb +8 -1
  52. data/app/models/decidim/scope.rb +7 -0
  53. data/app/models/decidim/static_page.rb +7 -0
  54. data/app/models/decidim/user.rb +5 -1
  55. data/app/models/decidim/user_group.rb +7 -0
  56. data/app/presenters/decidim/admin_log/feature_presenter.rb +43 -0
  57. data/app/presenters/decidim/admin_log/moderation_presenter.rb +48 -0
  58. data/app/presenters/decidim/admin_log/newsletter_presenter.rb +47 -0
  59. data/app/presenters/decidim/admin_log/newsletter_resource_presenter.rb +18 -0
  60. data/app/presenters/decidim/admin_log/organization_presenter.rb +84 -0
  61. data/app/presenters/decidim/admin_log/scope_presenter.rb +54 -0
  62. data/app/presenters/decidim/admin_log/static_page_presenter.rb +48 -0
  63. data/app/presenters/decidim/admin_log/static_page_resource_presenter.rb +18 -0
  64. data/app/presenters/decidim/admin_log/user_group_presenter.rb +31 -0
  65. data/app/presenters/decidim/admin_log/user_presenter.rb +59 -0
  66. data/app/presenters/decidim/area_presenter.rb +14 -0
  67. data/app/presenters/decidim/area_type_presenter.rb +14 -0
  68. data/app/presenters/decidim/category_presenter.rb +14 -0
  69. data/app/presenters/decidim/log/base_presenter.rb +253 -0
  70. data/app/presenters/decidim/log/diff_presenter.rb +120 -0
  71. data/app/presenters/decidim/log/resource_presenter.rb +71 -0
  72. data/app/presenters/decidim/log/space_presenter.rb +63 -0
  73. data/app/presenters/decidim/log/user_presenter.rb +85 -0
  74. data/app/presenters/decidim/log/value_types/area_presenter.rb +28 -0
  75. data/app/presenters/decidim/log/value_types/date_presenter.rb +20 -0
  76. data/app/presenters/decidim/log/value_types/default_presenter.rb +43 -0
  77. data/app/presenters/decidim/log/value_types/locale_presenter.rb +20 -0
  78. data/app/presenters/decidim/log/value_types/percentage_presenter.rb +21 -0
  79. data/app/presenters/decidim/log/value_types/scope_presenter.rb +28 -0
  80. data/app/presenters/decidim/log/value_types/scope_type_presenter.rb +28 -0
  81. data/app/presenters/decidim/user_presenter.rb +1 -1
  82. data/app/services/decidim/action_authorizer.rb +1 -1
  83. data/app/services/decidim/action_logger.rb +108 -0
  84. data/app/services/decidim/events_manager.rb +1 -1
  85. data/app/services/decidim/log/diff_changeset_calculator.rb +135 -0
  86. data/app/services/decidim/resource_search.rb +2 -8
  87. data/app/services/decidim/settings_change.rb +31 -0
  88. data/app/services/decidim/traceability.rb +57 -11
  89. data/app/types/decidim/core/component_type.rb +12 -0
  90. data/app/types/decidim/core/date_time_type.rb +12 -0
  91. data/app/types/decidim/core/date_type.rb +13 -0
  92. data/app/types/decidim/core/decidim_type.rb +23 -0
  93. data/app/types/decidim/core/localized_string_type.rb +14 -0
  94. data/app/types/decidim/core/organization_type.rb +20 -0
  95. data/app/types/decidim/core/participatory_space_type.rb +12 -0
  96. data/app/types/decidim/core/session_type.rb +19 -0
  97. data/app/types/decidim/core/statistic_type.rb +22 -0
  98. data/app/types/decidim/core/translated_field_type.rb +45 -0
  99. data/app/types/decidim/core/user_group_type.rb +39 -0
  100. data/app/types/decidim/core/user_type.rb +41 -0
  101. data/app/validators/etiquette_validator.rb +1 -1
  102. data/app/views/decidim/application/_attachments.html.erb +4 -0
  103. data/app/views/decidim/application/_collection.html.erb +14 -0
  104. data/app/views/decidim/application/_document.html.erb +19 -0
  105. data/app/views/decidim/application/_documents.html.erb +8 -23
  106. data/app/views/decidim/shared/_announcement.html.erb +3 -2
  107. data/app/views/decidim/shared/_tags.html.erb +1 -0
  108. data/app/views/decidim/widgets/_data_picker.html.erb +6 -0
  109. data/app/views/layouts/decidim/mailer.html.erb +2 -2
  110. data/config/initializers/devise.rb +3 -3
  111. data/config/locales/ca.yml +65 -11
  112. data/config/locales/en.yml +64 -10
  113. data/config/locales/es.yml +66 -12
  114. data/config/locales/eu.yml +61 -10
  115. data/config/locales/fi.yml +64 -10
  116. data/config/locales/fr.yml +64 -10
  117. data/config/locales/gl.yml +64 -10
  118. data/config/locales/it.yml +64 -10
  119. data/config/locales/nl.yml +64 -10
  120. data/config/locales/pl.yml +60 -10
  121. data/config/locales/pt-BR.yml +64 -10
  122. data/config/locales/pt.yml +64 -10
  123. data/config/locales/sv.yml +64 -10
  124. data/config/locales/uk.yml +72 -0
  125. data/db/migrate/20170215115407_add_organization_custom_reference.rb +1 -1
  126. data/db/migrate/20170313095436_add_available_authorizations_to_organization.rb +1 -1
  127. data/db/migrate/20171207182729_create_decidim_attachment_collections.rb +12 -0
  128. data/db/migrate/20180130093153_add_action_log.rb +18 -0
  129. data/db/migrate/20180206143340_fix_reference_for_all_resources.rb +13 -0
  130. data/db/migrate/20180215104821_create_decidim_area_types.rb +11 -0
  131. data/db/migrate/20180215104945_create_decidim_areas.rb +12 -0
  132. data/db/migrate/20180221101934_fix_nickname_index.rb +1 -1
  133. data/db/migrate/20180226140756_add_version_to_action_logs.rb +19 -0
  134. data/db/migrate/20180314085339_rename_maximum_votes_per_proposal_to_threshold_per_proposal.rb +27 -0
  135. data/db/migrate/20180326075746_change_event_name_and_class_to_rename_to_publish_proposal_event.rb +17 -0
  136. data/db/seeds.rb +28 -0
  137. data/lib/decidim/abilities/participatory_process_role_ability.rb +2 -2
  138. data/lib/decidim/api/author_interface.rb +25 -0
  139. data/lib/decidim/api/component_interface.rb +16 -0
  140. data/lib/decidim/api/participatory_space_interface.rb +38 -0
  141. data/lib/decidim/authorable.rb +8 -0
  142. data/lib/decidim/core.rb +27 -9
  143. data/lib/decidim/core/engine.rb +3 -4
  144. data/lib/decidim/core/test.rb +2 -0
  145. data/lib/decidim/core/test/factories.rb +62 -6
  146. data/lib/decidim/core/test/shared_examples/announcements_examples.rb +1 -1
  147. data/lib/decidim/core/test/shared_examples/comments_examples.rb +47 -5
  148. data/lib/decidim/core/test/shared_examples/component_type.rb +7 -0
  149. data/lib/decidim/core/test/shared_examples/has_attachment_collections.rb +63 -0
  150. data/lib/decidim/core/test/shared_examples/has_attachments.rb +21 -0
  151. data/lib/decidim/core/test/shared_examples/has_reference.rb +1 -1
  152. data/lib/decidim/core/test/shared_examples/simple_event.rb +27 -1
  153. data/lib/decidim/core/version.rb +1 -1
  154. data/lib/decidim/events/author_event.rb +1 -1
  155. data/lib/decidim/events/base_event.rb +1 -1
  156. data/lib/decidim/events/simple_event.rb +21 -0
  157. data/lib/decidim/exporters/excel.rb +1 -1
  158. data/lib/decidim/feature_manifest.rb +2 -0
  159. data/lib/decidim/form_builder.rb +37 -3
  160. data/lib/decidim/has_attachment_collections.rb +18 -0
  161. data/lib/decidim/has_attachments.rb +14 -0
  162. data/lib/decidim/has_category.rb +5 -0
  163. data/lib/decidim/has_reference.rb +4 -4
  164. data/lib/decidim/loggable.rb +32 -0
  165. data/lib/decidim/participable.rb +0 -2
  166. data/lib/decidim/participatory_space_manifest.rb +2 -0
  167. data/lib/decidim/publicable.rb +2 -2
  168. data/lib/decidim/query_extensions.rb +46 -14
  169. data/lib/decidim/resourceable.rb +15 -6
  170. data/lib/decidim/scopable.rb +35 -1
  171. data/lib/decidim/scopable_feature.rb +16 -0
  172. data/vendor/assets/javascripts/datepicker-locales/foundation-datepicker.ca.js +0 -0
  173. data/vendor/assets/javascripts/datepicker-locales/foundation-datepicker.es.js +0 -0
  174. data/vendor/assets/javascripts/datepicker-locales/foundation-datepicker.eu.js +0 -0
  175. data/vendor/assets/javascripts/datepicker-locales/foundation-datepicker.fi.js +0 -0
  176. data/vendor/assets/javascripts/leaflet.markercluster.js +0 -0
  177. metadata +91 -38
  178. data/app/commands/decidim/remove_admin.rb +0 -25
  179. data/app/helpers/decidim/feature_reference_helper.rb +0 -25
  180. data/lib/decidim/core/api.rb +0 -13
  181. data/lib/decidim/core/api/author_interface.rb +0 -18
  182. data/lib/decidim/core/api/decidim_type.rb +0 -17
  183. data/lib/decidim/core/api/localized_string_type.rb +0 -12
  184. data/lib/decidim/core/api/process_step_type.rb +0 -19
  185. data/lib/decidim/core/api/process_type.rb +0 -17
  186. data/lib/decidim/core/api/session_type.rb +0 -17
  187. data/lib/decidim/core/api/translated_field_type.rb +0 -43
  188. data/lib/decidim/core/api/user_group_type.rb +0 -37
  189. data/lib/decidim/core/api/user_type.rb +0 -39
  190. data/lib/decidim/devise_failure_app.rb +0 -36
  191. data/lib/decidim/has_scope.rb +0 -25
  192. data/lib/decidim/i18n_exceptions.rb +0 -15
@@ -4,6 +4,7 @@ require "decidim/core/test/shared_examples/authorable"
4
4
  require "decidim/core/test/shared_examples/publicable"
5
5
  require "decidim/core/test/shared_examples/localised_email"
6
6
  require "decidim/core/test/shared_examples/has_attachments"
7
+ require "decidim/core/test/shared_examples/has_attachment_collections"
7
8
  require "decidim/core/test/shared_examples/has_feature"
8
9
  require "decidim/core/test/shared_examples/has_scope"
9
10
  require "decidim/core/test/shared_examples/has_category"
@@ -19,3 +20,4 @@ require "decidim/core/test/shared_examples/scope_helper_examples"
19
20
  require "decidim/core/test/shared_examples/user_localised_email_examples"
20
21
  require "decidim/core/test/shared_examples/follows_examples"
21
22
  require "decidim/core/test/shared_examples/simple_event"
23
+ require "decidim/core/test/shared_examples/component_type"
@@ -31,6 +31,10 @@ FactoryBot.define do
31
31
  "#{Faker::Lorem.characters(4).upcase}-#{n}"
32
32
  end
33
33
 
34
+ sequence(:area_name) do |n|
35
+ "#{Faker::Lorem.sentence(1, true, 3)} #{n}"
36
+ end
37
+
34
38
  factory :category, class: "Decidim::Category" do
35
39
  name { Decidim::Faker::Localized.sentence(3) }
36
40
  description { Decidim::Faker::Localized.wrapped("<p>", "</p>") { Decidim::Faker::Localized.sentence(2) } }
@@ -105,15 +109,10 @@ FactoryBot.define do
105
109
 
106
110
  trait :officialized do
107
111
  officialized_at { Time.zone.now }
112
+ officialized_as { Decidim::Faker::Localized.sentence(3) }
108
113
  end
109
114
  end
110
115
 
111
- factory :participatory_process_user_role, class: "Decidim::ParticipatoryProcessUserRole" do
112
- user
113
- participatory_process { create :participatory_process, organization: user.organization }
114
- role "admin"
115
- end
116
-
117
116
  factory :user_group, class: "Decidim::UserGroup" do
118
117
  name { Faker::Educator.course }
119
118
  document_number { Faker::Number.number(8) + "X" }
@@ -181,10 +180,19 @@ FactoryBot.define do
181
180
  end
182
181
  end
183
182
 
183
+ factory :attachment_collection, class: "Decidim::AttachmentCollection" do
184
+ name { Decidim::Faker::Localized.sentence(1) }
185
+ description { Decidim::Faker::Localized.sentence(2) }
186
+ weight { Faker::Number.number(1) }
187
+
188
+ association :collection_for, factory: :participatory_process
189
+ end
190
+
184
191
  factory :attachment, class: "Decidim::Attachment" do
185
192
  title { Decidim::Faker::Localized.sentence(3) }
186
193
  description { Decidim::Faker::Localized.wrapped("<p>", "</p>") { Decidim::Faker::Localized.sentence(4) } }
187
194
  file { Decidim::Dev.test_file("city.jpeg", "image/jpeg") }
195
+ weight { Faker::Number.number(1) }
188
196
  attached_to { build(:participatory_process) }
189
197
  content_type { "image/jpeg" }
190
198
  file_size { 108_908 }
@@ -240,6 +248,17 @@ FactoryBot.define do
240
248
  end
241
249
  end
242
250
 
251
+ factory :area_type, class: "Decidim::AreaType" do
252
+ name { Decidim::Faker::Localized.word }
253
+ plural { Decidim::Faker::Localized.literal(name.values.first.pluralize) }
254
+ organization
255
+ end
256
+
257
+ factory :area, class: "Decidim::Area" do
258
+ name { Decidim::Faker::Localized.literal(generate(:area_name)) }
259
+ organization
260
+ end
261
+
243
262
  factory :dummy_resource, class: "Decidim::DummyResources::DummyResource" do
244
263
  title { generate(:name) }
245
264
  feature { create(:feature, manifest_name: "dummy") }
@@ -258,6 +277,10 @@ FactoryBot.define do
258
277
 
259
278
  subject { Decidim::Faker::Localized.sentence(3) }
260
279
  body { Decidim::Faker::Localized.wrapped("<p>", "</p>") { Decidim::Faker::Localized.sentence(4) } }
280
+
281
+ trait :sent do
282
+ sent_at { Time.current }
283
+ end
261
284
  end
262
285
 
263
286
  factory :moderation, class: "Decidim::Moderation" do
@@ -307,4 +330,37 @@ FactoryBot.define do
307
330
  }
308
331
  end
309
332
  end
333
+
334
+ factory :action_log, class: "Decidim::ActionLog" do
335
+ transient do
336
+ extra_data { {} }
337
+ end
338
+
339
+ organization { user.organization }
340
+ user
341
+ participatory_space { build :participatory_process, organization: organization }
342
+ feature { build :feature, participatory_space: participatory_space }
343
+ resource { build(:dummy_resource, feature: feature) }
344
+ action { "create" }
345
+ extra do
346
+ {
347
+ feature: {
348
+ manifest_name: feature.try(:manifest_name),
349
+ title: feature.try(:name) || feature.try(:title)
350
+ }.compact,
351
+ participatory_space: {
352
+ manifest_name: participatory_space.try(:class).try(:participatory_space_manifest).try(:name),
353
+ title: participatory_space.try(:name) || participatory_space.try(:title)
354
+ }.compact,
355
+ resource: {
356
+ title: resource.try(:name) || resource.try(:title)
357
+ }.compact,
358
+ user: {
359
+ ip: user.try(:current_sign_in_ip),
360
+ name: user.try(:name),
361
+ nickname: user.try(:nickname)
362
+ }.compact
363
+ }.deep_merge(extra_data)
364
+ end
365
+ end
310
366
  end
@@ -23,7 +23,7 @@ shared_examples "manage announcements" do
23
23
 
24
24
  context "when the general announcement is set" do
25
25
  before do
26
- current_feature.update_attributes!(
26
+ current_feature.update!(
27
27
  settings: {
28
28
  announcement: {
29
29
  en: "An important announcement",
@@ -94,20 +94,22 @@ shared_examples "comments" do
94
94
  let!(:comment_author) { create(:user, :confirmed, organization: organization) }
95
95
  let!(:comment) { create(:comment, commentable: commentable, author: comment_author) }
96
96
 
97
- before do
97
+ it "shows reply to the user" do
98
98
  visit resource_path
99
99
 
100
100
  expect(page).to have_selector(".comment__reply")
101
101
 
102
102
  within "#comments #comment_#{comment.id}" do
103
103
  click_button "Reply"
104
- expect(page).to have_selector(".add-comment")
105
- fill_in "add-comment-Decidim::Comments::Comment-#{comment.id}", with: "This is a reply"
104
+ end
105
+
106
+ expect(page).to have_selector("#comment_#{comment.id} .add-comment")
107
+ fill_in "add-comment-Decidim::Comments::Comment-#{comment.id}", with: "This is a reply"
108
+ within ".comment-thread .add-comment" do
106
109
  click_button "Send"
107
110
  end
108
- end
109
111
 
110
- it "shows reply to the user" do
112
+ expect(page).to have_selector(".comment-thread .comment--nested")
111
113
  expect(page).to have_reply_to(comment, "This is a reply")
112
114
  end
113
115
  end
@@ -172,5 +174,45 @@ shared_examples "comments" do
172
174
  end
173
175
  end
174
176
  end
177
+
178
+ describe "mentions" do
179
+ before do
180
+ visit resource_path
181
+
182
+ within ".add-comment form" do
183
+ fill_in "add-comment-#{commentable.commentable_type}-#{commentable.id}", with: content
184
+ click_button "Send"
185
+ end
186
+ end
187
+
188
+ context "when mentioning a valid user" do
189
+ let!(:mentioned_user) { create(:user, :confirmed, organization: organization) }
190
+ let(:content) { "A valid user mention: @#{mentioned_user.nickname}" }
191
+
192
+ it "replaces the mention with a link to the user's profile" do
193
+ expect(page).to have_comment_from(user, "A valid user mention: @#{mentioned_user.nickname}")
194
+ expect(page).to have_link "@#{mentioned_user.nickname}", href: "/profiles/#{mentioned_user.nickname}"
195
+ end
196
+ end
197
+
198
+ context "when mentioning an existing user outside current organization" do
199
+ let!(:mentioned_user) { create(:user, :confirmed, organization: create(:organization)) }
200
+ let(:content) { "This text mentions a user outside current organization: @#{mentioned_user.nickname}" }
201
+
202
+ it "ignores the mention" do
203
+ expect(page).to have_comment_from(user, "This text mentions a user outside current organization: @#{mentioned_user.nickname}")
204
+ expect(page).not_to have_link "@#{mentioned_user.nickname}"
205
+ end
206
+ end
207
+
208
+ context "when mentioning a non valid user" do
209
+ let(:content) { "This text mentions a @nonexistent user" }
210
+
211
+ it "ignores the mention" do
212
+ expect(page).to have_comment_from(user, "This text mentions a @nonexistent user")
213
+ expect(page).not_to have_link "@nonexistent"
214
+ end
215
+ end
216
+ end
175
217
  end
176
218
  end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ shared_examples_for "a component query type" do
4
+ it "implements ComponentInterface" do
5
+ expect(subject.interfaces).to include(Decidim::Core::ComponentInterface)
6
+ end
7
+ end
@@ -0,0 +1,63 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
4
+
5
+ shared_examples_for "has attachment collections" do
6
+ context "when it has attachment collections", processing_uploads_for: Decidim::AttachmentUploader do
7
+ let(:attachment_collection) { create(:attachment_collection, collection_for: collection_for) }
8
+ let!(:document) { create(:attachment, :with_pdf, attached_to: attached_to, attachment_collection: attachment_collection) }
9
+ let!(:other_document) { create(:attachment, :with_pdf, attached_to: attached_to, attachment_collection: nil) }
10
+
11
+ before do
12
+ visit current_path
13
+ end
14
+
15
+ it "shows them" do
16
+ within ".attachments .documents" do
17
+ expect(page).to have_content(/#{translated(attachment_collection.name, locale: :en)}/i)
18
+ end
19
+ end
20
+
21
+ it "show their documents" do
22
+ within ".attachments .documents #docs-collection-#{attachment_collection.id}", visible: false do
23
+ expect(page).to have_content(:all, /#{translated(document.title, locale: :en)}/i)
24
+ expect(page).not_to have_content(:all, /#{translated(other_document.title, locale: :en)}/i)
25
+ end
26
+ end
27
+ end
28
+
29
+ context "that are ordered by weight", processing_uploads_for: Decidim::AttachmentUploader do
30
+ let!(:last_attachment_collection) { create(:attachment_collection, collection_for: collection_for, weight: 2) }
31
+ let!(:document_one) { create(:attachment, :with_pdf, attached_to: attached_to, attachment_collection: last_attachment_collection) }
32
+
33
+ let!(:first_attachment_collection) { create(:attachment_collection, collection_for: collection_for, weight: 1) }
34
+ let!(:document_two) { create(:attachment, :with_pdf, attached_to: attached_to, attachment_collection: first_attachment_collection) }
35
+
36
+ before do
37
+ visit current_path
38
+ end
39
+
40
+ it "shows them ordered" do
41
+ within ".attachments .documents" do
42
+ expect(translated(first_attachment_collection.name, locale: :en)).to appear_before(translated(last_attachment_collection.name, locale: :en))
43
+ end
44
+ end
45
+ end
46
+
47
+ context "when collection is empty", processing_uploads_for: Decidim::AttachmentUploader do
48
+ let(:attachment_collection) { create(:attachment_collection, collection_for: collection_for) }
49
+ let!(:document) { create(:attachment, :with_pdf, attached_to: attached_to, attachment_collection: attachment_collection) }
50
+ let(:empty_attachment_collection) { create(:attachment_collection, collection_for: collection_for) }
51
+
52
+ before do
53
+ visit current_path
54
+ end
55
+
56
+ it "is not present" do
57
+ within ".attachments .documents" do
58
+ expect(page).to have_content(/#{translated(attachment_collection.name, locale: :en)}/i)
59
+ expect(page).not_to have_content(/#{translated(empty_attachment_collection.name, locale: :en)}/i)
60
+ end
61
+ end
62
+ end
63
+ end
@@ -22,4 +22,25 @@ shared_examples_for "has attachments" do
22
22
  end
23
23
  end
24
24
  end
25
+
26
+ context "that are ordered by weight", processing_uploads_for: Decidim::AttachmentUploader do
27
+ let!(:last_document) { create(:attachment, :with_pdf, attached_to: attached_to, weight: 2) }
28
+ let!(:first_document) { create(:attachment, :with_pdf, attached_to: attached_to, weight: 1) }
29
+ let!(:last_image) { create(:attachment, attached_to: attached_to, weight: 2) }
30
+ let!(:fist_image) { create(:attachment, attached_to: attached_to, weight: 1) }
31
+
32
+ before do
33
+ visit current_path
34
+ end
35
+
36
+ it "shows them ordered" do
37
+ within "div.wrapper .documents" do
38
+ expect(translated(first_document.title, locale: :en)).to appear_before(translated(last_document.title, locale: :en))
39
+ end
40
+
41
+ within "div.wrapper .images" do
42
+ expect(strip_tags(translated(fist_image.description, locale: :en))).to appear_before(strip_tags(translated(last_image.description, locale: :en)))
43
+ end
44
+ end
45
+ end
25
46
  end
@@ -14,7 +14,7 @@ shared_examples_for "has reference" do
14
14
 
15
15
  context "when there is a custom resource reference generator present" do
16
16
  before do
17
- allow(Decidim).to receive(:resource_reference_generator).and_return(->(resource, _feature) { "1234-#{resource.id}" })
17
+ allow(Decidim).to receive(:reference_generator).and_return(->(resource, _feature) { "1234-#{resource.id}" })
18
18
  end
19
19
 
20
20
  it "generates a valid reference" do
@@ -26,11 +26,14 @@ shared_context "simple event" do
26
26
  let(:resource_title) { resource.title["en"] }
27
27
  let(:participatory_space) { resource.participatory_space }
28
28
  let(:participatory_space_title) { participatory_space.title["en"] }
29
+ let(:participatory_space_path) { Decidim::ResourceLocatorPresenter.new(participatory_space).path }
30
+ let(:participatory_space_url) { Decidim::ResourceLocatorPresenter.new(participatory_space).url }
29
31
  let(:author) { resource.author }
30
32
  let(:author_presenter) { Decidim::UserPresenter.new(author) }
33
+ let(:i18n_scope) { event_name }
31
34
  end
32
35
 
33
- shared_examples_for "a simple event" do
36
+ shared_examples_for "a simple event" do |skip_space_checks|
34
37
  describe "types" do
35
38
  subject { described_class }
36
39
 
@@ -85,4 +88,27 @@ shared_examples_for "a simple event" do
85
88
  expect(subject.resource_url).to start_with("http")
86
89
  end
87
90
  end
91
+
92
+ unless skip_space_checks
93
+ describe "participatory_space_url" do
94
+ it "is generated correctly" do
95
+ expect(subject.participatory_space_url).to be_kind_of(String)
96
+ expect(subject.participatory_space_url).to start_with("http")
97
+ end
98
+ end
99
+ end
100
+
101
+ describe "i18n_options" do
102
+ subject { super().i18n_options }
103
+
104
+ it { is_expected.to include(resource_path: satisfy(&:present?)) }
105
+ it { is_expected.to include(resource_title: satisfy(&:present?)) }
106
+ it { is_expected.to include(resource_url: start_with("http")) }
107
+ it { is_expected.to include(scope: i18n_scope) }
108
+
109
+ unless skip_space_checks
110
+ it { is_expected.to include(participatory_space_title: satisfy(&:present?)) }
111
+ it { is_expected.to include(participatory_space_url: start_with("http")) }
112
+ end
113
+ end
88
114
  end
@@ -4,7 +4,7 @@ module Decidim
4
4
  # This holds the decidim-core version.
5
5
  module Core
6
6
  def self.version
7
- "0.9.3"
7
+ "0.10.0"
8
8
  end
9
9
  end
10
10
  end
@@ -30,7 +30,7 @@ module Decidim
30
30
 
31
31
  def author_presenter
32
32
  return unless author
33
- @author ||= Decidim::UserPresenter.new(author)
33
+ @author_presenter ||= Decidim::UserPresenter.new(author)
34
34
  end
35
35
 
36
36
  def author
@@ -86,7 +86,7 @@ module Decidim
86
86
  end
87
87
 
88
88
  def participatory_space
89
- return feature.participatory_space if feature
89
+ feature&.participatory_space
90
90
  end
91
91
 
92
92
  def resource_title
@@ -10,6 +10,7 @@ module Decidim
10
10
  class SimpleEvent < BaseEvent
11
11
  include Decidim::Events::EmailEvent
12
12
  include Decidim::Events::NotificationEvent
13
+ include Decidim::FeaturePathHelper
13
14
 
14
15
  class_attribute :i18n_interpolations
15
16
  self.i18n_interpolations = []
@@ -58,6 +59,25 @@ module Decidim
58
59
  default_i18n_options.merge(event_interpolations)
59
60
  end
60
61
 
62
+ # Caches the path for the given resource when it's a Decidim::Feature.
63
+ def resource_path
64
+ return super unless resource.is_a?(Decidim::Feature)
65
+ @resource_path ||= main_feature_path(resource)
66
+ end
67
+
68
+ # Caches the URL for the given resource when it's a Decidim::Feature.
69
+ def resource_url
70
+ return super unless resource.is_a?(Decidim::Feature)
71
+ @resource_url ||= main_feature_url(resource)
72
+ end
73
+
74
+ # Caches the URL for the resource's participatory space.
75
+ def participatory_space_url
76
+ return unless participatory_space
77
+
78
+ @participatory_space_url ||= ResourceLocatorPresenter.new(participatory_space).url
79
+ end
80
+
61
81
  private
62
82
 
63
83
  def event_interpolations
@@ -72,6 +92,7 @@ module Decidim
72
92
  resource_title: resource_title,
73
93
  resource_url: resource_url,
74
94
  participatory_space_title: participatory_space_title,
95
+ participatory_space_url: participatory_space_url,
75
96
  scope: i18n_scope
76
97
  }
77
98
  end
@@ -36,7 +36,7 @@ module Decidim
36
36
  end
37
37
 
38
38
  processed_collection.each_with_index do |resource, index|
39
- sheet.row(index + 1).replace headers.map { |header| resource[header] }
39
+ sheet.row(index + 1).replace(headers.map { |header| resource[header] })
40
40
  end
41
41
 
42
42
  output = StringIO.new