decidim-core 0.30.2 → 0.31.0.rc1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (774) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +0 -4
  3. data/app/cells/decidim/activity_cell.rb +0 -3
  4. data/app/cells/decidim/address/show.erb +1 -0
  5. data/app/cells/decidim/address_cell.rb +7 -1
  6. data/app/cells/decidim/amendable/amend_button_card/show.erb +2 -2
  7. data/app/cells/decidim/author/likes.erb +4 -0
  8. data/app/cells/decidim/author/show.erb +1 -3
  9. data/app/cells/decidim/author_cell.rb +5 -28
  10. data/app/cells/decidim/badge_cell.rb +1 -7
  11. data/app/cells/decidim/card_cell.rb +2 -12
  12. data/app/cells/decidim/card_metadata_cell.rb +4 -4
  13. data/app/cells/decidim/coauthorships_cell.rb +1 -1
  14. data/app/cells/decidim/collapsible_authors/show.erb +1 -1
  15. data/app/cells/decidim/content_blocks/hero_cell.rb +23 -4
  16. data/app/cells/decidim/content_blocks/hero_settings_form/show.erb +16 -2
  17. data/app/cells/decidim/content_blocks/highlighted_content_banner/show.erb +6 -6
  18. data/app/cells/decidim/content_blocks/highlighted_content_banner_cell.rb +28 -1
  19. data/app/cells/decidim/content_blocks/highlighted_content_banner_settings_form/show.erb +27 -0
  20. data/app/cells/decidim/content_blocks/highlighted_content_banner_settings_form_cell.rb +13 -0
  21. data/app/cells/decidim/content_blocks/highlighted_elements_for_component_settings_form/show.erb +9 -2
  22. data/app/cells/decidim/content_blocks/html_settings_form/show.erb +3 -1
  23. data/app/cells/decidim/content_blocks/last_activity_cell.rb +1 -1
  24. data/app/cells/decidim/content_blocks/last_activity_settings_form/show.erb +3 -1
  25. data/app/cells/decidim/content_blocks/menu_breadcrumb_last_activity_cell.rb +1 -1
  26. data/app/cells/decidim/content_blocks/participatory_space_extra_data/recent_users.erb +1 -1
  27. data/app/cells/decidim/content_blocks/participatory_space_hero/show.erb +0 -5
  28. data/app/cells/decidim/content_blocks/participatory_space_hero_cell.rb +1 -13
  29. data/app/cells/decidim/content_blocks/participatory_space_hero_settings_form/show.erb +10 -3
  30. data/app/cells/decidim/content_blocks/participatory_space_last_activity/content.erb +1 -1
  31. data/app/cells/decidim/content_blocks/participatory_space_last_activity/recent_avatars.erb +1 -1
  32. data/app/cells/decidim/content_blocks/participatory_space_last_activity_cell.rb +3 -3
  33. data/app/cells/decidim/content_blocks/participatory_space_main_data/title.erb +17 -5
  34. data/app/cells/decidim/content_blocks/participatory_space_main_data_cell.rb +4 -0
  35. data/app/cells/decidim/content_blocks/stats/show.erb +2 -3
  36. data/app/cells/decidim/data_consent/modal.erb +1 -1
  37. data/app/cells/decidim/like_block/show.erb +3 -0
  38. data/app/cells/decidim/{endorsement_block_cell.rb → like_block_cell.rb} +2 -2
  39. data/app/cells/decidim/like_buttons/button_content.erb +2 -0
  40. data/app/cells/decidim/like_buttons/show.erb +17 -0
  41. data/app/cells/decidim/{endorsement_buttons → like_buttons}/verification_modal.erb +3 -3
  42. data/app/cells/decidim/like_buttons_cell.rb +77 -0
  43. data/app/cells/decidim/likers_list/empty.erb +3 -0
  44. data/app/cells/decidim/{endorsers_list → likers_list}/full.erb +3 -3
  45. data/app/cells/decidim/likers_list/show.erb +20 -0
  46. data/app/cells/decidim/likers_list_cell.rb +64 -0
  47. data/app/cells/decidim/nav_links/show.erb +1 -1
  48. data/app/cells/decidim/notification_actions/buttons_cell.rb +1 -1
  49. data/app/cells/decidim/onboarding_action_message_cell.rb +1 -1
  50. data/app/cells/decidim/participatory_space_dropdown_metadata/metadata.erb +0 -8
  51. data/app/cells/decidim/participatory_space_dropdown_metadata_cell.rb +0 -8
  52. data/app/cells/decidim/profile/details.erb +1 -1
  53. data/app/cells/decidim/profile/tabs.erb +1 -1
  54. data/app/cells/decidim/profile_actions/show.erb +0 -1
  55. data/app/cells/decidim/profile_actions_cell.rb +5 -91
  56. data/app/cells/decidim/profile_cell.rb +4 -39
  57. data/app/cells/decidim/report_button/content.erb +2 -0
  58. data/app/cells/decidim/report_button/flag_modal.erb +1 -1
  59. data/app/cells/decidim/report_button_cell.rb +1 -1
  60. data/app/cells/decidim/report_user_button/flag_modal.erb +1 -1
  61. data/app/cells/decidim/resource_history_cell.rb +2 -1
  62. data/app/cells/decidim/resource_types_filter/show.erb +1 -1
  63. data/app/cells/decidim/share_button_cell.rb +1 -1
  64. data/app/cells/decidim/share_text_widget/modal.erb +16 -0
  65. data/app/cells/decidim/share_text_widget/show.erb +2 -0
  66. data/app/cells/decidim/share_text_widget_cell.rb +27 -0
  67. data/app/cells/decidim/share_widget/modal.erb +19 -8
  68. data/app/cells/decidim/share_widget/qr_code_modal.erb +26 -0
  69. data/app/cells/decidim/share_widget/show.erb +1 -0
  70. data/app/cells/decidim/share_widget_cell.rb +10 -6
  71. data/app/cells/decidim/statistic/show.erb +23 -5
  72. data/app/cells/decidim/statistic_cell.rb +28 -3
  73. data/app/cells/decidim/tab_panels/show.erb +1 -1
  74. data/app/cells/decidim/user_profile/show.erb +1 -1
  75. data/app/cells/decidim/user_profile_cell.rb +1 -9
  76. data/app/cells/decidim/version_author_cell.rb +0 -7
  77. data/app/commands/decidim/amendable/accept.rb +1 -3
  78. data/app/commands/decidim/amendable/create_draft.rb +2 -3
  79. data/app/commands/decidim/amendable/update_draft.rb +2 -3
  80. data/app/commands/decidim/create_ephemeral_user.rb +7 -1
  81. data/app/commands/decidim/create_omniauth_registration.rb +8 -7
  82. data/app/commands/decidim/create_report.rb +9 -1
  83. data/app/commands/decidim/destroy_account.rb +0 -5
  84. data/app/commands/decidim/like_resource.rb +52 -0
  85. data/app/commands/decidim/messaging/reply_to_conversation.rb +2 -21
  86. data/app/commands/decidim/messaging/start_conversation.rb +2 -21
  87. data/app/commands/decidim/unlike_resource.rb +34 -0
  88. data/app/commands/decidim/update_account.rb +1 -1
  89. data/app/controllers/concerns/decidim/ephemeral_session_checker.rb +6 -2
  90. data/app/controllers/concerns/decidim/user_profile.rb +0 -1
  91. data/app/controllers/decidim/account_controller.rb +1 -1
  92. data/app/controllers/decidim/amendments_controller.rb +4 -5
  93. data/app/controllers/decidim/application_controller.rb +2 -1
  94. data/app/controllers/decidim/devise/confirmations_controller.rb +0 -5
  95. data/app/controllers/decidim/devise/omniauth_registrations_controller.rb +1 -1
  96. data/app/controllers/decidim/devise/passwords_controller.rb +1 -1
  97. data/app/controllers/decidim/devise/registrations_controller.rb +1 -1
  98. data/app/controllers/decidim/doorkeeper/authorizations_controller.rb +19 -1
  99. data/app/controllers/decidim/download_your_data_controller.rb +2 -2
  100. data/app/controllers/decidim/likes_controller.rb +57 -0
  101. data/app/controllers/decidim/links_controller.rb +1 -0
  102. data/app/controllers/decidim/messaging/conversations_controller.rb +1 -8
  103. data/app/controllers/decidim/newsletters_controller.rb +1 -1
  104. data/app/controllers/decidim/notifications_settings_controller.rb +2 -2
  105. data/app/controllers/decidim/pages_controller.rb +0 -1
  106. data/app/controllers/decidim/profiles_controller.rb +2 -57
  107. data/app/controllers/decidim/qr_controller.rb +73 -0
  108. data/app/controllers/decidim/resource_autocomplete_controller.rb +56 -0
  109. data/app/controllers/decidim/user_activities_controller.rb +0 -1
  110. data/app/events/decidim/resource_liked_event.rb +36 -0
  111. data/app/forms/decidim/amendable/create_form.rb +0 -1
  112. data/app/forms/decidim/amendable/edit_form.rb +0 -1
  113. data/app/forms/decidim/amendable/form.rb +4 -4
  114. data/app/forms/decidim/ephemeral_user_form.rb +1 -0
  115. data/app/forms/decidim/notifications_settings_form.rb +1 -1
  116. data/app/forms/decidim/omniauth_registration_form.rb +1 -1
  117. data/app/forms/decidim/upload_validation_form.rb +9 -1
  118. data/app/helpers/decidim/amendments_helper.rb +1 -2
  119. data/app/helpers/decidim/animations_helper.rb +14 -0
  120. data/app/helpers/decidim/decidim_form_helper.rb +17 -6
  121. data/app/helpers/decidim/layout_helper.rb +1 -15
  122. data/app/helpers/decidim/likeable_helper.rb +46 -0
  123. data/app/helpers/decidim/messaging/conversation_helper.rb +1 -1
  124. data/app/helpers/decidim/omniauth_helper.rb +1 -1
  125. data/app/helpers/decidim/qr_code_helper.rb +37 -0
  126. data/app/helpers/decidim/rich_text_editor_helper.rb +0 -1
  127. data/app/helpers/decidim/sanitize_helper.rb +5 -5
  128. data/app/helpers/decidim/social_share_button_helper.rb +11 -10
  129. data/app/jobs/decidim/delete_inactive_participants_job.rb +41 -0
  130. data/app/jobs/decidim/process_inactive_participant_job.rb +48 -0
  131. data/app/mailers/decidim/participants_account_mailer.rb +38 -0
  132. data/app/mailers/decidim/user_group_mailer.rb +28 -0
  133. data/app/models/decidim/action_log.rb +3 -5
  134. data/app/models/decidim/amendment.rb +1 -1
  135. data/app/models/decidim/attachment_collection.rb +2 -0
  136. data/app/models/decidim/authorization_transfer.rb +0 -1
  137. data/app/models/decidim/coauthorship.rb +1 -1
  138. data/app/models/decidim/component.rb +4 -1
  139. data/app/models/decidim/{endorsement.rb → like.rb} +4 -4
  140. data/app/models/decidim/messaging/conversation.rb +3 -5
  141. data/app/models/decidim/messaging/message.rb +3 -15
  142. data/app/models/decidim/omniauth_provider.rb +1 -1
  143. data/app/models/decidim/organization.rb +3 -8
  144. data/app/models/decidim/participatory_space_role_config/{valuator.rb → evaluator.rb} +1 -1
  145. data/app/models/decidim/reminder_record.rb +1 -1
  146. data/app/models/decidim/searchable_resource.rb +16 -0
  147. data/app/models/decidim/taxonomy.rb +6 -1
  148. data/app/models/decidim/user.rb +32 -15
  149. data/app/models/decidim/user_base_entity.rb +2 -2
  150. data/app/packs/entrypoints/decidim_conference_diploma.scss +2 -2
  151. data/app/packs/entrypoints/decidim_core.scss +2 -2
  152. data/app/packs/entrypoints/decidim_editor.js +0 -4
  153. data/app/packs/entrypoints/decidim_map.scss +2 -2
  154. data/app/packs/entrypoints/decidim_overrides.scss +1 -1
  155. data/app/packs/entrypoints/decidim_qr.js +1 -0
  156. data/app/packs/images/decidim/remixicon.symbol.svg +3 -3
  157. data/app/packs/src/decidim/a11y.js +1 -120
  158. data/app/packs/src/decidim/append_redirect_url_to_modals.js +1 -1
  159. data/app/packs/src/decidim/attachments/file_or_link_tabs.js +1 -1
  160. data/app/packs/src/decidim/confirm.js +27 -20
  161. data/app/packs/src/decidim/controllers/.keep +0 -0
  162. data/app/packs/src/decidim/controllers/accordion/controller.js +100 -0
  163. data/app/packs/src/decidim/controllers/account_form/account_form.test.js +423 -0
  164. data/app/packs/src/decidim/controllers/account_form/controller.js +69 -0
  165. data/app/packs/src/decidim/{input_character_counter.js → controllers/character_counter/controller.js} +90 -106
  166. data/app/packs/src/decidim/controllers/clipboard_copy/clipboard_copy.test.js +305 -0
  167. data/app/packs/src/decidim/controllers/clipboard_copy/controller.js +403 -0
  168. data/app/packs/src/decidim/controllers/date_picker/controller.js +12 -0
  169. data/app/packs/src/decidim/controllers/delete_account_form/controller.js +45 -0
  170. data/app/packs/src/decidim/controllers/delete_account_form/delete_account_form.test.js +216 -0
  171. data/app/packs/src/decidim/controllers/dropdown/controller.js +125 -0
  172. data/app/packs/src/decidim/controllers/editor/controller.js +8 -0
  173. data/app/packs/src/decidim/controllers/emoji/controller.js +26 -0
  174. data/app/packs/src/decidim/{input_emoji.js → controllers/emoji/emoji.js} +1 -15
  175. data/app/packs/src/decidim/{form_filter.js → controllers/form_filter/controller.js} +68 -51
  176. data/app/packs/src/decidim/controllers/form_filter/form_filter.test.js +648 -0
  177. data/app/packs/src/decidim/controllers/form_validator/controller.js +23 -0
  178. data/app/packs/src/decidim/controllers/form_validator/form_validator.js +789 -0
  179. data/app/packs/src/decidim/controllers/form_validator/form_validator.test.js +685 -0
  180. data/app/packs/src/decidim/controllers/impersonation_warning/controller.js +137 -0
  181. data/app/packs/src/decidim/controllers/impersonation_warning/impersonation.test.js +382 -0
  182. data/app/packs/src/decidim/controllers/input_tags/controller.js +28 -0
  183. data/app/packs/src/decidim/controllers/mention/controller.js +243 -0
  184. data/app/packs/src/decidim/controllers/mention/input_mentions.test.js +562 -0
  185. data/app/packs/src/decidim/controllers/multiple_mentions/controller.js +215 -0
  186. data/app/packs/src/decidim/controllers/multiple_mentions/input_multiple_mentions.test.js +645 -0
  187. data/app/packs/src/decidim/controllers/notification_action/controller.js +210 -0
  188. data/app/packs/src/decidim/controllers/notification_action/notification_action.test.js +388 -0
  189. data/app/packs/src/decidim/controllers/password_toggler/controller.js +232 -0
  190. data/app/packs/src/decidim/controllers/password_toggler/password_toggler.test.js +229 -0
  191. data/app/packs/src/decidim/controllers/report_form/controller.js +184 -0
  192. data/app/packs/src/decidim/controllers/report_form/report_form_manager.test.js +511 -0
  193. data/app/packs/src/decidim/controllers/scroll_to_last/controller.js +9 -0
  194. data/app/packs/src/decidim/controllers/scroll_to_last/scroll_to_last_child.test.js +225 -0
  195. data/app/packs/src/decidim/controllers/sticky_buttons/controller.js +55 -0
  196. data/app/packs/src/decidim/controllers/sticky_buttons/sticky_buttons.test.js +334 -0
  197. data/app/packs/src/decidim/controllers/sticky_header/controller.js +116 -0
  198. data/app/packs/src/decidim/controllers/sticky_header/sticky_header.test.js +320 -0
  199. data/app/packs/src/decidim/controllers/toggle/controller.js +111 -0
  200. data/app/packs/src/decidim/controllers/toggle/toggle.test.js +260 -0
  201. data/app/packs/src/decidim/controllers/tooltip/controller.js +287 -0
  202. data/app/packs/src/decidim/controllers/tooltip/tooltip.test.js +380 -0
  203. data/app/packs/src/decidim/controllers/user_registration_form/controller.js +160 -0
  204. data/app/packs/src/decidim/controllers/user_registration_form/omniauth_registration_form.test.js +441 -0
  205. data/app/packs/src/decidim/controllers/user_registration_form/user_registration_form.test.js +386 -0
  206. data/app/packs/src/decidim/data_consent/index.js +1 -1
  207. data/app/packs/src/decidim/datalist_select.js +1 -1
  208. data/app/packs/src/decidim/datepicker/form_datepicker.js +1 -1
  209. data/app/packs/src/decidim/datepicker/generate_datepicker.js +2 -2
  210. data/app/packs/src/decidim/datepicker/generate_timepicker.js +2 -2
  211. data/app/packs/src/decidim/direct_uploads/upload_field.js +3 -5
  212. data/app/packs/src/decidim/direct_uploads/upload_modal.js +1 -1
  213. data/app/packs/src/decidim/dropdown_menu.js +1 -1
  214. data/app/packs/src/decidim/editor/common/input_dialog.js +1 -1
  215. data/app/packs/src/decidim/editor/common/suggestion.js +10 -2
  216. data/app/packs/src/decidim/editor/common/upload_dialog.js +1 -1
  217. data/app/packs/src/decidim/editor/extensions/decidim_kit/index.js +7 -7
  218. data/app/packs/src/decidim/editor/extensions/emoji/index.js +2 -3
  219. data/app/packs/src/decidim/editor/extensions/image/index.js +1 -1
  220. data/app/packs/src/decidim/editor/extensions/image/node_view.js +1 -1
  221. data/app/packs/src/decidim/editor/extensions/link/bubble_menu.js +1 -1
  222. data/app/packs/src/decidim/editor/extensions/link/index.js +1 -1
  223. data/app/packs/src/decidim/editor/extensions/mention/index.js +1 -2
  224. data/app/packs/src/decidim/editor/extensions/mention_resource/index.js +69 -0
  225. data/app/packs/src/decidim/editor/extensions/video_embed/index.js +1 -1
  226. data/app/packs/src/decidim/editor/index.js +6 -5
  227. data/app/packs/src/decidim/editor/test/extensions/decidim_kit.test.js +1 -2
  228. data/app/packs/src/decidim/editor/test/extensions/emoji.test.js +17 -0
  229. data/app/packs/src/decidim/editor/test/extensions/heading.test.js +2 -2
  230. data/app/packs/src/decidim/editor/toolbar.js +1 -1
  231. data/app/packs/src/decidim/form_attachments.js +1 -1
  232. data/app/packs/src/decidim/geocoding/attach_input.js +3 -0
  233. data/app/packs/src/decidim/geocoding/provider/here.js +1 -1
  234. data/app/packs/src/decidim/geocoding/provider/photon.js +1 -1
  235. data/app/packs/src/decidim/geocoding/reverse_geocoding.js +2 -2
  236. data/app/packs/src/decidim/geocoding.js +2 -2
  237. data/app/packs/src/decidim/index.js +127 -95
  238. data/app/packs/src/decidim/map/integration/forms.js +1 -1
  239. data/app/packs/src/decidim/map/legacy.js +1 -1
  240. data/app/packs/src/decidim/map/provider/default.js +1 -1
  241. data/app/packs/src/decidim/map/provider/here.js +1 -1
  242. data/app/packs/src/decidim/map.js +1 -1
  243. data/app/packs/src/decidim/{external_link.js → refactor/implementation/external_link.js} +1 -1
  244. data/app/packs/src/decidim/{onboarding_pending_action.js → refactor/integration/onboarding_pending_action.js} +4 -4
  245. data/app/packs/src/decidim/{check_boxes_tree.js → refactor/moved/check_boxes_tree.js} +24 -9
  246. data/app/packs/src/decidim/{i18n.test.js → refactor/moved/i18n.test.js} +1 -1
  247. data/app/packs/src/decidim/{icon.js → refactor/moved/icon.js} +2 -0
  248. data/app/packs/src/decidim/refactor/support/stimulus.js +39 -0
  249. data/app/packs/src/decidim/refactor/test/configuration.test.js +360 -0
  250. data/app/packs/src/decidim/{external_domain_warning.test.js → refactor/test/external_domain_warning.test.js} +1 -1
  251. data/app/packs/src/decidim/{external_link.test.js → refactor/test/external_link.test.js} +1 -1
  252. data/app/packs/src/decidim/results_listing.js +2 -2
  253. data/app/packs/src/decidim/security/selfxss_warning.js +1 -1
  254. data/app/packs/src/decidim/session_timeouter.js +1 -1
  255. data/app/packs/src/decidim/sw/push-permissions.js +1 -1
  256. data/app/packs/src/decidim/utilities/dom.js +1 -1
  257. data/app/packs/stylesheets/decidim/_accordion.scss +37 -3
  258. data/app/packs/stylesheets/decidim/_author.scss +0 -21
  259. data/app/packs/stylesheets/decidim/_buttons.scss +4 -0
  260. data/app/packs/stylesheets/decidim/_callout.scss +1 -1
  261. data/app/packs/stylesheets/decidim/_cards.scss +1 -1
  262. data/app/packs/stylesheets/decidim/_content_blocks.scss +1 -1
  263. data/app/packs/stylesheets/decidim/_cookies.scss +1 -1
  264. data/app/packs/stylesheets/decidim/_datepicker.scss +0 -4
  265. data/app/packs/stylesheets/decidim/_dropdown.scss +56 -19
  266. data/app/packs/stylesheets/decidim/_forms.scss +6 -6
  267. data/app/packs/stylesheets/decidim/_header.scss +17 -1
  268. data/app/packs/stylesheets/decidim/_labels.scss +1 -1
  269. data/app/packs/stylesheets/decidim/_layout.scss +12 -2
  270. data/app/packs/stylesheets/decidim/{_endorsers_list.scss → _likes_list.scss} +1 -1
  271. data/app/packs/stylesheets/decidim/_modal.scss +5 -1
  272. data/app/packs/stylesheets/decidim/_modal_share.scss +83 -9
  273. data/app/packs/stylesheets/decidim/_modal_update.scss +1 -5
  274. data/app/packs/stylesheets/decidim/_participatory_spaces.scss +1 -1
  275. data/app/packs/stylesheets/decidim/_rich_text.scss +13 -0
  276. data/app/packs/stylesheets/decidim/_statistics.scss +35 -3
  277. data/app/packs/stylesheets/decidim/_tooltip.scss +1 -1
  278. data/app/packs/stylesheets/decidim/_typography.scss +6 -0
  279. data/app/packs/stylesheets/decidim/_wizard_steps.scss +1 -1
  280. data/app/packs/stylesheets/decidim/application.scss +76 -76
  281. data/app/packs/stylesheets/decidim/editor.scss +11 -12
  282. data/app/packs/stylesheets/decidim/legacy/email.scss +6 -5
  283. data/app/packs/stylesheets/decidim/map.scss +5 -3
  284. data/app/packs/stylesheets/decidim/qr.scss +65 -0
  285. data/app/permissions/decidim/default_permissions.rb +16 -0
  286. data/app/permissions/decidim/permissions.rb +5 -26
  287. data/app/presenters/decidim/admin_log/base_user_presenter.rb +2 -2
  288. data/app/presenters/decidim/admin_log/organization_presenter.rb +0 -15
  289. data/app/presenters/decidim/home_stats_presenter.rb +4 -54
  290. data/app/presenters/decidim/log/base_presenter.rb +1 -1
  291. data/app/presenters/decidim/menu_item_presenter.rb +10 -3
  292. data/app/presenters/decidim/official_author_presenter.rb +0 -4
  293. data/app/presenters/decidim/participatory_space_private_user_presenter.rb +0 -4
  294. data/app/presenters/decidim/resource_locator_presenter.rb +15 -4
  295. data/app/presenters/decidim/resource_presenter.rb +8 -8
  296. data/app/presenters/decidim/stats_presenter.rb +39 -60
  297. data/app/presenters/decidim/taxonomy_presenter.rb +5 -1
  298. data/app/presenters/decidim/user_presenter.rb +0 -6
  299. data/app/queries/decidim/authorized_users.rb +26 -0
  300. data/app/queries/decidim/inactive_users_query.rb +31 -0
  301. data/app/queries/decidim/public_activities.rb +2 -2
  302. data/app/queries/decidim/stats_followers_count.rb +43 -0
  303. data/app/queries/decidim/stats_participants_count.rb +102 -0
  304. data/app/serializers/decidim/exporters/open_data_user_serializer.rb +1 -5
  305. data/app/serializers/decidim/exporters/participatory_space_serializer.rb +0 -1
  306. data/app/services/decidim/action_logger.rb +2 -1
  307. data/app/services/decidim/base_diff_renderer.rb +0 -17
  308. data/app/services/decidim/onboarding_manager.rb +4 -0
  309. data/app/services/decidim/open_data_exporter.rb +19 -11
  310. data/app/services/decidim/send_push_notification.rb +4 -3
  311. data/app/services/decidim/traceability.rb +1 -1
  312. data/app/validators/etiquette_validator.rb +7 -0
  313. data/app/validators/translated_etiquette_validator.rb +1 -0
  314. data/app/views/decidim/account/_old_password_field.html.erb +1 -1
  315. data/app/views/decidim/account/_password_fields.html.erb +1 -1
  316. data/app/views/decidim/account/delete.html.erb +1 -1
  317. data/app/views/decidim/account/show.html.erb +3 -3
  318. data/app/views/decidim/amendments/edit_draft.html.erb +0 -4
  319. data/app/views/decidim/amendments/new.html.erb +0 -4
  320. data/app/views/decidim/amendments/preview_draft.html.erb +1 -1
  321. data/app/views/decidim/application/_accordion_section.html.erb +1 -1
  322. data/app/views/decidim/application/_collection.html.erb +1 -1
  323. data/app/views/decidim/application/_radio_accordion.html.erb +30 -0
  324. data/app/views/decidim/devise/omniauth_registrations/new.html.erb +1 -1
  325. data/app/views/decidim/devise/omniauth_registrations/new_tos_fields.html.erb +1 -1
  326. data/app/views/decidim/devise/registrations/new.html.erb +1 -1
  327. data/app/views/decidim/devise/shared/_links.html.erb +1 -1
  328. data/app/views/decidim/doorkeeper/authorizations/new.html.erb +39 -8
  329. data/app/views/decidim/errors/internal_server_error.html.erb +1 -0
  330. data/app/views/decidim/likes/update_buttons_and_counters.js.erb +21 -0
  331. data/app/views/decidim/messaging/conversations/_add_conversation_users.html.erb +2 -2
  332. data/app/views/decidim/messaging/conversations/_reply_form.html.erb +1 -1
  333. data/app/views/decidim/messaging/conversations/_start.html.erb +1 -1
  334. data/app/views/decidim/messaging/conversations/create.js.erb +0 -1
  335. data/app/views/decidim/messaging/conversations/new.html.erb +1 -1
  336. data/app/views/decidim/messaging/conversations/show.html.erb +1 -1
  337. data/app/views/decidim/notifications_settings/show.html.erb +3 -3
  338. data/app/views/decidim/pages/_tabbed.html.erb +1 -1
  339. data/app/views/decidim/pages/index.html.erb +1 -1
  340. data/app/views/decidim/participants_account_mailer/inactivity_notification.html.erb +13 -0
  341. data/app/views/decidim/participants_account_mailer/removal_notification.html.erb +11 -0
  342. data/app/views/decidim/profiles/show.html.erb +1 -1
  343. data/app/views/decidim/qr/show.html.erb +28 -0
  344. data/app/views/decidim/searches/_filters.html.erb +18 -2
  345. data/app/views/decidim/searches/index.html.erb +5 -2
  346. data/app/views/decidim/shared/_confirm_modal.html.erb +5 -3
  347. data/app/views/decidim/shared/_filters.html.erb +2 -2
  348. data/app/views/decidim/shared/_orders.html.erb +1 -1
  349. data/app/views/decidim/shared/_resource_actions.html.erb +8 -5
  350. data/app/views/decidim/user_activities/index.html.erb +1 -1
  351. data/app/views/decidim/user_group_mailer/notify_deprecation_to_member.html.erb +15 -0
  352. data/app/views/decidim/user_group_mailer/notify_deprecation_to_owner.html.erb +22 -0
  353. data/app/views/layouts/decidim/_head.html.erb +15 -12
  354. data/app/views/layouts/decidim/_impersonation_warning.html.erb +1 -1
  355. data/app/views/layouts/decidim/_js_configuration.html.erb +17 -19
  356. data/app/views/layouts/decidim/_meta_tags_context.html.erb +3 -0
  357. data/app/views/layouts/decidim/_offline_banner.html.erb +1 -1
  358. data/app/views/layouts/decidim/_wrapper.html.erb +8 -6
  359. data/app/views/layouts/decidim/footer/_focus_mode_main.html.erb +7 -0
  360. data/app/views/layouts/decidim/footer/_main_language_chooser.html.erb +1 -1
  361. data/app/views/layouts/decidim/header/_close_ephemeral_session.html.erb +12 -2
  362. data/app/views/layouts/decidim/header/_focus_mode_back_button.html.erb +24 -0
  363. data/app/views/layouts/decidim/header/_main.html.erb +28 -22
  364. data/app/views/layouts/decidim/header/_main_links_desktop.html.erb +1 -1
  365. data/app/views/layouts/decidim/header/_main_links_dropdown.html.erb +18 -18
  366. data/app/views/layouts/decidim/header/_main_links_mobile_item_account.html.erb +1 -1
  367. data/app/views/layouts/decidim/header/_main_menu_mobile.html.erb +1 -1
  368. data/app/views/layouts/decidim/header/_menu_breadcrumb_desktop.html.erb +1 -1
  369. data/app/views/layouts/decidim/header/_menu_breadcrumb_items.html.erb +1 -1
  370. data/app/views/layouts/decidim/header/_menu_breadcrumb_mobile_tablet.html.erb +1 -1
  371. data/app/views/layouts/decidim/header/_mobile_language_choose.html.erb +1 -1
  372. data/app/views/layouts/decidim/mailer.html.erb +2 -2
  373. data/app/views/layouts/decidim/newsletter_base.html.erb +2 -2
  374. data/app/views/layouts/decidim/shared/_layout_two_col.html.erb +3 -1
  375. data/app/views/layouts/decidim/shared/_layout_user_profile.html.erb +7 -3
  376. data/config/assets.rb +3 -3
  377. data/config/initializers/devise.rb +8 -0
  378. data/config/initializers/omniauth.rb +1 -1
  379. data/config/locales/ar.yml +0 -209
  380. data/config/locales/bg.yml +0 -238
  381. data/config/locales/bs-BA.yml +0 -30
  382. data/config/locales/ca-IT.yml +112 -286
  383. data/config/locales/ca.yml +112 -286
  384. data/config/locales/cs.yml +85 -279
  385. data/config/locales/de.yml +112 -285
  386. data/config/locales/el.yml +0 -224
  387. data/config/locales/en.yml +112 -286
  388. data/config/locales/eo.yml +0 -2
  389. data/config/locales/es-MX.yml +112 -286
  390. data/config/locales/es-PY.yml +112 -286
  391. data/config/locales/es.yml +112 -286
  392. data/config/locales/eu.yml +125 -299
  393. data/config/locales/fi-plain.yml +112 -286
  394. data/config/locales/fi.yml +112 -286
  395. data/config/locales/fr-CA.yml +85 -275
  396. data/config/locales/fr.yml +85 -275
  397. data/config/locales/ga-IE.yml +0 -28
  398. data/config/locales/gl.yml +0 -140
  399. data/config/locales/hu.yml +0 -237
  400. data/config/locales/id-ID.yml +0 -136
  401. data/config/locales/is-IS.yml +0 -14
  402. data/config/locales/it.yml +1 -234
  403. data/config/locales/ja.yml +108 -282
  404. data/config/locales/lb.yml +0 -189
  405. data/config/locales/lt.yml +0 -240
  406. data/config/locales/lv.yml +0 -186
  407. data/config/locales/nl.yml +0 -189
  408. data/config/locales/no.yml +0 -189
  409. data/config/locales/pl.yml +0 -244
  410. data/config/locales/pt-BR.yml +0 -213
  411. data/config/locales/pt.yml +0 -189
  412. data/config/locales/ro-RO.yml +54 -218
  413. data/config/locales/ru.yml +0 -62
  414. data/config/locales/sk.yml +0 -164
  415. data/config/locales/sr-CS.yml +0 -31
  416. data/config/locales/sv.yml +80 -263
  417. data/config/locales/tr-TR.yml +0 -189
  418. data/config/locales/uk.yml +0 -23
  419. data/config/locales/zh-CN.yml +0 -180
  420. data/config/locales/zh-TW.yml +0 -229
  421. data/config/routes.rb +3 -36
  422. data/db/migrate/20250217192438_convert_user_groups_into_users.rb +38 -0
  423. data/db/migrate/20250221085317_add_user_type_to_action_logs.rb +12 -0
  424. data/db/migrate/20250221090905_create_decidim_api_jwt_denylist.rb +11 -0
  425. data/db/migrate/20250221091348_add_api_key_to_decidim_api_user.rb +7 -0
  426. data/db/migrate/20250327143657_remove_metrics_content_blocks.rb +9 -0
  427. data/db/migrate/20250401153444_enable_pkce.rb +8 -0
  428. data/db/migrate/20250416130426_rename_doorkeeper_scopes.rb +25 -0
  429. data/db/migrate/20250515105231_rename_endorsements_to_likes.rb +62 -0
  430. data/db/migrate/20250523104311_move_cta_to_hero_content_block.rb +34 -0
  431. data/db/migrate/20250527122040_move_highlighted_content_banner_settings_to_content_block.rb +69 -0
  432. data/db/migrate/20250603103953_add_refresh_tokens_enabled_to_doorkeeper_applications.rb +7 -0
  433. data/db/migrate/20250609073104_remove_not_null_on_active_storage_blobs_checksum.active_storage.rb +10 -0
  434. data/db/migrate/20250613122148_remove_hashtag_table_from_core.rb +7 -0
  435. data/decidim-core.gemspec +4 -4
  436. data/{app/helpers → lib}/decidim/action_authorization_helper.rb +5 -4
  437. data/lib/decidim/amendable.rb +4 -4
  438. data/lib/decidim/api/functions/user_entity_finder.rb +1 -1
  439. data/lib/decidim/api/input_filters/component_input_filter.rb +3 -3
  440. data/lib/decidim/api/input_filters/user_entity_input_filter.rb +0 -21
  441. data/lib/decidim/api/input_sorts/has_likeable_input_sort.rb +15 -0
  442. data/lib/decidim/api/interfaces/attachable_collection_interface.rb +13 -0
  443. data/lib/decidim/api/interfaces/author_interface.rb +1 -2
  444. data/lib/decidim/api/interfaces/authorable_interface.rb +2 -2
  445. data/lib/decidim/api/interfaces/coauthorable_interface.rb +1 -1
  446. data/lib/decidim/api/interfaces/component_interface.rb +6 -0
  447. data/lib/decidim/api/interfaces/followable_interface.rb +13 -0
  448. data/lib/decidim/api/interfaces/likeable_interface.rb +19 -0
  449. data/lib/decidim/api/interfaces/localizable_interface.rb +18 -0
  450. data/lib/decidim/api/interfaces/participatory_space_interface.rb +6 -8
  451. data/lib/decidim/api/interfaces/referable_interface.rb +13 -0
  452. data/lib/decidim/api/interfaces/timestamps_interface.rb +0 -1
  453. data/lib/decidim/api/interfaces/traceable_interface.rb +1 -1
  454. data/lib/decidim/api/types/attachment_collection_type.rb +14 -0
  455. data/lib/decidim/api/types/organization_type.rb +3 -1
  456. data/lib/decidim/api/types/session_type.rb +0 -5
  457. data/lib/decidim/api/types/statistic_type.rb +29 -3
  458. data/lib/decidim/api/types/trace_version_type.rb +1 -1
  459. data/lib/decidim/api/types/user_type.rb +1 -2
  460. data/lib/decidim/api_response_helper.rb +12 -0
  461. data/lib/decidim/asset_router/storage.rb +2 -4
  462. data/lib/decidim/assets/tailwind/instance.rb +1 -1
  463. data/lib/decidim/assets/tailwind/tailwind.config.js.erb +4 -3
  464. data/lib/decidim/attribute_encryptor.rb +1 -1
  465. data/lib/decidim/attributes/time_with_zone.rb +1 -1
  466. data/lib/decidim/authorable.rb +5 -34
  467. data/lib/decidim/coauthorable.rb +13 -31
  468. data/lib/decidim/content_parsers/blob_parser.rb +1 -1
  469. data/lib/decidim/content_parsers/mention_resource_parser.rb +23 -0
  470. data/lib/decidim/content_parsers/tag_parser.rb +2 -2
  471. data/lib/decidim/content_parsers/user_parser.rb +2 -2
  472. data/lib/decidim/content_parsers.rb +14 -2
  473. data/lib/decidim/content_processor.rb +1 -1
  474. data/lib/decidim/content_renderers/mention_resource_renderer.rb +77 -0
  475. data/lib/decidim/content_renderers.rb +1 -2
  476. data/lib/decidim/core/api.rb +7 -8
  477. data/lib/decidim/core/content_blocks/registry_manager.rb +19 -5
  478. data/lib/decidim/core/engine.rb +72 -104
  479. data/lib/decidim/core/menu.rb +0 -7
  480. data/lib/decidim/core/seeds.rb +11 -39
  481. data/lib/decidim/core/test/factories.rb +22 -121
  482. data/lib/decidim/core/test/shared_examples/authorable.rb +0 -17
  483. data/lib/decidim/core/test/shared_examples/coauthorable.rb +5 -48
  484. data/lib/decidim/core/test/shared_examples/comments_examples.rb +7 -56
  485. data/lib/decidim/core/test/shared_examples/likeable.rb +22 -0
  486. data/lib/decidim/core/test/shared_examples/manage_share_tokens_examples.rb +16 -3
  487. data/lib/decidim/core/test/shared_examples/map_examples.rb +1 -1
  488. data/lib/decidim/core/test/shared_examples/oauth_application_examples.rb +137 -0
  489. data/lib/decidim/core/test/shared_examples/participatory_space_dropdown_metadata_cell_examples.rb +0 -18
  490. data/lib/decidim/core/test/shared_examples/permissions.rb +0 -46
  491. data/lib/decidim/core/test/shared_examples/reports_examples.rb +2 -2
  492. data/lib/decidim/core/test/shared_examples/{resource_endorsed_event_examples.rb → resource_liked_event_examples.rb} +7 -7
  493. data/lib/decidim/core/test/shared_examples/resource_search_examples.rb +0 -14
  494. data/lib/decidim/core/test/shared_examples/searchable_results_examples.rb +8 -34
  495. data/lib/decidim/core/test/shared_examples/social_share_examples.rb +79 -0
  496. data/lib/decidim/core/test/shared_examples/system_like_resource_examples.rb +192 -0
  497. data/lib/decidim/core/test/shared_examples/uncommentable_component_examples.rb +2 -2
  498. data/lib/decidim/core/test/shared_examples/{with_endorsable_permissions_examples.rb → with_likeable_permissions_examples.rb} +22 -22
  499. data/lib/decidim/core/test.rb +6 -9
  500. data/lib/decidim/core/version.rb +1 -1
  501. data/lib/decidim/core.rb +237 -88
  502. data/lib/decidim/deprecations.rb +1 -1
  503. data/lib/decidim/download_your_data_serializers.rb +6 -3
  504. data/lib/decidim/env.rb +3 -1
  505. data/lib/decidim/events.rb +0 -1
  506. data/lib/decidim/form_builder.rb +26 -43
  507. data/lib/decidim/gamification/badge_scorer.rb +0 -2
  508. data/lib/decidim/gamification.rb +1 -1
  509. data/lib/decidim/has_conversations.rb +0 -44
  510. data/lib/decidim/has_workflows.rb +42 -0
  511. data/lib/decidim/icon_registry.rb +4 -4
  512. data/lib/decidim/legacy_form_builder.rb +17 -2
  513. data/lib/decidim/likeable.rb +24 -0
  514. data/lib/decidim/manifest_registry.rb +1 -1
  515. data/lib/decidim/map/provider/dynamic_map/here.rb +0 -19
  516. data/lib/decidim/map/provider/static_map/here.rb +2 -10
  517. data/lib/decidim/menu.rb +1 -1
  518. data/lib/decidim/moderation_tools.rb +1 -1
  519. data/lib/decidim/mutation_registry.rb +17 -0
  520. data/lib/decidim/newsletter_encryptor.rb +1 -1
  521. data/lib/decidim/oauth/token_generator.rb +35 -0
  522. data/lib/decidim/oauth.rb +7 -0
  523. data/lib/decidim/organization_settings.rb +2 -10
  524. data/lib/decidim/paddable.rb +1 -1
  525. data/lib/decidim/participatory_space_resourceable.rb +2 -2
  526. data/lib/decidim/participatory_space_user.rb +1 -1
  527. data/lib/decidim/pdf_signature_example.rb +108 -0
  528. data/lib/decidim/query.rb +1 -1
  529. data/lib/decidim/query_extensions.rb +0 -33
  530. data/lib/decidim/reportable.rb +1 -1
  531. data/lib/decidim/searchable.rb +4 -2
  532. data/lib/decidim/seeds.rb +8 -0
  533. data/lib/decidim/settings_manifest.rb +3 -2
  534. data/lib/decidim/{webpacker → shakapacker}/configuration.rb +4 -4
  535. data/lib/decidim/{webpacker → shakapacker}/runner.rb +3 -3
  536. data/lib/decidim/shakapacker/shakapacker.rb +8 -0
  537. data/lib/decidim/{webpacker → shakapacker}/shakapacker.yml +3 -1
  538. data/lib/decidim/{webpacker → shakapacker}/webpack/custom.js +1 -1
  539. data/lib/decidim/shakapacker.rb +34 -0
  540. data/lib/decidim/social_share_service_manifest.rb +7 -12
  541. data/lib/decidim/stats_registry.rb +15 -3
  542. data/{app/helpers → lib}/decidim/tooltip_helper.rb +3 -3
  543. data/lib/decidim/url_option_resolver.rb +1 -1
  544. data/lib/decidim/view_model.rb +0 -3
  545. data/lib/decidim/webpacker.rb +11 -20
  546. data/lib/decidim/workflow_registry.rb +61 -0
  547. data/lib/tasks/decidim_participants_tasks.rake +22 -0
  548. data/lib/tasks/{decidim_webpacker_tasks.rake → decidim_shakapacker_tasks.rake} +35 -33
  549. data/lib/tasks/decidim_tasks.rake +4 -1
  550. data/lib/tasks/decidim_taxonomies.rake +0 -34
  551. data/lib/tasks/upgrade/clean.rake +1 -1
  552. data/lib/tasks/upgrade/decidim_action_log_valuation_assignment.rake +13 -0
  553. data/lib/tasks/upgrade/decidim_change_valuator_tasks.rake +12 -0
  554. data/lib/tasks/upgrade/{decidim_deduplicate_endorsements.rake → decidim_deduplicate_likes.rake} +10 -10
  555. data/lib/tasks/upgrade/decidim_migrate_wysiwyg_content.rake +2 -2
  556. data/lib/tasks/upgrade/decidim_paper_trail_valuation_assignment.rake +13 -0
  557. data/lib/tasks/upgrade/user_groups_migration.rake +155 -0
  558. metadata +204 -256
  559. data/app/cells/decidim/author/endorsements.erb +0 -4
  560. data/app/cells/decidim/author/profile_minicard.erb +0 -30
  561. data/app/cells/decidim/content_blocks/organization_metrics_cell.rb +0 -21
  562. data/app/cells/decidim/content_blocks/participatory_space_metrics/content.erb +0 -18
  563. data/app/cells/decidim/content_blocks/participatory_space_metrics_cell.rb +0 -43
  564. data/app/cells/decidim/endorsement_block/show.erb +0 -3
  565. data/app/cells/decidim/endorsement_buttons/button_content.erb +0 -2
  566. data/app/cells/decidim/endorsement_buttons/select_identity_button.erb +0 -7
  567. data/app/cells/decidim/endorsement_buttons/show.erb +0 -17
  568. data/app/cells/decidim/endorsement_buttons_cell.rb +0 -87
  569. data/app/cells/decidim/endorsers_list/empty.erb +0 -3
  570. data/app/cells/decidim/endorsers_list/show.erb +0 -20
  571. data/app/cells/decidim/endorsers_list_cell.rb +0 -64
  572. data/app/cells/decidim/group_admins/show.erb +0 -34
  573. data/app/cells/decidim/group_admins_cell.rb +0 -8
  574. data/app/cells/decidim/group_members/show.erb +0 -46
  575. data/app/cells/decidim/group_members_cell.rb +0 -8
  576. data/app/cells/decidim/groups/show.erb +0 -14
  577. data/app/cells/decidim/groups_cell.rb +0 -22
  578. data/app/cells/decidim/members/show.erb +0 -12
  579. data/app/cells/decidim/members_cell.rb +0 -34
  580. data/app/cells/decidim/profile_actions/dropdown_actions.erb +0 -21
  581. data/app/cells/decidim/represent_user_group/show.erb +0 -11
  582. data/app/cells/decidim/represent_user_group_cell.rb +0 -46
  583. data/app/cells/decidim/user_conversation/conversation_header.erb +0 -14
  584. data/app/cells/decidim/user_conversation/messages.erb +0 -1
  585. data/app/cells/decidim/user_conversation/new.erb +0 -6
  586. data/app/cells/decidim/user_conversation/reply.erb +0 -9
  587. data/app/cells/decidim/user_conversation/show.erb +0 -19
  588. data/app/cells/decidim/user_conversation/start.erb +0 -12
  589. data/app/cells/decidim/user_conversation_cell.rb +0 -62
  590. data/app/cells/decidim/user_conversations/new_conversation_button.erb +0 -20
  591. data/app/cells/decidim/user_conversations/show.erb +0 -13
  592. data/app/cells/decidim/user_conversations_cell.rb +0 -28
  593. data/app/cells/decidim/user_group_pending_invitations_list/show.erb +0 -28
  594. data/app/cells/decidim/user_group_pending_invitations_list_cell.rb +0 -26
  595. data/app/cells/decidim/user_group_pending_requests_list/show.erb +0 -27
  596. data/app/cells/decidim/user_group_pending_requests_list_cell.rb +0 -26
  597. data/app/commands/decidim/accept_group_invitation.rb +0 -43
  598. data/app/commands/decidim/accept_user_group_join_request.rb +0 -53
  599. data/app/commands/decidim/create_user_group.rb +0 -73
  600. data/app/commands/decidim/demote_membership.rb +0 -57
  601. data/app/commands/decidim/endorse_resource.rb +0 -66
  602. data/app/commands/decidim/invite_user_to_group.rb +0 -63
  603. data/app/commands/decidim/join_user_group.rb +0 -57
  604. data/app/commands/decidim/leave_user_group.rb +0 -47
  605. data/app/commands/decidim/promote_membership.rb +0 -55
  606. data/app/commands/decidim/reject_group_invitation.rb +0 -42
  607. data/app/commands/decidim/reject_user_group_join_request.rb +0 -53
  608. data/app/commands/decidim/remove_user_from_group.rb +0 -53
  609. data/app/commands/decidim/unendorse_resource.rb +0 -39
  610. data/app/commands/decidim/update_user_group.rb +0 -72
  611. data/app/controllers/concerns/decidim/user_groups.rb +0 -23
  612. data/app/controllers/decidim/endorsements_controller.rb +0 -71
  613. data/app/controllers/decidim/group_email_confirmations_controller.rb +0 -32
  614. data/app/controllers/decidim/group_invites_controller.rb +0 -104
  615. data/app/controllers/decidim/group_members_controller.rb +0 -75
  616. data/app/controllers/decidim/groups_controller.rb +0 -99
  617. data/app/controllers/decidim/own_user_groups_controller.rb +0 -15
  618. data/app/controllers/decidim/user_conversations_controller.rb +0 -133
  619. data/app/controllers/decidim/user_group_join_requests_controller.rb +0 -72
  620. data/app/events/decidim/demoted_membership_event.rb +0 -28
  621. data/app/events/decidim/invited_to_group_event.rb +0 -62
  622. data/app/events/decidim/join_request_accepted_event.rb +0 -28
  623. data/app/events/decidim/join_request_created_event.rb +0 -28
  624. data/app/events/decidim/join_request_rejected_event.rb +0 -28
  625. data/app/events/decidim/promoted_to_admin_event.rb +0 -28
  626. data/app/events/decidim/removed_from_group_event.rb +0 -28
  627. data/app/events/decidim/resource_endorsed_event.rb +0 -36
  628. data/app/events/decidim/user_group_admin_event.rb +0 -37
  629. data/app/events/decidim/user_group_created_event.rb +0 -6
  630. data/app/events/decidim/user_group_updated_event.rb +0 -6
  631. data/app/forms/decidim/invite_user_to_group_form.rb +0 -29
  632. data/app/forms/decidim/user_group_form.rb +0 -85
  633. data/app/helpers/decidim/cta_button_helper.rb +0 -31
  634. data/app/helpers/decidim/endorsable_helper.rb +0 -84
  635. data/app/helpers/decidim/twitter_search_helper.rb +0 -14
  636. data/app/helpers/decidim/user_group_helper.rb +0 -22
  637. data/app/jobs/decidim/metric_job.rb +0 -15
  638. data/app/models/decidim/metric.rb +0 -25
  639. data/app/models/decidim/user_group.rb +0 -217
  640. data/app/models/decidim/user_group_membership.rb +0 -17
  641. data/app/packs/entrypoints/decidim_widget.js +0 -1
  642. data/app/packs/src/decidim/abide_form_validator_fixer.js +0 -44
  643. data/app/packs/src/decidim/account_form.js +0 -96
  644. data/app/packs/src/decidim/append_elements.js +0 -6
  645. data/app/packs/src/decidim/back_to_list.js +0 -26
  646. data/app/packs/src/decidim/change_report_form_behavior.js +0 -45
  647. data/app/packs/src/decidim/clipboard.js +0 -128
  648. data/app/packs/src/decidim/editor/extensions/hashtag/index.js +0 -66
  649. data/app/packs/src/decidim/editor/extensions/heading/index.js +0 -33
  650. data/app/packs/src/decidim/editor/test/extensions/hashtag.test.js +0 -105
  651. data/app/packs/src/decidim/form_filter.component_for_testing.js +0 -7
  652. data/app/packs/src/decidim/form_validator.js +0 -56
  653. data/app/packs/src/decidim/gallery.js +0 -5
  654. data/app/packs/src/decidim/impersonation.js +0 -23
  655. data/app/packs/src/decidim/input_autojump.js +0 -38
  656. data/app/packs/src/decidim/input_hashtags.js +0 -91
  657. data/app/packs/src/decidim/input_mentions.js +0 -143
  658. data/app/packs/src/decidim/input_multiple_mentions.js +0 -115
  659. data/app/packs/src/decidim/input_tags.js +0 -16
  660. data/app/packs/src/decidim/notifications_actions.js +0 -40
  661. data/app/packs/src/decidim/password_toggler.js +0 -104
  662. data/app/packs/src/decidim/remote_tooltips.js +0 -38
  663. data/app/packs/src/decidim/responsive_horizontal_tabs.js +0 -12
  664. data/app/packs/src/decidim/scroll_to_last_child.js +0 -14
  665. data/app/packs/src/decidim/slug_form.js +0 -9
  666. data/app/packs/src/decidim/sticky_footer.js +0 -48
  667. data/app/packs/src/decidim/sticky_header.js +0 -62
  668. data/app/packs/src/decidim/toggle.js +0 -37
  669. data/app/packs/src/decidim/tooltips.js +0 -152
  670. data/app/packs/src/decidim/user_registrations.js +0 -65
  671. data/app/packs/src/decidim/vizzs/areachart.js +0 -251
  672. data/app/packs/src/decidim/vizzs/index.js +0 -82
  673. data/app/packs/src/decidim/widget.js +0 -14
  674. data/app/packs/stylesheets/decidim/_hashtags.scss +0 -5
  675. data/app/packs/stylesheets/decidim/_metrics.scss +0 -70
  676. data/app/packs/stylesheets/decidim/_modal_identities.scss +0 -23
  677. data/app/presenters/decidim/admin_log/user_group_presenter.rb +0 -31
  678. data/app/presenters/decidim/hashtag_presenter.rb +0 -37
  679. data/app/presenters/decidim/metric_charts_presenter.rb +0 -92
  680. data/app/presenters/decidim/metric_object_presenter.rb +0 -32
  681. data/app/presenters/decidim/user_group_presenter.rb +0 -38
  682. data/app/queries/decidim/metric_manage.rb +0 -81
  683. data/app/queries/decidim/metric_measure.rb +0 -36
  684. data/app/queries/decidim/metrics/blocked_users_metric_manage.rb +0 -26
  685. data/app/queries/decidim/metrics/followers_metric_manage.rb +0 -65
  686. data/app/queries/decidim/metrics/participants_metric_manage.rb +0 -79
  687. data/app/queries/decidim/metrics/reported_users_metric_manage.rb +0 -26
  688. data/app/queries/decidim/metrics/user_reports_metric_manage.rb +0 -26
  689. data/app/queries/decidim/metrics/users_metric_manage.rb +0 -26
  690. data/app/queries/decidim/user_groups/accepted_memberships.rb +0 -36
  691. data/app/queries/decidim/user_groups/accepted_user_groups.rb +0 -38
  692. data/app/queries/decidim/user_groups/accepted_users.rb +0 -36
  693. data/app/queries/decidim/user_groups/admin_memberships.rb +0 -37
  694. data/app/queries/decidim/user_groups/invited_memberships.rb +0 -36
  695. data/app/queries/decidim/user_groups/manageable_user_groups.rb +0 -39
  696. data/app/queries/decidim/user_groups/member_memberships.rb +0 -37
  697. data/app/resolvers/decidim/core/metric_resolver.rb +0 -71
  698. data/app/resolvers/decidim/hashtags_resolver.rb +0 -15
  699. data/app/serializers/decidim/exporters/open_data_metric_serializer.rb +0 -22
  700. data/app/serializers/decidim/exporters/open_data_user_group_serializer.rb +0 -38
  701. data/app/views/decidim/endorsements/_identity.html.erb +0 -4
  702. data/app/views/decidim/endorsements/identities.html.erb +0 -18
  703. data/app/views/decidim/endorsements/update_buttons_and_counters.js.erb +0 -25
  704. data/app/views/decidim/group_invites/index.html.erb +0 -26
  705. data/app/views/decidim/groups/_form.html.erb +0 -17
  706. data/app/views/decidim/groups/edit.html.erb +0 -19
  707. data/app/views/decidim/groups/new.html.erb +0 -23
  708. data/app/views/decidim/messaging/conversation_mailer/comanagers_new_conversation.html.erb +0 -17
  709. data/app/views/decidim/messaging/conversation_mailer/comanagers_new_message.html.erb +0 -17
  710. data/app/views/decidim/messaging/conversation_mailer/new_group_conversation.html.erb +0 -17
  711. data/app/views/decidim/messaging/conversation_mailer/new_group_message.html.erb +0 -17
  712. data/app/views/decidim/own_user_groups/index.html.erb +0 -10
  713. data/app/views/decidim/shared/_extended_navigation_bar.html.erb +0 -50
  714. data/app/views/decidim/user_conversations/index.html.erb +0 -4
  715. data/app/views/decidim/user_conversations/show.html.erb +0 -4
  716. data/app/views/decidim/user_conversations/update.js.erb +0 -8
  717. data/config/initializers/new_framework_defaults_7_0.rb +0 -145
  718. data/lib/decidim/api/input_filters/has_hastaggable_input_filter.rb +0 -15
  719. data/lib/decidim/api/input_sorts/has_endorsable_input_sort.rb +0 -15
  720. data/lib/decidim/api/interfaces/endorsable_interface.rb +0 -19
  721. data/lib/decidim/api/types/hashtag_type.rb +0 -13
  722. data/lib/decidim/api/types/metric_history_type.rb +0 -20
  723. data/lib/decidim/api/types/metric_type.rb +0 -13
  724. data/lib/decidim/api/types/user_group_type.rb +0 -55
  725. data/lib/decidim/content_parsers/hashtag_parser.rb +0 -66
  726. data/lib/decidim/content_parsers/user_group_parser.rb +0 -33
  727. data/lib/decidim/content_renderers/hashtag_renderer.rb +0 -78
  728. data/lib/decidim/content_renderers/user_group_renderer.rb +0 -31
  729. data/lib/decidim/core/test/shared_examples/amendable_interface_examples.rb +0 -14
  730. data/lib/decidim/core/test/shared_examples/amendable_proposals_interface_examples.rb +0 -50
  731. data/lib/decidim/core/test/shared_examples/assembly_announcements_examples.rb +0 -38
  732. data/lib/decidim/core/test/shared_examples/attachable_interface_examples.rb +0 -16
  733. data/lib/decidim/core/test/shared_examples/authorable_interface_examples.rb +0 -59
  734. data/lib/decidim/core/test/shared_examples/categories_container_examples.rb +0 -22
  735. data/lib/decidim/core/test/shared_examples/categorizable_interface_examples.rb +0 -27
  736. data/lib/decidim/core/test/shared_examples/coauthorable_interface_examples.rb +0 -91
  737. data/lib/decidim/core/test/shared_examples/endorsable.rb +0 -69
  738. data/lib/decidim/core/test/shared_examples/endorsable_interface_examples.rb +0 -22
  739. data/lib/decidim/core/test/shared_examples/fingerprintable_interface_examples.rb +0 -17
  740. data/lib/decidim/core/test/shared_examples/input_filter_examples.rb +0 -118
  741. data/lib/decidim/core/test/shared_examples/input_sort_examples.rb +0 -126
  742. data/lib/decidim/core/test/shared_examples/metric_manage_shared_context.rb +0 -9
  743. data/lib/decidim/core/test/shared_examples/participatory_space_resourcable_interface_examples.rb +0 -43
  744. data/lib/decidim/core/test/shared_examples/process_announcements_examples.rb +0 -37
  745. data/lib/decidim/core/test/shared_examples/scopable_interface_examples.rb +0 -19
  746. data/lib/decidim/core/test/shared_examples/system_endorse_resource_examples.rb +0 -298
  747. data/lib/decidim/core/test/shared_examples/taxonomizable_interface_examples.rb +0 -20
  748. data/lib/decidim/core/test/shared_examples/timestamps_interface_examples.rb +0 -21
  749. data/lib/decidim/core/test/shared_examples/traceable_interface_examples.rb +0 -47
  750. data/lib/decidim/download_your_data_serializers/download_your_data_user_group_serializer.rb +0 -21
  751. data/lib/decidim/endorsable.rb +0 -29
  752. data/lib/decidim/events/user_group_event.rb +0 -43
  753. data/lib/decidim/hashtag.rb +0 -13
  754. data/lib/decidim/metric_manifest.rb +0 -35
  755. data/lib/decidim/metric_operation.rb +0 -58
  756. data/lib/decidim/metric_operation_manifest.rb +0 -21
  757. data/lib/decidim/metric_registry.rb +0 -109
  758. data/lib/gem_overrides/shakapacker/runner.rb +0 -9
  759. data/lib/tasks/decidim_metrics_tasks.rake +0 -89
  760. /data/app/cells/decidim/{endorsement_buttons/disabled_endorsements.erb → like_buttons/disabled_likes.erb} +0 -0
  761. /data/app/packs/src/decidim/{configuration.js → refactor/implementation/configuration.js} +0 -0
  762. /data/app/packs/src/decidim/{external_domain_warning.js → refactor/implementation/external_domain_warning.js} +0 -0
  763. /data/app/packs/src/decidim/{autocomplete.js → refactor/moved/autocomplete.js} +0 -0
  764. /data/app/packs/src/decidim/{delayed.js → refactor/moved/delayed.js} +0 -0
  765. /data/app/packs/src/decidim/{focus_guard.js → refactor/moved/focus_guard.js} +0 -0
  766. /data/app/packs/src/decidim/{history.js → refactor/moved/history.js} +0 -0
  767. /data/app/packs/src/decidim/{i18n.js → refactor/moved/i18n.js} +0 -0
  768. /data/lib/decidim/core/test/shared_examples/{endorsements_controller_shared_context.rb → likes_controller_shared_context.rb} +0 -0
  769. /data/{app/helpers → lib}/decidim/resource_helper.rb +0 -0
  770. /data/lib/decidim/{webpacker → shakapacker}/esbuild.config.js +0 -0
  771. /data/lib/decidim/{webpacker → shakapacker}/postcss.config.js +0 -0
  772. /data/lib/decidim/{webpacker → shakapacker}/tsconfig.json +0 -0
  773. /data/lib/decidim/{webpacker → shakapacker}/webpack/.modernizrrc +0 -0
  774. /data/lib/decidim/{webpacker → shakapacker}/webpack/webpack.config.js +0 -0
