decidim-core 0.22.0 → 0.23.0

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

Potentially problematic release.


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

Files changed (306) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/config/decidim_core_manifest.js +5 -0
  3. data/app/assets/javascripts/decidim.js.es6 +2 -0
  4. data/app/assets/javascripts/decidim/ajax_modals.js.es6 +3 -3
  5. data/app/assets/javascripts/decidim/confirm.js.es6 +3 -2
  6. data/app/assets/javascripts/decidim/core/bundle.js +1 -1
  7. data/app/assets/javascripts/decidim/core/bundle.js.map +1 -1
  8. data/app/assets/javascripts/decidim/diff_mode_dropdown.js.es6 +18 -4
  9. data/app/assets/javascripts/decidim/editor.js.es6 +3 -3
  10. data/app/assets/javascripts/decidim/geocoding.js.es6 +60 -0
  11. data/app/assets/javascripts/decidim/geocoding/attach_input.js.es6 +106 -0
  12. data/app/assets/javascripts/decidim/geocoding/format_address.js.es6 +29 -0
  13. data/app/assets/javascripts/decidim/geocoding/provider/here.js.es6 +107 -0
  14. data/app/assets/javascripts/decidim/geocoding/provider/photon.js.es6 +77 -0
  15. data/app/assets/javascripts/decidim/map.js.es6 +34 -124
  16. data/app/assets/javascripts/decidim/map/controller.js.es6 +92 -0
  17. data/app/assets/javascripts/decidim/map/controller/markers.js.es6 +65 -0
  18. data/app/assets/javascripts/decidim/map/controller/static.es6 +48 -0
  19. data/app/assets/javascripts/decidim/map/factory.js.es6 +51 -0
  20. data/app/assets/javascripts/decidim/map/icon.js.es6 +31 -0
  21. data/app/assets/javascripts/decidim/map/legacy.js.es6 +87 -0
  22. data/app/assets/javascripts/decidim/map/provider/default.js.es6 +22 -0
  23. data/app/assets/javascripts/decidim/map/provider/here.js.es6 +22 -0
  24. data/app/assets/javascripts/decidim/security/selfxss_warning.js.es6 +19 -0
  25. data/app/assets/stylesheets/decidim/_decidim.scss +2 -0
  26. data/app/assets/stylesheets/decidim/modules/_cards.scss +15 -0
  27. data/app/assets/stylesheets/decidim/modules/_forms.scss +14 -0
  28. data/app/assets/stylesheets/decidim/modules/_layout.scss +11 -3
  29. data/app/assets/stylesheets/decidim/modules/_map.scss +35 -0
  30. data/app/assets/stylesheets/decidim/modules/_progress-bar.scss +4 -0
  31. data/app/assets/stylesheets/decidim/modules/_reveal.scss +5 -0
  32. data/app/assets/stylesheets/decidim/modules/_status-labels.scss +2 -1
  33. data/app/cells/decidim/author/flag.erb +1 -1
  34. data/app/cells/decidim/author/profile_inline.erb +2 -2
  35. data/app/cells/decidim/author_cell.rb +5 -2
  36. data/app/cells/decidim/card_cell.rb +21 -7
  37. data/app/cells/decidim/card_m/show.erb +1 -1
  38. data/app/cells/decidim/card_m_cell.rb +6 -4
  39. data/app/cells/decidim/collapsible_authors_cell.rb +1 -1
  40. data/app/cells/decidim/diff/diff_mode_html.erb +5 -5
  41. data/app/cells/decidim/follow_button/show.erb +6 -6
  42. data/app/cells/decidim/follow_button_cell.rb +8 -0
  43. data/app/cells/decidim/progress_bar/show.erb +11 -4
  44. data/app/cells/decidim/progress_bar_cell.rb +20 -1
  45. data/app/cells/decidim/translation_bar/show.erb +6 -0
  46. data/app/cells/decidim/translation_bar_cell.rb +52 -0
  47. data/app/cells/decidim/version_cell.rb +1 -1
  48. data/app/cells/decidim/versions_list_cell.rb +1 -1
  49. data/app/commands/decidim/amendable/accept.rb +9 -3
  50. data/app/commands/decidim/amendable/create_draft.rb +2 -0
  51. data/app/commands/decidim/amendable/update_draft.rb +2 -0
  52. data/app/commands/decidim/attachment_methods.rb +12 -5
  53. data/app/commands/decidim/destroy_account.rb +1 -0
  54. data/app/commands/decidim/gallery_methods.rb +16 -9
  55. data/app/commands/decidim/messaging/reply_to_conversation.rb +1 -1
  56. data/app/commands/decidim/multiple_attachments_methods.rb +56 -0
  57. data/app/controllers/concerns/decidim/devise_controllers.rb +1 -0
  58. data/app/controllers/concerns/decidim/filter_resource.rb +24 -6
  59. data/app/controllers/concerns/decidim/flaggable.rb +20 -0
  60. data/app/controllers/concerns/decidim/force_authentication.rb +1 -0
  61. data/app/controllers/concerns/decidim/impersonate_users.rb +1 -1
  62. data/app/controllers/concerns/decidim/needs_snippets.rb +20 -0
  63. data/app/controllers/concerns/decidim/paginable.rb +5 -1
  64. data/app/controllers/concerns/decidim/withdrawable.rb +20 -0
  65. data/app/controllers/decidim/application_controller.rb +16 -0
  66. data/app/controllers/decidim/components/base_controller.rb +6 -1
  67. data/app/controllers/decidim/cookie_policy_controller.rb +6 -3
  68. data/app/controllers/decidim/messaging/conversations_controller.rb +5 -2
  69. data/app/forms/decidim/account_form.rb +5 -1
  70. data/app/forms/decidim/amendable/create_form.rb +1 -1
  71. data/app/forms/decidim/amendable/form.rb +44 -3
  72. data/app/forms/decidim/attachment_form.rb +5 -1
  73. data/app/forms/decidim/user_group_form.rb +5 -1
  74. data/app/helpers/decidim/cells_helper.rb +3 -15
  75. data/app/helpers/decidim/check_boxes_tree_helper.rb +21 -12
  76. data/app/helpers/decidim/cookies_helper.rb +1 -1
  77. data/app/helpers/decidim/decidim_form_helper.rb +1 -1
  78. data/app/helpers/decidim/filter_params_helper.rb +30 -0
  79. data/app/helpers/decidim/map_helper.rb +86 -23
  80. data/app/helpers/decidim/orders_helper.rb +6 -1
  81. data/app/helpers/decidim/paginate_helper.rb +3 -1
  82. data/app/helpers/decidim/scopes_helper.rb +4 -4
  83. data/app/helpers/decidim/translations_helper.rb +7 -1
  84. data/app/jobs/decidim/machine_translation_fields_job.rb +30 -0
  85. data/app/jobs/decidim/machine_translation_resource_job.rb +113 -0
  86. data/app/jobs/decidim/machine_translation_save_job.rb +33 -0
  87. data/app/mailers/decidim/reported_mailer.rb +8 -1
  88. data/app/models/decidim/action_log.rb +1 -1
  89. data/app/models/decidim/area.rb +3 -0
  90. data/app/models/decidim/area_type.rb +4 -0
  91. data/app/models/decidim/attachment.rb +30 -2
  92. data/app/models/decidim/attachment_collection.rb +3 -0
  93. data/app/models/decidim/authorization.rb +3 -0
  94. data/app/models/decidim/category.rb +4 -0
  95. data/app/models/decidim/component.rb +7 -0
  96. data/app/models/decidim/content_block.rb +11 -1
  97. data/app/models/decidim/contextual_help_section.rb +4 -0
  98. data/app/models/decidim/follow.rb +3 -1
  99. data/app/models/decidim/messaging/message.rb +1 -1
  100. data/app/models/decidim/moderation.rb +1 -1
  101. data/app/models/decidim/newsletter.rb +3 -0
  102. data/app/models/decidim/oauth_application.rb +2 -0
  103. data/app/models/decidim/organization.rb +53 -9
  104. data/app/models/decidim/scope.rb +4 -1
  105. data/app/models/decidim/scope_type.rb +3 -0
  106. data/app/models/decidim/share_token.rb +49 -0
  107. data/app/models/decidim/static_page.rb +4 -1
  108. data/app/models/decidim/static_page_topic.rb +3 -0
  109. data/app/models/decidim/user_base_entity.rb +6 -2
  110. data/app/permissions/decidim/permissions.rb +9 -0
  111. data/app/presenters/decidim/log/base_presenter.rb +1 -1
  112. data/app/presenters/decidim/log/value_types/default_presenter.rb +1 -1
  113. data/app/presenters/decidim/official_author_presenter.rb +36 -0
  114. data/app/presenters/decidim/resource_locator_presenter.rb +63 -12
  115. data/app/queries/decidim/similar_emendations.rb +4 -4
  116. data/app/scrubbers/decidim/user_input_scrubber.rb +1 -1
  117. data/app/serializers/decidim/importers/participatory_space_components_importer.rb +1 -1
  118. data/app/services/decidim/base_diff_renderer.rb +17 -0
  119. data/app/services/decidim/open_data_exporter.rb +2 -0
  120. data/app/services/decidim/resource_search.rb +95 -6
  121. data/app/services/decidim/static_map_generator.rb +10 -26
  122. data/app/uploaders/decidim/application_uploader.rb +15 -1
  123. data/app/uploaders/decidim/attachment_uploader.rb +23 -17
  124. data/app/uploaders/decidim/banner_image_uploader.rb +1 -1
  125. data/app/uploaders/decidim/hero_image_uploader.rb +1 -1
  126. data/app/uploaders/decidim/homepage_image_uploader.rb +1 -1
  127. data/app/uploaders/decidim/image_uploader.rb +6 -2
  128. data/app/uploaders/decidim/oauth_application_logo_uploader.rb +1 -1
  129. data/app/uploaders/decidim/official_image_footer_uploader.rb +1 -1
  130. data/app/uploaders/decidim/official_image_header_uploader.rb +1 -1
  131. data/app/uploaders/decidim/organization_logo_uploader.rb +1 -1
  132. data/app/uploaders/decidim/record_image_uploader.rb +15 -0
  133. data/app/validators/etiquette_validator.rb +0 -7
  134. data/app/validators/geocoding_validator.rb +9 -4
  135. data/app/validators/passthru_validator.rb +111 -0
  136. data/app/validators/scope_belongs_to_component_validator.rb +16 -0
  137. data/app/validators/uploader_content_type_validator.rb +44 -0
  138. data/app/views/decidim/authorization_modals/_content.html.erb +2 -2
  139. data/app/views/decidim/devise/registrations/new.html.erb +3 -1
  140. data/app/views/decidim/devise/sessions/new.html.erb +3 -1
  141. data/app/views/decidim/messaging/conversations/_error_modal.html.erb +21 -0
  142. data/app/views/decidim/messaging/conversations/error.js.erb +10 -0
  143. data/app/views/decidim/notification_mailer/event_received.html.erb +2 -2
  144. data/app/views/decidim/reported_mailer/report.html.erb +49 -3
  145. data/app/views/decidim/scopes/_scopes_picker_input.html.erb +15 -14
  146. data/app/views/decidim/searches/_filters.html.erb +1 -0
  147. data/app/views/decidim/shared/_login_modal.html.erb +14 -3
  148. data/app/views/decidim/shared/_static_map.html.erb +1 -1
  149. data/app/views/layouts/decidim/_head.html.erb +2 -0
  150. data/app/views/layouts/decidim/_js_configuration.html.erb +7 -1
  151. data/config/locales/am-ET.yml +1 -0
  152. data/config/locales/ar.yml +3 -4
  153. data/config/locales/bg.yml +1508 -0
  154. data/config/locales/ca.yml +35 -8
  155. data/config/locales/cs.yml +34 -7
  156. data/config/locales/da.yml +1 -0
  157. data/config/locales/de.yml +23 -4
  158. data/config/locales/el.yml +0 -4
  159. data/config/locales/en.yml +30 -3
  160. data/config/locales/eo.yml +92 -0
  161. data/config/locales/es-MX.yml +28 -1
  162. data/config/locales/es-PY.yml +28 -1
  163. data/config/locales/es.yml +44 -17
  164. data/config/locales/et.yml +1 -0
  165. data/config/locales/eu.yml +3 -4
  166. data/config/locales/fi-plain.yml +28 -1
  167. data/config/locales/fi.yml +29 -2
  168. data/config/locales/fr-CA.yml +32 -4
  169. data/config/locales/fr.yml +61 -33
  170. data/config/locales/ga-IE.yml +0 -8
  171. data/config/locales/gl.yml +3 -4
  172. data/config/locales/hr.yml +1 -0
  173. data/config/locales/hu.yml +7 -4
  174. data/config/locales/id-ID.yml +3 -4
  175. data/config/locales/is-IS.yml +3 -9
  176. data/config/locales/is.yml +463 -0
  177. data/config/locales/it.yml +36 -8
  178. data/config/locales/ja-JP.yml +25 -16
  179. data/config/locales/ja.yml +1605 -0
  180. data/config/locales/ko-KR.yml +1 -0
  181. data/config/locales/ko.yml +1 -0
  182. data/config/locales/lt.yml +1 -0
  183. data/config/locales/{lv-LV.yml → lv.yml} +0 -4
  184. data/config/locales/mt.yml +1 -0
  185. data/config/locales/nl.yml +25 -3
  186. data/config/locales/no.yml +133 -6
  187. data/config/locales/om-ET.yml +1 -0
  188. data/config/locales/pl.yml +88 -71
  189. data/config/locales/pt-BR.yml +3 -4
  190. data/config/locales/pt.yml +10 -4
  191. data/config/locales/ro-RO.yml +10 -4
  192. data/config/locales/ru.yml +3 -10
  193. data/config/locales/sk.yml +3 -4
  194. data/config/locales/sl.yml +8 -7
  195. data/config/locales/so-SO.yml +1 -0
  196. data/config/locales/sr-CS.yml +0 -7
  197. data/config/locales/sv.yml +17 -6
  198. data/config/locales/ti-ER.yml +1 -0
  199. data/config/locales/tr-TR.yml +3 -4
  200. data/config/locales/uk.yml +3 -11
  201. data/config/locales/vi-VN.yml +1 -0
  202. data/config/locales/vi.yml +1 -0
  203. data/config/locales/zh-CN.yml +1584 -0
  204. data/config/locales/zh-TW.yml +1 -0
  205. data/db/migrate/20200525184143_add_enable_machine_translation_to_decidim_organizations.rb +7 -0
  206. data/db/migrate/20200702073419_create_decidim_share_tokens.rb +16 -0
  207. data/db/migrate/20200707132401_add_comments_max_length_to_decidim_organization.rb +7 -0
  208. data/db/migrate/20200730142511_add_file_upload_settings_to_decidim_organizations.rb +36 -0
  209. data/db/migrate/20200806092109_add_machine_translation_display_priority_to_organizations.rb +17 -0
  210. data/db/migrate/20201004160335_remove_notifications_with_continuity_badge.rb +9 -0
  211. data/db/seeds.rb +5 -4
  212. data/lib/decidim/authorable.rb +22 -1
  213. data/lib/decidim/authorization_form_builder.rb +7 -0
  214. data/lib/decidim/coauthorable.rb +22 -0
  215. data/lib/decidim/component_manifest.rb +1 -1
  216. data/lib/decidim/content_processor.rb +52 -29
  217. data/lib/decidim/content_renderers/base_renderer.rb +1 -1
  218. data/lib/decidim/content_renderers/hashtag_renderer.rb +2 -0
  219. data/lib/decidim/content_renderers/link_renderer.rb +4 -1
  220. data/lib/decidim/content_renderers/user_group_renderer.rb +3 -1
  221. data/lib/decidim/content_renderers/user_renderer.rb +3 -1
  222. data/lib/decidim/core.rb +67 -12
  223. data/lib/decidim/core/engine.rb +60 -21
  224. data/lib/decidim/core/test.rb +6 -0
  225. data/lib/decidim/core/test/factories.rb +34 -8
  226. data/lib/decidim/core/test/shared_examples/amendable/accept_amendment_examples.rb +4 -4
  227. data/lib/decidim/core/test/shared_examples/amendable_proposals_interface_examples.rb +8 -8
  228. data/lib/decidim/core/test/shared_examples/comments_examples.rb +52 -1
  229. data/lib/decidim/core/test/shared_examples/embed_resource_examples.rb +49 -0
  230. data/lib/decidim/core/test/shared_examples/follows_examples.rb +3 -3
  231. data/lib/decidim/core/test/shared_examples/manage_component_share_tokens.rb +83 -0
  232. data/lib/decidim/core/test/shared_examples/map_examples.rb +186 -0
  233. data/lib/decidim/core/test/shared_examples/preview_component_with_share_token_examples.rb +55 -0
  234. data/lib/decidim/core/test/shared_examples/resource_search_examples.rb +200 -0
  235. data/lib/decidim/core/test/shared_examples/scopable_resource_examples.rb +43 -0
  236. data/lib/decidim/core/test/shared_examples/scope_helper_examples.rb +12 -1
  237. data/lib/decidim/core/test/shared_examples/searchable_participatory_space_examples.rb +2 -2
  238. data/lib/decidim/core/test/shared_examples/searchable_results_examples.rb +15 -2
  239. data/lib/decidim/core/test/shared_examples/simple_event.rb +7 -0
  240. data/lib/decidim/core/test/shared_examples/system_endorse_resource_examples.rb +1 -0
  241. data/lib/decidim/core/test/shared_examples/traceable_interface_examples.rb +1 -1
  242. data/lib/decidim/core/test/shared_examples/uncommentable_component_examples.rb +1 -1
  243. data/lib/decidim/core/version.rb +1 -1
  244. data/lib/decidim/diffy_extension.rb +21 -0
  245. data/lib/decidim/events/base_event.rb +11 -9
  246. data/lib/decidim/exporters.rb +7 -0
  247. data/lib/decidim/exporters/csv.rb +15 -1
  248. data/lib/decidim/exporters/excel.rb +1 -1
  249. data/lib/decidim/exporters/export_manifest.rb +29 -0
  250. data/lib/decidim/exporters/pdf.rb +56 -0
  251. data/lib/decidim/file_validator_humanizer.rb +98 -0
  252. data/lib/decidim/form_builder.rb +65 -54
  253. data/lib/decidim/geocodable.rb +79 -0
  254. data/lib/decidim/has_attachments.rb +10 -0
  255. data/lib/decidim/has_upload_validations.rb +36 -0
  256. data/lib/decidim/map.rb +214 -0
  257. data/lib/decidim/map/autocomplete.rb +67 -0
  258. data/lib/decidim/map/dynamic_map.rb +89 -0
  259. data/lib/decidim/map/frontend.rb +97 -0
  260. data/lib/decidim/map/geocoding.rb +115 -0
  261. data/lib/decidim/map/provider.rb +12 -0
  262. data/lib/decidim/map/provider/autocomplete/here.rb +20 -0
  263. data/lib/decidim/map/provider/autocomplete/osm.rb +20 -0
  264. data/lib/decidim/map/provider/dynamic_map/here.rb +51 -0
  265. data/lib/decidim/map/provider/dynamic_map/osm.rb +13 -0
  266. data/lib/decidim/map/provider/geocoding/here.rb +58 -0
  267. data/lib/decidim/map/provider/geocoding/osm.rb +30 -0
  268. data/lib/decidim/map/provider/here.rb +21 -0
  269. data/lib/decidim/map/provider/osm.rb +22 -0
  270. data/lib/decidim/map/provider/static_map/here.rb +35 -0
  271. data/lib/decidim/map/provider/static_map/osm.rb +29 -0
  272. data/lib/decidim/map/static_map.rb +133 -0
  273. data/lib/decidim/map/utility.rb +38 -0
  274. data/lib/decidim/organization_settings.rb +267 -0
  275. data/lib/decidim/resource_manifest.rb +1 -1
  276. data/lib/decidim/scopable.rb +9 -6
  277. data/lib/decidim/scopable_component.rb +29 -1
  278. data/lib/decidim/scopable_participatory_space.rb +19 -0
  279. data/lib/decidim/scopable_resource.rb +21 -0
  280. data/lib/decidim/search_resource_fields_mapper.rb +15 -2
  281. data/lib/decidim/searchable.rb +4 -0
  282. data/lib/decidim/settings_manifest.rb +2 -1
  283. data/lib/decidim/shareable_with_token.rb +27 -0
  284. data/lib/decidim/snippets.rb +30 -0
  285. data/lib/decidim/translatable_attributes.rb +42 -4
  286. data/lib/decidim/translatable_resource.rb +78 -0
  287. data/lib/decidim/view_model.rb +1 -0
  288. data/lib/tasks/decidim_locales_tasks.rake +35 -0
  289. data/lib/tasks/decidim_tasks.rake +1 -0
  290. data/vendor/assets/javascripts/datepicker-locales/foundation-datepicker.bg.js +14 -0
  291. data/vendor/assets/javascripts/datepicker-locales/foundation-datepicker.da.js +14 -0
  292. data/vendor/assets/javascripts/datepicker-locales/foundation-datepicker.eo.js +17 -0
  293. data/vendor/assets/javascripts/datepicker-locales/foundation-datepicker.et.js +18 -0
  294. data/vendor/assets/javascripts/datepicker-locales/foundation-datepicker.fr-CA.js +16 -0
  295. data/vendor/assets/javascripts/datepicker-locales/foundation-datepicker.ga.js +15 -0
  296. data/vendor/assets/javascripts/datepicker-locales/foundation-datepicker.hr.js +13 -0
  297. data/vendor/assets/javascripts/datepicker-locales/foundation-datepicker.is.js +14 -0
  298. data/vendor/assets/javascripts/datepicker-locales/foundation-datepicker.ja.js +16 -0
  299. data/vendor/assets/javascripts/datepicker-locales/foundation-datepicker.lt.js +16 -0
  300. data/vendor/assets/javascripts/datepicker-locales/foundation-datepicker.lv.js +17 -0
  301. data/vendor/assets/javascripts/datepicker-locales/foundation-datepicker.mt.js +15 -0
  302. data/vendor/assets/javascripts/datepicker-locales/foundation-datepicker.sl.js +14 -0
  303. data/vendor/assets/javascripts/datepicker-locales/foundation-datepicker.sr.js +16 -0
  304. metadata +138 -26
  305. data/app/helpers/decidim/multi_translation_helper.rb +0 -0
  306. data/lib/decidim/hashtaggable.rb +0 -24
