decidim-dev 0.21.0 → 0.23.2
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.
- checksums.yaml +4 -4
- data/app/assets/images/decidim/dummy.svg +1 -4
- data/app/assets/images/decidim/gamification/badges/test.svg +1 -145
- data/app/commands/decidim/dummy_resources/create_dummy_resource.rb +48 -0
- data/app/controllers/decidim/dummy_resources/dummy_resources_controller.rb +1 -0
- data/app/forms/decidim/dummy_resources/dummy_resource_form.rb +3 -0
- data/app/mailers/decidim/dummy_resources/dummy_resource_mailer.rb +17 -0
- data/app/views/decidim/dummy_resources/dummy_resources/show.html.erb +4 -0
- data/config/locales/am-ET.yml +1 -0
- data/config/locales/bg-BG.yml +56 -0
- data/config/locales/bg.yml +56 -0
- data/config/locales/ca.yml +15 -0
- data/config/locales/cs.yml +16 -1
- data/config/locales/da-DK.yml +1 -0
- data/config/locales/da.yml +1 -0
- data/config/locales/de.yml +17 -1
- data/config/locales/el.yml +55 -0
- data/config/locales/en.yml +15 -0
- data/config/locales/eo.yml +1 -0
- data/config/locales/es-MX.yml +15 -0
- data/config/locales/es-PY.yml +15 -0
- data/config/locales/es.yml +15 -0
- data/config/locales/et-EE.yml +1 -0
- data/config/locales/et.yml +1 -0
- data/config/locales/fi-plain.yml +15 -0
- data/config/locales/fi.yml +15 -0
- data/config/locales/fr-CA.yml +56 -0
- data/config/locales/fr.yml +15 -0
- data/config/locales/ga-IE.yml +1 -0
- data/config/locales/hr-HR.yml +1 -0
- data/config/locales/hr.yml +1 -0
- data/config/locales/hu.yml +9 -0
- data/config/locales/is.yml +21 -0
- data/config/locales/it.yml +17 -2
- data/config/locales/ja-JP.yml +56 -0
- data/config/locales/ja.yml +56 -0
- data/config/locales/ko-KR.yml +1 -0
- data/config/locales/ko.yml +1 -0
- data/config/locales/lt-LT.yml +1 -0
- data/config/locales/lt.yml +1 -0
- data/config/locales/lv.yml +54 -0
- data/config/locales/mt-MT.yml +1 -0
- data/config/locales/mt.yml +1 -0
- data/config/locales/nl.yml +15 -0
- data/config/locales/om-ET.yml +1 -0
- data/config/locales/pl.yml +26 -10
- data/config/locales/pt-BR.yml +1 -1
- data/config/locales/pt.yml +26 -10
- data/config/locales/ro-RO.yml +56 -0
- data/config/locales/si-LK.yml +1 -0
- data/config/locales/sk-SK.yml +47 -0
- data/config/locales/sk.yml +47 -0
- data/config/locales/sl.yml +5 -0
- data/config/locales/so-SO.yml +1 -0
- data/config/locales/sr-CS.yml +8 -0
- data/config/locales/sv.yml +15 -0
- data/config/locales/sw-KE.yml +1 -0
- data/config/locales/ti-ER.yml +1 -0
- data/config/locales/tr-TR.yml +25 -9
- data/config/locales/vi-VN.yml +1 -0
- data/config/locales/vi.yml +1 -0
- data/config/locales/zh-CN.yml +56 -0
- data/config/locales/zh-TW.yml +1 -0
- data/lib/decidim/dev.rb +2 -0
- data/lib/decidim/dev/assets/5000x5000.png +0 -0
- data/lib/decidim/dev/assets/assemblies.json +816 -0
- data/lib/decidim/dev/assets/assemblies_with_null.json +135 -0
- data/lib/decidim/dev/assets/city.jpeg +0 -0
- data/lib/decidim/dev/assets/city2.jpeg +0 -0
- data/lib/decidim/dev/assets/city3.jpeg +0 -0
- data/lib/decidim/dev/assets/geocoder_result_here.json +72 -0
- data/lib/decidim/dev/assets/geocoder_result_osm.json +150 -0
- data/lib/decidim/dev/assets/import_participatory_space_private_users_nok.csv +2 -0
- data/lib/decidim/dev/dummy_translator.rb +32 -0
- data/lib/decidim/dev/test/rspec_support/authorization.rb +3 -0
- data/lib/decidim/dev/test/rspec_support/capybara.rb +5 -1
- data/lib/decidim/dev/test/rspec_support/capybara_data_picker.rb +15 -5
- data/lib/decidim/dev/test/rspec_support/capybara_scopes_picker.rb +5 -5
- data/lib/decidim/dev/test/rspec_support/component.rb +111 -9
- data/lib/decidim/dev/test/rspec_support/component_context.rb +1 -2
- data/lib/decidim/dev/test/rspec_support/confirmation_helpers.rb +60 -0
- data/lib/decidim/dev/test/rspec_support/content_processing.rb +2 -2
- data/lib/decidim/dev/test/rspec_support/frontend.rb +20 -0
- data/lib/decidim/dev/test/rspec_support/geocoder.rb +150 -6
- data/lib/decidim/dev/test/rspec_support/helpers.rb +2 -2
- data/lib/decidim/dev/test/rspec_support/organization.rb +7 -0
- data/lib/decidim/dev/test/rspec_support/rake_tasks.rb +75 -0
- data/lib/decidim/dev/test/rspec_support/translation_helpers.rb +2 -0
- data/lib/decidim/dev/version.rb +1 -1
- data/lib/tasks/generators.rake +2 -1
- data/lib/tasks/locale_checker.rake +1 -1
- metadata +62 -14
- data/lib/decidim/dev/test/rspec_support/capybara_proposals_picker.rb +0 -51
|
@@ -10,7 +10,7 @@ module Capybara
|
|
|
10
10
|
match do |scope_picker|
|
|
11
11
|
data_picker = scope_picker.data_picker
|
|
12
12
|
scope_name = expected ? translated(expected.name) : t("decidim.scopes.global")
|
|
13
|
-
expect(data_picker).to have_selector(".picker-values div input[value='#{expected&.id || scope_picker.global_value}']", visible:
|
|
13
|
+
expect(data_picker).to have_selector(".picker-values div input[value='#{expected&.id || scope_picker.global_value}']", visible: :all)
|
|
14
14
|
expect(data_picker).to have_selector(:xpath, "//div[contains(@class,'picker-values')]/div/a[text()[contains(.,'#{scope_name}')]]")
|
|
15
15
|
end
|
|
16
16
|
end
|
|
@@ -19,7 +19,7 @@ module Capybara
|
|
|
19
19
|
match do |scope_picker|
|
|
20
20
|
data_picker = scope_picker.data_picker
|
|
21
21
|
scope_name = expected ? translated(expected.name) : t("decidim.scopes.global")
|
|
22
|
-
expect(data_picker).not_to have_selector(".picker-values div input[value='#{expected&.id || scope_picker.global_value}']", visible:
|
|
22
|
+
expect(data_picker).not_to have_selector(".picker-values div input[value='#{expected&.id || scope_picker.global_value}']", visible: :all)
|
|
23
23
|
expect(data_picker).not_to have_selector(:xpath, "//div[contains(@class,'picker-values')]/div/a[text()[contains(.,'#{scope_name}')]]")
|
|
24
24
|
end
|
|
25
25
|
end
|
|
@@ -27,7 +27,7 @@ module Capybara
|
|
|
27
27
|
def scope_pick(scope_picker, scope)
|
|
28
28
|
data_picker = scope_picker.data_picker
|
|
29
29
|
# use scope_repick to change single scope picker selected scope
|
|
30
|
-
expect(data_picker).to have_selector(".picker-values:empty", visible:
|
|
30
|
+
expect(data_picker).to have_selector(".picker-values:empty", visible: :all) if data_picker.has_css?(".picker-single")
|
|
31
31
|
|
|
32
32
|
expect(data_picker).to have_selector(".picker-prompt")
|
|
33
33
|
data_picker.find(".picker-prompt").click
|
|
@@ -41,7 +41,7 @@ module Capybara
|
|
|
41
41
|
def scope_repick(scope_picker, old_scope, new_scope)
|
|
42
42
|
data_picker = scope_picker.data_picker
|
|
43
43
|
|
|
44
|
-
expect(data_picker).to have_selector(".picker-values div input[value='#{old_scope&.id || scope_picker.global_value}']", visible:
|
|
44
|
+
expect(data_picker).to have_selector(".picker-values div input[value='#{old_scope&.id || scope_picker.global_value}']", visible: :all)
|
|
45
45
|
data_picker.find(:xpath, "//div[contains(@class,'picker-values')]/div/input[@value='#{old_scope&.id || scope_picker.global_value}']/../a").click
|
|
46
46
|
|
|
47
47
|
# browse to lowest common parent between old and new scope
|
|
@@ -57,7 +57,7 @@ module Capybara
|
|
|
57
57
|
def scope_unpick(scope_picker, scope)
|
|
58
58
|
data_picker = scope_picker.data_picker
|
|
59
59
|
|
|
60
|
-
expect(data_picker).to have_selector(".picker-values div input[value='#{scope&.id || scope_picker.global_value}']", visible:
|
|
60
|
+
expect(data_picker).to have_selector(".picker-values div input[value='#{scope&.id || scope_picker.global_value}']", visible: :all)
|
|
61
61
|
data_picker.find(".picker-values div input[value='#{scope&.id || scope_picker.global_value}']").click
|
|
62
62
|
|
|
63
63
|
expect(scope_picker).to have_scope_not_picked(scope)
|
|
@@ -29,6 +29,7 @@ module Decidim
|
|
|
29
29
|
root to: proc { [200, {}, ["DUMMY ENGINE"]] }
|
|
30
30
|
|
|
31
31
|
resources :dummy_resources do
|
|
32
|
+
resources :nested_dummy_resources
|
|
32
33
|
get :foo, on: :member
|
|
33
34
|
end
|
|
34
35
|
end
|
|
@@ -38,6 +39,10 @@ module Decidim
|
|
|
38
39
|
engine_name "dummy_admin"
|
|
39
40
|
|
|
40
41
|
routes do
|
|
42
|
+
resources :dummy_resources do
|
|
43
|
+
resources :nested_dummy_resources
|
|
44
|
+
end
|
|
45
|
+
|
|
41
46
|
root to: proc { [200, {}, ["DUMMY ADMIN ENGINE"]] }
|
|
42
47
|
end
|
|
43
48
|
end
|
|
@@ -53,7 +58,7 @@ module Decidim
|
|
|
53
58
|
include Reportable
|
|
54
59
|
include Authorable
|
|
55
60
|
include HasCategory
|
|
56
|
-
include
|
|
61
|
+
include ScopableResource
|
|
57
62
|
include Decidim::Comments::Commentable
|
|
58
63
|
include Followable
|
|
59
64
|
include Traceable
|
|
@@ -63,8 +68,12 @@ module Decidim
|
|
|
63
68
|
include Paddable
|
|
64
69
|
include Amendable
|
|
65
70
|
include Decidim::NewsletterParticipant
|
|
66
|
-
include
|
|
71
|
+
include ::Decidim::Endorsable
|
|
72
|
+
include Decidim::HasAttachments
|
|
73
|
+
include Decidim::ShareableWithToken
|
|
74
|
+
include Decidim::TranslatableResource
|
|
67
75
|
|
|
76
|
+
translatable_fields :title
|
|
68
77
|
searchable_fields(
|
|
69
78
|
scope_id: { scope: :id },
|
|
70
79
|
participatory_space: { component: :participatory_space },
|
|
@@ -97,10 +106,51 @@ module Decidim
|
|
|
97
106
|
end
|
|
98
107
|
|
|
99
108
|
def self.newsletter_participant_ids(component)
|
|
100
|
-
Decidim::DummyResources::DummyResource.where(component: component)
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
109
|
+
authors_ids = Decidim::DummyResources::DummyResource.where(component: component)
|
|
110
|
+
.where(decidim_author_type: Decidim::UserBaseEntity.name)
|
|
111
|
+
.where.not(author: nil)
|
|
112
|
+
.group(:decidim_author_id)
|
|
113
|
+
.pluck(:decidim_author_id)
|
|
114
|
+
commentators_ids = Decidim::Comments::Comment.user_commentators_ids_in(Decidim::DummyResources::DummyResource.where(component: component))
|
|
115
|
+
(authors_ids + commentators_ids).flatten.compact.uniq
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
class NestedDummyResource < ApplicationRecord
|
|
120
|
+
include Decidim::Resourceable
|
|
121
|
+
belongs_to :dummy_resource
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
class CoauthorableDummyResource < ApplicationRecord
|
|
125
|
+
include ::Decidim::Coauthorable
|
|
126
|
+
include HasComponent
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
class OfficialAuthorPresenter
|
|
130
|
+
def name
|
|
131
|
+
self.class.name
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
def nickname
|
|
135
|
+
UserBaseEntity.nicknamize(name)
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
def deleted?
|
|
139
|
+
false
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
def respond_to_missing?
|
|
143
|
+
true
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
def method_missing(method, *args)
|
|
147
|
+
if method.to_s.ends_with?("?")
|
|
148
|
+
false
|
|
149
|
+
elsif [:avatar_url, :profile_path, :badge, :followers_count].include?(method)
|
|
150
|
+
""
|
|
151
|
+
else
|
|
152
|
+
super
|
|
153
|
+
end
|
|
104
154
|
end
|
|
105
155
|
end
|
|
106
156
|
end
|
|
@@ -128,10 +178,14 @@ Decidim.register_component(:dummy) do |component|
|
|
|
128
178
|
component.newsletter_participant_entities = ["Decidim::DummyResources::DummyResource"]
|
|
129
179
|
|
|
130
180
|
component.settings(:global) do |settings|
|
|
181
|
+
settings.attribute :scopes_enabled, type: :boolean, default: false
|
|
182
|
+
settings.attribute :scope_id, type: :scope
|
|
131
183
|
settings.attribute :comments_enabled, type: :boolean, default: true
|
|
184
|
+
settings.attribute :comments_max_length, type: :integer, required: false
|
|
132
185
|
settings.attribute :resources_permissions_enabled, type: :boolean, default: true
|
|
133
186
|
settings.attribute :dummy_global_attribute_1, type: :boolean
|
|
134
|
-
settings.attribute :dummy_global_attribute_2, type: :boolean
|
|
187
|
+
settings.attribute :dummy_global_attribute_2, type: :boolean, readonly: ->(_context) { false }
|
|
188
|
+
settings.attribute :readonly_attribute, type: :boolean, default: true, readonly: ->(_context) { true }
|
|
135
189
|
settings.attribute :enable_pads_creation, type: :boolean, default: false
|
|
136
190
|
settings.attribute :amendments_enabled, type: :boolean, default: false
|
|
137
191
|
settings.attribute :dummy_global_translatable_text, type: :text, translated: true, editor: true, required: true
|
|
@@ -140,12 +194,15 @@ Decidim.register_component(:dummy) do |component|
|
|
|
140
194
|
component.settings(:step) do |settings|
|
|
141
195
|
settings.attribute :comments_blocked, type: :boolean, default: false
|
|
142
196
|
settings.attribute :dummy_step_attribute_1, type: :boolean
|
|
143
|
-
settings.attribute :dummy_step_attribute_2, type: :boolean
|
|
197
|
+
settings.attribute :dummy_step_attribute_2, type: :boolean, readonly: ->(_context) { false }
|
|
144
198
|
settings.attribute :dummy_step_translatable_text, type: :text, translated: true, editor: true, required: true
|
|
199
|
+
settings.attribute :readonly_step_attribute, type: :boolean, default: true, readonly: ->(_context) { true }
|
|
145
200
|
settings.attribute :amendment_creation_enabled, type: :boolean, default: true
|
|
146
201
|
settings.attribute :amendment_reaction_enabled, type: :boolean, default: true
|
|
147
202
|
settings.attribute :amendment_promotion_enabled, type: :boolean, default: true
|
|
148
203
|
settings.attribute :amendments_visibility, type: :string, default: "all"
|
|
204
|
+
settings.attribute :endorsements_enabled, type: :boolean, default: false
|
|
205
|
+
settings.attribute :endorsements_blocked, type: :boolean, default: false
|
|
149
206
|
end
|
|
150
207
|
|
|
151
208
|
component.register_resource(:dummy_resource) do |resource|
|
|
@@ -156,6 +213,19 @@ Decidim.register_component(:dummy) do |component|
|
|
|
156
213
|
resource.searchable = true
|
|
157
214
|
end
|
|
158
215
|
|
|
216
|
+
component.register_resource(:nested_dummy_resource) do |resource|
|
|
217
|
+
resource.name = :nested_dummy
|
|
218
|
+
resource.model_class_name = "Decidim::DummyResources::NestedDummyResource"
|
|
219
|
+
end
|
|
220
|
+
|
|
221
|
+
component.register_resource(:coauthorable_dummy_resource) do |resource|
|
|
222
|
+
resource.name = :coauthorable_dummy
|
|
223
|
+
resource.model_class_name = "Decidim::DummyResources::CoauthorableDummyResource"
|
|
224
|
+
resource.template = "decidim/coauthorabledummy_resource/linked_dummys"
|
|
225
|
+
resource.actions = %w(foo-coauthorable)
|
|
226
|
+
resource.searchable = false
|
|
227
|
+
end
|
|
228
|
+
|
|
159
229
|
component.register_stat :dummies_count_high, primary: true, priority: Decidim::StatsRegistry::HIGH_PRIORITY do |components, _start_at, _end_at|
|
|
160
230
|
components.count * 10
|
|
161
231
|
end
|
|
@@ -179,13 +249,15 @@ RSpec.configure do |config|
|
|
|
179
249
|
unless ActiveRecord::Base.connection.data_source_exists?("decidim_dummy_resources_dummy_resources")
|
|
180
250
|
ActiveRecord::Migration.create_table :decidim_dummy_resources_dummy_resources do |t|
|
|
181
251
|
t.jsonb :translatable_text
|
|
182
|
-
t.
|
|
252
|
+
t.jsonb :title
|
|
183
253
|
t.string :body
|
|
184
254
|
t.text :address
|
|
185
255
|
t.float :latitude
|
|
186
256
|
t.float :longitude
|
|
187
257
|
t.datetime :published_at
|
|
188
258
|
t.integer :coauthorships_count, null: false, default: 0
|
|
259
|
+
t.integer :endorsements_count, null: false, default: 0
|
|
260
|
+
t.integer :comments_count, null: false, default: 0
|
|
189
261
|
|
|
190
262
|
t.references :decidim_component, index: false
|
|
191
263
|
t.integer :decidim_author_id, index: false
|
|
@@ -195,6 +267,36 @@ RSpec.configure do |config|
|
|
|
195
267
|
t.references :decidim_scope, index: false
|
|
196
268
|
t.string :reference
|
|
197
269
|
|
|
270
|
+
t.timestamps
|
|
271
|
+
end
|
|
272
|
+
end
|
|
273
|
+
unless ActiveRecord::Base.connection.data_source_exists?("decidim_dummy_resources_nested_dummy_resources")
|
|
274
|
+
ActiveRecord::Migration.create_table :decidim_dummy_resources_nested_dummy_resources do |t|
|
|
275
|
+
t.jsonb :translatable_text
|
|
276
|
+
t.string :title
|
|
277
|
+
|
|
278
|
+
t.references :dummy_resource, index: false
|
|
279
|
+
t.timestamps
|
|
280
|
+
end
|
|
281
|
+
end
|
|
282
|
+
unless ActiveRecord::Base.connection.data_source_exists?("decidim_dummy_resources_coauthorable_dummy_resources")
|
|
283
|
+
ActiveRecord::Migration.create_table :decidim_dummy_resources_coauthorable_dummy_resources do |t|
|
|
284
|
+
t.jsonb :translatable_text
|
|
285
|
+
t.string :title
|
|
286
|
+
t.string :body
|
|
287
|
+
t.text :address
|
|
288
|
+
t.float :latitude
|
|
289
|
+
t.float :longitude
|
|
290
|
+
t.datetime :published_at
|
|
291
|
+
t.integer :coauthorships_count, null: false, default: 0
|
|
292
|
+
t.integer :endorsements_count, null: false, default: 0
|
|
293
|
+
t.integer :comments_count, null: false, default: 0
|
|
294
|
+
|
|
295
|
+
t.references :decidim_component, index: false
|
|
296
|
+
t.references :decidim_category, index: false
|
|
297
|
+
t.references :decidim_scope, index: false
|
|
298
|
+
t.string :reference
|
|
299
|
+
|
|
198
300
|
t.timestamps
|
|
199
301
|
end
|
|
200
302
|
end
|
|
@@ -19,8 +19,7 @@ shared_context "with a component" do
|
|
|
19
19
|
participatory_space: participatory_space)
|
|
20
20
|
end
|
|
21
21
|
|
|
22
|
-
let!(:category) { create :category, participatory_space:
|
|
23
|
-
|
|
22
|
+
let!(:category) { create :category, participatory_space: participatory_space }
|
|
24
23
|
let!(:scope) { create :scope, organization: organization }
|
|
25
24
|
|
|
26
25
|
before do
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Helpers that get automatically included in component specs.
|
|
4
|
+
module ConfirmationHelpers
|
|
5
|
+
# Overrides the Capybara default accept_confirm because we have replaced the
|
|
6
|
+
# system's own confirmation modal with foundation based modal.
|
|
7
|
+
#
|
|
8
|
+
# See:
|
|
9
|
+
# https://github.com/teamcapybara/capybara/blob/44621209496fe4dd352709799a0061a80d97d562/lib/capybara/session.rb#L647
|
|
10
|
+
def accept_confirm(_text = nil, **_options)
|
|
11
|
+
yield if block_given?
|
|
12
|
+
|
|
13
|
+
# The test can already be "within", so find the body using xpath
|
|
14
|
+
message = nil
|
|
15
|
+
body = find(:xpath, "/html/body")
|
|
16
|
+
within(body.find(".confirm-reveal")) do
|
|
17
|
+
message = find(".confirm-modal-content").text
|
|
18
|
+
find("a.button[data-confirm-ok]").click
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
message
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# Overrides the Capybara default dismiss_confirm because we have replaced the
|
|
25
|
+
# system's own confirmation modal with foundation based modal.
|
|
26
|
+
#
|
|
27
|
+
# See:
|
|
28
|
+
# https://github.com/teamcapybara/capybara/blob/44621209496fe4dd352709799a0061a80d97d562/lib/capybara/session.rb#L657
|
|
29
|
+
def dismiss_confirm(_text = nil, **_options)
|
|
30
|
+
yield if block_given?
|
|
31
|
+
|
|
32
|
+
# The test can already be "within", so find the body using xpath
|
|
33
|
+
message = nil
|
|
34
|
+
body = find(:xpath, "/html/body")
|
|
35
|
+
within(body.find(".confirm-reveal")) do
|
|
36
|
+
message = find(".confirm-modal-content").text
|
|
37
|
+
find("a.button[data-confirm-cancel]").click
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
message
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# Used to accept the "onbeforeunload" event's normal browser confirm modal
|
|
44
|
+
# as this cannot be overridden. Original confirm dismiss implementation in
|
|
45
|
+
# Capybara.
|
|
46
|
+
def accept_page_unload(text = nil, **options, &blk)
|
|
47
|
+
page.send(:accept_modal, :confirm, text, options, &blk)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# Used to dismiss the "onbeforeunload" event's normal browser confirm modal
|
|
51
|
+
# as this cannot be overridden. Original confirm dismiss implementation in
|
|
52
|
+
# Capybara.
|
|
53
|
+
def dismiss_page_unload(text = nil, **options, &blk)
|
|
54
|
+
page.send(:dismiss_modal, :confirm, text, options, &blk)
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
RSpec.configure do |config|
|
|
59
|
+
config.include ConfirmationHelpers, type: :system
|
|
60
|
+
end
|
|
@@ -12,7 +12,7 @@ module Decidim
|
|
|
12
12
|
end
|
|
13
13
|
|
|
14
14
|
class ContentRenderers::DummyFooRenderer < ContentRenderers::BaseRenderer
|
|
15
|
-
def render
|
|
15
|
+
def render(_options = nil)
|
|
16
16
|
content.gsub("%lorem%", "<em>neque dicta enim quasi</em>")
|
|
17
17
|
end
|
|
18
18
|
end
|
|
@@ -28,7 +28,7 @@ module Decidim
|
|
|
28
28
|
end
|
|
29
29
|
|
|
30
30
|
class ContentRenderers::DummyBarRenderer < ContentRenderers::BaseRenderer
|
|
31
|
-
def render
|
|
31
|
+
def render(_options = nil)
|
|
32
32
|
content.gsub("*ipsum*", "<em>illo qui voluptas</em>")
|
|
33
33
|
end
|
|
34
34
|
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module FrontendHelpers
|
|
4
|
+
# Thanks to:
|
|
5
|
+
# https://medium.com/@coorasse/catch-javascript-errors-in-your-system-tests-89c2fe6773b1
|
|
6
|
+
def expect_no_js_errors
|
|
7
|
+
errors = page.driver.browser.manage.logs.get(:browser)
|
|
8
|
+
return if errors.blank?
|
|
9
|
+
|
|
10
|
+
aggregate_failures "javascript errors" do
|
|
11
|
+
errors.each do |error|
|
|
12
|
+
expect(error.level).not_to eq("SEVERE"), error.message
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
RSpec.configure do |config|
|
|
19
|
+
config.include FrontendHelpers, type: :system
|
|
20
|
+
end
|
|
@@ -8,6 +8,69 @@ module GeocoderHelpers
|
|
|
8
8
|
address,
|
|
9
9
|
result
|
|
10
10
|
)
|
|
11
|
+
Decidim::Map::Provider::Autocomplete::Test.add_stub(
|
|
12
|
+
address,
|
|
13
|
+
coordinates
|
|
14
|
+
)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
# Waits for the front-end geocoding request to finish in order to ensure there
|
|
18
|
+
# are no pending requests when proceeding.
|
|
19
|
+
def fill_in_geocoding(attribute, options = {})
|
|
20
|
+
fill_in attribute, options
|
|
21
|
+
expect(page).to have_selector(".tribute-container ul#results", count: 1)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
module_function
|
|
25
|
+
|
|
26
|
+
public def configure_maps
|
|
27
|
+
# Set maps configuration in test mode
|
|
28
|
+
Decidim.maps = {
|
|
29
|
+
provider: :test,
|
|
30
|
+
api_key: "1234123412341234",
|
|
31
|
+
static: { url: "https://www.example.org/my_static_map" },
|
|
32
|
+
autocomplete: { url: "/photon_api" } # Locally drawn route for the tests
|
|
33
|
+
}
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
module Decidim::Map::Provider
|
|
38
|
+
module Geocoding
|
|
39
|
+
class Test < ::Decidim::Map::Geocoding; end
|
|
40
|
+
end
|
|
41
|
+
module Autocomplete
|
|
42
|
+
class Test < ::Decidim::Map::Autocomplete
|
|
43
|
+
def self.stubs
|
|
44
|
+
@stubs ||= []
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def self.add_stub(address, coordinates)
|
|
48
|
+
stubs.push(
|
|
49
|
+
properties: address.is_a?(Hash) ? address : { street: address },
|
|
50
|
+
geometry: { coordinates: coordinates }
|
|
51
|
+
)
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def self.clear_stubs
|
|
55
|
+
@stubs = []
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def builder_options
|
|
59
|
+
{ url: configuration.fetch(:url, nil) }.compact
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
class Builder < Decidim::Map::Autocomplete::Builder
|
|
63
|
+
def javascript_snippets
|
|
64
|
+
template.javascript_include_tag("decidim/geocoding/provider/photon")
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
module DynamicMap
|
|
70
|
+
class Test < ::Decidim::Map::DynamicMap; end
|
|
71
|
+
end
|
|
72
|
+
module StaticMap
|
|
73
|
+
class Test < ::Decidim::Map::StaticMap; end
|
|
11
74
|
end
|
|
12
75
|
end
|
|
13
76
|
|
|
@@ -15,16 +78,97 @@ RSpec.configure do |config|
|
|
|
15
78
|
config.include GeocoderHelpers
|
|
16
79
|
|
|
17
80
|
config.before(:suite) do
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
81
|
+
GeocoderHelpers.configure_maps
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
config.after(:each, :configures_map) do
|
|
85
|
+
# Ensure the initializer is always re-run after the examples because
|
|
86
|
+
# otherwise the utilities could remain unregistered which causes issues with
|
|
87
|
+
# further tests.
|
|
88
|
+
Decidim::Core::Engine.initializers.each do |i|
|
|
89
|
+
next unless i.name == "decidim.maps"
|
|
90
|
+
|
|
91
|
+
i.run
|
|
92
|
+
break
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
# Ensure the utility configuration is reset after each example for it to be
|
|
96
|
+
# reloaded the next time.
|
|
97
|
+
Decidim::Map.reset_utility_configuration!
|
|
98
|
+
configure_maps
|
|
24
99
|
end
|
|
25
100
|
|
|
26
101
|
config.before(:each, :serves_map) do
|
|
27
102
|
stub_request(:get, %r{https://www\.example\.org/my_static_map})
|
|
28
103
|
.to_return(body: "map_data")
|
|
29
104
|
end
|
|
105
|
+
|
|
106
|
+
config.before(:each, :serves_geocoding_autocomplete) do
|
|
107
|
+
# Clear the autocomplete stubs
|
|
108
|
+
Decidim::Map::Provider::Autocomplete::Test.clear_stubs
|
|
109
|
+
|
|
110
|
+
photon_response = lambda do
|
|
111
|
+
{
|
|
112
|
+
features: [
|
|
113
|
+
{
|
|
114
|
+
properties: {
|
|
115
|
+
name: "Park",
|
|
116
|
+
street: "Street1",
|
|
117
|
+
housenumber: "1",
|
|
118
|
+
postcode: "123456",
|
|
119
|
+
city: "City1",
|
|
120
|
+
state: "State1",
|
|
121
|
+
country: "Country1"
|
|
122
|
+
},
|
|
123
|
+
geometry: {
|
|
124
|
+
coordinates: [1.123, 2.234]
|
|
125
|
+
}
|
|
126
|
+
},
|
|
127
|
+
{
|
|
128
|
+
properties: {
|
|
129
|
+
street: "Street2",
|
|
130
|
+
postcode: "654321",
|
|
131
|
+
city: "City2",
|
|
132
|
+
country: "Country2"
|
|
133
|
+
},
|
|
134
|
+
geometry: {
|
|
135
|
+
coordinates: [3.345, 4.456]
|
|
136
|
+
}
|
|
137
|
+
},
|
|
138
|
+
{
|
|
139
|
+
properties: {
|
|
140
|
+
street: "Street3",
|
|
141
|
+
housenumber: "3",
|
|
142
|
+
postcode: "142536",
|
|
143
|
+
city: "City3",
|
|
144
|
+
country: "Country3"
|
|
145
|
+
},
|
|
146
|
+
geometry: {
|
|
147
|
+
coordinates: [5.567, 6.678]
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
]
|
|
151
|
+
}.tap do |response|
|
|
152
|
+
Decidim::Map::Provider::Autocomplete::Test.stubs.length.positive? &&
|
|
153
|
+
response[:features] = Decidim::Map::Provider::Autocomplete::Test.stubs
|
|
154
|
+
end
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
# The Photon API path needs to be mounted in the application itself because
|
|
158
|
+
# otherwise we would have to run a separate server for the API itself.
|
|
159
|
+
# Mocking the request would not work here because the call to the Photon API
|
|
160
|
+
# is initialized by the front-end to the URL specified for the maps
|
|
161
|
+
# geocoding autocompletion configuration which is not proxied by the
|
|
162
|
+
# headless browser running the Capybara tests.
|
|
163
|
+
Rails.application.routes.disable_clear_and_finalize = true
|
|
164
|
+
Rails.application.routes.draw do
|
|
165
|
+
get "photon_api", to: ->(_) { [200, { "Content-Type" => "application/json" }, [photon_response.call.to_json.to_s]] }
|
|
166
|
+
end
|
|
167
|
+
Rails.application.routes.disable_clear_and_finalize = false
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
config.after(:each, :serves_geocoding_autocomplete) do
|
|
171
|
+
# Reset the routes back to original
|
|
172
|
+
Rails.application.reload_routes!
|
|
173
|
+
end
|
|
30
174
|
end
|