decidim-dev 0.27.4 → 0.28.0.rc4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (97) hide show
  1. checksums.yaml +4 -4
  2. data/app/commands/decidim/dummy_resources/create_dummy_resource.rb +0 -1
  3. data/app/events/decidim/dummy_resources/dummy_resource_event.rb +10 -0
  4. data/app/jobs/decidim/dummy_resources/hide_all_created_by_author_job.rb +13 -0
  5. data/app/models/decidim/dummy_resources/application_record.rb +9 -0
  6. data/app/models/decidim/dummy_resources/coauthorable_dummy_resource.rb +10 -0
  7. data/app/models/decidim/dummy_resources/dummy_resource.rb +93 -0
  8. data/app/models/decidim/dummy_resources/nested_dummy_resource.rb +10 -0
  9. data/app/packs/src/decidim/dev/accessibility.js +3 -3
  10. data/app/packs/src/decidim/dev/test/custom_map_factory.js +1 -1
  11. data/app/packs/stylesheets/decidim/dev/_accessibility.scss +24 -24
  12. data/app/packs/stylesheets/decidim/dev/_map.scss +10 -0
  13. data/app/packs/stylesheets/decidim/dev.scss +1 -0
  14. data/app/presenters/decidim/dummy_resources/official_author_presenter.rb +33 -0
  15. data/app/serializers/decidim/dummy_resources/dummy_serializer.rb +21 -0
  16. data/app/views/decidim/dummy_resources/dummy_resources/show.html.erb +22 -12
  17. data/config/locales/ar.yml +0 -1
  18. data/config/locales/bg.yml +0 -1
  19. data/config/locales/cs.yml +4 -4
  20. data/config/locales/de.yml +2 -2
  21. data/config/locales/el.yml +0 -1
  22. data/config/locales/en.yml +1 -1
  23. data/config/locales/es-MX.yml +1 -1
  24. data/config/locales/es-PY.yml +1 -1
  25. data/config/locales/eu.yml +14 -8
  26. data/config/locales/gl.yml +0 -1
  27. data/config/locales/hu.yml +0 -1
  28. data/config/locales/id-ID.yml +0 -1
  29. data/config/locales/it.yml +0 -1
  30. data/config/locales/lv.yml +0 -1
  31. data/config/locales/nl.yml +0 -1
  32. data/config/locales/no.yml +0 -1
  33. data/config/locales/pl.yml +0 -1
  34. data/config/locales/pt-BR.yml +0 -1
  35. data/config/locales/pt.yml +0 -1
  36. data/config/locales/ru.yml +0 -1
  37. data/config/locales/sk.yml +0 -1
  38. data/config/locales/sq-AL.yml +1 -0
  39. data/config/locales/sv.yml +1 -1
  40. data/config/locales/th-TH.yml +1 -0
  41. data/config/locales/tr-TR.yml +0 -1
  42. data/config/locales/zh-CN.yml +0 -1
  43. data/config/rubocop/disabled.yml +11 -0
  44. data/config/rubocop/faker.yml +480 -0
  45. data/config/rubocop/rails.yml +105 -0
  46. data/config/rubocop/rspec.yml +69 -0
  47. data/config/rubocop/ruby.yml +1207 -0
  48. data/lib/decidim/dev/assets/import_participatory_space_private_users.csv +2 -2
  49. data/lib/decidim/dev/assets/import_participatory_space_private_users_invalid_col_sep.csv +2 -0
  50. data/lib/decidim/dev/assets/import_participatory_space_private_users_nok.csv +2 -2
  51. data/lib/decidim/dev/assets/import_participatory_space_private_users_with_bom.csv +1 -1
  52. data/lib/decidim/dev/assets/iso-8859-15.md +1 -1
  53. data/lib/decidim/dev/assets/participatory_text.md +4 -2
  54. data/lib/decidim/dev/assets/verify_user_groups.csv +22 -22
  55. data/lib/decidim/dev/engine.rb +4 -3
  56. data/lib/decidim/dev/test/factories.rb +2 -0
  57. data/lib/decidim/dev/test/form_to_param_shared_examples.rb +1 -1
  58. data/lib/decidim/dev/test/promoted_participatory_processes_shared_examples.rb +9 -9
  59. data/lib/decidim/dev/test/rspec_support/accessibility_examples.rb +119 -1
  60. data/lib/decidim/dev/test/rspec_support/attachment_helpers.rb +2 -2
  61. data/lib/decidim/dev/test/rspec_support/bullet.rb +32 -0
  62. data/lib/decidim/dev/test/rspec_support/capybara.rb +26 -21
  63. data/lib/decidim/dev/test/rspec_support/cell_matchers.rb +1 -1
  64. data/lib/decidim/dev/test/rspec_support/component.rb +1 -311
  65. data/lib/decidim/dev/test/rspec_support/component_context.rb +10 -10
  66. data/lib/decidim/dev/test/rspec_support/confirmation_helpers.rb +18 -14
  67. data/lib/decidim/dev/test/rspec_support/data_consent.rb +2 -2
  68. data/lib/decidim/dev/test/rspec_support/dynamic_attach.rb +19 -4
  69. data/lib/decidim/dev/test/rspec_support/editor_context.rb +35 -0
  70. data/lib/decidim/dev/test/rspec_support/engine_examples.rb +15 -0
  71. data/lib/decidim/dev/test/rspec_support/filters.rb +11 -0
  72. data/lib/decidim/dev/test/rspec_support/forms_validations.rb +20 -0
  73. data/lib/decidim/dev/test/rspec_support/geocoder.rb +7 -7
  74. data/lib/decidim/dev/test/rspec_support/helpers.rb +187 -34
  75. data/lib/decidim/dev/test/rspec_support/imports_controller_shared_examples.rb +11 -11
  76. data/lib/decidim/dev/test/rspec_support/tom_select.rb +26 -0
  77. data/lib/decidim/dev/test/rspec_support/translation_helpers.rb +8 -8
  78. data/lib/decidim/dev/test/rspec_support/warden.rb +1 -1
  79. data/lib/decidim/dev/test/rspec_support/webpacker.rb +10 -0
  80. data/lib/decidim/dev/test/spec_helper.rb +14 -3
  81. data/lib/decidim/dev/test/w3c_rspec_validators_overrides.rb +1 -5
  82. data/lib/decidim/dev/version.rb +1 -1
  83. data/lib/decidim/dev.rb +9 -0
  84. data/lib/decidim/dummy_resources/admin.rb +8 -0
  85. data/lib/decidim/dummy_resources/admin_engine.rb +43 -0
  86. data/lib/decidim/dummy_resources/component.rb +94 -0
  87. data/lib/decidim/dummy_resources/engine.rb +28 -0
  88. data/lib/decidim/dummy_resources.rb +20 -0
  89. data/lib/tasks/lighthouse_report.rake +29 -7
  90. data/rubocop-decidim.yml +13 -0
  91. metadata +121 -66
  92. data/config/environment.rb +0 -0
  93. data/lib/decidim/dev/test/rspec_support/capybara_data_picker.rb +0 -36
  94. data/lib/decidim/dev/test/rspec_support/capybara_scopes_picker.rb +0 -92
  95. data/lib/decidim/dev/test/rspec_support/summary_notification.rb +0 -51
  96. data/lib/rubocop/cop/decidim/hash_shorthand_syntax_backports.rb +0 -175
  97. data/lib/rubocop/cop/decidim.rb +0 -9