@@ -100,28 +100,67 @@ module Decidim
100
100
  ActionView::Base.raise_on_missing_translations = true unless Rails.env.production?
101
101
  end
102
102
 
103
- initializer "decidim.geocoding" do
104
- if Decidim.geocoder.present?
105
- config = {
106
- # geocoding service (see below for supported options):
107
- lookup: :here
108
- # IP address geocoding service (see below for supported options):
109
- # :ip_lookup => :maxmind,
110
- # geocoding service request timeout, in seconds (default 3):
111
- # :timeout => 5,
112
- # set default units to kilometers:
113
- # :units => :km,
114
- # caching (see below for details):
115
- # :cache => Redis.new,
116
- # :cache_prefix => "..."
103
+ initializer "decidim.geocoding", after: :load_config_initializers do
104
+ Geocoder.configure(Decidim.geocoder) if Decidim.geocoder.present?
105
+ end
106
+
107
+ initializer "decidim.geocoding_extensions", after: "geocoder.insert_into_active_record" do
108
+ # Include it in ActiveRecord base in order to apply it to all models
109
+ # that may be using the `geocoded_by` or `reverse_geocoded_by` class
110
+ # methods injected by the Geocoder gem.
111
+ ActiveSupport.on_load :active_record do
112
+ ActiveRecord::Base.send(:include, Decidim::Geocodable)
113
+ end
114
+ end
115
+
116
+ initializer "decidim.maps" do
117
+ Decidim::Map.register_category(:dynamic, Decidim::Map::Provider::DynamicMap)
118
+ Decidim::Map.register_category(:static, Decidim::Map::Provider::StaticMap)
119
+ Decidim::Map.register_category(:geocoding, Decidim::Map::Provider::Geocoding)
120
+ Decidim::Map.register_category(:autocomplete, Decidim::Map::Provider::Autocomplete)
121
+ end
122
+
123
+ # This keeps backwards compatibility with the old style of map
124
+ # configuration through Decidim.geocoder.
125
+ initializer "decidim.maps_legacysupport", after: :load_config_initializers do
126
+ next if Decidim.maps.present?
127
+ next if Decidim.geocoder.blank?
128
+
129
+ legacy_api_key ||= begin
130
+ if Decidim.geocoder[:here_api_key].present?
131
+ Decidim.geocoder.fetch(:here_api_key)
132
+ elsif Decidim.geocoder[:here_app_id].present?
133
+ [
134
+ Decidim.geocoder.fetch(:here_app_id),
135
+ Decidim.geocoder.fetch(:here_app_code)
136
+ ]
137
+ end
138
+ end
139
+ next unless legacy_api_key
140
+
141
+ ActiveSupport::Deprecation.warn(
142
+ <<~DEPRECATION.strip
143
+ Configuring maps functionality has changed.
144
+
145
+ Please update your current Decidim.geocoder configurations to the following format:
146
+
147
+ Decidim.configure do |config|
148
+ config.maps = {
149
+ provider: :here,
150
+ api_key: Rails.application.secrets.maps[:api_key],
151
+ static: { url: "#{Decidim.geocoder.fetch(:static_map_url)}" }
152
+ }
153
+ end
154
+ DEPRECATION
155
+ )
156
+ Decidim.configure do |config|
157
+ config.maps = {
158
+ provider: :here,
159
+ api_key: legacy_api_key,
160
+ static: {
161
+ url: Decidim.geocoder.fetch(:static_map_url)
162
+ }
117
163
  }
118
- # to use an API key:
119
- config[:api_key] = if Decidim.geocoder[:here_api_key].present?
120
- Decidim.geocoder.fetch(:here_api_key)
121
- else
122
- [Decidim.geocoder.fetch(:here_app_id), Decidim.geocoder.fetch(:here_app_code)]
123
- end
124
- Geocoder.configure(config)
125
164
  end
126
165
  end
127
166
 
@@ -24,6 +24,7 @@ require "decidim/core/test/shared_examples/user_localised_email_examples"
24
24
  require "decidim/core/test/shared_examples/follows_examples"
25
25
  require "decidim/core/test/shared_examples/simple_event"
26
26
  require "decidim/core/test/shared_examples/component_type"
27
+ require "decidim/core/test/shared_examples/scopable_resource_examples"
27
28
  require "decidim/core/test/shared_examples/fingerprint_examples"
28
29
  require "decidim/core/test/shared_examples/searchable_results_examples"
29
30
  require "decidim/core/test/shared_examples/has_space_in_mcell_examples"
@@ -54,4 +55,9 @@ require "decidim/core/test/shared_examples/rich_text_editor_examples"
54
55
  require "decidim/core/test/shared_examples/back_to_list_button_examples"
55
56
  require "decidim/core/test/shared_examples/permissions"
56
57
  require "decidim/core/test/shared_examples/admin_resource_gallery_examples"
58
+ require "decidim/core/test/shared_examples/map_examples"
59
+ require "decidim/core/test/shared_examples/preview_component_with_share_token_examples"
60
+ require "decidim/core/test/shared_examples/manage_component_share_tokens"
57
61
  require "decidim/core/test/shared_examples/metric_manage_shared_context"
62
+ require "decidim/core/test/shared_examples/embed_resource_examples"
63
+ require "decidim/core/test/shared_examples/resource_search_examples"
@@ -13,7 +13,7 @@ end
13
13
 
14
14
  FactoryBot.define do
15
15
  sequence(:title) do |n|
16
- "#{Faker::Lorem.sentence(3)} #{n}"
16
+ "#{Faker::Lorem.sentence(3)} #{n}".delete("'")
17
17
  end
18
18
 
19
19
  sequence(:name) do |n|
@@ -21,11 +21,11 @@ FactoryBot.define do
21
21
  end
22
22
 
23
23
  sequence(:nickname) do |n|
24
- "#{Faker::Lorem.characters(rand(1..10))}_#{n}"
24
+ "#{Faker::Lorem.characters(rand(1..10))}_#{n}".gsub("'", "_")
25
25
  end
26
26
 
27
27
  sequence(:hashtag_name) do |n|
28
- "#{Faker::Lorem.characters(rand(1..10))}_#{n}"
28
+ "#{Faker::Lorem.characters(rand(1..10))}_#{n}".gsub("'", "_")
29
29
  end
30
30
 
31
31
  sequence(:email) do |n|
@@ -37,7 +37,7 @@ FactoryBot.define do
37
37
  end
38
38
 
39
39
  sequence(:slug) do |n|
40
- "#{Faker::Internet.slug(nil, "-")}-#{n}"
40
+ "#{Faker::Internet.slug(nil, "-")}-#{n}".gsub("'", "_")
41
41
  end
42
42
 
43
43
  sequence(:scope_name) do |n|
@@ -89,8 +89,10 @@ FactoryBot.define do
89
89
  badges_enabled { true }
90
90
  user_groups_enabled { true }
91
91
  send_welcome_notification { true }
92
+ comments_max_length { 1000 }
92
93
  admin_terms_of_use_body { Decidim::Faker::Localized.wrapped("<p>", "</p>") { generate_localized_title } }
93
94
  force_users_to_authenticate_before_access_organization { false }
95
+ machine_translation_display_priority { "original" }
94
96
  smtp_settings do
95
97
  {
96
98
  "from" => "test@example.org",
@@ -100,6 +102,7 @@ FactoryBot.define do
100
102
  "address" => "smtp.example.org"
101
103
  }
102
104
  end
105
+ file_upload_settings { Decidim::OrganizationSettings.default(:upload) }
103
106
 
104
107
  after(:create) do |organization|
105
108
  tos_page = Decidim::StaticPage.find_by(slug: "terms-and-conditions", organization: organization)
@@ -181,9 +184,9 @@ FactoryBot.define do
181
184
  sequence(:name) { |n| "#{Faker::Company.name} #{n}" }
182
185
  email { generate(:user_group_email) }
183
186
  nickname { generate(:nickname) }
184
- avatar { Decidim::Dev.test_file("avatar.jpg", "image/jpeg") }
185
187
  about { "<script>alert(\"ABOUT\");</script>" + Faker::Lorem.paragraph(2) }
186
188
  organization
189
+ avatar { Decidim::Dev.test_file("avatar.jpg", "image/jpeg") } # Keep after organization
187
190
 
188
191
  transient do
189
192
  users { [] }
@@ -258,7 +261,7 @@ FactoryBot.define do
258
261
  organization { build(:organization) }
259
262
 
260
263
  trait :default do
261
- slug { (Decidim::StaticPage::DEFAULT_PAGES - ["terms-and-conditions"]).sample }
264
+ slug { Decidim::StaticPage::DEFAULT_PAGES.sample }
262
265
  end
263
266
 
264
267
  trait :tos do
@@ -295,10 +298,10 @@ FactoryBot.define do
295
298
  factory :attachment, class: "Decidim::Attachment" do
296
299
  title { generate_localized_title }
297
300
  description { Decidim::Faker::Localized.wrapped("<p>", "</p>") { generate_localized_title } }
298
- file { Decidim::Dev.test_file("city.jpeg", "image/jpeg") }
299
301
  weight { Faker::Number.number(1) }
300
302
  attached_to { build(:participatory_process) }
301
303
  content_type { "image/jpeg" }
304
+ file { Decidim::Dev.test_file("city.jpeg", "image/jpeg") } # Keep after attached_to
302
305
  file_size { 108_908 }
303
306
 
304
307
  trait :with_image do
@@ -447,7 +450,7 @@ FactoryBot.define do
447
450
  # user_groups correspondence to users is by sorting order
448
451
  user_groups { [] }
449
452
  end
450
- title { generate(:name) }
453
+ title { Decidim::Faker::Localized.localized { generate(:name) } }
451
454
  component { create(:component, manifest_name: "dummy") }
452
455
  author { create(:user, :confirmed, organization: component.organization) }
453
456
  scope { create(:scope, organization: component.organization) }
@@ -465,6 +468,11 @@ FactoryBot.define do
465
468
  end
466
469
  end
467
470
 
471
+ factory :nested_dummy_resource, class: "Decidim::DummyResources::NestedDummyResource" do
472
+ title { generate(:name) }
473
+ dummy_resource { create(:dummy_resource) }
474
+ end
475
+
468
476
  factory :coauthorable_dummy_resource, class: "Decidim::DummyResources::CoauthorableDummyResource" do
469
477
  title { generate(:name) }
470
478
  component { create(:component, manifest_name: "dummy") }
@@ -683,4 +691,22 @@ FactoryBot.define do
683
691
  author { build(:user, organization: resource.organization) }
684
692
  user_group { create(:user_group, verified_at: Time.current, organization: resource.organization, users: [author]) }
685
693
  end
694
+
695
+ factory :share_token, class: "Decidim::ShareToken" do
696
+ token_for { build(:component) }
697
+ user { build(:user, organization: token_for.organization) }
698
+
699
+ before(:create) do |object|
700
+ object.organization ||= object.token_for.organization
701
+ end
702
+
703
+ trait :expired do
704
+ expires_at { 1.day.ago }
705
+ end
706
+
707
+ trait :used do
708
+ times_used { 3 }
709
+ last_used_at { 1.hour.ago }
710
+ end
711
+ end
686
712
  end
@@ -26,18 +26,18 @@ shared_examples "accept amendment" do
26
26
  amendable.creator_author,
27
27
  { state: "accepted" },
28
28
  visibility: "public-only"
29
- ).and_call_original
29
+ ).and_return(amendment)
30
30
 
