]> git.openstreetmap.org Git - rails.git/blob - test/controllers/searches_controller_test.rb
Merge pull request #6394 from openstreetmap/dependabot/github_actions/ruby/setup...
[rails.git] / test / controllers / searches_controller_test.rb
1 # frozen_string_literal: true
2
3 require "test_helper"
4
5 class SearchesControllerTest < ActionDispatch::IntegrationTest
6   ##
7   # test all routes which lead to this controller
8   def test_routes
9     assert_routing(
10       { :path => "/search", :method => :get },
11       { :controller => "searches", :action => "show" }
12     )
13   end
14
15   ##
16   # Test identification with no arguments
17   def test_identify_error
18     get search_path
19     assert_response :bad_request
20
21     get search_path, :xhr => true
22     assert_response :bad_request
23   end
24
25   ##
26   # Test identification of basic lat/lon pairs
27   def test_identify_latlon_basic
28     [
29       "50.06773 14.37742",
30       "50.06773/14.37742",
31       "50.06773, 14.37742",
32       "+50.06773 +14.37742",
33       "+50.06773, +14.37742",
34       "+50.06773/+14.37742"
35     ].each do |code|
36       latlon_check code, 50.06773, 14.37742
37     end
38   end
39
40   ##
41   # Test identification of lat/lon pairs using N/E with degrees
42   def test_identify_latlon_ne_d
43     [
44       "N50.06773 E14.37742",
45       "N50.06773, E14.37742",
46       "50.06773N 14.37742E",
47       "50.06773N, 14.37742E"
48     ].each do |code|
49       latlon_check code, 50.06773, 14.37742
50     end
51   end
52
53   ##
54   # Test identification of integer lat/lon pairs using N/E with degrees
55   def test_identify_latlon_ne_d_int_deg
56     [
57       "N50 E14",
58       "N50° E14°",
59       "50N 14E",
60       "50°N 14°E"
61     ].each do |code|
62       latlon_check code, 50, 14
63     end
64   end
65
66   ##
67   # Test identification of lat/lon pairs using N/W with degrees
68   def test_identify_latlon_nw_d
69     [
70       "N50.06773 W14.37742",
71       "N50.06773, W14.37742",
72       "50.06773N 14.37742W",
73       "50.06773N, 14.37742W"
74     ].each do |code|
75       latlon_check code, 50.06773, -14.37742
76     end
77   end
78
79   ##
80   # Test identification of lat/lon pairs using S/E with degrees
81   def test_identify_latlon_se_d
82     [
83       "S50.06773 E14.37742",
84       "S50.06773, E14.37742",
85       "50.06773S 14.37742E",
86       "50.06773S, 14.37742E"
87     ].each do |code|
88       latlon_check code, -50.06773, 14.37742
89     end
90   end
91
92   ##
93   # Test identification of lat/lon pairs using S/W with degrees
94   def test_identify_latlon_sw_d
95     [
96       "S50.06773 W14.37742",
97       "S50.06773, W14.37742",
98       "50.06773S 14.37742W",
99       "50.06773S, 14.37742W"
100     ].each do |code|
101       latlon_check code, -50.06773, -14.37742
102     end
103   end
104
105   ##
106   # Test identification of lat/lon pairs using N/E with degrees/mins
107   def test_identify_latlon_ne_dm
108     [
109       "N 50° 04.064 E 014° 22.645",
110       "N 50° 04.064' E 014° 22.645",
111       "N 50° 04.064', E 014° 22.645'",
112       "N50° 04.064 E14° 22.645",
113       "N 50 04.064 E 014 22.645",
114       "N50 4.064 E14 22.645",
115       "50° 04.064' N, 014° 22.645' E"
116     ].each do |code|
117       latlon_check code, 50.06773, 14.37742
118     end
119   end
120
121   ##
122   # Test identification of lat/lon pairs using N/W with degrees/mins
123   def test_identify_latlon_nw_dm
124     [
125       "N 50° 04.064 W 014° 22.645",
126       "N 50° 04.064' W 014° 22.645",
127       "N 50° 04.064', W 014° 22.645'",
128       "N50° 04.064 W14° 22.645",
129       "N 50 04.064 W 014 22.645",
130       "N50 4.064 W14 22.645",
131       "50° 04.064' N, 014° 22.645' W"
132     ].each do |code|
133       latlon_check code, 50.06773, -14.37742
134     end
135   end
136
137   ##
138   # Test identification of lat/lon pairs using S/E with degrees/mins
139   def test_identify_latlon_se_dm
140     [
141       "S 50° 04.064 E 014° 22.645",
142       "S 50° 04.064' E 014° 22.645",
143       "S 50° 04.064', E 014° 22.645'",
144       "S50° 04.064 E14° 22.645",
145       "S 50 04.064 E 014 22.645",
146       "S50 4.064 E14 22.645",
147       "50° 04.064' S, 014° 22.645' E"
148     ].each do |code|
149       latlon_check code, -50.06773, 14.37742
150     end
151   end
152
153   ##
154   # Test identification of lat/lon pairs using S/W with degrees/mins
155   def test_identify_latlon_sw_dm
156     [
157       "S 50° 04.064 W 014° 22.645",
158       "S 50° 04.064' W 014° 22.645",
159       "S 50° 04.064', W 014° 22.645'",
160       "S50° 04.064 W14° 22.645",
161       "S 50 04.064 W 014 22.645",
162       "S50 4.064 W14 22.645",
163       "50° 04.064' S, 014° 22.645' W"
164     ].each do |code|
165       latlon_check code, -50.06773, -14.37742
166     end
167   end
168
169   ##
170   # Test identification of lat/lon pairs using N/E with degrees/mins/secs
171   def test_identify_latlon_ne_dms
172     [
173       "N 50° 4' 03.828\" E 14° 22' 38.712\"",
174       "N 50° 4' 03.828\", E 14° 22' 38.712\"",
175       "N 50° 4′ 03.828″, E 14° 22′ 38.712″",
176       "N50 4 03.828 E14 22 38.712",
177       "N50 4 03.828, E14 22 38.712",
178       "50°4'3.828\"N 14°22'38.712\"E"
179     ].each do |code|
180       latlon_check code, 50.06773, 14.37742
181     end
182   end
183
184   ##
185   # Test identification of lat/lon pairs using N/W with degrees/mins/secs
186   def test_identify_latlon_nw_dms
187     [
188       "N 50° 4' 03.828\" W 14° 22' 38.712\"",
189       "N 50° 4' 03.828\", W 14° 22' 38.712\"",
190       "N 50° 4′ 03.828″, W 14° 22′ 38.712″",
191       "N50 4 03.828 W14 22 38.712",
192       "N50 4 03.828, W14 22 38.712",
193       "50°4'3.828\"N 14°22'38.712\"W"
194     ].each do |code|
195       latlon_check code, 50.06773, -14.37742
196     end
197   end
198
199   ##
200   # Test identification of lat/lon pairs using S/E with degrees/mins/secs
201   def test_identify_latlon_se_dms
202     [
203       "S 50° 4' 03.828\" E 14° 22' 38.712\"",
204       "S 50° 4' 03.828\", E 14° 22' 38.712\"",
205       "S 50° 4′ 03.828″, E 14° 22′ 38.712″",
206       "S50 4 03.828 E14 22 38.712",
207       "S50 4 03.828, E14 22 38.712",
208       "50°4'3.828\"S 14°22'38.712\"E"
209     ].each do |code|
210       latlon_check code, -50.06773, 14.37742
211     end
212   end
213
214   ##
215   # Test identification of lat/lon pairs using S/W with degrees/mins/secs
216   def test_identify_latlon_sw_dms
217     [
218       "S 50° 4' 03.828\" W 14° 22' 38.712\"",
219       "S 50° 4' 03.828\", W 14° 22' 38.712\"",
220       "S 50° 4′ 03.828″, W 14° 22′ 38.712″",
221       "S50 4 03.828 W14 22 38.712",
222       "S50 4 03.828, W14 22 38.712",
223       "50°4'3.828\"S 14°22'38.712\"W"
224     ].each do |code|
225       latlon_check code, -50.06773, -14.37742
226     end
227   end
228
229   ##
230   # Test identification of lat/lon pairs with missing fractions
231   def test_no_identify_latlon_ne_missing_fraction_part
232     [
233       "N50. E14.",
234       "N50.° E14.°",
235       "50.N 14.E",
236       "50.°N 14.°E",
237       "N50 1.' E14 2.'",
238       "N50° 1.' E14° 2.'",
239       "50N 1.' 14 2.'E",
240       "50° 1.'N 14° 2.'E",
241       "N50 1' 3,\" E14 2' 4.\"",
242       "N50° 1' 3.\" E14° 2' 4.\"",
243       "50N 1' 3.\" 14 2' 4.\"E",
244       "50° 1' 3.\"N 14° 2' 4.\"E"
245     ].each do |code|
246       get search_path(:query => code)
247       assert_response :success
248       assert_template :show
249       assert_template :layout => "map"
250       assert_equal %w[nominatim], assigns(:sources).pluck(:name)
251     end
252   end
253
254   #
255   # Test identification of lat/lon pairs with mixed precision
256   def test_identify_latlon_ne_mixed_precision
257     latlon_check "N1 5 E15",    1.083333, 15
258     latlon_check "N1 5 9 E15",  1.085833, 15
259     latlon_check "N1 5 9 E1 5", 1.085833, 1.083333
260     latlon_check "N15 E1 5",    15, 1.083333
261     latlon_check "N15 E1 5 9",  15, 1.085833
262     latlon_check "N1 5 E1 5 9", 1.083333, 1.085833
263   end
264
265   #
266   # Test identification of lat/lon pairs with values close to zero
267   def test_identify_latlon_close_to_zero
268     [
269       "0.0000123 -0.0000456",
270       "+0.0000123 -0.0000456",
271       "N 0° 0' 0.4428\", W 0° 0' 1.6416\""
272     ].each do |code|
273       latlon_check code, 0.0000123, -0.0000456
274     end
275   end
276
277   ##
278   # Test identification of US zipcodes
279   def test_identify_us_postcode
280     %w[
281       12345
282       12345-6789
283     ].each do |code|
284       search_check code, %w[nominatim]
285     end
286   end
287
288   ##
289   # Test identification of UK postcodes using examples from
290   # http://en.wikipedia.org/wiki/Postcodes_in_the_United_Kingdom
291   def test_identify_uk_postcode
292     [
293       "EC1A 1BB",
294       "W1A 1HQ",
295       "M1 1AA",
296       "B33 8TH",
297       "CR2 6XH",
298       "DN55 1PT"
299     ].each do |code|
300       search_check code, %w[nominatim]
301     end
302   end
303
304   ##
305   # Test identification of Canadian postcodes
306   def test_identify_ca_postcode
307     search_check "A1B 2C3", %w[nominatim]
308   end
309
310   ##
311   # Test identification fall through to the default case
312   def test_identify_default
313     search_check "foo bar baz", %w[nominatim]
314   end
315
316   ##
317   # Test the nominatim reverse JSON search
318   def test_search_osm_nominatim_reverse_json
319     with_http_stubs "nominatim" do
320       post search_nominatim_reverse_query_path(:lat => 51.7632, :lon => -0.0076, :zoom => 15, :format => "json"), :xhr => true
321       result_name_check_json("Broxbourne, Hertfordshire, East of England, England, United Kingdom")
322
323       post search_nominatim_reverse_query_path(:lat => 51.7632, :lon => -0.0076, :zoom => 17, :format => "json"), :xhr => true
324       result_name_check_json("Dinant Link Road, Broxbourne, Hertfordshire, East of England, England, EN11 8HX, United Kingdom")
325
326       post search_nominatim_reverse_query_path(:lat => 13.7709, :lon => 100.50507, :zoom => 19, :format => "json"), :xhr => true
327       result_name_check_json("MM Steak&Grill, ถนนศรีอยุธยา, บางขุนพรหม, กรุงเทพมหานคร, เขตดุสิต, กรุงเทพมหานคร, 10300, ประเทศไทย")
328     end
329   end
330
331   private
332
333   def latlon_check(query, lat, lon)
334     get search_path(:query => query)
335     assert_response :success
336     assert_template :show
337     assert_template :layout => "map"
338     assert_equal %w[latlon nominatim_reverse], assigns(:sources).pluck(:name)
339     assert_nil @controller.params[:query]
340     assert_match(/^[+-]?\d+(?:\.\d+)?$/, @controller.params[:lat])
341     assert_match(/^[+-]?\d+(?:\.\d+)?$/, @controller.params[:lon])
342     assert_in_delta lat, @controller.params[:lat].to_f
343     assert_in_delta lon, @controller.params[:lon].to_f
344
345     get search_path(:query => query), :xhr => true
346     assert_response :success
347     assert_template :show
348     assert_template :layout => "xhr"
349     assert_equal %w[latlon nominatim_reverse], assigns(:sources).pluck(:name)
350     assert_nil @controller.params[:query]
351     assert_match(/^[+-]?\d+(?:\.\d+)?$/, @controller.params[:lat])
352     assert_match(/^[+-]?\d+(?:\.\d+)?$/, @controller.params[:lon])
353     assert_in_delta lat, @controller.params[:lat].to_f
354     assert_in_delta lon, @controller.params[:lon].to_f
355   end
356
357   def search_check(query, sources)
358     get search_path(:query => query)
359     assert_response :success
360     assert_template :show
361     assert_template :layout => "map"
362     assert_equal sources, assigns(:sources).pluck(:name)
363
364     get search_path(:query => query), :xhr => true
365     assert_response :success
366     assert_template :show
367     assert_template :layout => "xhr"
368     assert_equal sources, assigns(:sources).pluck(:name)
369   end
370
371   def result_name_check_json(name)
372     assert_response :success
373     js = ActiveSupport::JSON.decode(@response.body)
374     assert_not_nil js
375     assert_equal name, js[0]["name"]
376   end
377 end