@@ -1,36 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Capybara
4
- module DataPicker
5
- def select_data_picker(id, multiple: nil, global_value: "")
6
- Struct.new(:data_picker, :global_value).new(find_data_picker(id, multiple: multiple), global_value)
7
- end
8
-
9
- def find_data_picker(id, multiple: nil)
10
- if multiple.nil?
11
- expect(page).to have_selector("div.data-picker[id$='#{id}']")
12
- else
13
- expect(page).to have_selector("div.data-picker.picker-#{multiple ? "multiple" : "single"}[id$='#{id}']")
14
- end
15
- first("div.data-picker[id$='#{id}']")
16
- end
17
-
18
- def data_picker_pick_current
19
- body = find(:xpath, "//body")
20
- expect(body).to have_selector("#data_picker-modal .picker-footer a[data-picker-choose]", wait: 2)
21
- body.find("#data_picker-modal .picker-footer a[data-picker-choose]").click
22
- end
23
-
24
- def data_picker_choose_value(value)
25
- body = find(:xpath, "//body")
26
- expect(body).to have_selector("#data_picker-modal input[data-picker-choose][type=checkbox][value=\"#{value}\"]")
27
- body.find("#data_picker-modal input[data-picker-choose][type=checkbox][value=\"#{value}\"]").click
28
- end
29
-
30
- def data_picker_close
31
- body = find(:xpath, "//body")
32
- expect(body).to have_selector("#data_picker-modal .picker-footer a[data-close]")
33
- body.find("#data_picker-modal .picker-footer a[data-close]").click
34
- end
35
- end
36
- end
@@ -1,92 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative "capybara_data_picker"
4
-
5
- module Capybara
6
- module ScopesPicker
7
- include DataPicker
8
-
9
- RSpec::Matchers.define :have_scope_picked do |expected|
10
- match do |scope_picker|
11
- data_picker = scope_picker.data_picker
12
- scope_name = expected ? translated(expected.name) : t("decidim.scopes.global")
13
-
14
- expect(data_picker).to have_selector(".picker-values div input[value='#{expected&.id || scope_picker.global_value}']", visible: :all)
15
- expect(data_picker).to have_selector(:xpath, "//div[contains(@class,'picker-values')]/div/a[text()[contains(.,'#{scope_name}')]]")
16
- end
17
- end
18
-
19
- RSpec::Matchers.define :have_scope_not_picked do |expected|
20
- match do |scope_picker|
21
- data_picker = scope_picker.data_picker
22
- scope_name = expected ? translated(expected.name) : t("decidim.scopes.global")
23
- expect(data_picker).not_to have_selector(".picker-values div input[value='#{expected&.id || scope_picker.global_value}']", visible: :all)
24
- expect(data_picker).not_to have_selector(:xpath, "//div[contains(@class,'picker-values')]/div/a[text()[contains(.,'#{scope_name}')]]")
25
- end
26
- end
27
-
28
- def scope_pick(scope_picker, scope)
29
- data_picker = scope_picker.data_picker
30
- # use scope_repick to change single scope picker selected scope
31
- expect(data_picker).to have_selector(".picker-values:empty", visible: :all) if data_picker.has_css?(".picker-single")
32
-
33
- expect(data_picker).to have_selector(".picker-prompt")
34
- data_picker.find(".picker-prompt").click
35
-
36
- scope_picker_browse_scopes(scope.part_of_scopes) if scope
37
- data_picker_pick_current
38
-
39
- expect(scope_picker).to have_scope_picked(scope)
40
- end
41
-
42
- def scope_repick(element_id, old_scope, new_scope)
43
- scope_picker = select_data_picker(element_id)
44
-
45
- data_picker = scope_picker.data_picker
46
-
47
- expect(data_picker).to have_selector(".picker-values div input[value='#{old_scope&.id || scope_picker.global_value}']", visible: :all)
48
- data_picker.find(:xpath, "//div[contains(@class,'picker-values')]/div/input[@value='#{old_scope&.id || scope_picker.global_value}']/../a").click
49
-
50
- # browse to lowest common parent between old and new scope
51
- parent_scope = (old_scope.part_of_scopes & new_scope.part_of_scopes).last
52
-
53
- scope_picker_browse_scope(parent_scope, back: true)
54
- scope_picker_browse_scopes(new_scope.part_of_scopes - old_scope.part_of_scopes)
55
- data_picker_pick_current
56
-
57
- scope_picker = select_data_picker(element_id)
58
-
59
- expect(scope_picker).to have_scope_picked(new_scope)
60
- end
61
-
62
- def scope_unpick(scope_picker, scope)
63
- data_picker = scope_picker.data_picker
64
-
65
- expect(data_picker).to have_selector(".picker-values div input[value='#{scope&.id || scope_picker.global_value}']", visible: :all)
66
- data_picker.find(".picker-values div input[value='#{scope&.id || scope_picker.global_value}']").click
67
-
68
- expect(scope_picker).to have_scope_not_picked(scope)
69
- end
70
-
71
- private
72
-
73
- def scope_picker_browse_scopes(scopes)
74
- scopes.each do |scope|
75
- scope_picker_browse_scope(scope)
76
- sleep(2)
77
- end
78
- end
79
-
80
- def scope_picker_browse_scope(scope, back: false)
81
- body = find(:xpath, "//body")
82
- where = back ? "header" : "content"
83
- scope_name = scope ? translated(scope.name) : t("decidim.scopes.global")
84
- expect(body).to have_selector("#data_picker-modal .picker-#{where} a", text: scope_name)
85
- body.find("#data_picker-modal .picker-#{where} a", text: scope_name).click
86
- end
87
- end
88
- end
89
-
90
- RSpec.configure do |config|
91
- config.include Capybara::ScopesPicker, type: :system
92
- end
@@ -1,51 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module RSpec::Core
4
- module Notifications
5
- class SummaryNotification
6
- # Override the original method to add the full path to the spec file and the correct rspec command to rerun the failed spec
7
- # The goal is to be able to copy-paste the command to rerun the failed spec without having to manually add the full path to the spec file
8
- #
9
- # So, instead of:
10
- # > rspec ./spec/system/registration_spec.rb:27
11
- #
12
- # We get:
13
- # > bin/rspec ./decidim-core/spec/system/registration_spec.rb:27
14
- #
15
- # Original code in rspec-core: https://github.com/rspec/rspec-core/blob/8caecca0b9b299ccbaa5c7ea5dd885ab42cd57d3/lib/rspec/core/notifications.rb#L365
16
- def colorized_rerun_commands(colorizer=::RSpec::Core::Formatters::ConsoleCodes)
17
- rspec_command = running_with_rspec_wrapper? ? "bin/rspec" : "rspec"
18
- "\nFailed examples:\n\n" +
19
- failed_examples.map do |example|
20
- colorizer.wrap("#{rspec_command} #{rerun_argument_for(example)}", RSpec.configuration.failure_color) + " " +
21
- colorizer.wrap("# #{example.full_description}", RSpec.configuration.detail_color)
22
- end.join("\n")
23
- end
24
-
25
- private
26
-
27
- def running_with_rspec_wrapper?
28
- $0 == "bin/rspec"
29
- end
30
-
31
- def rerun_argument_for(example)
32
- if running_with_rspec_wrapper?
33
- location = location_rerun_argument_for_decidim(example)
34
- else
35
- location = example.location_rerun_argument
36
- end
37
- return location unless duplicate_rerun_locations.include?(location)
38
-
39
- conditionally_quote(example.id)
40
- end
41
-
42
- def location_rerun_argument_for_decidim(example)
43
- absolute_file_path = example.metadata[:absolute_file_path]
44
- file_path = example.metadata[:file_path][1..-1]
45
- module_dir = absolute_file_path.gsub(file_path, "").split("/")[-1]
46
-
47
- "./#{module_dir}#{file_path}:#{example.metadata[:line_number]}"
48
- end
49
- end
50
- end
51
- end
@@ -1,175 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- #
4
- # Originally copied from https://github.com/koic/rubocop/blob/master/lib/rubocop/cop/mixin/hash_shorthand_syntax.rb
5
- # Copyright (c) 2012-22 Bozhidar Batsov
6
- # MIT License
7
- #
8
-
9
- module RuboCop
10
- module Cop
11
- # This module checks for Ruby 3.1's hash value omission syntax.
12
- #
13
- # For using this on Decidim, we have added the Decidim namespace and also the Backports prefix
14
- # to the module name
15
- module Decidim
16
- module HashShorthandSyntaxBackports
17
- OMIT_HASH_VALUE_MSG = "Omit the hash value."
18
- EXPLICIT_HASH_VALUE_MSG = "Include the hash value."
19
- DO_NOT_MIX_MSG_PREFIX = "Do not mix explicit and implicit hash values."
20
- DO_NOT_MIX_OMIT_VALUE_MSG = "#{DO_NOT_MIX_MSG_PREFIX} #{OMIT_HASH_VALUE_MSG}".freeze
21
- DO_NOT_MIX_EXPLICIT_VALUE_MSG = "#{DO_NOT_MIX_MSG_PREFIX} #{EXPLICIT_HASH_VALUE_MSG}".freeze
22
-
23
- def on_hash_for_mixed_shorthand(hash_node)
24
- return if ignore_mixed_hash_shorthand_syntax?(hash_node)
25
-
26
- hash_value_type_breakdown = breakdown_value_types_of_hash(hash_node)
27
-
28
- if hash_with_mixed_shorthand_syntax?(hash_value_type_breakdown)
29
- mixed_shorthand_syntax_check(hash_value_type_breakdown)
30
- else
31
- no_mixed_shorthand_syntax_check(hash_value_type_breakdown)
32
- end
33
- end
34
-
35
- def on_pair(node)
36
- return if ignore_hash_shorthand_syntax?(node)
37
-
38
- hash_key_source = node.key.source
39
-
40
- if enforced_shorthand_syntax == "always"
41
- return if node.value_omission? || require_hash_value?(hash_key_source, node)
42
-
43
- message = OMIT_HASH_VALUE_MSG
44
- replacement = "#{hash_key_source}:"
45
- self.config_to_allow_offenses = { "Enabled" => false }
46
- else
47
- return unless node.value_omission?
48
-
49
- message = EXPLICIT_HASH_VALUE_MSG
50
- replacement = "#{hash_key_source}: #{hash_key_source}"
51
- end
52
-
53
- register_offense(node, message, replacement)
54
- end
55
-
56
- private
57
-
58
- def register_offense(node, message, replacement)
59
- add_offense(node.value, message:) do |corrector|
60
- corrector.replace(node, replacement)
61
- end
62
- end
63
-
64
- def ignore_mixed_hash_shorthand_syntax?(hash_node)
65
- target_ruby_version <= 3.0 || enforced_shorthand_syntax != "consistent" ||
66
- !hash_node.hash_type?
67
- end
68
-
69
- def ignore_hash_shorthand_syntax?(pair_node)
70
- target_ruby_version <= 3.0 || enforced_shorthand_syntax == "either" ||
71
- enforced_shorthand_syntax == "consistent" ||
72
- !pair_node.parent.hash_type?
73
- end
74
-
75
- def enforced_shorthand_syntax
76
- cop_config.fetch("EnforcedShorthandSyntax", "always")
77
- end
78
-
79
- def require_hash_value?(hash_key_source, node)
80
- return true if !node.key.sym_type? || require_hash_value_for_around_hash_literal?(node)
81
-
82
- hash_value = node.value
83
- return true unless hash_value.send_type? || hash_value.lvar_type?
84
-
85
- hash_key_source != hash_value.source || hash_key_source.end_with?("!", "?")
86
- end
87
-
88
- def require_hash_value_for_around_hash_literal?(node)
89
- return false unless (ancestor = node.parent.parent)
90
- return false if ancestor.send_type? && ancestor.method?(:[])
91
-
92
- !node.parent.braces? && !use_element_of_hash_literal_as_receiver?(ancestor, node.parent) &&
93
- (use_modifier_form_without_parenthesized_method_call?(ancestor) ||
94
- without_parentheses_call_expr_follows?(ancestor))
95
- end
96
-
97
- def use_element_of_hash_literal_as_receiver?(ancestor, parent)
98
- # `{value:}.do_something` is a valid syntax.
99
- ancestor.send_type? && ancestor.receiver == parent
100
- end
101
-
102
- def use_modifier_form_without_parenthesized_method_call?(ancestor)
103
- return false if ancestor.respond_to?(:parenthesized?) && ancestor.parenthesized?
104
-
105
- ancestor.ancestors.any? { |node| node.respond_to?(:modifier_form?) && node.modifier_form? }
106
- end
107
-
108
- def without_parentheses_call_expr_follows?(ancestor)
109
- return false unless ancestor.respond_to?(:parenthesized?) && !ancestor.parenthesized?
110
-
111
- right_sibling = ancestor.right_sibling
112
- right_sibling ||= ancestor.each_ancestor.find do |node|
113
- node.assignment? || node.send_type?
114
- end&.right_sibling
115
-
116
- !!right_sibling
117
- end
118
-
119
- def breakdown_value_types_of_hash(hash_node)
120
- hash_node.pairs.group_by do |pair_node|
121
- if pair_node.value_omission?
122
- :value_omitted
123
- elsif require_hash_value?(pair_node.key.source, pair_node)
124
- :value_needed
125
- else
126
- :value_omittable
127
- end
128
- end
129
- end
130
-
131
- def hash_with_mixed_shorthand_syntax?(hash_value_type_breakdown)
132
- hash_value_type_breakdown.keys.size > 1
133
- end
134
-
135
- def hash_with_values_that_cant_be_omitted?(hash_value_type_breakdown)
136
- hash_value_type_breakdown[:value_needed]&.any?
137
- end
138
-
139
- def each_omitted_value_pair(hash_value_type_breakdown, &)
140
- hash_value_type_breakdown[:value_omitted]&.each(&)
141
- end
142
-
143
- def each_omittable_value_pair(hash_value_type_breakdown, &)
144
- hash_value_type_breakdown[:value_omittable]&.each(&)
145
- end
146
-
147
- def mixed_shorthand_syntax_check(hash_value_type_breakdown)
148
- if hash_with_values_that_cant_be_omitted?(hash_value_type_breakdown)
149
- each_omitted_value_pair(hash_value_type_breakdown) do |pair_node|
150
- hash_key_source = pair_node.key.source
151
- replacement = "#{hash_key_source}: #{hash_key_source}"
152
- register_offense(pair_node, DO_NOT_MIX_EXPLICIT_VALUE_MSG, replacement)
153
- end
154
- else
155
- each_omittable_value_pair(hash_value_type_breakdown) do |pair_node|
156
- hash_key_source = pair_node.key.source
157
- replacement = "#{hash_key_source}:"
158
- register_offense(pair_node, DO_NOT_MIX_OMIT_VALUE_MSG, replacement)
159
- end
160
- end
161
- end
162
-
163
- def no_mixed_shorthand_syntax_check(hash_value_type_breakdown)
164
- return if hash_with_values_that_cant_be_omitted?(hash_value_type_breakdown)
165
-
166
- each_omittable_value_pair(hash_value_type_breakdown) do |pair_node|
167
- hash_key_source = pair_node.key.source
168
- replacement = "#{hash_key_source}:"
169
- register_offense(pair_node, OMIT_HASH_VALUE_MSG, replacement)
170
- end
171
- end
172
- end
173
- end
174
- end
175
- end
@@ -1,9 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Rubocop
4
- module Cop
5
- class Decidim < Base
6
- include HashShortandSyntaxBacports
7
- end
8
- end
9
- end