decidim-dev 0.21.0 → 0.23.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|