decidim-core 0.29.2 → 0.29.4

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 (147) hide show
  1. checksums.yaml +4 -4
  2. data/app/cells/decidim/address/show.erb +3 -3
  3. data/app/cells/decidim/author/show.erb +2 -4
  4. data/app/cells/decidim/content_blocks/participatory_space_extra_data/extra_data.erb +2 -2
  5. data/app/cells/decidim/participatory_space_dropdown_metadata/metadata.erb +4 -4
  6. data/app/cells/decidim/participatory_space_dropdown_metadata/show.erb +5 -3
  7. data/app/cells/decidim/profile_actions/show.erb +1 -1
  8. data/app/cells/decidim/report_button/already_reported_modal.erb +2 -2
  9. data/app/cells/decidim/report_button/flag_modal.erb +13 -27
  10. data/app/cells/decidim/report_button_cell.rb +2 -8
  11. data/app/cells/decidim/report_user_button/already_reported_modal.erb +11 -0
  12. data/app/cells/decidim/report_user_button/flag_modal.erb +46 -0
  13. data/app/cells/decidim/report_user_button/show.erb +2 -0
  14. data/app/cells/decidim/report_user_button_cell.rb +59 -0
  15. data/app/cells/decidim/resource_types_filter/show.erb +1 -1
  16. data/app/cells/decidim/resource_types_filter_cell.rb +6 -6
  17. data/app/cells/decidim/user_activity/show.erb +1 -1
  18. data/app/commands/decidim/create_omniauth_registration.rb +14 -8
  19. data/app/commands/decidim/create_report.rb +6 -7
  20. data/app/commands/decidim/invite_user.rb +1 -1
  21. data/app/commands/decidim/search.rb +14 -0
  22. data/app/controllers/concerns/decidim/participatory_space_context.rb +4 -1
  23. data/app/controllers/decidim/profiles_controller.rb +2 -2
  24. data/app/controllers/decidim/reports_controller.rb +7 -2
  25. data/app/controllers/decidim/user_activities_controller.rb +1 -1
  26. data/app/forms/decidim/account_form.rb +5 -2
  27. data/app/forms/decidim/omniauth_registration_form.rb +1 -1
  28. data/app/forms/decidim/registration_form.rb +1 -1
  29. data/app/helpers/decidim/menu_helper.rb +2 -2
  30. data/app/helpers/decidim/orders_helper.rb +2 -1
  31. data/app/helpers/decidim/paginate_helper.rb +1 -1
  32. data/app/helpers/decidim/participatory_space_helpers.rb +1 -1
  33. data/app/helpers/decidim/tooltip_helper.rb +4 -1
  34. data/app/jobs/decidim/hide_child_resources_job.rb +24 -0
  35. data/app/mailers/decidim/notifications_digest_mailer.rb +7 -1
  36. data/app/mailers/decidim/reported_mailer.rb +18 -2
  37. data/app/models/decidim/action_log.rb +1 -9
  38. data/app/models/decidim/report.rb +1 -1
  39. data/app/models/decidim/user.rb +0 -4
  40. data/app/models/decidim/user_base_entity.rb +4 -0
  41. data/app/packs/src/decidim/datepicker/datepicker_functions.js +3 -3
  42. data/app/packs/src/decidim/index.js +4 -2
  43. data/app/packs/src/decidim/input_character_counter.js +1 -1
  44. data/app/packs/src/decidim/map/provider/here.js +1 -1
  45. data/app/packs/stylesheets/decidim/_cards.scss +1 -1
  46. data/app/packs/stylesheets/decidim/_content_blocks.scss +4 -0
  47. data/app/packs/stylesheets/decidim/_hashtags.scss +5 -0
  48. data/app/packs/stylesheets/decidim/_header.scss +65 -40
  49. data/app/packs/stylesheets/decidim/application.scss +1 -0
  50. data/app/permissions/decidim/default_permissions.rb +2 -0
  51. data/app/presenters/decidim/log/user_presenter.rb +1 -0
  52. data/app/presenters/decidim/notification_to_mailer_presenter.rb +7 -3
  53. data/app/presenters/decidim/user_presenter.rb +1 -1
  54. data/app/queries/decidim/last_activity.rb +25 -0
  55. data/app/services/decidim/base_diff_renderer.rb +2 -0
  56. data/app/services/decidim/static_map_generator.rb +1 -1
  57. data/app/views/decidim/last_activities/index.html.erb +1 -1
  58. data/app/views/decidim/messaging/conversations/_reply_form.html.erb +1 -2
  59. data/app/views/decidim/messaging/conversations/_start.html.erb +1 -1
  60. data/app/views/decidim/reported_mailer/hidden_automatically.html.erb +25 -0
  61. data/app/views/decidim/reported_mailer/hidden_manually.html.erb +25 -0
  62. data/app/views/decidim/reported_mailer/report.html.erb +1 -1
  63. data/app/views/decidim/searches/_count.html.erb +1 -1
  64. data/app/views/decidim/searches/_filters.html.erb +40 -38
  65. data/app/views/decidim/shared/_orders.html.erb +2 -2
  66. data/app/views/decidim/shared/_results_per_page.html.erb +1 -1
  67. data/app/views/kaminari/decidim/_page.html.erb +1 -1
  68. data/app/views/kaminari/decidim/_paginator.html.erb +1 -1
  69. data/app/views/layouts/decidim/_logo.html.erb +2 -2
  70. data/app/views/layouts/decidim/footer/_main_legal.html.erb +1 -1
  71. data/app/views/layouts/decidim/header/_menu_breadcrumb_main_dropdown_desktop.html.erb +5 -11
  72. data/app/views/layouts/decidim/header/_menu_breadcrumb_mobile_tablet.html.erb +5 -5
  73. data/config/locales/ar.yml +41 -34
  74. data/config/locales/bg.yml +10 -30
  75. data/config/locales/bs-BA.yml +2 -0
  76. data/config/locales/ca-IT.yml +2122 -0
  77. data/config/locales/ca.yml +69 -30
  78. data/config/locales/cs.yml +73 -36
  79. data/config/locales/de.yml +64 -26
  80. data/config/locales/el.yml +10 -21
  81. data/config/locales/en.yml +56 -17
  82. data/config/locales/eo.yml +2 -0
  83. data/config/locales/es-MX.yml +69 -30
  84. data/config/locales/es-PY.yml +74 -35
  85. data/config/locales/es.yml +72 -33
  86. data/config/locales/eu.yml +128 -91
  87. data/config/locales/fi-plain.yml +44 -34
  88. data/config/locales/fi.yml +46 -36
  89. data/config/locales/fr-CA.yml +72 -29
  90. data/config/locales/fr.yml +71 -28
  91. data/config/locales/ga-IE.yml +4 -4
  92. data/config/locales/gl.yml +25 -20
  93. data/config/locales/hu.yml +9 -29
  94. data/config/locales/id-ID.yml +24 -21
  95. data/config/locales/is-IS.yml +10 -6
  96. data/config/locales/it.yml +35 -32
  97. data/config/locales/ja.yml +70 -30
  98. data/config/locales/lb.yml +24 -27
  99. data/config/locales/lt.yml +5 -23
  100. data/config/locales/lv.yml +18 -20
  101. data/config/locales/nl.yml +23 -23
  102. data/config/locales/no.yml +18 -21
  103. data/config/locales/pl.yml +7 -27
  104. data/config/locales/pt-BR.yml +11 -30
  105. data/config/locales/pt.yml +18 -21
  106. data/config/locales/ro-RO.yml +239 -92
  107. data/config/locales/ru.yml +23 -13
  108. data/config/locales/sk.yml +29 -23
  109. data/config/locales/sl.yml +4 -0
  110. data/config/locales/sr-CS.yml +2 -0
  111. data/config/locales/sv.yml +49 -37
  112. data/config/locales/tr-TR.yml +25 -28
  113. data/config/locales/uk.yml +12 -7
  114. data/config/locales/zh-CN.yml +18 -20
  115. data/config/locales/zh-TW.yml +8 -22
  116. data/db/migrate/20171212103803_create_unique_nicknames.rb +1 -1
  117. data/db/migrate/20180221101934_fix_nickname_index.rb +1 -1
  118. data/db/migrate/20180706104107_add_nickname_to_managed_users.rb +1 -1
  119. data/db/migrate/20181001124950_move_users_groups_to_users_table.rb +1 -1
  120. data/db/migrate/20190412131728_fix_user_names.rb +1 -1
  121. data/lib/decidim/asset_router/storage.rb +7 -2
  122. data/lib/decidim/attributes/time_with_zone.rb +5 -1
  123. data/lib/decidim/content_parsers/blob_parser.rb +10 -8
  124. data/lib/decidim/content_parsers/user_parser.rb +1 -1
  125. data/lib/decidim/core/test/shared_examples/reports_examples.rb +48 -6
  126. data/lib/decidim/core/test/shared_examples/social_share_examples.rb +32 -0
  127. data/lib/decidim/core/test/shared_examples/uncommentable_component_examples.rb +26 -0
  128. data/lib/decidim/core/test/shared_examples/versions_controller_examples.rb +26 -0
  129. data/lib/decidim/core/version.rb +1 -1
  130. data/lib/decidim/map/provider/dynamic_map/here.rb +1 -40
  131. data/lib/decidim/map/provider/static_map/here.rb +34 -0
  132. data/lib/decidim/moderation_tools.rb +16 -2
  133. data/lib/decidim/nicknamizable.rb +6 -9
  134. data/lib/decidim/reportable.rb +6 -2
  135. data/lib/decidim/translatable_attributes.rb +5 -1
  136. data/lib/tasks/upgrade/clean_hidden_resources.rake +33 -0
  137. data/lib/tasks/upgrade/decidim_fix_nickname_uniqueness.rake +23 -20
  138. metadata +17 -15
  139. data/app/cells/decidim/author/flag.erb +0 -6
  140. data/app/cells/decidim/author/flag_user.erb +0 -14
  141. data/app/cells/decidim/flag_modal/flag_user.erb +0 -34
  142. data/app/cells/decidim/flag_modal/show.erb +0 -52
  143. data/app/cells/decidim/flag_modal_cell.rb +0 -56
  144. data/app/cells/decidim/profile_sidebar/show.erb +0 -167
  145. data/app/cells/decidim/profile_sidebar_cell.rb +0 -68
  146. data/app/packs/src/decidim/vendor/leaflet-tilelayer-here.js +0 -212
  147. data/app/views/decidim/reported_mailer/hide.html.erb +0 -9
