decidim-dev 0.27.9 → 0.28.0.rc4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (95) 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 -9
  19. data/config/locales/de.yml +1 -1
  20. data/config/locales/el.yml +0 -1
  21. data/config/locales/en.yml +1 -1
  22. data/config/locales/es-MX.yml +1 -1
  23. data/config/locales/es-PY.yml +1 -1
  24. data/config/locales/eu.yml +3 -3
  25. data/config/locales/gl.yml +0 -1
  26. data/config/locales/hu.yml +2 -3
  27. data/config/locales/id-ID.yml +0 -1
  28. data/config/locales/it.yml +0 -1
  29. data/config/locales/lv.yml +0 -1
  30. data/config/locales/nl.yml +0 -1
  31. data/config/locales/no.yml +0 -1
  32. data/config/locales/pl.yml +0 -9
  33. data/config/locales/pt-BR.yml +0 -9
  34. data/config/locales/pt.yml +0 -1
  35. data/config/locales/ru.yml +0 -1
  36. data/config/locales/sk.yml +0 -1
  37. data/config/locales/sv.yml +1 -2
  38. data/config/locales/tr-TR.yml +0 -1
  39. data/config/locales/zh-CN.yml +0 -1
  40. data/config/rubocop/disabled.yml +11 -0
  41. data/config/rubocop/faker.yml +480 -0
  42. data/config/rubocop/rails.yml +105 -0
  43. data/config/rubocop/rspec.yml +69 -0
  44. data/config/rubocop/ruby.yml +1207 -0
  45. data/lib/decidim/dev/assets/import_participatory_space_private_users.csv +2 -2
  46. data/lib/decidim/dev/assets/import_participatory_space_private_users_invalid_col_sep.csv +2 -0
  47. data/lib/decidim/dev/assets/import_participatory_space_private_users_nok.csv +2 -2
  48. data/lib/decidim/dev/assets/import_participatory_space_private_users_with_bom.csv +1 -1
  49. data/lib/decidim/dev/assets/iso-8859-15.md +1 -1
  50. data/lib/decidim/dev/assets/participatory_text.md +4 -2
  51. data/lib/decidim/dev/assets/verify_user_groups.csv +22 -22
  52. data/lib/decidim/dev/engine.rb +4 -3
  53. data/lib/decidim/dev/test/factories.rb +3 -5
  54. data/lib/decidim/dev/test/form_to_param_shared_examples.rb +1 -1
  55. data/lib/decidim/dev/test/promoted_participatory_processes_shared_examples.rb +9 -9
  56. data/lib/decidim/dev/test/rspec_support/accessibility_examples.rb +119 -1
  57. data/lib/decidim/dev/test/rspec_support/attachment_helpers.rb +2 -2
  58. data/lib/decidim/dev/test/rspec_support/bullet.rb +32 -0
  59. data/lib/decidim/dev/test/rspec_support/capybara.rb +26 -25
  60. data/lib/decidim/dev/test/rspec_support/cell_matchers.rb +1 -1
  61. data/lib/decidim/dev/test/rspec_support/component.rb +1 -311
  62. data/lib/decidim/dev/test/rspec_support/component_context.rb +10 -10
  63. data/lib/decidim/dev/test/rspec_support/confirmation_helpers.rb +18 -14
  64. data/lib/decidim/dev/test/rspec_support/data_consent.rb +2 -2
  65. data/lib/decidim/dev/test/rspec_support/dynamic_attach.rb +19 -4
  66. data/lib/decidim/dev/test/rspec_support/editor_context.rb +35 -0
  67. data/lib/decidim/dev/test/rspec_support/engine_examples.rb +15 -0
  68. data/lib/decidim/dev/test/rspec_support/filters.rb +11 -0
  69. data/lib/decidim/dev/test/rspec_support/forms_validations.rb +20 -0
  70. data/lib/decidim/dev/test/rspec_support/geocoder.rb +3 -3
  71. data/lib/decidim/dev/test/rspec_support/helpers.rb +187 -34
  72. data/lib/decidim/dev/test/rspec_support/imports_controller_shared_examples.rb +11 -11
  73. data/lib/decidim/dev/test/rspec_support/tom_select.rb +26 -0
  74. data/lib/decidim/dev/test/rspec_support/translation_helpers.rb +8 -8
  75. data/lib/decidim/dev/test/rspec_support/warden.rb +1 -1
  76. data/lib/decidim/dev/test/rspec_support/webmock.rb +1 -1
  77. data/lib/decidim/dev/test/rspec_support/webpacker.rb +4 -22
  78. data/lib/decidim/dev/test/spec_helper.rb +14 -3
  79. data/lib/decidim/dev/test/w3c_rspec_validators_overrides.rb +1 -5
  80. data/lib/decidim/dev/version.rb +1 -1
  81. data/lib/decidim/dev.rb +9 -0
  82. data/lib/decidim/dummy_resources/admin.rb +8 -0
  83. data/lib/decidim/dummy_resources/admin_engine.rb +43 -0
  84. data/lib/decidim/dummy_resources/component.rb +94 -0
  85. data/lib/decidim/dummy_resources/engine.rb +28 -0
  86. data/lib/decidim/dummy_resources.rb +20 -0
  87. data/lib/tasks/lighthouse_report.rake +29 -7
  88. data/rubocop-decidim.yml +13 -0
  89. metadata +117 -93
  90. data/config/locales/he-IL.yml +0 -1
  91. data/decidim-dev.gemspec +0 -58
  92. data/lib/decidim/dev/test/rspec_support/capybara_data_picker.rb +0 -36
  93. data/lib/decidim/dev/test/rspec_support/capybara_scopes_picker.rb +0 -92
  94. data/lib/decidim/dev/test/rspec_support/concurrency.rb +0 -23
  95. data/lib/decidim/dev/test/rspec_support/decidim_sanitization.rb +0 -5
