]> git.openstreetmap.org Git - rails.git/blob - test/controllers/api/notes_controller_test.rb
DRY tests with assertions to check whether an email was received
[rails.git] / test / controllers / api / notes_controller_test.rb
1 # frozen_string_literal: true
2
3 require "test_helper"
4
5 module Api
6   class NotesControllerTest < ActionDispatch::IntegrationTest
7     def setup
8       super
9       # Stub nominatim response for note locations
10       stub_request(:get, %r{^https://nominatim\.openstreetmap\.org/reverse\?})
11         .to_return(:status => 404)
12     end
13
14     ##
15     # test all routes which lead to this controller
16     def test_routes
17       assert_routing(
18         { :path => "/api/0.6/notes", :method => :post },
19         { :controller => "api/notes", :action => "create" }
20       )
21       assert_routing(
22         { :path => "/api/0.6/notes/1", :method => :get },
23         { :controller => "api/notes", :action => "show", :id => "1" }
24       )
25       assert_recognizes(
26         { :controller => "api/notes", :action => "show", :id => "1", :format => "xml" },
27         { :path => "/api/0.6/notes/1.xml", :method => :get }
28       )
29       assert_routing(
30         { :path => "/api/0.6/notes/1.rss", :method => :get },
31         { :controller => "api/notes", :action => "show", :id => "1", :format => "rss" }
32       )
33       assert_routing(
34         { :path => "/api/0.6/notes/1.json", :method => :get },
35         { :controller => "api/notes", :action => "show", :id => "1", :format => "json" }
36       )
37       assert_routing(
38         { :path => "/api/0.6/notes/1.gpx", :method => :get },
39         { :controller => "api/notes", :action => "show", :id => "1", :format => "gpx" }
40       )
41       assert_routing(
42         { :path => "/api/0.6/notes/1/comment", :method => :post },
43         { :controller => "api/notes", :action => "comment", :id => "1" }
44       )
45       assert_routing(
46         { :path => "/api/0.6/notes/1/close", :method => :post },
47         { :controller => "api/notes", :action => "close", :id => "1" }
48       )
49       assert_routing(
50         { :path => "/api/0.6/notes/1/reopen", :method => :post },
51         { :controller => "api/notes", :action => "reopen", :id => "1" }
52       )
53       assert_routing(
54         { :path => "/api/0.6/notes/1", :method => :delete },
55         { :controller => "api/notes", :action => "destroy", :id => "1" }
56       )
57
58       assert_routing(
59         { :path => "/api/0.6/notes", :method => :get },
60         { :controller => "api/notes", :action => "index" }
61       )
62       assert_recognizes(
63         { :controller => "api/notes", :action => "index", :format => "xml" },
64         { :path => "/api/0.6/notes.xml", :method => :get }
65       )
66       assert_routing(
67         { :path => "/api/0.6/notes.rss", :method => :get },
68         { :controller => "api/notes", :action => "index", :format => "rss" }
69       )
70       assert_routing(
71         { :path => "/api/0.6/notes.json", :method => :get },
72         { :controller => "api/notes", :action => "index", :format => "json" }
73       )
74       assert_routing(
75         { :path => "/api/0.6/notes.gpx", :method => :get },
76         { :controller => "api/notes", :action => "index", :format => "gpx" }
77       )
78
79       assert_routing(
80         { :path => "/api/0.6/notes/search", :method => :get },
81         { :controller => "api/notes", :action => "search" }
82       )
83       assert_recognizes(
84         { :controller => "api/notes", :action => "search", :format => "xml" },
85         { :path => "/api/0.6/notes/search.xml", :method => :get }
86       )
87       assert_routing(
88         { :path => "/api/0.6/notes/search.rss", :method => :get },
89         { :controller => "api/notes", :action => "search", :format => "rss" }
90       )
91       assert_routing(
92         { :path => "/api/0.6/notes/search.json", :method => :get },
93         { :controller => "api/notes", :action => "search", :format => "json" }
94       )
95       assert_routing(
96         { :path => "/api/0.6/notes/search.gpx", :method => :get },
97         { :controller => "api/notes", :action => "search", :format => "gpx" }
98       )
99
100       assert_routing(
101         { :path => "/api/0.6/notes/feed", :method => :get },
102         { :controller => "api/notes", :action => "feed", :format => "rss" }
103       )
104     end
105
106     def test_create_anonymous_success
107       assert_difference "Note.count", 1 do
108         assert_difference "NoteComment.count", 1 do
109           assert_no_difference "NoteSubscription.count" do
110             post api_notes_path(:lat => -1.0, :lon => -1.0, :text => "This is a comment", :format => "json")
111           end
112         end
113       end
114       assert_response :success
115       js = ActiveSupport::JSON.decode(@response.body)
116       assert_not_nil js
117       assert_equal "Feature", js["type"]
118       assert_equal "Point", js["geometry"]["type"]
119       assert_equal [-1.0, -1.0], js["geometry"]["coordinates"]
120       assert_equal "open", js["properties"]["status"]
121       assert_equal 1, js["properties"]["comments"].count
122       assert_equal "opened", js["properties"]["comments"].last["action"]
123       assert_equal "This is a comment", js["properties"]["comments"].last["text"]
124       assert_nil js["properties"]["comments"].last["user"]
125       id = js["properties"]["id"]
126
127       get api_note_path(id, :format => "json")
128       assert_response :success
129       js = ActiveSupport::JSON.decode(@response.body)
130       assert_not_nil js
131       assert_equal "Feature", js["type"]
132       assert_equal "Point", js["geometry"]["type"]
133       assert_equal [-1.0, -1.0], js["geometry"]["coordinates"]
134       assert_equal id, js["properties"]["id"]
135       assert_equal "open", js["properties"]["status"]
136       assert_equal 1, js["properties"]["comments"].count
137       assert_equal "opened", js["properties"]["comments"].last["action"]
138       assert_equal "This is a comment", js["properties"]["comments"].last["text"]
139       assert_nil js["properties"]["comments"].last["user"]
140     end
141
142     def test_create_anonymous_fail
143       assert_no_difference "Note.count" do
144         assert_no_difference "NoteComment.count" do
145           post api_notes_path(:lon => -1.0, :text => "This is a comment")
146         end
147       end
148       assert_response :bad_request
149
150       assert_no_difference "Note.count" do
151         assert_no_difference "NoteComment.count" do
152           post api_notes_path(:lat => -1.0, :text => "This is a comment")
153         end
154       end
155       assert_response :bad_request
156
157       assert_no_difference "Note.count" do
158         assert_no_difference "NoteComment.count" do
159           post api_notes_path(:lat => -1.0, :lon => -1.0)
160         end
161       end
162       assert_response :bad_request
163
164       assert_no_difference "Note.count" do
165         assert_no_difference "NoteComment.count" do
166           post api_notes_path(:lat => -1.0, :lon => -1.0, :text => "")
167         end
168       end
169       assert_response :bad_request
170
171       assert_no_difference "Note.count" do
172         assert_no_difference "NoteComment.count" do
173           post api_notes_path(:lat => -100.0, :lon => -1.0, :text => "This is a comment")
174         end
175       end
176       assert_response :bad_request
177
178       assert_no_difference "Note.count" do
179         assert_no_difference "NoteComment.count" do
180           post api_notes_path(:lat => -1.0, :lon => -200.0, :text => "This is a comment")
181         end
182       end
183       assert_response :bad_request
184
185       assert_no_difference "Note.count" do
186         assert_no_difference "NoteComment.count" do
187           post api_notes_path(:lat => "abc", :lon => -1.0, :text => "This is a comment")
188         end
189       end
190       assert_response :bad_request
191
192       assert_no_difference "Note.count" do
193         assert_no_difference "NoteComment.count" do
194           post api_notes_path(:lat => -1.0, :lon => "abc", :text => "This is a comment")
195         end
196       end
197       assert_response :bad_request
198
199       assert_no_difference "Note.count" do
200         assert_no_difference "NoteComment.count" do
201           post api_notes_path(:lat => -1.0, :lon => -1.0, :text => "x\u0000y")
202         end
203       end
204       assert_response :bad_request
205     end
206
207     def test_create_success
208       user = create(:user)
209       auth_header = bearer_authorization_header user
210       assert_difference "Note.count", 1 do
211         assert_difference "NoteComment.count", 1 do
212           assert_difference "NoteSubscription.count", 1 do
213             post api_notes_path(:lat => -1.0, :lon => -1.0, :text => "This is a comment", :format => "json"), :headers => auth_header
214           end
215         end
216       end
217       assert_response :success
218       js = ActiveSupport::JSON.decode(@response.body)
219       assert_not_nil js
220       assert_equal "Feature", js["type"]
221       assert_equal "Point", js["geometry"]["type"]
222       assert_equal [-1.0, -1.0], js["geometry"]["coordinates"]
223       assert_equal "open", js["properties"]["status"]
224       assert_equal 1, js["properties"]["comments"].count
225       assert_equal "opened", js["properties"]["comments"].last["action"]
226       assert_equal "This is a comment", js["properties"]["comments"].last["text"]
227       assert_equal user.display_name, js["properties"]["comments"].last["user"]
228
229       note = Note.last
230       subscription = NoteSubscription.last
231       assert_equal user, subscription.user
232       assert_equal note, subscription.note
233     end
234
235     def test_create_no_scope_fail
236       user = create(:user)
237       auth_header = bearer_authorization_header user, :scopes => %w[read_prefs]
238
239       assert_no_difference "Note.count" do
240         post api_notes_path(:lat => -1.0, :lon => -1.0, :text => "This is a description", :format => "json"), :headers => auth_header
241
242         assert_response :forbidden
243       end
244     end
245
246     def test_comment_success
247       open_note_with_comment = create(:note_with_comments)
248       user = create(:user)
249       auth_header = bearer_authorization_header user
250       assert_difference "NoteComment.count", 1 do
251         assert_difference "NoteSubscription.count", 1 do
252           assert_no_difference "ActionMailer::Base.deliveries.size" do
253             perform_enqueued_jobs do
254               post comment_api_note_path(open_note_with_comment, :text => "This is an additional comment", :format => "json"), :headers => auth_header
255             end
256           end
257         end
258       end
259       assert_response :success
260       js = ActiveSupport::JSON.decode(@response.body)
261       assert_not_nil js
262       assert_equal "Feature", js["type"]
263       assert_equal open_note_with_comment.id, js["properties"]["id"]
264       assert_equal "open", js["properties"]["status"]
265       assert_equal 2, js["properties"]["comments"].count
266       assert_equal "commented", js["properties"]["comments"].last["action"]
267       assert_equal "This is an additional comment", js["properties"]["comments"].last["text"]
268       assert_equal user.display_name, js["properties"]["comments"].last["user"]
269
270       subscription = NoteSubscription.last
271       assert_equal user, subscription.user
272       assert_equal open_note_with_comment, subscription.note
273
274       get api_note_path(open_note_with_comment, :format => "json")
275       assert_response :success
276       js = ActiveSupport::JSON.decode(@response.body)
277       assert_not_nil js
278       assert_equal "Feature", js["type"]
279       assert_equal open_note_with_comment.id, js["properties"]["id"]
280       assert_equal "open", js["properties"]["status"]
281       assert_equal 2, js["properties"]["comments"].count
282       assert_equal "commented", js["properties"]["comments"].last["action"]
283       assert_equal "This is an additional comment", js["properties"]["comments"].last["text"]
284       assert_equal user.display_name, js["properties"]["comments"].last["user"]
285     end
286
287     def test_comment_without_notifications_success
288       # Ensure that emails are sent to users
289       first_user = create(:user)
290       second_user = create(:user)
291       third_user = create(:user)
292
293       note_with_comments_by_users = create(:note) do |note|
294         create(:note_comment, :note => note, :author => first_user)
295         create(:note_comment, :note => note, :author => second_user)
296       end
297
298       auth_header = bearer_authorization_header third_user
299
300       assert_difference "NoteComment.count", 1 do
301         assert_difference "NoteSubscription.count", 1 do
302           assert_no_difference "ActionMailer::Base.deliveries.size" do
303             perform_enqueued_jobs do
304               post comment_api_note_path(note_with_comments_by_users, :text => "This is an additional comment", :format => "json"), :headers => auth_header
305             end
306           end
307         end
308       end
309       assert_response :success
310       js = ActiveSupport::JSON.decode(@response.body)
311       assert_not_nil js
312       assert_equal "Feature", js["type"]
313       assert_equal note_with_comments_by_users.id, js["properties"]["id"]
314       assert_equal "open", js["properties"]["status"]
315       assert_equal 3, js["properties"]["comments"].count
316       assert_equal "commented", js["properties"]["comments"].last["action"]
317       assert_equal "This is an additional comment", js["properties"]["comments"].last["text"]
318       assert_equal third_user.display_name, js["properties"]["comments"].last["user"]
319
320       subscription = NoteSubscription.last
321       assert_equal third_user, subscription.user
322       assert_equal note_with_comments_by_users, subscription.note
323
324       get api_note_path(note_with_comments_by_users, :format => "json")
325       assert_response :success
326       js = ActiveSupport::JSON.decode(@response.body)
327       assert_not_nil js
328       assert_equal "Feature", js["type"]
329       assert_equal note_with_comments_by_users.id, js["properties"]["id"]
330       assert_equal "open", js["properties"]["status"]
331       assert_equal 3, js["properties"]["comments"].count
332       assert_equal "commented", js["properties"]["comments"].last["action"]
333       assert_equal "This is an additional comment", js["properties"]["comments"].last["text"]
334       assert_equal third_user.display_name, js["properties"]["comments"].last["user"]
335     end
336
337     def test_comment_with_notifications_success
338       # Ensure that emails are sent to users
339       first_user = create(:user)
340       second_user = create(:user)
341       third_user = create(:user)
342
343       note_with_comments_by_users = create(:note, :author => first_user) do |note|
344         create(:note_comment, :note => note, :author => first_user)
345         create(:note_comment, :note => note, :author => second_user)
346       end
347       create(:note_subscription, :note => note_with_comments_by_users, :user => first_user)
348       create(:note_subscription, :note => note_with_comments_by_users, :user => second_user)
349
350       auth_header = bearer_authorization_header third_user
351
352       assert_difference "NoteComment.count", 1 do
353         assert_difference "NoteSubscription.count", 1 do
354           assert_difference "ActionMailer::Base.deliveries.size", 2 do
355             perform_enqueued_jobs do
356               post comment_api_note_path(note_with_comments_by_users, :text => "This is an additional comment", :format => "json"), :headers => auth_header
357             end
358           end
359         end
360       end
361       assert_response :success
362       js = ActiveSupport::JSON.decode(@response.body)
363       assert_not_nil js
364       assert_equal "Feature", js["type"]
365       assert_equal note_with_comments_by_users.id, js["properties"]["id"]
366       assert_equal "open", js["properties"]["status"]
367       assert_equal 3, js["properties"]["comments"].count
368       assert_equal "commented", js["properties"]["comments"].last["action"]
369       assert_equal "This is an additional comment", js["properties"]["comments"].last["text"]
370       assert_equal third_user.display_name, js["properties"]["comments"].last["user"]
371
372       subscription = NoteSubscription.last
373       assert_equal third_user, subscription.user
374       assert_equal note_with_comments_by_users, subscription.note
375
376       assert_email_received first_user.email, "[OpenStreetMap] #{third_user.display_name} has commented on one of your notes"
377       assert_email_received second_user.email, "[OpenStreetMap] #{third_user.display_name} has commented on a note you are interested in"
378
379       get api_note_path(note_with_comments_by_users, :format => "json")
380       assert_response :success
381       js = ActiveSupport::JSON.decode(@response.body)
382       assert_not_nil js
383       assert_equal "Feature", js["type"]
384       assert_equal note_with_comments_by_users.id, js["properties"]["id"]
385       assert_equal "open", js["properties"]["status"]
386       assert_equal 3, js["properties"]["comments"].count
387       assert_equal "commented", js["properties"]["comments"].last["action"]
388       assert_equal "This is an additional comment", js["properties"]["comments"].last["text"]
389       assert_equal third_user.display_name, js["properties"]["comments"].last["user"]
390     end
391
392     def test_comment_twice_success
393       open_note_with_comment = create(:note_with_comments)
394       user = create(:user)
395       auth_header = bearer_authorization_header user
396       assert_difference "NoteComment.count", 1 do
397         assert_difference "NoteSubscription.count", 1 do
398           assert_no_difference "ActionMailer::Base.deliveries.size" do
399             perform_enqueued_jobs do
400               post comment_api_note_path(open_note_with_comment, :text => "This is an additional comment", :format => "json"), :headers => auth_header
401             end
402           end
403         end
404       end
405       assert_response :success
406       js = ActiveSupport::JSON.decode(@response.body)
407       assert_not_nil js
408       assert_equal 2, js["properties"]["comments"].count
409
410       subscription = NoteSubscription.last
411       assert_equal user, subscription.user
412       assert_equal open_note_with_comment, subscription.note
413
414       assert_difference "NoteComment.count", 1 do
415         assert_no_difference "NoteSubscription.count" do
416           assert_no_difference "ActionMailer::Base.deliveries.size" do
417             perform_enqueued_jobs do
418               post comment_api_note_path(open_note_with_comment, :text => "This is a second additional comment", :format => "json"), :headers => auth_header
419             end
420           end
421         end
422       end
423       assert_response :success
424       js = ActiveSupport::JSON.decode(@response.body)
425       assert_not_nil js
426       assert_equal 3, js["properties"]["comments"].count
427     end
428
429     def test_comment_fail
430       open_note_with_comment = create(:note_with_comments)
431
432       user = create(:user)
433
434       assert_no_difference "NoteComment.count" do
435         post comment_api_note_path(open_note_with_comment)
436         assert_response :unauthorized
437       end
438
439       auth_header = bearer_authorization_header user
440
441       assert_no_difference "NoteComment.count" do
442         post comment_api_note_path(open_note_with_comment), :headers => auth_header
443       end
444       assert_response :bad_request
445
446       assert_no_difference "NoteComment.count" do
447         post comment_api_note_path(open_note_with_comment, :text => ""), :headers => auth_header
448       end
449       assert_response :bad_request
450
451       assert_no_difference "NoteComment.count" do
452         post comment_api_note_path(12345, :text => "This is an additional comment"), :headers => auth_header
453       end
454       assert_response :not_found
455
456       hidden_note_with_comment = create(:note_with_comments, :status => "hidden")
457
458       assert_no_difference "NoteComment.count" do
459         post comment_api_note_path(hidden_note_with_comment, :text => "This is an additional comment"), :headers => auth_header
460       end
461       assert_response :gone
462
463       closed_note_with_comment = create(:note_with_comments, :closed)
464
465       assert_no_difference "NoteComment.count" do
466         post comment_api_note_path(closed_note_with_comment, :text => "This is an additional comment"), :headers => auth_header
467       end
468       assert_response :conflict
469
470       assert_no_difference "NoteComment.count" do
471         post comment_api_note_path(open_note_with_comment, :text => "x\u0000y"), :headers => auth_header
472       end
473       assert_response :bad_request
474     end
475
476     def test_close_success
477       open_note_with_comment = create(:note_with_comments)
478       user = create(:user)
479
480       post close_api_note_path(open_note_with_comment, :text => "This is a close comment", :format => "json")
481       assert_response :unauthorized
482
483       auth_header = bearer_authorization_header user
484
485       assert_difference "NoteSubscription.count", 1 do
486         post close_api_note_path(open_note_with_comment, :text => "This is a close comment", :format => "json"), :headers => auth_header
487       end
488       assert_response :success
489       js = ActiveSupport::JSON.decode(@response.body)
490       assert_not_nil js
491       assert_equal "Feature", js["type"]
492       assert_equal open_note_with_comment.id, js["properties"]["id"]
493       assert_equal "closed", js["properties"]["status"]
494       assert_equal 2, js["properties"]["comments"].count
495       assert_equal "closed", js["properties"]["comments"].last["action"]
496       assert_equal "This is a close comment", js["properties"]["comments"].last["text"]
497       assert_equal user.display_name, js["properties"]["comments"].last["user"]
498
499       subscription = NoteSubscription.last
500       assert_equal user, subscription.user
501       assert_equal open_note_with_comment, subscription.note
502
503       get api_note_path(open_note_with_comment.id, :format => "json")
504       assert_response :success
505       js = ActiveSupport::JSON.decode(@response.body)
506       assert_not_nil js
507       assert_equal "Feature", js["type"]
508       assert_equal open_note_with_comment.id, js["properties"]["id"]
509       assert_equal "closed", js["properties"]["status"]
510       assert_equal 2, js["properties"]["comments"].count
511       assert_equal "closed", js["properties"]["comments"].last["action"]
512       assert_equal "This is a close comment", js["properties"]["comments"].last["text"]
513       assert_equal user.display_name, js["properties"]["comments"].last["user"]
514     end
515
516     def test_close_fail
517       post close_api_note_path(12345)
518       assert_response :unauthorized
519
520       auth_header = bearer_authorization_header
521
522       post close_api_note_path(12345), :headers => auth_header
523       assert_response :not_found
524
525       hidden_note_with_comment = create(:note_with_comments, :status => "hidden")
526
527       post close_api_note_path(hidden_note_with_comment), :headers => auth_header
528       assert_response :gone
529
530       closed_note_with_comment = create(:note_with_comments, :closed)
531
532       post close_api_note_path(closed_note_with_comment), :headers => auth_header
533       assert_response :conflict
534     end
535
536     def test_reopen_success
537       closed_note_with_comment = create(:note_with_comments, :closed)
538       user = create(:user)
539
540       post reopen_api_note_path(closed_note_with_comment, :text => "This is a reopen comment", :format => "json")
541       assert_response :unauthorized
542
543       auth_header = bearer_authorization_header user
544
545       assert_difference "NoteSubscription.count", 1 do
546         post reopen_api_note_path(closed_note_with_comment, :text => "This is a reopen comment", :format => "json"), :headers => auth_header
547       end
548       assert_response :success
549       js = ActiveSupport::JSON.decode(@response.body)
550       assert_not_nil js
551       assert_equal "Feature", js["type"]
552       assert_equal closed_note_with_comment.id, js["properties"]["id"]
553       assert_equal "open", js["properties"]["status"]
554       assert_equal 3, js["properties"]["comments"].count
555       assert_equal "reopened", js["properties"]["comments"].last["action"]
556       assert_equal "This is a reopen comment", js["properties"]["comments"].last["text"]
557       assert_equal user.display_name, js["properties"]["comments"].last["user"]
558
559       subscription = NoteSubscription.last
560       assert_equal user, subscription.user
561       assert_equal closed_note_with_comment, subscription.note
562
563       get api_note_path(closed_note_with_comment, :format => "json")
564       assert_response :success
565       js = ActiveSupport::JSON.decode(@response.body)
566       assert_not_nil js
567       assert_equal "Feature", js["type"]
568       assert_equal closed_note_with_comment.id, js["properties"]["id"]
569       assert_equal "open", js["properties"]["status"]
570       assert_equal 3, js["properties"]["comments"].count
571       assert_equal "reopened", js["properties"]["comments"].last["action"]
572       assert_equal "This is a reopen comment", js["properties"]["comments"].last["text"]
573       assert_equal user.display_name, js["properties"]["comments"].last["user"]
574     end
575
576     def test_reopen_fail
577       hidden_note_with_comment = create(:note_with_comments, :status => "hidden")
578
579       post reopen_api_note_path(hidden_note_with_comment)
580       assert_response :unauthorized
581
582       auth_header = bearer_authorization_header
583
584       post reopen_api_note_path(12345), :headers => auth_header
585       assert_response :not_found
586
587       post reopen_api_note_path(hidden_note_with_comment), :headers => auth_header
588       assert_response :gone
589
590       open_note_with_comment = create(:note_with_comments)
591
592       post reopen_api_note_path(open_note_with_comment), :headers => auth_header
593       assert_response :conflict
594     end
595
596     def test_show_success
597       open_note = create(:note_with_comments)
598
599       get api_note_path(open_note, :format => "xml")
600       assert_response :success
601       assert_equal "application/xml", @response.media_type
602       assert_select "osm", :count => 1 do
603         assert_select "note[lat='#{open_note.lat}'][lon='#{open_note.lon}']", :count => 1 do
604           assert_select "id", open_note.id.to_s
605           assert_select "url", api_note_url(open_note, :format => "xml")
606           assert_select "comment_url", comment_api_note_url(open_note, :format => "xml")
607           assert_select "close_url", close_api_note_url(open_note, :format => "xml")
608           assert_select "date_created", open_note.created_at.to_s
609           assert_select "status", open_note.status
610           assert_select "comments", :count => 1 do
611             assert_select "comment", :count => 1
612           end
613         end
614       end
615
616       get api_note_path(open_note, :format => "rss")
617       assert_response :success
618       assert_equal "application/rss+xml", @response.media_type
619       assert_select "rss", :count => 1 do
620         assert_select "channel", :count => 1 do
621           assert_select "item", :count => 1 do
622             assert_select "link", note_url(open_note)
623             assert_select "guid", api_note_url(open_note)
624             assert_select "pubDate", open_note.created_at.to_fs(:rfc822)
625             assert_select "geo|lat", open_note.lat.to_s
626             assert_select "geo|long", open_note.lon.to_s
627             assert_select "georss|point", "#{open_note.lon} #{open_note.lon}"
628           end
629         end
630       end
631
632       get api_note_path(open_note, :format => "json")
633       assert_response :success
634       assert_equal "application/json", @response.media_type
635       js = ActiveSupport::JSON.decode(@response.body)
636       assert_not_nil js
637       assert_equal "Feature", js["type"]
638       assert_equal "Point", js["geometry"]["type"]
639       assert_equal open_note.lat, js["geometry"]["coordinates"][0]
640       assert_equal open_note.lon, js["geometry"]["coordinates"][1]
641       assert_equal open_note.id, js["properties"]["id"]
642       assert_equal api_note_url(open_note, :format => "json"), js["properties"]["url"]
643       assert_equal comment_api_note_url(open_note, :format => "json"), js["properties"]["comment_url"]
644       assert_equal close_api_note_url(open_note, :format => "json"), js["properties"]["close_url"]
645       assert_equal open_note.created_at.to_s, js["properties"]["date_created"]
646       assert_equal open_note.status, js["properties"]["status"]
647
648       get api_note_path(open_note, :format => "gpx")
649       assert_response :success
650       assert_equal "application/gpx+xml", @response.media_type
651       assert_select "gpx", :count => 1 do
652         assert_select "wpt[lat='#{open_note.lat}'][lon='#{open_note.lon}']", :count => 1 do
653           assert_select "time", :count => 1
654           assert_select "name", "Note: #{open_note.id}"
655           assert_select "desc", :count => 1
656           assert_select "link[href='http://www.example.com/note/#{open_note.id}']", :count => 1
657           assert_select "extensions", :count => 1 do
658             assert_select "id", open_note.id.to_s
659             assert_select "url", api_note_url(open_note, :format => "gpx")
660             assert_select "comment_url", comment_api_note_url(open_note, :format => "gpx")
661             assert_select "close_url", close_api_note_url(open_note, :format => "gpx")
662           end
663         end
664       end
665     end
666
667     def test_show_hidden_comment
668       note_with_hidden_comment = create(:note) do |note|
669         create(:note_comment, :note => note, :body => "Valid comment for hidden note")
670         create(:note_comment, :note => note, :visible => false)
671         create(:note_comment, :note => note, :body => "Another valid comment for hidden note")
672       end
673
674       get api_note_path(note_with_hidden_comment, :format => "json")
675       assert_response :success
676       js = ActiveSupport::JSON.decode(@response.body)
677       assert_not_nil js
678       assert_equal "Feature", js["type"]
679       assert_equal note_with_hidden_comment.id, js["properties"]["id"]
680       assert_equal 2, js["properties"]["comments"].count
681       assert_equal "Valid comment for hidden note", js["properties"]["comments"][0]["text"]
682       assert_equal "Another valid comment for hidden note", js["properties"]["comments"][1]["text"]
683     end
684
685     def test_show_fail
686       get api_note_path(12345)
687       assert_response :not_found
688
689       get api_note_path(create(:note, :status => "hidden"))
690       assert_response :gone
691     end
692
693     def test_destroy_success
694       open_note_with_comment = create(:note_with_comments)
695       user = create(:user)
696       moderator_user = create(:moderator_user)
697
698       delete api_note_path(open_note_with_comment, :text => "This is a hide comment", :format => "json")
699       assert_response :unauthorized
700
701       auth_header = bearer_authorization_header user
702
703       delete api_note_path(open_note_with_comment, :text => "This is a hide comment", :format => "json"), :headers => auth_header
704       assert_response :forbidden
705
706       auth_header = bearer_authorization_header moderator_user
707
708       delete api_note_path(open_note_with_comment, :text => "This is a hide comment", :format => "json"), :headers => auth_header
709       assert_response :success
710       js = ActiveSupport::JSON.decode(@response.body)
711       assert_not_nil js
712       assert_equal "Feature", js["type"]
713       assert_equal open_note_with_comment.id, js["properties"]["id"]
714       assert_equal "hidden", js["properties"]["status"]
715       assert_equal 2, js["properties"]["comments"].count
716       assert_equal "hidden", js["properties"]["comments"].last["action"]
717       assert_equal "This is a hide comment", js["properties"]["comments"].last["text"]
718       assert_equal moderator_user.display_name, js["properties"]["comments"].last["user"]
719
720       get api_note_path(open_note_with_comment, :format => "json"), :headers => auth_header
721       assert_response :success
722
723       auth_header = bearer_authorization_header user
724
725       get api_note_path(open_note_with_comment, :format => "json"), :headers => auth_header
726       assert_response :gone
727     end
728
729     def test_destroy_fail
730       user = create(:user)
731       moderator_user = create(:moderator_user)
732
733       delete api_note_path(12345, :format => "json")
734       assert_response :unauthorized
735
736       auth_header = bearer_authorization_header user
737
738       delete api_note_path(12345, :format => "json"), :headers => auth_header
739       assert_response :forbidden
740
741       auth_header = bearer_authorization_header moderator_user
742
743       delete api_note_path(12345, :format => "json"), :headers => auth_header
744       assert_response :not_found
745
746       hidden_note_with_comment = create(:note_with_comments, :status => "hidden")
747
748       delete api_note_path(hidden_note_with_comment, :format => "json"), :headers => auth_header
749       assert_response :gone
750     end
751
752     def test_index_success
753       position = (1.1 * GeoRecord::SCALE).to_i
754       create(:note_with_comments, :latitude => position, :longitude => position)
755       create(:note_with_comments, :latitude => position, :longitude => position)
756
757       get api_notes_path(:bbox => "1,1,1.2,1.2", :format => "rss")
758       assert_response :success
759       assert_equal "application/rss+xml", @response.media_type
760       assert_select "rss", :count => 1 do
761         assert_select "channel", :count => 1 do
762           assert_select "description", :text => /1\.2/, :count => 1
763           assert_select "item", :count => 2
764         end
765       end
766
767       get api_notes_path(:bbox => "1,1,1.2,1.2", :format => "json")
768       assert_response :success
769       assert_equal "application/json", @response.media_type
770       js = ActiveSupport::JSON.decode(@response.body)
771       assert_not_nil js
772       assert_equal "FeatureCollection", js["type"]
773       assert_equal 2, js["features"].count
774
775       get api_notes_path(:bbox => "1,1,1.2,1.2", :format => "xml")
776       assert_response :success
777       assert_equal "application/xml", @response.media_type
778       assert_select "osm", :count => 1 do
779         assert_select "note", :count => 2
780       end
781
782       get api_notes_path(:bbox => "1,1,1.2,1.2", :format => "gpx")
783       assert_response :success
784       assert_equal "application/gpx+xml", @response.media_type
785       assert_select "gpx", :count => 1 do
786         assert_select "wpt", :count => 2
787       end
788     end
789
790     def test_index_limit
791       position = (1.1 * GeoRecord::SCALE).to_i
792       create(:note_with_comments, :latitude => position, :longitude => position)
793       create(:note_with_comments, :latitude => position, :longitude => position)
794
795       get api_notes_path(:bbox => "1,1,1.2,1.2", :limit => 1, :format => "rss")
796       assert_response :success
797       assert_equal "application/rss+xml", @response.media_type
798       assert_select "rss", :count => 1 do
799         assert_select "channel", :count => 1 do
800           assert_select "item", :count => 1
801         end
802       end
803
804       get api_notes_path(:bbox => "1,1,1.2,1.2", :limit => 1, :format => "json")
805       assert_response :success
806       assert_equal "application/json", @response.media_type
807       js = ActiveSupport::JSON.decode(@response.body)
808       assert_not_nil js
809       assert_equal "FeatureCollection", js["type"]
810       assert_equal 1, js["features"].count
811
812       get api_notes_path(:bbox => "1,1,1.2,1.2", :limit => 1, :format => "xml")
813       assert_response :success
814       assert_equal "application/xml", @response.media_type
815       assert_select "osm", :count => 1 do
816         assert_select "note", :count => 1
817       end
818
819       get api_notes_path(:bbox => "1,1,1.2,1.2", :limit => 1, :format => "gpx")
820       assert_response :success
821       assert_equal "application/gpx+xml", @response.media_type
822       assert_select "gpx", :count => 1 do
823         assert_select "wpt", :count => 1
824       end
825
826       get api_notes_path(:bbox => "1,1,1.2,1.2", :limit => Settings.max_note_query_limit, :format => "rss")
827       assert_response :success
828     end
829
830     def test_index_empty_area
831       get api_notes_path(:bbox => "5,5,5.1,5.1", :format => "rss")
832       assert_response :success
833       assert_equal "application/rss+xml", @response.media_type
834       assert_select "rss", :count => 1 do
835         assert_select "channel", :count => 1 do
836           assert_select "item", :count => 0
837         end
838       end
839
840       get api_notes_path(:bbox => "5,5,5.1,5.1", :format => "json")
841       assert_response :success
842       assert_equal "application/json", @response.media_type
843       js = ActiveSupport::JSON.decode(@response.body)
844       assert_not_nil js
845       assert_equal "FeatureCollection", js["type"]
846       assert_equal 0, js["features"].count
847
848       get api_notes_path(:bbox => "5,5,5.1,5.1", :format => "xml")
849       assert_response :success
850       assert_equal "application/xml", @response.media_type
851       assert_select "osm", :count => 1 do
852         assert_select "note", :count => 0
853       end
854
855       get api_notes_path(:bbox => "5,5,5.1,5.1", :format => "gpx")
856       assert_response :success
857       assert_equal "application/gpx+xml", @response.media_type
858       assert_select "gpx", :count => 1 do
859         assert_select "wpt", :count => 0
860       end
861     end
862
863     def test_index_large_area
864       get api_notes_path(:bbox => "-2.5,-2.5,2.5,2.5", :format => :json)
865       assert_response :success
866       assert_equal "application/json", @response.media_type
867
868       get api_notes_path(:l => "-2.5", :b => "-2.5", :r => "2.5", :t => "2.5", :format => :json)
869       assert_response :success
870       assert_equal "application/json", @response.media_type
871
872       get api_notes_path(:bbox => "-10,-10,12,12", :format => :json)
873       assert_response :bad_request
874       assert_equal "text/plain", @response.media_type
875
876       get api_notes_path(:l => "-10", :b => "-10", :r => "12", :t => "12", :format => :json)
877       assert_response :bad_request
878       assert_equal "text/plain", @response.media_type
879     end
880
881     def test_index_closed
882       create(:note_with_comments, :closed, :closed_at => Time.now.utc - 5.days)
883       create(:note_with_comments, :closed, :closed_at => Time.now.utc - 100.days)
884       create(:note_with_comments, :status => "hidden")
885       create(:note_with_comments)
886
887       # Open notes + closed in last 7 days
888       get api_notes_path(:bbox => "1,1,1.7,1.7", :closed => "7", :format => "json")
889       assert_response :success
890       assert_equal "application/json", @response.media_type
891       js = ActiveSupport::JSON.decode(@response.body)
892       assert_not_nil js
893       assert_equal "FeatureCollection", js["type"]
894       assert_equal 2, js["features"].count
895
896       # Only open notes
897       get api_notes_path(:bbox => "1,1,1.7,1.7", :closed => "0", :format => "json")
898       assert_response :success
899       assert_equal "application/json", @response.media_type
900       js = ActiveSupport::JSON.decode(@response.body)
901       assert_not_nil js
902       assert_equal "FeatureCollection", js["type"]
903       assert_equal 1, js["features"].count
904
905       # Open notes + all closed notes
906       get api_notes_path(:bbox => "1,1,1.7,1.7", :closed => "-1", :format => "json")
907       assert_response :success
908       assert_equal "application/json", @response.media_type
909       js = ActiveSupport::JSON.decode(@response.body)
910       assert_not_nil js
911       assert_equal "FeatureCollection", js["type"]
912       assert_equal 3, js["features"].count
913     end
914
915     def test_index_bad_params
916       get api_notes_path
917       assert_response :bad_request
918       assert_equal "The parameter bbox is required", @response.body
919
920       get api_notes_path(:bbox => "-2.5,-2.5,2.5")
921       assert_response :bad_request
922
923       get api_notes_path(:bbox => "-2.5,-2.5,2.5,2.5,2.5")
924       assert_response :bad_request
925
926       get api_notes_path(:b => "-2.5", :r => "2.5", :t => "2.5")
927       assert_response :bad_request
928
929       get api_notes_path(:l => "-2.5", :r => "2.5", :t => "2.5")
930       assert_response :bad_request
931
932       get api_notes_path(:l => "-2.5", :b => "-2.5", :t => "2.5")
933       assert_response :bad_request
934
935       get api_notes_path(:l => "-2.5", :b => "-2.5", :r => "2.5")
936       assert_response :bad_request
937
938       get api_notes_path(:bbox => "1,1,1.7,1.7", :limit => "0", :format => "json")
939       assert_response :bad_request
940
941       get api_notes_path(:bbox => "1,1,1.7,1.7", :limit => Settings.max_note_query_limit + 1, :format => "json")
942       assert_response :bad_request
943     end
944
945     def test_search_success
946       create(:note_with_comments)
947
948       get search_api_notes_path(:q => "note comment", :format => "xml")
949       assert_response :success
950       assert_equal "application/xml", @response.media_type
951       assert_select "osm", :count => 1 do
952         assert_select "note", :count => 1
953       end
954
955       get search_api_notes_path(:q => "note comment", :format => "json")
956       assert_response :success
957       assert_equal "application/json", @response.media_type
958       js = ActiveSupport::JSON.decode(@response.body)
959       assert_not_nil js
960       assert_equal "FeatureCollection", js["type"]
961       assert_equal 1, js["features"].count
962
963       get search_api_notes_path(:q => "note comment", :format => "rss")
964       assert_response :success
965       assert_equal "application/rss+xml", @response.media_type
966       assert_select "rss", :count => 1 do
967         assert_select "channel", :count => 1 do
968           assert_select "item", :count => 1
969         end
970       end
971
972       get search_api_notes_path(:q => "note comment", :format => "gpx")
973       assert_response :success
974       assert_equal "application/gpx+xml", @response.media_type
975       assert_select "gpx", :count => 1 do
976         assert_select "wpt", :count => 1
977       end
978
979       get search_api_notes_path(:q => "note comment", :limit => Settings.max_note_query_limit, :format => "xml")
980       assert_response :success
981     end
982
983     def test_search_by_display_name_success
984       user = create(:user)
985
986       create(:note) do |note|
987         create(:note_comment, :note => note, :author => user)
988       end
989
990       get search_api_notes_path(:display_name => user.display_name, :format => "xml")
991       assert_response :success
992       assert_equal "application/xml", @response.media_type
993       assert_select "osm", :count => 1 do
994         assert_select "note", :count => 1
995       end
996
997       get search_api_notes_path(:display_name => user.display_name, :format => "json")
998       assert_response :success
999       assert_equal "application/json", @response.media_type
1000       js = ActiveSupport::JSON.decode(@response.body)
1001       assert_not_nil js
1002       assert_equal "FeatureCollection", js["type"]
1003       assert_equal 1, js["features"].count
1004
1005       get search_api_notes_path(:display_name => user.display_name, :format => "rss")
1006       assert_response :success
1007       assert_equal "application/rss+xml", @response.media_type
1008       assert_select "rss", :count => 1 do
1009         assert_select "channel", :count => 1 do
1010           assert_select "item", :count => 1
1011         end
1012       end
1013
1014       get search_api_notes_path(:display_name => user.display_name, :format => "gpx")
1015       assert_response :success
1016       assert_equal "application/gpx+xml", @response.media_type
1017       assert_select "gpx", :count => 1 do
1018         assert_select "wpt", :count => 1
1019       end
1020     end
1021
1022     def test_search_by_user_success
1023       user = create(:user)
1024
1025       create(:note) do |note|
1026         create(:note_comment, :note => note, :author => user)
1027       end
1028
1029       get search_api_notes_path(:user => user.id, :format => "xml")
1030       assert_response :success
1031       assert_equal "application/xml", @response.media_type
1032       assert_select "osm", :count => 1 do
1033         assert_select "note", :count => 1
1034       end
1035
1036       get search_api_notes_path(:user => user.id, :format => "json")
1037       assert_response :success
1038       assert_equal "application/json", @response.media_type
1039       js = ActiveSupport::JSON.decode(@response.body)
1040       assert_not_nil js
1041       assert_equal "FeatureCollection", js["type"]
1042       assert_equal 1, js["features"].count
1043
1044       get search_api_notes_path(:user => user.id, :format => "rss")
1045       assert_response :success
1046       assert_equal "application/rss+xml", @response.media_type
1047       assert_select "rss", :count => 1 do
1048         assert_select "channel", :count => 1 do
1049           assert_select "item", :count => 1
1050         end
1051       end
1052
1053       get search_api_notes_path(:user => user.id, :format => "gpx")
1054       assert_response :success
1055       assert_equal "application/gpx+xml", @response.media_type
1056       assert_select "gpx", :count => 1 do
1057         assert_select "wpt", :count => 1
1058       end
1059
1060       user2 = create(:user)
1061       get search_api_notes_path(:user => user2.id, :format => "xml")
1062       assert_response :success
1063       assert_equal "application/xml", @response.media_type
1064       assert_select "osm", :count => 1 do
1065         assert_select "note", :count => 0
1066       end
1067     end
1068
1069     def test_search_by_time_success
1070       note1 = create(:note, :created_at => "2020-02-01T00:00:00Z", :updated_at => "2020-04-01T00:00:00Z")
1071       note2 = create(:note, :created_at => "2020-03-01T00:00:00Z", :updated_at => "2020-05-01T00:00:00Z")
1072
1073       get search_api_notes_path(:from => "2020-02-15T00:00:00Z", :to => "2020-04-15T00:00:00Z", :format => "xml")
1074       assert_response :success
1075       assert_equal "application/xml", @response.media_type
1076       assert_select "osm", :count => 1 do
1077         assert_select "note", :count => 1 do
1078           assert_select "id", note2.id.to_s
1079         end
1080       end
1081
1082       get search_api_notes_path(:from => "2020-02-15T00:00:00Z", :to => "2020-04-15T00:00:00Z", :sort => "updated_at", :format => "xml")
1083       assert_response :success
1084       assert_equal "application/xml", @response.media_type
1085       assert_select "osm", :count => 1 do
1086         assert_select "note", :count => 1 do
1087           assert_select "id", note1.id.to_s
1088         end
1089       end
1090     end
1091
1092     def test_search_by_bbox_success
1093       notes = Array.new(5) do |i|
1094         position = ((1.0 + (i * 0.1)) * GeoRecord::SCALE).to_i
1095         create(:note_with_comments, :created_at => Time.parse("2020-01-01T00:00:00Z") + i.day, :latitude => position, :longitude => position)
1096       end
1097
1098       get search_api_notes_path(:bbox => "1.0,1.0,1.6,1.6", :sort => "created_at", :order => "oldest", :format => "xml")
1099       assert_response :success
1100       assert_equal "application/xml", @response.media_type
1101       assert_notes_in_order notes
1102
1103       get search_api_notes_path(:bbox => "1.25,1.25,1.45,1.45", :sort => "created_at", :order => "oldest", :format => "xml")
1104       assert_response :success
1105       assert_equal "application/xml", @response.media_type
1106       assert_notes_in_order [notes[3], notes[4]]
1107
1108       get search_api_notes_path(:bbox => "2.0,2.0,2.5,2.5", :sort => "created_at", :order => "oldest", :format => "xml")
1109       assert_response :success
1110       assert_equal "application/xml", @response.media_type
1111       assert_notes_in_order []
1112     end
1113
1114     def test_search_no_match
1115       create(:note_with_comments)
1116
1117       get search_api_notes_path(:q => "no match", :format => "xml")
1118       assert_response :success
1119       assert_equal "application/xml", @response.media_type
1120       assert_select "osm", :count => 1 do
1121         assert_select "note", :count => 0
1122       end
1123
1124       get search_api_notes_path(:q => "no match", :format => "json")
1125       assert_response :success
1126       assert_equal "application/json", @response.media_type
1127       js = ActiveSupport::JSON.decode(@response.body)
1128       assert_not_nil js
1129       assert_equal "FeatureCollection", js["type"]
1130       assert_equal 0, js["features"].count
1131
1132       get search_api_notes_path(:q => "no match", :format => "rss")
1133       assert_response :success
1134       assert_equal "application/rss+xml", @response.media_type
1135       assert_select "rss", :count => 1 do
1136         assert_select "channel", :count => 1 do
1137           assert_select "item", :count => 0
1138         end
1139       end
1140
1141       get search_api_notes_path(:q => "no match", :format => "gpx")
1142       assert_response :success
1143       assert_equal "application/gpx+xml", @response.media_type
1144       assert_select "gpx", :count => 1 do
1145         assert_select "wpt", :count => 0
1146       end
1147     end
1148
1149     def test_search_by_time_no_match
1150       create(:note_with_comments)
1151
1152       get search_api_notes_path(:from => "01.01.2010", :to => "01.10.2010", :format => "xml")
1153       assert_response :success
1154       assert_equal "application/xml", @response.media_type
1155       assert_select "osm", :count => 1 do
1156         assert_select "note", :count => 0
1157       end
1158
1159       get search_api_notes_path(:from => "01.01.2010", :to => "01.10.2010", :format => "json")
1160       assert_response :success
1161       assert_equal "application/json", @response.media_type
1162       js = ActiveSupport::JSON.decode(@response.body)
1163       assert_not_nil js
1164       assert_equal "FeatureCollection", js["type"]
1165       assert_equal 0, js["features"].count
1166
1167       get search_api_notes_path(:from => "01.01.2010", :to => "01.10.2010", :format => "rss")
1168       assert_response :success
1169       assert_equal "application/rss+xml", @response.media_type
1170       assert_select "rss", :count => 1 do
1171         assert_select "channel", :count => 1 do
1172           assert_select "item", :count => 0
1173         end
1174       end
1175
1176       get search_api_notes_path(:from => "01.01.2010", :to => "01.10.2010", :format => "gpx")
1177       assert_response :success
1178       assert_equal "application/gpx+xml", @response.media_type
1179       assert_select "gpx", :count => 1 do
1180         assert_select "wpt", :count => 0
1181       end
1182     end
1183
1184     def test_search_bad_params
1185       get search_api_notes_path(:q => "no match", :limit => "0", :format => "json")
1186       assert_response :bad_request
1187
1188       get search_api_notes_path(:q => "no match", :limit => Settings.max_note_query_limit + 1, :format => "json")
1189       assert_response :bad_request
1190
1191       get search_api_notes_path(:display_name => "non-existent")
1192       assert_response :bad_request
1193
1194       get search_api_notes_path(:user => "-1")
1195       assert_response :bad_request
1196
1197       get search_api_notes_path(:from => "wrong-date", :to => "wrong-date")
1198       assert_response :bad_request
1199
1200       get search_api_notes_path(:from => "01.01.2010", :to => "2010.01.2010")
1201       assert_response :bad_request
1202     end
1203
1204     def test_feed_success
1205       position = (1.1 * GeoRecord::SCALE).to_i
1206       create(:note_with_comments, :latitude => position, :longitude => position)
1207       create(:note_with_comments, :latitude => position, :longitude => position)
1208       position = (1.5 * GeoRecord::SCALE).to_i
1209       create(:note_with_comments, :latitude => position, :longitude => position)
1210       create(:note_with_comments, :latitude => position, :longitude => position)
1211
1212       get feed_api_notes_path(:format => "rss")
1213       assert_response :success
1214       assert_equal "application/rss+xml", @response.media_type
1215       assert_select "rss", :count => 1 do
1216         assert_select "channel", :count => 1 do
1217           assert_select "item", :count => 4
1218         end
1219       end
1220
1221       get feed_api_notes_path(:bbox => "1,1,1.2,1.2", :format => "rss")
1222       assert_response :success
1223       assert_equal "application/rss+xml", @response.media_type
1224       assert_select "rss", :count => 1 do
1225         assert_select "channel", :count => 1 do
1226           assert_select "description", :text => /1\.2/, :count => 1
1227           assert_select "item", :count => 2
1228         end
1229       end
1230
1231       get feed_api_notes_path(:bbox => "1,1,1.2,1.2", :limit => Settings.max_note_query_limit, :format => "rss")
1232       assert_response :success
1233     end
1234
1235     def test_feed_fail
1236       get feed_api_notes_path(:bbox => "1,1,1.2", :format => "rss")
1237       assert_response :bad_request
1238
1239       get feed_api_notes_path(:bbox => "1,1,1.2,1.2,1.2", :format => "rss")
1240       assert_response :bad_request
1241
1242       get feed_api_notes_path(:bbox => "1,1,1.2,1.2", :limit => "0", :format => "rss")
1243       assert_response :bad_request
1244
1245       get feed_api_notes_path(:bbox => "1,1,1.2,1.2", :limit => Settings.max_note_query_limit + 1, :format => "rss")
1246       assert_response :bad_request
1247     end
1248
1249     private
1250
1251     def assert_notes_in_order(notes)
1252       assert_select "osm>note", notes.size
1253       notes.each_with_index do |note, index|
1254         assert_select "osm>note:nth-child(#{index + 1})>id", :text => note.id.to_s, :count => 1
1255       end
1256     end
1257   end
1258 end