decidim-dev 0.27.10 → 0.28.0.rc4

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 (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.10"
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