31
31
  expect(Decidim.traceability)
32
- .to receive(:update!)
32
+ .to receive(:perform_action!)
33
33
  .with(
34
+ :update,
34
35
  amendable,
35
36
  emendation.creator_author,
36
- { body: emendation.body, title: emendation.title },
37
37
  visibility: "public-only"
38
38
  ).and_call_original
39
39
 
40
- expect { command.call }.to change(Decidim::ActionLog, :count).by(2)
40
+ command.call
41
41
  end
42
42
 
43
43
  it "notifies the change" do
@@ -5,14 +5,14 @@ require "spec_helper"
5
5
  shared_examples_for "amendable proposals interface" do
6
6
  describe "amendments" do
7
7
  let(:query) do
8
- "{ amendments {
8
+ '{ amendments {
9
9
  state
10
- amendable { ...on Proposal { title } }
10
+ amendable { ...on Proposal { title { translation(locale: "en") } } }
11
11
  amendableType
12
- emendation { ...on Proposal { title } }
12
+ emendation { ...on Proposal { title { translation(locale: "en") } } }
13
13
  emendationType
14
14
  amender { name }
15
- } }"
15
+ } }'
16
16
  end
17
17
 
18
18
  it "includes the amendments states" do
@@ -33,13 +33,13 @@ shared_examples_for "amendable proposals interface" do
33
33
  end
