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