@@ -0,0 +1,137 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
4
+
5
+ module OAuthSystemSpecHelpers
6
+ def visit_oauth_authorization_page(scope = nil)
7
+ scope ||= self.scope
8
+ authorization = oauth_authorization_details(scope)
9
+ visit "/oauth/authorize?#{URI.encode_www_form(authorization[:params])}"
10
+ expect(page).to have_content("Log in")
11
+
12
+ within "#session_new_user" do
13
+ fill_in :session_user_email, with: user.email
14
+ fill_in :session_user_password, with: "decidim123456789"
15
+ find("*[type=submit]").click
16
+ end
17
+
18
+ expect(page).to have_content("Logged in successfully.")
19
+
20
+ authorization
21
+ end
22
+
23
+ def oauth_api_authorization(scope)
24
+ token = oauth_api_token(scope)
25
+ %w(token_type access_token).map { |key| token[key] }.join(" ")
26
+ end
27
+
28
+ # Runs through the whole OAuth authorization code flow to fetch a valid OAuth
29
+ # token with the given scopes.
30
+ def oauth_api_token(scope)
31
+ authorization = visit_oauth_authorization_page(scope)
32
+
33
+ click_on "Authorize application"
34
+
35
+ expect(page).to have_content("Authorization code:")
36
+
37
+ page_params = Rack::Utils.parse_query(URI.parse(page.current_url).query)
38
+ raise "Invalid OAuth state returned." if page_params["state"] != authorization[:state]
39
+
40
+ code = page_params["code"]
41
+ oauth_fetch_token(code, authorization[:verifier])
42
+ end
43
+
44
+ def oauth_authorization_details(scope)
45
+ # https://datatracker.ietf.org/doc/html/rfc6749#appendix-A.5
46
+ chars = Array(0x20..0x7E).map(&:chr)
47
+ state = Base64.urlsafe_encode64(oauth_random_string(chars, 36), padding: false)
48
+
49
+ # https://datatracker.ietf.org/doc/html/rfc7636#section-4.1
50
+ chars = Array(0x30..0x39).map(&:chr) + Array(0x41..0x5A).map(&:chr) +
51
+ Array(0x61..0x7A).map(&:chr) + "-._~".chars
52
+ verifier = oauth_random_string(chars, 96)
53
+ challenge = Base64.urlsafe_encode64(Digest::SHA256.digest(verifier), padding: false)
54
+
55
+ # https://datatracker.ietf.org/doc/html/rfc6749#section-4.1.1
56
+ # https://datatracker.ietf.org/doc/html/rfc7636
57
+ params = {
58
+ response_type: "code",
59
+ client_id: oauth_application.uid,
60
+ redirect_uri:,
61
+ scope:,
62
+ state:,
63
+ code_challenge: challenge,
64
+ code_challenge_method: "S256"
65
+ }
66
+
67
+ { params:, state:, verifier: }
68
+ end
69
+
70
+ def oauth_fetch_token(code, verifier)
71
+ # https://datatracker.ietf.org/doc/html/rfc6749#section-4.1.3
72
+ # https://datatracker.ietf.org/doc/html/rfc7636
73
+ uri = URI.parse("#{organization_host}/oauth/token")
74
+ request = Net::HTTP::Post.new(uri)
75
+ data = {
76
+ grant_type: "authorization_code",
77
+ code:,
78
+ redirect_uri:,
79
+ client_id: oauth_application.uid,
80
+ code_verifier: verifier
81
+ }
82
+ data[:client_secret] = oauth_application.secret if confidential
83
+ request.set_form_data(data)
84
+
85
+ http = Net::HTTP.new(uri.host, uri.port)
86
+ response = http.request(request)
87
+ raise "Invalid response from token request: #{response.code}" unless response.is_a?(Net::HTTPOK)
88
+ raise "Unexpected content type from token request: #{response.content_type}" unless response.content_type == "application/json"
89
+
90
+ JSON.parse(response.body)
91
+ end
92
+
93
+ def oauth_random_string(chars, length)
94
+ Array.new(length) { chars[SecureRandom.random_number(chars.length)] }.join
95
+ end
96
+ end
97
+
98
+ shared_context "with oauth application" do
99
+ include OAuthSystemSpecHelpers
100
+
101
+ let!(:organization) { create(:organization) }
102
+ let(:organization_host) { "http://#{organization.host}:#{Capybara.server_port}" }
103
+ let!(:user) { create(:user, :confirmed, organization:) }
104
+ let(:available_scopes) { Doorkeeper.config.scopes.to_s }
105
+ let(:oauth_application) do
106
+ create(
107
+ :oauth_application,
108
+ organization:,
109
+ scopes: available_scopes,
110
+ confidential:,
111
+ redirect_uri:
112
+ )
113
+ end
114
+ # Doorkeeper defines a special action for passing the authorization code back
115
+ # to native apps. This should be primarily used only with public clients but
116
+ # for the sake of testing, we use the same redirect URI for testing both types
117
+ # of OAuth applications.
118
+ let(:redirect_uri) { "#{organization_host}/oauth/authorize/native" }
119
+ let(:confidential) { true }
120
+
121
+ around do |example|
122
+ config = WebMock::Config.instance
123
+ orig_allow = config.allow
124
+ config.allow << %r{http://[0-9]+\.lvh\.me:#{Capybara.server_port}/}
125
+
126
+ example.run
127
+
128
+ config.allow = orig_allow
129
+ end
130
+
131
+ before do
132
+ allow(Doorkeeper.config).to receive(:force_ssl_in_redirect_uri).and_return(false)
133
+ oauth_application
134
+
135
+ switch_to_host(organization.host)
136
+ end
137
+ end
@@ -79,21 +79,3 @@ shared_examples_for "participatory space dropdown metadata cell" do
79
79
  end
80
80
  end
81
81
  end
82
-
83
- shared_examples_for "participatory space dropdown metadata cell hashtag" do
84
- context "when the hashtag is blank" do
85
- let(:hashtag) { nil }
86
-
87
- it "does not render the hashtag symbol" do
88
- expect(subject).to have_no_content("#")
89
- end
90
- end
91
-
92
- context "when the hashtag is present" do
93
- let(:hashtag) { "space_is_the_place" }
94
-
95
- it "renders the hashtag" do
96
- expect(subject).to have_link("#space_is_the_place")
97
- end
98
- end
99
- end
@@ -5,7 +5,6 @@ require "spec_helper"
5
5
  shared_examples_for "general conversation permissions" do
6
6
  let(:context) { { conversation: } }
7
7
  let(:another_user) { create(:user) }
8
- let(:group) { create(:user_group) }
9
8
 
10
9
  context "when the originator of the conversation is the user" do
11
10
  let!(:conversation) do
@@ -64,51 +63,6 @@ shared_examples_for "general conversation permissions" do
64
63
  it { is_expected.to eq false }
65
64
  end
66
65
  end
67
-
68
- context "when the originator of the conversation is a group" do
69
- let(:context) { { conversation:, interlocutor: group } }
70
- let!(:conversation) do
71
- Decidim::Messaging::Conversation.start!(
72
- originator: group,
73
- interlocutors: [another_user],
74
- body: "who wants apples?"
75
- )
76
- end
77
-
78
- it { is_expected.to eq true }
79
- end
80
-
81
- context "when the group is an interlocutor" do
82
- let(:context) { { conversation:, interlocutor: group } }
83
- let!(:conversation) do
84
- Decidim::Messaging::Conversation.start!(
85
- originator: another_user,
86
- interlocutors: [group],
87
- body: "who wants apples?"
88
- )
89
- end
90
-
91
- it { is_expected.to eq true }
92
-
93
- context "and group is not specified as interlocutor" do
94
- let(:context) { { conversation: } }
95
-
96
- it { is_expected.to eq false }
97
- end
98
- end
99
-
100
- context "when the group is not in the conversation" do
101
- let(:context) { { conversation:, interlocutor: group } }
102
- let!(:conversation) do
103
- Decidim::Messaging::Conversation.start!(
104
- originator: another_user,
105
- interlocutors: [create(:user_group)],
106
- body: "who wants apples?"
107
- )
108
- end
109
-
110
- it { is_expected.to eq false }
111
- end
112
66
  end
113
67
 
114
68
  shared_examples_for "restricted conversation permissions" do
@@ -185,8 +185,8 @@ shared_examples "reports by user type" do
185
185
  include_examples "higher user role reports"
186
186
  include_examples "higher user role hides"
187
187
  end
188
- context "When reporting user is process valuator" do
189
- let!(:user) { create(:process_valuator, :confirmed, participatory_process:) }
188
+ context "When reporting user is process evaluator" do
189
+ let!(:user) { create(:process_evaluator, :confirmed, participatory_process:) }
190
190
  include_examples "higher user role reports"
191
191
  include_examples "higher user role does not have hide"
192
192
  end
@@ -2,14 +2,14 @@
2
2
 
3
3
  require "spec_helper"
4
4
 
5
- shared_examples_for "resource endorsed event" do
5
+ shared_examples_for "resource liked event" do
6
6
  include_context "when a simple event"
7
7
 
8
- let(:event_name) { "decidim.events.resource_endorsed" }
8
+ let(:event_name) { "decidim.events.resource_liked" }
9
9
  let(:author) { create(:user, organization: resource.organization) }
10
10
 
11
- let(:extra) { { endorser_id: author.id } }
12
- let(:endorsement) { create(:endorsement, resource:, author:) }
11
+ let(:extra) { { liker_id: author.id } }
12
+ let(:like) { create(:like, resource:, author:) }
13
13
  let(:resource_path) { resource_locator(resource).path }
14
14
  let(:follower) { create(:user, organization: resource.organization) }
15
15
  let(:follow) { create(:follow, followable: author, user: follower) }
@@ -30,7 +30,7 @@ shared_examples_for "resource endorsed event" do
30
30
 
31
31
  describe "email_subject" do
32
32
  it "is generated correctly" do
33
- expect(subject.email_subject).to eq("#{author_presenter.nickname} has performed a new endorsement")
33
+ expect(subject.email_subject).to eq("#{author_presenter.nickname} has performed a new like")
34
34
  end
35
35
  end
36
36
 
@@ -39,7 +39,7 @@ shared_examples_for "resource endorsed event" do
39
39
  it "is generated correctly" do
40
40
  expect(subject.email_intro)
41
41
  .to eq("#{author.name} #{author_presenter.nickname}, who you are following, " \
42
- "has just endorsed \"#{resource_title}\" and we think it may be interesting to you. Check it out and contribute:")
42
+ "has just liked \"#{resource_title}\" and we think it may be interesting to you. Check it out and contribute:")
43
43
  end