34
34
 
35
35
  it "returns amendable as parent proposal" do
36
- amendment_amendables = response["amendments"].map { |amendment| amendment["amendable"] }
37
- expect(amendment_amendables).to include(*model.amendments.map(&:amendable).map { |p| { "title" => p.title } })
36
+ amendment_amendables = response["amendments"].map { |amendment| amendment["amendable"] }.map { |title| title["title"]["translation"] }
37
+ expect(amendment_amendables).to include(*model.amendments.map(&:amendable).map { |p| p.title["en"] })
38
38
  end
39
39
 
40
40
  it "returns emendations received" do
41
- amendment_emendations = response["amendments"].map { |amendment| amendment["emendation"] }
42
- expect(amendment_emendations).to include(*model.amendments.map(&:emendation).map { |p| { "title" => p.title } })
41
+ amendment_emendations = response["amendments"].map { |amendment| amendment["emendation"] }.map { |title| title["title"]["translation"] }
42
+ expect(amendment_emendations).to include(*model.amendments.map(&:emendation).map { |p| p.title["en"] })
43
43
  end
44
44
 
45
45
  it "returns amender as emendation author" do
@@ -9,6 +9,10 @@ shared_examples "comments" do
9
9
  switch_to_host(organization.host)
10
10
  end
11
11
 