@@ -25,6 +25,8 @@ zh-CN:
25
25
  password_confirmation: 确认您的密码
26
26
  personal_url: 个人网址
27
27
  remove_avatar: 删除头像
28
+ user_group:
29
+ avatar: 头像
28
30
  models:
29
31
  decidim/attachment_created_event: 附文
30
32
  decidim/component_published_event: 活动组件
@@ -316,6 +318,8 @@ zh-CN:
316
318
  view_all: 查看全部
317
319
  metrics:
318
320
  name: 组织指标
321
+ participatory_space_metrics:
322
+ name: 指标
319
323
  stats:
320
324
  name: 组织统计
321
325
  sub_hero:
@@ -701,6 +705,8 @@ zh-CN:
701
705
  new_conversation: 新建对话
702
706
  next: 下一个
703
707
  title: 对话
708
+ reply_form:
709
+ placeholder: 您的回复...
704
710
  show:
705
711
  back: 回到所有对话
706
712
  chat_with: 对话
@@ -715,11 +721,9 @@ zh-CN:
715
721
  participants:
716
722
  description: 组织中的活跃参与者人数
717
723
  object: 参与者
718
- title: 参加者
719
724
  users:
720
725
  description: 参加组织的人数
721
726
  object: 参与者
722
- title: 参加者
723
727
  newsletter_mailer:
724
728
  newsletter:
725
729
  unsubscribe: 选择不接收这种类型的电子邮件, <a href="%{link}" target="_blank" class="unsubscribe">取消订阅</a>。
@@ -814,29 +818,23 @@ zh-CN:
814
818
  conversations: 对话
815
819
  followers: 关注者
816
820
  following: 关注的问题
821
+ group_admins: 管理管理员
822
+ group_members: 管理成员
817
823
  groups: 群組
818
824
  members: 成员
819
825
  officialized: 官方参与者
820
- sidebar:
821
- badges:
822
- info: 徽章是通过在平台上执行特定活动赚取的。
823
- title: 徽章
824
826
  user:
825
- create_user_group: 创建组
826
- edit_profile: 编辑配置文件
827
- edit_user_group: 编辑群组资料
828
- invite_user: Invite participant
829
- join_user_group: 加入组的请求
830
- leave_user_group: 离开组
831
- manage_user_group_admins: 管理管理员
832
- manage_user_group_users: 管理成员
833
- resend_email_confirmation_instructions: 重新发送电子邮件确认说明
827
+ actions:
828
+ create_user_group: 创建组
829
+ edit_profile: 编辑配置文件
830
+ edit_user_group: 编辑群组资料
831
+ invite_user: Invite participant
832
+ join_user_group: 加入组的请求
833
+ leave_user_group: 离开组
834
+ manage_user_group_admins: 管理管理员
835
+ manage_user_group_users: 管理成员
836
+ resend_email_confirmation_instructions: 重新发送电子邮件确认说明
834
837
  reported_mailer:
835
- hide:
836
- hello: 您好 %{name},
837
- manage_moderations: 管理版面
838
- report_html: <p>以下 <a href="%{url}">内容</a> 已被自动隐藏。</p>
839
- subject: 资源已自动隐藏
840
838
  report:
841
839
  authors: 作者
842
840
  content: 报告的内容
@@ -31,6 +31,8 @@ zh-TW:
31
31
  personal_url: 個人 URL
32
32
  remove_avatar: 刪除頭像
33
33
  tos_agreement: 同意服務條款
34
+ user_group:
35
+ avatar: 頭像
34
36
  models:
35
37
  decidim/attachment_created_event: 附件
36
38
  decidim/component_published_event: 啟用組件
@@ -474,6 +476,8 @@ zh-TW:
474
476
  view_all: 檢視全部
475
477
  metrics:
476
478
  name: 組織指標
479
+ participatory_space_metrics:
480
+ name: 指標
477
481
  static_page:
478
482
  section:
479
483
  name: 節
@@ -562,7 +566,6 @@ zh-TW:
562
566
  drag_and_drop_help: 通過拖放或粘貼方式添加圖片。
563
567
  endorsement_buttons_cell:
564
568
  already_endorsed: 不喜歡
565
- endorse: 喜歡!
566
569
  endorsements:
567
570
  identities:
568
571
  done: 已完成
@@ -1216,14 +1219,12 @@ zh-TW:
1216
1219
  conversations: 對話
1217
1220
  followers: 追隨者
1218
1221
  following: 關注
1222
+ group_admins: 管理管理員
1223
+ group_members: 管理成員
1219
1224
  groups: 群組
1220
1225
  members: 成員
1221
1226
  officialized: 正式認證參與者
1222
1227
  send_private_message: 發送私人訊息
1223
- sidebar:
1224
- badges:
1225
- info: 徽章是通過在平台上執行特定活動而獲得的。
1226
- title: 徽章
1227
1228
  user:
1228
1229
  actions:
1229
1230
  create_user_group: 建立群組
@@ -1231,26 +1232,14 @@ zh-TW:
1231
1232
  edit_user_group: 編輯群組資料
1232
1233
  invite_user: 邀請參與者
1233
1234
  join_user_group: 申請加入群組
1235
+ leave_user_group: 退出群組
1234
1236
  manage_user_group_admins: 管理管理員
1235
1237
  manage_user_group_users: 管理成員
1236
1238
  message: 訊息
1239
+ resend_email_confirmation_instructions: 重新發送電子郵件確認指示
1237
1240
  confirmation_instructions_sent: 電子郵件確認指示已發送.
1238
- create_user_group: 建立群組
1239
- edit_profile: 編輯個人資料
1240
- edit_user_group: 編輯群組資料
1241
1241
  fill_in_email_to_confirm_it: 請填寫您的群組電子郵件以進行確認.
1242
- invite_user: 邀請參與者
1243
- join_user_group: 申請加入群組
1244
- leave_user_group: 退出群組
1245
- manage_user_group_admins: 管理管理員
1246
- manage_user_group_users: 管理成員
1247
- resend_email_confirmation_instructions: 重新發送電子郵件確認指示
1248
1242
  reported_mailer:
1249
- hide:
1250
- hello: 哈囉,%{name},
1251
- manage_moderations: 管理版主
1252
- report_html: <p>以下<a href="%{url}">內容</a>已自動隱藏。</p>
1253
- subject: 一個資源已被自動隱藏。
1254
1243
  report:
1255
1244
  authors: 作者
1256
1245
  content: 已檢舉內容
@@ -1331,14 +1320,11 @@ zh-TW:
1331
1320
  flag_user_modal:
1332
1321
  already_reported: 此內容已被舉報,將由管理員進行審查。
1333
1322
  block: 封鎖此參與者
1334
- close: 關閉
1335
- description: 關於該使用者有什麼不適當的行為?
1336
1323
  does_not_belong: 包含非法活動、自殺威脅、個人資訊或其他您認為不適合在%{organization_name} 上的內容。
1337
1324
  hide: 隱藏所有內容
1338
1325
  offensive: 包含種族主義、性別歧視、辱罵、人身攻擊、死亡威脅、自殺要求或任何形式的仇恨言論
1339
1326
  report: 報告
1340
1327
  spam: 包含點閱率誘導、廣告、詐騙或自動腳本。
1341
- title: 舉報不適當的使用者
1342
1328
  floating_help:
1343
1329
  help: 幫助
1344
1330
  mentions_modal:
@@ -11,7 +11,7 @@ class CreateUniqueNicknames < ActiveRecord::Migration[5.1]
11
11
  add_column :decidim_users, :nickname, :string, limit: 20
12
12
 
13
13
  User.where.not(name: nil).find_each do |user|
14
- user.update!(nickname: UserBaseEntity.nicknamize(user.name, decidim_organization_id: user.decidim_organization_id))
14
+ user.update!(nickname: UserBaseEntity.nicknamize(user.name, user.decidim_organization_id))
15
15
  end
16
16
 
17
17
  add_index :decidim_users,
@@ -11,7 +11,7 @@ class FixNicknameIndex < ActiveRecord::Migration[5.1]
11
11
  User.where(nickname: nil)
12
12
  .where(deleted_at: nil)
13
13
  .where(managed: false)
14
- .find_each { |u| u.update(nickname: UserBaseEntity.nicknamize(u.name, decidim_organization_id: u.decidim_organization_id)) }
14
+ .find_each { |u| u.update(nickname: UserBaseEntity.nicknamize(u.name, u.decidim_organization_id)) }
15
15
 
16
16
  # rubocop:disable Rails/SkipsModelValidations
17
17
  User.where(nickname: nil).update_all("nickname = ''")