44
44
  end
45
45
 
@@ -48,7 +48,7 @@ shared_examples_for "resource endorsed event" do
48
48
 
49
49
  it "is generated correctly" do
50
50
  expect(subject.notification_title)
51
- .to include("The <a href=\"#{resource_path}\">#{resource_title}</a> #{resource_type} has been endorsed by ")
51
+ .to include("The <a href=\"#{resource_path}\">#{resource_title}</a> #{resource_type} has been liked by ")
52
52
 
53
53
  expect(subject.notification_title)
54
54
  .to include("<a href=\"/profiles/#{author.nickname}\">#{author.name} #{author_presenter.nickname}</a>.")
@@ -225,7 +225,6 @@ shared_examples_for "a resource search with origin" do |factory_name|
225
225
 
226
226
  describe "results" do
227
227
  let!(:official_resource) { create(factory_name, :official, { component: }.merge(factory_params)) }
228
- let!(:user_group_resource) { create(factory_name, :user_group_author, { component: }.merge(factory_params)) }
229
228
  let!(:participant_resource) { create(factory_name, :participant_author, { component: }.merge(factory_params)) }
230
229
 
231
230
  if FactoryBot.factories[factory_name].defined_traits.map(&:name).include?(:meeting_resource)
@@ -246,7 +245,6 @@ shared_examples_for "a resource search with origin" do |factory_name|
246
245
  it "returns only official resources" do