12
+ after do
13
+ expect_no_js_errors
14
+ end
15
+
12
16
  it "shows the list of comments for the resource" do
13
17
  visit resource_path
14
18
 
@@ -18,7 +22,7 @@ shared_examples "comments" do
18
22
  within "#comments" do
19
23
  comments.each do |comment|
20
24
  expect(page).to have_content comment.author.name
21
- expect(page).to have_content comment.body
25
+ expect(page).to have_content comment.body.values.first
22
26
  end
23
27
  end
24
28
  end
@@ -61,6 +65,35 @@ shared_examples "comments" do
61
65
  expect(page).to have_selector(".add-comment form")
62
66
  end
63
67
 
68
+ context "when no default comments length specified" do
69
+ it "displays the numbers of characters left" do
70
+ within ".add-comment form" do
71
+ expect(page).to have_content("1000 characters left")
72
+ end
73
+ end
74
+ end
75
+
76
+ context "when organization has a default comments length params" do
77
+ let!(:organization) { create(:organization, comments_max_length: 2000) }
78
+
79
+ it "displays the numbers of characters left" do
80
+ within ".add-comment form" do
81
+ expect(page).to have_content("2000 characters left")
82
+ end
83
+ end
84
+
85
+ context "when component has a default comments length params" do
86
+ it "displays the numbers of characters left" do
87
+ component.update!(settings: { comments_max_length: 3000 })
88
+ visit current_path
89
+
90
+ within ".add-comment form" do
91
+ expect(page).to have_content("3000 characters left")
92
+ end
93
+ end
94
+ end
95
+ end
96
+
64
97
  context "when user adds a new comment" do