@@ -7,7 +7,7 @@ class AddNicknameToManagedUsers < ActiveRecord::Migration[5.2]
7
7
 
8
8
  def up
9
9
  User.where(managed: true, nickname: nil).includes(:organization).find_each do |user|
10
- user.nickname = UserBaseEntity.nicknamize(user.name, organization: user.organization)
10
+ user.nickname = UserBaseEntity.nicknamize(user.name, user.decidim_organization_id)
11
11
  user.save
12
12
  end
13
13
  end
@@ -64,7 +64,7 @@ class MoveUsersGroupsToUsersTable < ActiveRecord::Migration[5.2]
64
64
  verified_at: old_user_group.verified_at
65
65
  }
66
66
  new_attributes = clean_attributes.merge(
67
- nickname: UserBaseEntity.nicknamize(clean_attributes["name"]),
67
+ nickname: UserBaseEntity.nicknamize(clean_attributes["name"], old_user_group.decidim_organization_id),
68
68
  extended_data:
69
69
  )
70
70
  new_user_group = NewUserGroup.create!(new_attributes)
@@ -23,7 +23,7 @@ class FixUserNames < ActiveRecord::Migration[5.2]
23
23
 
24
24
  entity.name = entity.name.delete(characters_to_remove).strip
25
25
  sanitized_nickname = entity.nickname.delete(characters_to_remove).strip
26
- entity.nickname = UserBaseEntity.nicknamize(sanitized_nickname, organization: entity.organization)
26
+ entity.nickname = UserBaseEntity.nicknamize(sanitized_nickname, entity.decidim_organization_id)
27
27
  entity.save(validate: false)
28
28
  end
29
29
  end
@@ -52,8 +52,13 @@ module Decidim
52
52
  when ActiveStorage::Blob
53
53
  blob_url(**)
54
54
  else # ActiveStorage::VariantWithRecord, ActiveStorage::Variant
55
- ensure_current_host(nil, **)
56
- representation_url(**)
55
+ if blob && blob.attachments.any?
56
+ ensure_current_host(blob.attachments.first&.record, **)
57
+ representation_url(**)
58
+ else
59
+ ensure_current_host(nil, **)
60
+ representation_url(**, only_path: true)
61
+ end
57
62
  end
58
63
  end
59
64
 
@@ -23,7 +23,11 @@ module Decidim
23
23
  def cast_value(value)
24
24
  return value unless value.is_a?(String)
25
25
 
26
- Time.zone.strptime(value, I18n.t("time.formats.decidim_short"))
26
+ if Date._iso8601(value).present?
27
+ Time.zone.iso8601(value)
28
+ else
29
+ Time.zone.strptime(value, I18n.t("time.formats.decidim_short"))
30
+ end
27
31
  rescue ArgumentError
28
32
  fallback = super
29
33
  return fallback unless fallback.is_a?(Time)
@@ -20,19 +20,19 @@ module Decidim
20
20
  # https://github.com/rails/rails/blob/a7e379896552ce43b822385c03c37f2bd47739d3/activestorage/config/routes.rb#L5-L14