@@ -1,55 +1,208 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  # Helpers that get automatically included in component specs.
4
- module Decidim::ComponentTestHelpers
5
- def click_submenu_link(text)
6
- within ".secondary-nav--subnav" do
7
- click_link text
4
+ module Decidim
5
+ module ComponentTestHelpers
6
+ def click_submenu_link(text)
7
+ within ".secondary-nav--subnav" do
8
+ click_link text
9
+ end
8
10
  end
9
- end
10
11
 
11
- def within_user_menu
12
- within ".topbar__user__logged" do
13
- find("a", text: user.name).click
14
- yield
12
+ def within_user_menu
13
+ main_bar_selector = ".main-bar"
14
+
15
+ within main_bar_selector do
16
+ find("#trigger-dropdown-account").click
17
+
18
+ yield
19
+ end
15
20
  end
16
- end
17
21
 
18
- def within_language_menu
19
- within ".topbar__dropmenu.language-choose" do
20
- find("ul.dropdown.menu").click
21
- yield
22
+ def within_admin_sidebar_menu
23
+ within("[id='admin-sidebar-menu-settings']") do
24
+ yield
25
+ end
22
26
  end
23
- end
24
27
 
25
- def stripped(text)
26
- text.gsub(/^<p>/, "").gsub(%r{</p>$}, "")
27
- end
28
+ def within_admin_menu
29
+ click_button "Manage"
30
+ within("[id*='dropdown-menu-settings']") do
31
+ yield
32
+ end
33
+ end
34
+
35
+ def within_language_menu(options = {})
36
+ within(options[:admin] ? ".topbar__dropmenu.language-choose" : "footer") do
37
+ find(options[:admin] ? "#admin-menu-trigger" : "#trigger-dropdown-language-chooser").click
38
+ yield
39
+ end
40
+ end
41
+
42
+ def stripped(text)
43
+ text.gsub(/^<p>/, "").gsub(%r{</p>$}, "")
44
+ end
28
45
 