65
98
  before do
66
99
  within ".add-comment form" do
@@ -286,5 +319,23 @@ shared_examples "comments" do
286
319
  end
287
320
  end
288
321
  end
322
+
323
+ describe "hashtags", :slow do
324
+ let(:content) { "A comment with a hashtag #decidim" }
325
+
326
+ before do
327
+ visit resource_path
328
+
329
+ within ".add-comment form" do
330
+ fill_in "add-comment-#{commentable.commentable_type}-#{commentable.id}", with: content
331
+ click_button "Send"
332
+ end
333
+ end
334
+
335
+ it "replaces the hashtag with a link to the hashtag search" do
336
+ expect(page).to have_comment_from(user, "A comment with a hashtag #decidim", wait: 20)
337
+ expect(page).to have_link "#decidim", href: "/search?term=%23decidim"
338
+ end
339
+ end
289
340
  end
290
341
  end
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ shared_examples_for "an embed resource" do |options|
4
+ if options.is_a?(Hash) && options[:skip_space_checks]
5
+ let(:organization) { resource.organization }
6
+
7
+ before do
8
+ switch_to_host(organization.host)
9
+ end
10
+ else
11
+ include_context "with a component"
12
+ end
13
+
14
+ context "when visiting the embed page for a resource" do
15
+ before do
16
+ visit resource_locator(resource).path
17
+ visit "#{current_path}/embed"
18
+ end
19
+
20
+ it "renders the page correctly" do
21
+ if resource.title.is_a?(Hash)
22
+ expect(page).to have_i18n_content(resource.title)
23
+ else
24
+ expect(page).to have_content(resource.title)
25
+ end
26
+
27
+ expect(page).to have_content(organization.name)
28
+ end
29
+
30
+ unless options.is_a?(Hash) && options[:skip_space_checks]
31
+ context "when the participatory_space is a process" do
32
+ it "shows the process name" do
33
+ expect(page).to have_i18n_content(participatory_process.title)
34
+ end
35
+ end
36
+
37
+ context "when the participatory_space is an assembly" do
38
+ let(:assembly) do
39
+ create(:assembly, organization: organization)
40
+ end
41
+ let(:participatory_space) { assembly }
42
+
43
+ it "shows the assembly name" do
44
+ expect(page).to have_i18n_content(assembly.title)
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
@@ -10,7 +10,7 @@ shared_examples "follows" do
10
10
  context "when not following the followable" do