21
21
  BLOB_REGEX = %r{
22
22
  # Group 1: Host part
23
- (
23
+ (?<host_part>
24
24
  # Group 2: Domain and subpath part
25
- https?://((?!/rails).)+
25
+ #{URI::DEFAULT_PARSER.make_regexp(%w(https http))}
26
26
  )?
27
27
  /rails/active_storage
28
28
  # Group 3: Blob path, representation path or disk service path
29
- /(blobs/redirect|blobs/proxy|blobs|representations/redirect|representations/proxy|representations|disk)
29
+ /(?<type_part>blobs/redirect|blobs/proxy|blobs|representations/redirect|representations/proxy|representations|disk)
30
30
  # Group 4: Signed ID for blobs or encoded key for disk service
31
- /([^/]+)
31
+ /(?<key_part>[^/]+)
32
32
  # Group 5: Variation part (only for representations)
33
33
  (
34
34
  # Group 6: Variation key for representations
35
- /([\w.=-]+)
35
+ /(?<variation_part>[\w.=-]+)
36
36
  )?
37
37
  # Group 7: Filename
38
38
  /([\w.=-]+)
@@ -46,8 +46,10 @@ module Decidim
46
46
 
47
47
  def replace_blobs(text)
48
48
  text.gsub(BLOB_REGEX) do |match|
49
- type_part = Regexp.last_match(3)
50
- key_part = Regexp.last_match(4)
49
+ named_captures = Regexp.last_match.named_captures
50
+
51
+ type_part = named_captures["type_part"]
52
+ key_part = named_captures["key_part"]
51
53
 
52
54
  variation_key = nil
53
55
  blob =
@@ -59,7 +61,7 @@ module Decidim
59
61
  # Representation or blob
60
62
  if type_part.start_with?("representations")
61
63
  # Representation
62
- variation_part = Regexp.last_match(6)
64
+ variation_part = named_captures["variation_part"]
63
65
  variation_key = generate_variation_key(variation_part)
64
66
  end
65
67
 
@@ -49,7 +49,7 @@ module Decidim
49
49
 
50
50
  def existing_mentionables
51
51
  @existing_mentionables ||= mentionable_class.where(
52
- "decidim_organization_id = ? AND LOWER(nickname) IN (?)",
52
+ "decidim_organization_id = ? AND nickname IN (?)",
53
53
  current_organization.id,
54
54
  content_nicknames
55
55
  )
@@ -33,17 +33,46 @@ shared_examples "higher user role hides" do
33
33
  before do
34
34
  login_as user, scope: :user
35
35
  end
36
- around do |example|
37
- previous = Capybara.raise_server_errors
38
36
 
39
- Capybara.raise_server_errors = false
40
- example.run
41
- Capybara.raise_server_errors = previous
37
+ it "reports the resource" do
38
+ visit reportable_path
39
+
40
+ expect(page).to have_css(%(button[data-dialog-open="flagModal"]))
41
+ find(%(button[data-dialog-open="flagModal"])).click
42
+ expect(page).to have_css(".flag-modal", visible: :visible)
43
+
44
+ within ".flag-modal" do
45
+ find(:css, "input[name='report[hide]']").set(true)
46
+ click_on "Hide"
47
+ end
48
+
49
+ sleep(1)
50
+
51
+ expect(page).to have_current_path(reportable_index_path, ignore_query: true)
52
+
53
+ expect(reportable.reload).to be_hidden
42
54
  end
55
+ end
56
+ end
57
+
58
+ shared_examples "higher user role hides resource with comments" do
59
+ context "and the admin hides a resource with comments" do
60
+ let!(:comments) { create_list(:comment, 2, body: "Dummy comment", commentable: reportable, author: user) }
61
+
62
+ before do
63
+ login_as user, scope: :user
64
+ end
65
+
66
+ it "hides the resource" do
67
+ visit decidim.search_path
68
+ expect(page).to have_content(translated(comments.first.body))
69
+ expect(page).to have_content(translated(comments.second.body))
43
70
 
44
- it "reports the resource" do
45
71
  visit reportable_path
46
72
 
73
+ expect(page).to have_content(translated(comments.first.body))
74
+ expect(page).to have_content(translated(comments.second.body))
75
+
47
76
  expect(page).to have_css(%(button[data-dialog-open="flagModal"]))
48
77
  find(%(button[data-dialog-open="flagModal"])).click
49
78
  expect(page).to have_css(".flag-modal", visible: :visible)
@@ -53,7 +82,19 @@ shared_examples "higher user role hides" do
53
82
  click_on "Hide"
54
83
  end
55
84
 
85
+ sleep(1)
86
+
87
+ expect(page).to have_current_path(reportable_index_path, ignore_query: true)
88
+
89
+ perform_enqueued_jobs
90
+
56
91
  expect(reportable.reload).to be_hidden
92
+ expect(comments.first.reload).to be_hidden
93
+ expect(comments.second.reload).to be_hidden
94
+
95
+ visit decidim.search_path
96
+ expect(page).to have_no_content(translated(comments.first.body))
97
+ expect(page).to have_no_content(translated(comments.second.body))
57
98
  end
58
99
  end
59
100
  end
@@ -120,6 +161,7 @@ shared_examples "reports by user type" do
120
161
  let!(:user) { create(:user, :admin, :confirmed, organization:) }
121
162
  include_examples "higher user role reports"
122
163
  include_examples "higher user role hides"
164
+ include_examples "higher user role hides resource with comments"
123
165
  end
124
166
  context "When reporting user is process admin" do
125
167
  let!(:user) { create :process_admin, :confirmed, participatory_process: }
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
4
+
5
+ def visit_resource
6
+ return visit resource if resource.is_a?(String)
7
+
8
+ return visit decidim.root_path if resource.is_a?(Decidim::Organization)
9
+
10
+ visit resource_locator(resource).path
11
+ end
12
+
13
+ shared_examples "a social share widget" do
14
+ it "has the social share button" do
15
+ visit_resource
16
+
17
+ expect(page).to have_css('button[data-dialog-open="socialShare"]')
18
+ end
19
+
20
+ it "lists all the expected social share providers" do
21
+ visit_resource
22
+ click_on "Share"
23
+
24
+ within "#socialShare" do
25
+ expect(page).to have_css('a[title="Share to X"]')
26
+ expect(page).to have_css('a[title="Share to Facebook"]')
27
+ expect(page).to have_css('a[title="Share to WhatsApp"]')
28
+ expect(page).to have_css('a[title="Share to Telegram"]')
29
+ expect(page).to have_css(".share-modal__input")
30
+ end
31
+ end
32
+ end
@@ -8,6 +8,7 @@ shared_examples "an uncommentable component" do
8
8
  manifest:,
9
9
  participatory_space:)
10
10
  end
11
+ let!(:comment) { create(:comment, commentable: resources.first) }
11
12
 
12
13
  it "does not displays comments count" do
13
14
  component.update!(settings: { comments_enabled: false })
@@ -18,4 +19,29 @@ shared_examples "an uncommentable component" do
18
19
  expect(page).to have_no_link(resource_locator(resource).path)
19
20
  end
20
21
  end
22
+
23
+ describe "when search a comment in the global search" do
24
+ it "does displays the comments" do
25
+ visit decidim.root_path
26
+
27
+ within ".main-bar__search" do
28
+ fill_in "term", with: comment.body["en"]
29
+ find("input#input-search").native.send_keys :enter
30
+ end
31
+
32
+ expect(page).to have_content("1 Results for the search")
33
+ end
34
+
35
+ it "does not displays the comment when comments are disable" do
36
+ component.update!(settings: { comments_enabled: false })
37
+ visit decidim.root_path
38
+
39
+ within ".main-bar__search" do
40
+ fill_in "term", with: comment.body["en"]
41
+ find("input#input-search").native.send_keys :enter
42
+ end
43
+
44
+ expect(page).to have_content("0 Results for the search")
45
+ end
46
+ end
21
47
  end
@@ -2,6 +2,32 @@
2
2
 
3
3
  require "spec_helper"
4
4
 
5
+ shared_examples "a version of a hidden object" do
6
+ before do
7
+ visit resource_path
8
+ click_on "see other versions"
9
+ click_on("Version 1 of #{hidden_object.reload.versions.size}")
10
+ end
11
+
12
+ around do |example|
13
+ previous = Capybara.raise_server_errors
14
+
15
+ Capybara.raise_server_errors = false
16
+ example.run
17
+ Capybara.raise_server_errors = previous
18
+ end
19
+
20
+ it "shows an error page" do
21
+ expect(page).to have_content("Changes at")
22
+
23
+ create(:moderation, reportable: hidden_object, hidden_at: 1.day.ago)
24
+
25
+ visit current_path
26
+
27
+ expect(page).to have_content(ActiveRecord::RecordNotFound)
28
+ end
29
+ end
30
+
5
31
  shared_examples "versions controller" do
6
32
  let(:base_params) do
7
33
  if resource.is_a?(Decidim::Participable)
@@ -4,7 +4,7 @@ module Decidim
4
4
  # This holds the decidim-core version.
5
5
  module Core
6
6
  def self.version
7
- "0.29.2"
7
+ "0.29.4"
8
8
  end
9
9
  end
10
10
  end
@@ -49,46 +49,7 @@ module Decidim
49
49
  private
50
50
 
51
51
  def language_code
52
- primary = I18n.locale.to_s
53
- secondary = primary.split("-")[0]
54
- available_language_codes[primary] || available_language_codes[secondary] || ""
55
- end
56
-
57
- def available_language_codes
58
- @available_language_codes ||= {
59
- "ar" => "ara", # Arabic
60
- "eu" => "baq", # Basque
61
- "ca" => "cat", # Catalan
62
- "zh" => "chi", # Chinese (simplified)
63
- # "" => "cht", # Chinese (traditional)
64
- "cs" => "cze", # Czech
65
- "da" => "dan", # Danish
66
- "nl" => "dut", # Dutch
67
- "en" => "eng", # English
68
- "fi" => "fin", # Finnish
69
- "fr" => "fre", # French
70
- "de" => "ger", # German
71
- "ga" => "gle", # Gaelic
72
- "el" => "gre", # Greek
73
- "he" => "heb", # Hebrew
74
- "hi" => "hin", # Hindi
75
- "id" => "ind", # Indonesian
76
- "it" => "ita", # Italian
77
- "no" => "nor", # Norwegian
78
- "fa" => "per", # Persian
79
- "pl" => "pol", # Polish
80
- "pt" => "por", # Portuguese
81
- "ru" => "rus", # Russian
82
- "si" => "sin", # Sinhalese
83
- "es" => "spa", # Spanish
84
- "sv" => "swe", # Swedish
85
- "th" => "tha", # Thai
86
- "tr" => "tur", # Turkish
87
- "uk" => "ukr", # Ukrainian
88
- "ur" => "urd", # Urdu
89
- "vi" => "vie", # Vietnamese
90
- "cy" => "wel" # Welsh
91
- }
52
+ I18n.locale.to_s
92
53
  end
93
54
  end
94
55
  end
@@ -6,8 +6,42 @@ module Decidim
6
6
  module StaticMap
7
7
  # The static map utility class for the HERE maps service
8
8
  class Here < ::Decidim::Map::StaticMap
9
+ def url(latitude:, longitude:, options: {})
10
+ map_url = configuration.fetch(:url, nil)
11
+ return super unless map_url
12
+
13
+ return super unless map_url.include?("mia/v3")
14
+
15
+ w = options[:width] || Decidim::Map::StaticMap::DEFAULT_SIZE
16
+ h = options[:height] || Decidim::Map::StaticMap::DEFAULT_SIZE
17
+
18
+ params = {
19
+ apiKey: configuration[:api_key],
20
+ overlay: "point:#{latitude},#{longitude};icon=cp;size=large|#{latitude},#{longitude};style=circle;width=50m;color=%231B9D2C60"
21
+ }
22
+
23
+ URI.parse("#{map_url}:radius=90/#{w}x#{h}/png8").tap do |uri|
24
+ uri.query = URI.encode_www_form(params)
25
+ end.to_s
26
+ end
27
+
9
28
  # @See Decidim::Map::StaticMap#url_params
10
29
  def url_params(latitude:, longitude:, options: {})
30
+ ActiveSupport::Deprecation.warn(
31
+ <<~DEPRECATION.strip
32
+ Please use a V3 version HERE maps.
33
+ For further information, see:
34
+ https://www.here.com/docs/bundle/map-image-migration-guide-v3/page/README.html
35
+ Also make sure your Decidim.maps configurations are using the
36
+ up to date format.
37
+ You need to change:
38
+ static_url = "https://image.maps.ls.hereapi.com/mia/1.6/mapview" if static_provider == "here" && static_url.blank?
39
+ to:
40
+ static_url = "https://image.maps.hereapi.com/mia/v3/base/mc/overlay" if static_provider == "here"
41
+ in your config/initializers/decidim.rb file.
42
+ DEPRECATION
43
+ )
44
+
11
45
  params = {
12
46
  c: "#{latitude}, #{longitude}",
13
47
  z: options[:zoom] || Decidim::Map::StaticMap::DEFAULT_ZOOM,
@@ -59,9 +59,11 @@ module Decidim
59
59
  event_class: Decidim::ResourceHiddenEvent,
60
60
  resource: @reportable,
61
61
  extra: {
62
- report_reasons:
62
+ report_reasons:,
63
+ force_email: true
63
64
  },
64
- affected_users: @reportable.try(:authors) || [@reportable.try(:normalized_author)]
65
+ affected_users:,
66
+ force_send: true
65
67
  }
66
68
 
67
69
  Decidim::EventsManager.publish(**data)
@@ -80,10 +82,22 @@ module Decidim
80
82
  @reportable.moderation.update!(hidden_at: Time.current)
81
83
  @reportable.try(:touch)
82
84
  end
85
+
86
+ if @reportable.is_a?(Decidim::Comments::Commentable)
87
+ @reportable.comment_threads.each do |comment|
88
+ Decidim::HideChildResourcesJob.perform_later(comment, @current_user.id)
89
+ end
90
+ end
91
+
92
+ send_notification_to_author
83
93
  end
84
94
 
85
95
  private
86
96
 
97
+ def affected_users
98
+ @affected_users ||= (@reportable.try(:authors) || [@reportable.try(:author)]).select { |author| author.is_a?(Decidim::User) }
99
+ end
100
+
87
101
  def report_reasons
88
102
  @reportable.moderation.reports.pluck(:reason).uniq
89
103
  end
@@ -27,19 +27,16 @@ module Decidim
27
27
  # * Disambiguates it so it is unique.
28
28
  #
29
29
  # name - the String to nicknamize
30
- # scope - a Hash with extra values to scope the nickname to
30
+ # organization_id - the organization id we are using as scope for the uniqueness
31
31
  #
32
32
  # Example to nicknamize a user name, scoped to the organization:
33
33
  #
34
- # nicknamize(user_name, organization: current_organization)
34
+ # nicknamize(user_name, organization_id)
35
35
  #
36
- def nicknamize(name, scope = {})
36
+ def nicknamize(name, organization_id)
37
37
  return unless name
38
38
 
39
- disambiguate(
40
- name.parameterize(separator: "_")[nickname_length_range],
41
- scope
42
- )
39
+ disambiguate(name.parameterize(separator: "_")[nickname_length_range], organization_id)
43
40
  end
44
41
 
45
42
  private
@@ -48,11 +45,11 @@ module Decidim
48
45
  (0...nickname_max_length)
49
46
  end
50
47
 
51
- def disambiguate(name, scope)
48
+ def disambiguate(name, organization_id)
52
49
  candidate = name
53
50
 
54
51
  2.step do |n|
55
- return candidate if Decidim::UserBaseEntity.where("nickname ILIKE ?", candidate.downcase).where(scope).empty?
52
+ return candidate if Decidim::UserBaseEntity.where(nickname: candidate.downcase).where(decidim_organization_id: organization_id).empty?
56
53
 
57
54
  candidate = numbered_variation_of(name, n)
58
55
  end