247
246
  expect(subject).to have_escaped_html(translated(official_resource.try(:title) || official_resource.try(:name)))
248
247
  expect(subject).not_to have_escaped_html(translated(participant_resource.try(:title) || participant_resource.try(:name)))
249
- expect(subject).not_to have_escaped_html(translated(user_group_resource.try(:title) || user_group_resource.try(:name)))
250
248
  end
251
249
  end
252
250
 
@@ -256,17 +254,6 @@ shared_examples_for "a resource search with origin" do |factory_name|
256
254
  it "returns only citizen resources" do
257
255
  expect(subject).not_to have_escaped_html(translated(official_resource.try(:title) || official_resource.try(:name)))
258
256
  expect(subject).to have_escaped_html(translated(participant_resource.try(:title) || participant_resource.try(:name)))
259
- expect(subject).not_to have_escaped_html(translated(user_group_resource.try(:title) || user_group_resource.try(:name)))
260
- end
261
- end
262
-
263
- context "when filtering user groups resources" do
264
- let(:origins) { %w(user_group) }
265
-
266
- it "returns only user groups resources" do
267
- expect(subject).not_to have_escaped_html(translated(official_resource.try(:title) || official_resource.try(:name)))
268
- expect(subject).not_to have_escaped_html(translated(participant_resource.try(:title) || participant_resource.try(:name)))
269
- expect(subject).to have_escaped_html(translated(user_group_resource.try(:title) || user_group_resource.try(:name)))
270
257
  end