29
- def within_flash_messages
30
- within ".flash" do
31
- yield
46
+ def within_flash_messages
47
+ within ".flash", match: :first do
48
+ yield
49
+ end
50
+ end
51
+
52
+ def expect_user_logged
53
+ expect(page).to have_css(".main-bar #trigger-dropdown-account")
54
+ end
55
+
56
+ def have_admin_callout(text)
57
+ within_flash_messages do
58
+ have_content text
59
+ end
60
+ end
61
+
62
+ def stub_get_request_with_format(rq_url, rs_format)
63
+ stub_request(:get, rq_url)
64
+ .with(
65
+ headers: {
66
+ "Accept" => "*/*",
67
+ "Accept-Encoding" => "gzip;q=1.0,deflate;q=0.6,identity;q=0.3",
68
+ "User-Agent" => "Ruby"
69
+ }
70
+ )
71
+ .to_return(status: 200, body: "", headers: { content_type: rs_format })
32
72
  end
33
73
  end
34
74
 
35
- def expect_user_logged
36
- expect(page).to have_css(".topbar__user__logged")
75
+ module FrontEndDataTestHelpers
76
+ def paste_content(content, target_selector)
77
+ page.execute_script(
78
+ <<~JS
79
+ var dt = new DataTransfer();
80
+ dt.setData("text/html", #{content.to_json});
81
+ dt.setData("text/plain", #{content.to_json});
82
+
83
+ var element = document.querySelector("#{target_selector}");
84
+ element.dispatchEvent(new ClipboardEvent("paste", { clipboardData: dt }));
85
+ JS
86
+ )
87
+ end
37
88
  end
38
89
 
39
- def have_admin_callout(text)
40
- have_selector(".callout--full", text: text)
90
+ module FrontEndPointerTestHelpers
91
+ def drag(selector, mode: "mouse", direction: nil, amount: 0)
92
+ move =
93
+ case direction
94
+ when "left"
95
+ "x -= #{amount}"
96
+ when "right"
97
+ "x += #{amount}"
98
+ when "top"
99
+ "y -= #{amount}"
100
+ when "bottom"
101
+ "y += #{amount}"
102
+ end
103
+
104
+ events =
105
+ if mode == "touch"
106
+ <<~JS
107
+ var evStart = new Event("touchstart");
108
+ evStart.touches = [{ pageX: rect.x, pageY: rect.y }];
109
+ var evMove = new Event("touchmove");
110
+ evMove.touches = [{ pageX: x, pageY: y }];
111
+
112
+ element.dispatchEvent(evStart);
113
+ document.dispatchEvent(evMove);
114
+ document.dispatchEvent(new Event("touchend"));
115
+ JS
116
+ else
117
+ <<~JS
118
+ element.dispatchEvent(new MouseEvent("mousedown", { clientX: rect.x, clientY: rect.y }));
119
+ document.dispatchEvent(new MouseEvent("mousemove", { clientX: x, clientY: y }));
120
+ document.dispatchEvent(new MouseEvent("mouseup"));
121
+ JS
122
+ end
123
+
124
+ page.execute_script(
125
+ <<~JS
126
+ var element = document.querySelector("#{selector}");
127
+ var rect = element.getBoundingClientRect();
128
+
129
+ var x = rect.x;
130
+ var y = rect.y;
131
+ #{move};
132
+
133
+ #{events}
134
+ JS
135
+ )
136
+ end
41
137
  end
42
138
 
43
- def stub_get_request_with_format(rq_url, rs_format)
44
- stub_request(:get, rq_url)
45
- .with(
46
- headers: {
47
- "Accept" => "*/*",
48
- "Accept-Encoding" => "gzip;q=1.0,deflate;q=0.6,identity;q=0.3",
49
- "User-Agent" => "Ruby"
50
- }
139
+ module FrontEndFileTestHelpers
140
+ def file_to_frontend(filename)
141
+ filepath = Decidim::Dev.asset(filename)
142
+ mime = MiniMime.lookup_by_filename(filepath).content_type
143
+ encoded = Base64.encode64(File.read(filepath))
144
+
145
+ {
146
+ filename:,
147
+ data_url: "data:application/octet-binary;base64,#{encoded.gsub("\n", "")}",
148
+ mime_type: mime
149
+ }
150
+ end
151
+
152
+ def add_file(filename, target_selector, event)
153
+ file = file_to_frontend(filename)
154
+
155
+ page.execute_script(
156
+ <<~JS
157
+ var dataUrl = "#{file[:data_url]}";
158
+ fetch(dataUrl).then(function(res) { return res.arrayBuffer(); }).then(function (buffer) {
159
+ var file = new File([buffer], "#{filename}", { type: "#{file[:mime_type]}" });
160
+ var dropzone = document.querySelector("#{target_selector}");
161
+
162
+ var dt = new DataTransfer();
163
+ dt.items.add(file);
164
+
165
+ if ("#{event}" === "drop") {
166
+ var ev = new Event("drop");
167
+ ev.dataTransfer = dt;
168
+ dropzone.dispatchEvent(ev);
169
+ } else {
170
+ // Simulates selecting the file through the browser's file selector
171
+ var input = dropzone.querySelector("input[type='file']");
172
+ input.files = dt.files;
173
+ input.dispatchEvent(new Event("change", { bubbles: true }));
174
+ }
175
+ });
176
+ JS
177
+ )
178
+
179
+ # Wait for the file to be uploaded
180
+ within "[data-dropzone-items]" do
181
+ expect(page).to have_content(filename)
182
+ end
183
+ end
184
+
185
+ def paste_file(filename, target_selector)
186
+ file = file_to_frontend(filename)
187
+
188
+ page.execute_script(
189
+ <<~JS
190
+ var dataUrl = "#{file[:data_url]}";
191
+ fetch(dataUrl).then(function(res) { return res.arrayBuffer(); }).then(function (buffer) {
192
+ var file = new File([buffer], "#{filename}", { type: "#{file[:mime_type]}" });
193
+
194
+ var dt = new DataTransfer();
195
+ dt.items.add(file);
196
+
197
+ var element = document.querySelector("#{target_selector}");
198
+ element.dispatchEvent(new ClipboardEvent("paste", { clipboardData: dt }));
199
+ });
200
+ JS
51
201
  )
52
- .to_return(status: 200, body: "", headers: { content_type: rs_format })
202
+
203
+ # Wait for the file to be uploaded
204
+ sleep 1
205
+ end
53
206
  end
54
207
  end
55
208
 
@@ -2,8 +2,8 @@
2
2
 
3
3
  shared_examples "admin imports controller" do
4
4
  let!(:organization) { create(:organization) }
5
- let!(:user) { create(:user, :admin, :confirmed, organization: organization) }
6
- let!(:component) { create(:component, participatory_space: participatory_space, manifest_name: "dummy") }
5
+ let!(:user) { create(:user, :admin, :confirmed, organization:) }
6
+ let!(:component) { create(:component, participatory_space:, manifest_name: "dummy") }
7
7
 
8
8
  let(:default_params) do
9
9
  {
@@ -23,11 +23,11 @@ shared_examples "admin imports controller" do
23
23
  # will always create a record for each data row regardless of the data.
24
24
  let(:file) { upload_test_file(Decidim::Dev.test_file("import_proposals.csv", "text/csv")) }
25
25
  let(:params) do
26
- default_params.merge(extra_params).merge(file: file)
26
+ default_params.merge(extra_params).merge(file:)
27
27
  end
28
28
 
29
29
  it "imports dummies" do
30
- post(:create, params: params)
30
+ post(:create, params:)
31
31
  expect(response).to have_http_status(:found)
32
32
  expect(flash[:notice]).not_to be_empty
33
33
 
@@ -42,14 +42,14 @@ shared_examples "admin imports controller" do
42
42
 
43
43
  describe "GET example" do
44
44
  let(:params) do
45
- default_params.merge(extra_params).merge(format: format)
45
+ default_params.merge(extra_params).merge(format:)
46
46
  end
47
47
 
48
48
  context "with CSV format" do
49
49
  let(:format) { "csv" }
50
50
 
51
51
  it "creates a correct CSV example file" do
52
- get(:example, params: params)
52
+ get(:example, params:)
53
53
 
54
54
  expect(response).to have_http_status(:ok)
55
55
  expect(response.content_type).to eq("text/csv")
@@ -66,7 +66,7 @@ shared_examples "admin imports controller" do
66
66
  let(:format) { "json" }
67
67
 
68
68
  it "creates a correct JSON example file" do
69
- get(:example, params: params)
69
+ get(:example, params:)
70
70
 
71
71
  expect(response).to have_http_status(:ok)
72
72
  expect(response.content_type).to eq("application/json")
@@ -83,7 +83,7 @@ shared_examples "admin imports controller" do
83
83
  let(:format) { "xlsx" }
84
84
 
85
85
  it "creates a correct XLSX example file" do
86
- get(:example, params: params)
86
+ get(:example, params:)
87
87
 
88
88
  expect(response).to have_http_status(:ok)
89
89
  expect(response.content_type).to eq(
@@ -109,7 +109,7 @@ shared_examples "admin imports controller" do
109
109
  let(:format) { "foo" }
110
110
 
111
111
  it "raises ActionController::UnknownFormat" do
112
- expect { get(:example, params: params) }.to raise_error(
112
+ expect { get(:example, params:) }.to raise_error(
113
113
  ActionController::UnknownFormat
114
114
  )
115
115
  end
@@ -124,7 +124,7 @@ shared_examples "admin imports controller" do
124
124
 
125
125
  describe "POST create" do
126
126
  it "raises ActionController::RoutingError" do
127
- expect { post(:create, params: params) }.to raise_error(
127
+ expect { post(:create, params:) }.to raise_error(
128
128
  ActionController::RoutingError
129
129
  )
130
130
  end
@@ -132,7 +132,7 @@ shared_examples "admin imports controller" do
132
132
 
133
133
  describe "GET example" do
134
134
  it "raises ActionController::RoutingError" do
135
- expect { get(:example, params: params) }.to raise_error(
135
+ expect { get(:example, params:) }.to raise_error(
136
136
  ActionController::RoutingError
137
137
  )
138
138
  end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ # https://github.com/orchidjs/tom-select/discussions/71#discussioncomment-641757
4
+ module Capybara
5
+ module TomSelect
6
+ # A helper for Capyabara tests that need to set values from a tom-select.js input.
7
+ #
8
+ # This is a really hacky approach using execute_javascript, but it works. Not sure if there is
9
+ # a better way, we could try actually interacting with the on-screen tom-select-provided UI,
10
+ # but we are taking the easy way out for now.
11
+ #
12
+ # @param option_id can be the `id` value of an option in the select, OR for select multiple inputs,
13
+ # can be an array of such IDs.
14
+ #
15
+ # @example tom_select("#select_id", option_id: "2")
16
+ # @example tom_select("#select_id", option_id: ["2", "10"]) # `multiple` input.
17
+ def tom_select(select_selector, option_id:)
18
+ js_str = %(document.querySelector("#{select_selector}").tomselect.setValue(#{option_id.inspect}))
19
+ execute_script(js_str)
20
+ end
21
+ end
22
+ end
23
+
24
+ RSpec.configure do |config|
25
+ config.include Capybara::TomSelect, type: :system
26
+ end
@@ -4,7 +4,7 @@
4
4
  module TranslationHelpers
5
5
  # Allows using the `t` shortcut inside specs just like in views
6
6
  def t(key, scope: nil)
7
- I18n.t(key, scope: scope, raise: true)
7
+ I18n.t(key, scope:, raise: true)
8
8
  end
9
9
 
10
10
  # Gives the localized version of the attribute for the given locale. The
@@ -25,16 +25,16 @@ module TranslationHelpers
25
25
  # field - the field that holds the translations
26
26
  # upcase - a boolean to indicate whether the string must be checked upcased or not.
27
27
  def have_i18n_content(field, upcase: false, strip_tags: false)
28
- have_content(i18n_content(field, upcase: upcase, strip_tags: strip_tags).strip)
28
+ have_content(i18n_content(field, upcase:, strip_tags:).strip)
29
29
  end
30
30
 
31
- # Checks that the current page doesn't have some translated content. It strips
31
+ # Checks that the current page does not have some translated content. It strips
32
32
  # the HTML tags from the field (in case there are any).
33
33
  #
34
34
  # field - the field that holds the translations
35
35
  # upcase - a boolean to indicate whether the string must be checked upcased or not.
36
36
  def have_no_i18n_content(field, upcase: false)
37
- have_no_content(i18n_content(field, upcase: upcase))
37
+ have_no_content(i18n_content(field, upcase:))
38
38
  end
39
39
 
40
40
  # Handles how to fill in i18n form fields.
@@ -90,8 +90,8 @@ module TranslationHelpers
90
90
  raise ArgumentError if params[:with].blank?
91
91
 
92
92
  page.execute_script <<-SCRIPT
93
- $('##{locator}').siblings('.editor-container').find('.ql-editor')[0].innerHTML = "#{params[:with]}";
94
- $('##{locator}').val("#{params[:with]}")
93
+ document.querySelector('##{locator} .editor-container .ProseMirror').innerHTML = `#{params[:with]}`;
94
+ document.querySelector('##{locator} input').value = `#{params[:with]}`;
95
95
  SCRIPT
96
96
  end
97
97
 
@@ -100,8 +100,8 @@ module TranslationHelpers
100
100
  # locator - The input field ID. The DOM element is selected using jQuery.
101
101
  def clear_editor(locator)
102
102
  page.execute_script <<-SCRIPT
103
- $('##{locator}').siblings('.editor-container').find('.ql-editor')[0].innerHTML = "<p><br></p>";
104
- $('##{locator}').val("")
103
+ document.querySelector('##{locator} .editor-container .ProseMirror').innerHTML = '<p><br class="ProseMirror-trailingBreak"></p>';
104
+ document.querySelector('##{locator} input').value = "";
105
105
  SCRIPT
106
106
  end
107
107
 
@@ -11,7 +11,7 @@ module Decidim
11
11
  def relogin_as(user, scope: :user)
12
12
  logout scope
13
13
 
14
- login_as user, scope: scope
14
+ login_as user, scope:
15
15
  end
16
16
  end
17
17
  end
@@ -2,4 +2,4 @@
2
2
 
3
3
  require "webmock/rspec"
4
4
 
5
- WebMock.disable_net_connect!(allow_localhost: true, allow: %r{https://validator\.w3\.org/})
5
+ WebMock.disable_net_connect!(allow_localhost: true, allow: %r{https://validator.w3.org/})
@@ -1,28 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  RSpec.configure do |config|
4
- config.before(:all) do
5
- raise "Rails.root directory does not exist" unless Rails.root.exist?
6
- raise "package.json file does not exist" unless Rails.root.join("package.json").exist?
7
- raise "Node modules directory does not exist" unless Rails.root.join("node_modules").exist?
8
-
4
+ config.before(:all, type: :system) do
5
+ Dir.chdir(Rails.root) { Webpacker.compile }
6
+ end
7
+ config.before(:all, type: :mailer) do
9
8
  Dir.chdir(Rails.root) { Webpacker.compile }
10
- rescue Errno::ENOENT
11
- node_modules_contents = `ls #{Rails.root.join("node_modules")}`
12
-
13
- message = <<~ERROR
14
- There was an error during the Webpacker compilation
15
- #{"=" * 80}
16
- Node version: #{`node -v`}
17
- #{"=" * 80}
18
- NPM version: #{`npm -v`}
19
- #{"=" * 80}
20
- Node modules packages: #{`npm list`}
21
- #{"=" * 80}
22
- Node modules contents: #{node_modules_contents}
23
- #{"=" * 80}
24
- ERROR
25
-
26
- raise message
27
9
  end
28
10
  end
@@ -5,9 +5,7 @@ require "rspec/rails"
5
5
  require "rspec/cells"
6
6
  require "byebug"
7
7
  require "wisper/rspec/stub_wisper_publisher"
8
- require "db-query-matchers"
9
8
  require "action_view/helpers/sanitize_helper"
10
- require "axe-rspec"
11
9
  require "w3c_rspec_validators"
12
10
  require "decidim/dev/test/w3c_rspec_validators_overrides"
13
11
 
@@ -25,12 +23,25 @@ RSpec.configure do |config|
25
23
  config.order = :random
26
24
  config.raise_errors_for_deprecations!
27
25
  config.example_status_persistence_file_path = ".rspec-failures"
26
+ config.filter_run_when_matching :focus
27
+ config.profile_examples = 10
28
+ config.default_formatter = "doc" if config.files_to_run.one?
28
29
 
29
- # If you're not using ActiveRecord, or you'd prefer not to run each of your
30
+ # If you are not using ActiveRecord, or you'd prefer not to run each of your
30
31
  # examples within a transaction, comment the following line or assign false
31
32
  # instead of true.
32
33
  config.use_transactional_fixtures = true
33
34
 
34
35
  config.include ActionView::Helpers::SanitizeHelper
35
36
  config.include ERB::Util
37
+
38
+ config.before :all, type: :system do
39
+ ActiveStorage.service_urls_expire_in = 24.hours
40
+ end
41
+
42
+ config.before :all do
43
+ Decidim.content_security_policies_extra = {
44
+ "img-src": %w(https://via.placeholder.com)
45
+ }
46
+ end
36
47
  end
@@ -3,11 +3,8 @@
3
3
  # This is a temporary fix to ignore some HTML/CSS validation issues with the
4
4
  # Decidim HTML validation process.
5
5
  #
6
- # See:
7
- # - https://github.com/decidim/decidim/issues/8596
8
- # - https://github.com/decidim/decidim/pull/10014
6
+ # See: https://github.com/decidim/decidim/pull/10014
9
7
  # Related:
10
- # - https://github.com/w3c/css-validator/issues/355
11
8
  # - https://github.com/rails/rails/issues/46405
12
9
  # - https://github.com/foundation/foundation-sites/pull/12496
13
10
  module W3CValidators
@@ -22,7 +19,6 @@ module W3CValidators
22
19
 
23
20
  def ignore_errors
24
21
  @ignore_errors ||= [
25
- "CSS: “--content-height”: One operand must be a number.",
26
22
  "An “input” element with a “type” attribute whose value is “hidden” must not have an “autocomplete” attribute whose value is “on” or “off”.",
27
23
  "An “input” element with a “type” attribute whose value is “hidden” must not have any “aria-*” attributes."
28
24
  ]
@@ -4,7 +4,7 @@ module Decidim
4
4
  # This holds the decidim-dev version.
5
5
  module Dev
6
6
  def self.version
7
- "0.27.9"
7
+ "0.28.0.rc4"
8
8
  end
9
9
  end
10
10
  end
data/lib/decidim/dev.rb CHANGED
@@ -2,6 +2,15 @@
2
2
 
3
3
  require "decidim/dev/railtie"
4
4
 
5
+ # The next 4 uncommented lines are used to register the Decidim::DummyResources namespace to the autoloader
6
+ # We cannot rely on Rails autoloading because some of the classes that are required within that namespace
7
+ # are needed before Rails is being available (e.g. FactoryBot)
8
+ # After 1 day of various attempts, this is the only way I found to make it work.
9
+ app_paths = %w(commands controllers events forms jobs mailers models presenters serializers)
10
+ app_paths.each do |path|
11
+ ActiveSupport::Dependencies.autoload_paths += [File.absolute_path("#{__dir__}/../../app/#{path}")]
12
+ end
13
+
5
14
  module Decidim
6
15
  # Decidim::Dev holds all the convenience logic and libraries to be able to
7
16
  # create external libraries that create test apps and test themselves against
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module DummyResources
5
+ module Admin
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module DummyResources
5
+ class AdminEngine < Rails::Engine
6
+ engine_name "dummy_admin"
7
+
8
+ routes do
9
+ resources :dummy_resources do
10
+ resources :nested_dummy_resources
11
+ end
12
+
13
+ root to: proc { [200, {}, ["DUMMY ADMIN ENGINE"]] }
14
+ end
15
+
16
+ initializer "dummy_admin.imports" do
17
+ class ::DummyCreator < Decidim::Admin::Import::Creator
18
+ def self.resource_klass
19
+ Decidim::DummyResources::DummyResource
20
+ end
21
+
22
+ def produce
23
+ resource
24
+ end
25
+
26
+ private
27
+
28
+ def resource
29
+ @resource ||= Decidim::DummyResources::DummyResource.new(
30
+ title: { en: "Dummy" },
31
+ author: context[:current_user],
32
+ component:
33
+ )
34
+ end
35
+
36
+ def component
37
+ context[:current_component]
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end