11
11
  context "when user clicks the Follow button" do
12
12
  it "makes the user follow the followable" do
13
- visit resource_locator(followable).path
13
+ visit followable_path
14
14
  expect do
15
15
  click_button "Follow"
16
16
  expect(page).to have_content "Stop following"
@@ -26,7 +26,7 @@ shared_examples "follows" do
26
26
 
27
27
  context "when user clicks the Follow button" do
28
28
  it "makes the user follow the followable" do
29
- visit resource_locator(followable).path
29
+ visit followable_path
30
30
  expect do
31
31
  click_button "Stop following"
32
32
  expect(page).to have_content "Follow"
@@ -42,7 +42,7 @@ shared_examples "follows" do
42
42
 
43
43
  context "when user clicks the Follow button" do
44
44
  it "makes the user follow the followable" do
45
- visit resource_locator(followable).path
45
+ visit followable_path
46
46
  expect do
47
47
  click_button "Already following #{translated(followable.participatory_space.title)}"
48
48
  expect(page).to have_content "Stop following"
@@ -0,0 +1,83 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.shared_examples "manage component share tokens" do
4
+ let!(:components_path) { participatory_space_components_path(participatory_space) }
5
+
6
+ context "when visiting the components page for the participatory space" do
7
+ before do
8
+ visit components_path
9
+ end
10
+
11
+ it "has a share button that opens the share url for the component" do
12
+ share_window = window_opened_by { click_link "Share", wait: 2 }
13
+
14
+ within_window share_window do
15
+ expect(page).to have_current_path(component.share_tokens.reload.last.url)
16
+ end
17
+ end
18
+ end
19
+
20
+ context "when visiting the component configuration page" do
21
+ context "when there are tokens" do
22
+ let!(:share_tokens) { create_list(:share_token, 3, token_for: component, organization: component.organization) }
23
+ let!(:share_token) { share_tokens.last }
24
+
25
+ before do
26
+ visit components_path
27
+
28
+ within find("tr", text: component.name["en"]) do
29
+ click_link "Configure"
30
+ end
31
+ end
32
+
33
+ it "displays all tokens" do
34
+ within ".share_tokens" do
35
+ expect(page).to have_selector("tbody tr", count: 3)
36
+ end
37
+ end
38
+
39
+ it "displays relevant attributes for each token" do
40
+ share_tokens.each do |share_token|
41
+ within ".share_tokens tbody" do
42
+ expect(page).to have_content share_token.token
43
+ expect(page).to have_content share_token.user.name
44
+ end
45
+ end
46
+ end
47
+
48
+ it "has a share link for each token" do
49
+ urls = share_tokens.map(&:url).map { |url| url.split("?").first }
50
+ within ".share_tokens tbody tr:first-child" do
51
+ share_window = window_opened_by { click_link "Share" }
52
+
53
+ within_window share_window do
54
+ expect(urls).to include(page.current_path)
55
+ end
56
+ end
57
+ end
58
+
59
+ it "has a link to delete tokens" do
60
+ within ".share_tokens tbody tr:first-child" do
61
+ accept_confirm { click_link "Delete" }
62
+ end
63
+
64
+ expect(page).to have_admin_callout("successfully")
65
+ expect(page).to have_selector("tbody tr", count: 2)
66
+ end
67
+ end
68
+
69
+ context "when there are no tokens" do
70
+ before do
71
+ visit components_path
72
+
73
+ within find("tr", text: component.name["en"]) do
74
+ click_link "Configure"
75
+ end
76
+ end
77
+
78
+ it "displays empty message" do
79
+ expect(page).to have_content "There are no active tokens"
80
+ end
81
+ end
82
+ end
83
+ end