271
258
  end
272
259
 
@@ -277,7 +264,6 @@ shared_examples_for "a resource search with origin" do |factory_name|
277
264
  it "returns only meeting resources" do
278
265
  expect(subject).not_to have_escaped_html(translated(official_resource.try(:title) || official_resource.try(:name)))
279
266
  expect(subject).not_to have_escaped_html(translated(participant_resource.try(:title) || participant_resource.try(:name)))
280
- expect(subject).not_to have_escaped_html(translated(user_group_resource.try(:title) || user_group_resource.try(:name)))
281
267
  expect(subject).to have_escaped_html(translated(meeting_resource.try(:title) || meeting_resource.try(:name)))
282
268
  end
283
269
  end
@@ -20,22 +20,9 @@ shared_examples "searchable results" do
20
20
  find(search_input_selector).native.send_keys :enter
21
21
 
22
22
  expect(page).to have_current_path decidim.search_path, ignore_query: true
23
- expect(page).to have_content(%(Results for the search: "#{term}"))
23
+ expect(page).to have_content(%(results for the search: "#{term}"))
24
24
  expect(page).to have_css(".filter-search.filter-container")
25
- expect(page.find("#search-count h1").text.to_i).to be_positive
26
- end
27
-
28
- it "finds content by hashtag" do
29
- if respond_to?(:hashtag)
30
- fill_in "term", with: hashtag
31
- find(search_input_selector).native.send_keys :enter
32
-
33
- expect(page.find("#search-count h1").text.to_i).to be_positive
34
-
35
- within "#results" do
36
- expect(page).to have_content(hashtag)
37
- end
38
- end
25
+ expect(page.find("#search-count h2").text.to_i).to be_positive
39
26
  end
40
27
 
41
28
  context "when moderation is involved" do
@@ -47,9 +34,9 @@ shared_examples "searchable results" do
47
34
  find(search_input_selector).native.send_keys :enter
48
35
 
49
36
  expect(page).to have_current_path decidim.search_path, ignore_query: true
50
- expect(page).to have_content(%(Results for the search: "#{term}"))
37
+ expect(page).to have_content(%(results for the search: "#{term}"))
51
38
  expect(page).to have_css(".filter-search.filter-container")
52
- expect(page.find("#search-count h1").text.to_i).to be_positive
39
+ expect(page.find("#search-count h2").text.to_i).to be_positive
53
40
 
54
41
  searchables.each do |searchable|
55
42
  next unless searchable.is_a?(Decidim::Reportable)
@@ -66,9 +53,9 @@ shared_examples "searchable results" do
66
53
  find(search_input_selector).native.send_keys :enter
67
54
 
68
55
  expect(page).to have_current_path decidim.search_path, ignore_query: true
69
- expect(page).to have_content(%(Results for the search: "#{term}"))
56
+ expect(page).to have_content(%(results for the search: "#{term}"))
70
57
  expect(page).to have_css(".filter-search.filter-container")
71
- expect(page.find("#search-count h1").text.to_i).not_to be_positive
58
+ expect(page.find("#search-count h2").text.to_i).not_to be_positive
72
59
  end
73
60
  end
74
61
 
@@ -82,22 +69,9 @@ shared_examples "searchable results" do
82
69
  find(search_input_selector).native.send_keys :enter
83
70
 
84
71
  expect(page).to have_current_path decidim.search_path, ignore_query: true
85
- expect(page).to have_content(%(Results for the search: "#{term}"))
72
+ expect(page).to have_content(%(results for the search: "#{term}"))
86
73
  expect(page).to have_css(".filter-search.filter-container")
87
- expect(page.find("#search-count h1").text.to_i).not_to be_positive
88
- end
89
-
90
- it "does not find content by hashtag" do
91
- if respond_to?(:hashtag)
92
- fill_in "term", with: hashtag
93
- find(search_input_selector).native.send_keys :enter
94
-
95
- expect(page.find("#search-count h1").text.to_i).not_to be_positive
96
-
97
- within "#results" do
98
- expect(page).to have_no_content(hashtag)
99
- end
100
- end
74
+ expect(page.find("#search-count h2").text.to_i).not_to be_positive
101
75
  end
102
76
  end
103
77
 
@@ -40,7 +40,86 @@ shared_examples "a social share widget" do
40
40
  expect(page).to have_css('a[title="Share to Facebook"]')
41
41
  expect(page).to have_css('a[title="Share to WhatsApp"]')
42
42
  expect(page).to have_css('a[title="Share to Telegram"]')
43
+ expect(page).to have_css('a[title="Share to QR"]')
43
44
  expect(page).to have_css(".share-modal__input")
44
45
  end
45
46
  end
46
47
  end
48
+
49
+ shared_examples "a social share via QR code" do
50
+ let(:title) { resource.presenter.title }
51
+ let(:parameterized_title) { CGI.escapeHTML(title) }
52
+ let!(:card_image) { nil }
53
+
54
+ it "properly generates a resolvable url" do
55
+ visit_resource
56
+ click_on "Share"
57
+
58
+ execute_script("window.location.href = document.getElementById('urlShareLink').value")
59
+
60
+ expect(page).to have_current_path(resource_locator(resource).path, ignore_query: true)
61
+ end
62
+
63
+ context "when the url is malformed" do
64
+ it_behaves_like "a 404 page" do
65
+ let(:target_path) { decidim.qr_path(resource: "Missing") }
66
+ end
67
+ end
68
+
69
+ it "has the QR code" do
70
+ visit_resource
71
+ click_on "Share"
72
+ click_on "Share to QR"
73
+
74
+ expect(page).to have_content("QR Code")
75
+ within "#QRCodeDialog" do
76
+ expect(page).to have_css(%(img[alt="QR Code"]))
77
+ expect(page).to have_link("Print poster")
78
+ expect(page).to have_content(title)
79
+ expect(page).to have_link("Download")
80
+ end
81
+ end
82
+
83
+ it "downloads the QR code", download: true do
84
+ visit_resource
85
+ click_on "Share"
86
+ click_on "Share to QR"
87
+ click_on "Download"
88
+
89
+ wait_for_download
90
+
91
+ expect(downloads.length).to eq(1)
92
+ expect(download_path).to match(/.*\.png/)
93
+ end
94
+
95
+ it "displays the QR code page" do
96
+ visit_resource
97
+ click_on "Share"
98
+ click_on "Share to QR"
99
+ click_on "Print poster"
100
+ expect(page).to have_content("Scan the QR code")
101
+ expect(page).to have_css(%(img[alt="QR Code for #{parameterized_title}"]))
102
+
103
+ expect(page).to have_css(%(img[src*="#{card_image}"])) unless card_image.nil?
104
+ expect(page).to have_content(title)
105
+
106
+ expect(page).to have_content(translated(organization.name))
107
+ end
108
+
109
+ it "generates the same QR code" do
110
+ visit_resource
111
+ click_on "Share"
112
+ click_on "Share to QR"
113
+
114
+ image = "Avoid comparing empty strings"
115
+
116
+ within "#QRCodeDialog" do
117
+ image = find("img")[:src]
118
+ end
119
+
120
+ click_on "Print poster"
121
+ new_image = find(%(img[alt="QR Code for #{parameterized_title}"]))[:src]
122
+
123
+ expect(image).to eq(new_image)
124
+ end
125
+ end
@@ -0,0 +1,192 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
4
+
5
+ shared_context "with resources to be liked or not" do
6
+ include_context "with a component"
7
+
8
+ # Should be overridden and create one main resource
9
+ let!(:resource) { nil }
10
+ # the name of the resource to be clicked from the component view
11
+ let(:resource_name) { nil }
12
+ # Should be overridden and create 3 extra resources in the current component
13
+ let!(:resources) { nil }
14
+ end
15
+
16
+ shared_examples "Like resource system specs" do
17
+ def expect_page_not_to_include_likes
18
+ expect(page).to have_no_button("Like")
19
+ expect(page).to have_no_css("#resource-#{resource.id}-likes-count")
20
+ end
21
+
22
+ def visit_resource
23
+ visit_component
24
+ click_on resource_name
25
+ end
26
+
27
+ context "when likes are not enabled" do
28
+ let(:component_traits) { [:with_likes_disabled] }
29
+
30
+ context "when the user is not logged in" do
31
+ it "does not show the like resource button and counts" do
32
+ visit_resource
33
+ expect_page_not_to_include_likes
34
+ end
35
+ end
36
+
37
+ context "when the user is logged in" do
38
+ before do
39
+ login_as user, scope: :user
40
+ end
41
+
42
+ it "does not show the like resource button and counts" do
43
+ visit_resource
44
+ expect_page_not_to_include_likes
45
+ end
46
+ end
47
+ end
48
+
49
+ context "when likes are enabled but blocked" do
50
+ let(:component_traits) { [:with_likes_enabled, :with_likes_blocked] }
51
+
52
+ it "shows the likes count and the like button is disabled" do
53
+ visit_resource
54
+ expect(page).to have_css("#resource-#{resource.id}-like-block button[disabled='true']")
55
+ end
56
+ end
57
+
58
+ context "when likes are enabled" do
59
+ let(:component_traits) { [:with_likes_enabled] }
60
+
61
+ context "when the user is not logged in" do
62
+ it "is given the option to sign in" do
63
+ visit_resource
64
+ within "#resource-#{resource.id}-like-block" do
65
+ click_on "Like"
66
+ end
67
+
68
+ expect(page).to have_css("#loginModal", visible: :visible)
69
+ end
70
+ end
71
+
72
+ context "when the user is logged in" do
73
+ before do
74
+ login_as user, scope: :user
75
+ end
76
+
77
+ context "when the resource is not liked yet" do
78
+ it "is able to like the resource" do
79
+ visit_resource
80
+ within "#resource-#{resource.id}-like-block" do
81
+ click_on "Like"
82
+ expect(page).to have_button("Like")
83
+ expect(page).to have_css('svg use[href*="ri-heart-fill"]')
84
+ expect(page).to have_css('#like-button[aria-label="Undo the like"]')
85
+ end
86
+ end
87
+
88
+ it "has likes from other users" do
89
+ author = create(:user, :confirmed, organization: resource.organization)
90
+ create(:like, resource:, author:)
91
+ visit_resource
92
+ within "#liker-list-#{resource.id}" do
93
+ expect(page).to have_content("Liked by #{author.name}")
94
+ click_on author.name
95
+ end
96
+ expect(page).to have_content("Liked by")
97
+ within "#likesModal-#{resource.id}" do
98
+ expect(page).to have_content(author.name)
99
+ expect(page).to have_no_content(user.name)
100
+ end
101
+ end
102
+ end
103
+
104
+ context "when the resource is already liked" do
105
+ let!(:like) { create(:like, resource:, author: user) }
106
+
107
+ it "is not able to like it again" do
108
+ visit_resource
109
+ within "#resource-#{resource.id}-like-block" do
110
+ expect(page).to have_css('svg use[href*="ri-heart-fill"]')
111
+ expect(page).to have_css('#like-button[aria-label="Undo the like"]')
112
+ expect(page).to have_no_css('svg use[href*="ri-heart-line"]')
113
+ end
114
+ end
115
+
116
+ it "is able to undo the like" do
117
+ visit_resource
118
+ within "#resource-#{resource.id}-like-block" do
119
+ expect(page).to have_css('svg use[href*="ri-heart-fill"]')
120
+ expect(page).to have_css('#like-button[aria-label="Undo the like"]')
121
+ click_on "Like"
122
+ expect(page).to have_css('svg use[href*="ri-heart-line"]')
123
+ expect(page).to have_css('#like-button[aria-label="Like"]')
124
+ expect(page).to have_button("Like")
125
+ end
126
+ end
127
+
128
+ it "can show the likes pop-up" do
129
+ visit_resource
130
+ within "#liker-list-#{resource.id}" do
131
+ expect(page).to have_content("Liked by you")
132
+ click_on "you"
133
+ end
134
+ expect(page).to have_content("Liked by")
135
+ within "#likesModal-#{resource.id}" do
136
+ expect(page).to have_content(user.name)
137
+ end
138
+ end
139
+ end
140
+
141
+ context "when verification is required" do
142
+ let(:permissions) do
143
+ {
144
+ like: {
145
+ authorization_handlers: {
146
+ "dummy_authorization_handler" => { "options" => {} }
147
+ }
148
+ }
149
+ }
150
+ end
151
+
152
+ before do
153
+ organization.available_authorizations = ["dummy_authorization_handler"]
154
+ organization.save!
155
+ component.update(permissions:)
156
+ end
157
+
158
+ context "when user is NOT verified" do
159
+ it "is NOT able to like" do
160
+ visit_resource
161
+ within "#resource-#{resource.id}-like-block" do
162
+ click_on "Like"
163
+ end
164
+ expect(page).to have_css("#authorizationModal", visible: :visible)
165
+ end
166
+ end
167
+
168
+ context "when user IS verified" do
169
+ before do
170
+ handler_params = { user: }
171
+ handler_name = "dummy_authorization_handler"
172
+ handler = Decidim::AuthorizationHandler.handler_for(handler_name, handler_params)
173
+
174
+ Decidim::Authorization.create_or_update_from(handler)
175
+ end
176
+
177
+ it "IS able to like", :slow do
178
+ visit_resource
179
+ within "#resource-#{resource.id}-like-block" do
180
+ expect(page).to have_css('svg use[href*="ri-heart-line"]')
181
+ expect(page).to have_css('#like-button[aria-label="Like"]')
182
+ click_on "Like"
183
+ expect(page).to have_button("Like")
184
+ expect(page).to have_css('#like-button[aria-label="Undo the like"]')
185
+ expect(page).to have_css('svg use[href*="ri-heart-fill"]')
186
+ end
187
+ end
188
+ end
189
+ end
190
+ end
191
+ end
192
+ end