]> git.openstreetmap.org Git - rails.git/blob - test/controllers/api/notes_controller_test.rb
Merge pull request #6393 from tomhughes/logstash
[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       email = ActionMailer::Base.deliveries.find { |e| e.to.first == first_user.email }
377       assert_not_nil email
378       assert_equal 1, email.to.length
379       assert_equal "[OpenStreetMap] #{third_user.display_name} has commented on one of your notes", email.subject
380       assert_equal first_user.email, email.to.first
381
382       email = ActionMailer::Base.deliveries.find { |e| e.to.first == second_user.email }
383       assert_not_nil email
384       assert_equal 1, email.to.length
385       assert_equal "[OpenStreetMap] #{third_user.display_name} has commented on a note you are interested in", email.subject
386
387       get api_note_path(note_with_comments_by_users, :format => "json")
388       assert_response :success
389       js = ActiveSupport::JSON.decode(@response.body)
390       assert_not_nil js
391       assert_equal "Feature", js["type"]
392       assert_equal note_with_comments_by_users.id, js["properties"]["id"]
393       assert_equal "open", js["properties"]["status"]
394       assert_equal 3, js["properties"]["comments"].count
395       assert_equal "commented", js["properties"]["comments"].last["action"]
396       assert_equal "This is an additional comment", js["properties"]["comments"].last["text"]
397       assert_equal third_user.display_name, js["properties"]["comments"].last["user"]
398     end
399
400     def test_comment_twice_success
401       open_note_with_comment = create(:note_with_comments)
402       user = create(:user)
403       auth_header = bearer_authorization_header user
404       assert_difference "NoteComment.count", 1 do
405         assert_difference "NoteSubscription.count", 1 do
406           assert_no_difference "ActionMailer::Base.deliveries.size" do
407             perform_enqueued_jobs do
408               post comment_api_note_path(open_note_with_comment, :text => "This is an additional comment", :format => "json"), :headers => auth_header
409             end
410           end
411         end
412       end
413       assert_response :success
414       js = ActiveSupport::JSON.decode(@response.body)
415       assert_not_nil js
416       assert_equal 2, js["properties"]["comments"].count
417
418       subscription = NoteSubscription.last
419       assert_equal user, subscription.user
420       assert_equal open_note_with_comment, subscription.note
421
422       assert_difference "NoteComment.count", 1 do
423         assert_no_difference "NoteSubscription.count" do
424           assert_no_difference "ActionMailer::Base.deliveries.size" do
425             perform_enqueued_jobs do
426               post comment_api_note_path(open_note_with_comment, :text => "This is a second additional comment", :format => "json"), :headers => auth_header
427             end
428           end
429         end
430       end
431       assert_response :success
432       js = ActiveSupport::JSON.decode(@response.body)
433       assert_not_nil js
434       assert_equal 3, js["properties"]["comments"].count
435     end
436
437     def test_comment_fail
438       open_note_with_comment = create(:note_with_comments)
439
440       user = create(:user)
441
442       assert_no_difference "NoteComment.count" do
443         post comment_api_note_path(open_note_with_comment)
444         assert_response :unauthorized
445       end
446
447       auth_header = bearer_authorization_header user
448
449       assert_no_difference "NoteComment.count" do
450         post comment_api_note_path(open_note_with_comment), :headers => auth_header
451       end
452       assert_response :bad_request
453
454       assert_no_difference "NoteComment.count" do
455         post comment_api_note_path(open_note_with_comment, :text => ""), :headers => auth_header
456       end
457       assert_response :bad_request
458
459       assert_no_difference "NoteComment.count" do
460         post comment_api_note_path(12345, :text => "This is an additional comment"), :headers => auth_header
461       end
462       assert_response :not_found
463
464       hidden_note_with_comment = create(:note_with_comments, :status => "hidden")
465
466       assert_no_difference "NoteComment.count" do
467         post comment_api_note_path(hidden_note_with_comment, :text => "This is an additional comment"), :headers => auth_header
468       end
469       assert_response :gone
470
471       closed_note_with_comment = create(:note_with_comments, :closed)
472
473       assert_no_difference "NoteComment.count" do
474         post comment_api_note_path(closed_note_with_comment, :text => "This is an additional comment"), :headers => auth_header
475       end
476       assert_response :conflict
477
478       assert_no_difference "NoteComment.count" do
479         post comment_api_note_path(open_note_with_comment, :text => "x\u0000y"), :headers => auth_header
480       end
481       assert_response :bad_request
482     end
483
484     def test_close_success
485       open_note_with_comment = create(:note_with_comments)
486       user = create(:user)
487
488       post close_api_note_path(open_note_with_comment, :text => "This is a close comment", :format => "json")
489       assert_response :unauthorized
490
491       auth_header = bearer_authorization_header user
492
493       assert_difference "NoteSubscription.count", 1 do
494         post close_api_note_path(open_note_with_comment, :text => "This is a close comment", :format => "json"), :headers => auth_header
495       end
496       assert_response :success
497       js = ActiveSupport::JSON.decode(@response.body)
498       assert_not_nil js
499       assert_equal "Feature", js["type"]
500       assert_equal open_note_with_comment.id, js["properties"]["id"]
501       assert_equal "closed", js["properties"]["status"]
502       assert_equal 2, js["properties"]["comments"].count
503       assert_equal "closed", js["properties"]["comments"].last["action"]
504       assert_equal "This is a close comment", js["properties"]["comments"].last["text"]
505       assert_equal user.display_name, js["properties"]["comments"].last["user"]
506
507       subscription = NoteSubscription.last
508       assert_equal user, subscription.user
509       assert_equal open_note_with_comment, subscription.note
510
511       get api_note_path(open_note_with_comment.id, :format => "json")
512       assert_response :success
513       js = ActiveSupport::JSON.decode(@response.body)
514       assert_not_nil js
515       assert_equal "Feature", js["type"]
516       assert_equal open_note_with_comment.id, js["properties"]["id"]
517       assert_equal "closed", js["properties"]["status"]
518       assert_equal 2, js["properties"]["comments"].count
519       assert_equal "closed", js["properties"]["comments"].last["action"]
520       assert_equal "This is a close comment", js["properties"]["comments"].last["text"]
521       assert_equal user.display_name, js["properties"]["comments"].last["user"]
522     end
523
524     def test_close_fail
525       post close_api_note_path(12345)
526       assert_response :unauthorized
527
528       auth_header = bearer_authorization_header
529
530       post close_api_note_path(12345), :headers => auth_header
531       assert_response :not_found
532
533       hidden_note_with_comment = create(:note_with_comments, :status => "hidden")
534
535       post close_api_note_path(hidden_note_with_comment), :headers => auth_header
536       assert_response :gone
537
538       closed_note_with_comment = create(:note_with_comments, :closed)
539
540       post close_api_note_path(closed_note_with_comment), :headers => auth_header
541       assert_response :conflict
542     end
543
544     def test_reopen_success
545       closed_note_with_comment = create(:note_with_comments, :closed)
546       user = create(:user)
547
548       post reopen_api_note_path(closed_note_with_comment, :text => "This is a reopen comment", :format => "json")
549       assert_response :unauthorized
550
551       auth_header = bearer_authorization_header user
552
553       assert_difference "NoteSubscription.count", 1 do
554         post reopen_api_note_path(closed_note_with_comment, :text => "This is a reopen comment", :format => "json"), :headers => auth_header
555       end
556       assert_response :success
557       js = ActiveSupport::JSON.decode(@response.body)
558       assert_not_nil js
559       assert_equal "Feature", js["type"]
560       assert_equal closed_note_with_comment.id, js["properties"]["id"]
561       assert_equal "open", js["properties"]["status"]
562       assert_equal 3, js["properties"]["comments"].count
563       assert_equal "reopened", js["properties"]["comments"].last["action"]
564       assert_equal "This is a reopen comment", js["properties"]["comments"].last["text"]
565       assert_equal user.display_name, js["properties"]["comments"].last["user"]
566
567       subscription = NoteSubscription.last
568       assert_equal user, subscription.user
569       assert_equal closed_note_with_comment, subscription.note
570
571       get api_note_path(closed_note_with_comment, :format => "json")
572       assert_response :success
573       js = ActiveSupport::JSON.decode(@response.body)
574       assert_not_nil js
575       assert_equal "Feature", js["type"]
576       assert_equal closed_note_with_comment.id, js["properties"]["id"]
577       assert_equal "open", js["properties"]["status"]
578       assert_equal 3, js["properties"]["comments"].count
579       assert_equal "reopened", js["properties"]["comments"].last["action"]
580       assert_equal "This is a reopen comment", js["properties"]["comments"].last["text"]
581       assert_equal user.display_name, js["properties"]["comments"].last["user"]
582     end
583
584     def test_reopen_fail
585       hidden_note_with_comment = create(:note_with_comments, :status => "hidden")
586
587       post reopen_api_note_path(hidden_note_with_comment)
588       assert_response :unauthorized
589
590       auth_header = bearer_authorization_header
591
592       post reopen_api_note_path(12345), :headers => auth_header
593       assert_response :not_found
594
595       post reopen_api_note_path(hidden_note_with_comment), :headers => auth_header
596       assert_response :gone
597
598       open_note_with_comment = create(:note_with_comments)
599
600       post reopen_api_note_path(open_note_with_comment), :headers => auth_header
601       assert_response :conflict
602     end
603
604     def test_show_success
605       open_note = create(:note_with_comments)
606
607       get api_note_path(open_note, :format => "xml")
608       assert_response :success
609       assert_equal "application/xml", @response.media_type
610       assert_select "osm", :count => 1 do
611         assert_select "note[lat='#{open_note.lat}'][lon='#{open_note.lon}']", :count => 1 do
612           assert_select "id", open_note.id.to_s
613           assert_select "url", api_note_url(open_note, :format => "xml")
614           assert_select "comment_url", comment_api_note_url(open_note, :format => "xml")
615           assert_select "close_url", close_api_note_url(open_note, :format => "xml")
616           assert_select "date_created", open_note.created_at.to_s
617           assert_select "status", open_note.status
618           assert_select "comments", :count => 1 do
619             assert_select "comment", :count => 1
620           end
621         end
622       end
623
624       get api_note_path(open_note, :format => "rss")
625       assert_response :success
626       assert_equal "application/rss+xml", @response.media_type
627       assert_select "rss", :count => 1 do
628         assert_select "channel", :count => 1 do
629           assert_select "item", :count => 1 do
630             assert_select "link", note_url(open_note)
631             assert_select "guid", api_note_url(open_note)
632             assert_select "pubDate", open_note.created_at.to_fs(:rfc822)
633             assert_select "geo|lat", open_note.lat.to_s
634             assert_select "geo|long", open_note.lon.to_s
635             assert_select "georss|point", "#{open_note.lon} #{open_note.lon}"
636           end
637         end
638       end
639
640       get api_note_path(open_note, :format => "json")
641       assert_response :success
642       assert_equal "application/json", @response.media_type
643       js = ActiveSupport::JSON.decode(@response.body)
644       assert_not_nil js
645       assert_equal "Feature", js["type"]
646       assert_equal "Point", js["geometry"]["type"]
647       assert_equal open_note.lat, js["geometry"]["coordinates"][0]
648       assert_equal open_note.lon, js["geometry"]["coordinates"][1]
649       assert_equal open_note.id, js["properties"]["id"]
650       assert_equal api_note_url(open_note, :format => "json"), js["properties"]["url"]
651       assert_equal comment_api_note_url(open_note, :format => "json"), js["properties"]["comment_url"]
652       assert_equal close_api_note_url(open_note, :format => "json"), js["properties"]["close_url"]
653       assert_equal open_note.created_at.to_s, js["properties"]["date_created"]
654       assert_equal open_note.status, js["properties"]["status"]
655
656       get api_note_path(open_note, :format => "gpx")
657       assert_response :success
658       assert_equal "application/gpx+xml", @response.media_type
659       assert_select "gpx", :count => 1 do
660         assert_select "wpt[lat='#{open_note.lat}'][lon='#{open_note.lon}']", :count => 1 do
661           assert_select "time", :count => 1
662           assert_select "name", "Note: #{open_note.id}"
663           assert_select "desc", :count => 1
664           assert_select "link[href='http://www.example.com/note/#{open_note.id}']", :count => 1
665           assert_select "extensions", :count => 1 do
666             assert_select "id", open_note.id.to_s
667             assert_select "url", api_note_url(open_note, :format => "gpx")
668             assert_select "comment_url", comment_api_note_url(open_note, :format => "gpx")
669             assert_select "close_url", close_api_note_url(open_note, :format => "gpx")
670           end
671         end
672       end
673     end
674
675     def test_show_hidden_comment
676       note_with_hidden_comment = create(:note) do |note|
677         create(:note_comment, :note => note, :body => "Valid comment for hidden note")
678         create(:note_comment, :note => note, :visible => false)
679         create(:note_comment, :note => note, :body => "Another valid comment for hidden note")
680       end
681
682       get api_note_path(note_with_hidden_comment, :format => "json")
683       assert_response :success
684       js = ActiveSupport::JSON.decode(@response.body)
685       assert_not_nil js
686       assert_equal "Feature", js["type"]
687       assert_equal note_with_hidden_comment.id, js["properties"]["id"]
688       assert_equal 2, js["properties"]["comments"].count
689       assert_equal "Valid comment for hidden note", js["properties"]["comments"][0]["text"]
690       assert_equal "Another valid comment for hidden note", js["properties"]["comments"][1]["text"]
691     end
692
693     def test_show_fail
694       get api_note_path(12345)
695       assert_response :not_found
696
697       get api_note_path(create(:note, :status => "hidden"))
698       assert_response :gone
699     end
700
701     def test_destroy_success
702       open_note_with_comment = create(:note_with_comments)
703       user = create(:user)
704       moderator_user = create(:moderator_user)
705
706       delete api_note_path(open_note_with_comment, :text => "This is a hide comment", :format => "json")
707       assert_response :unauthorized
708
709       auth_header = bearer_authorization_header user
710
711       delete api_note_path(open_note_with_comment, :text => "This is a hide comment", :format => "json"), :headers => auth_header
712       assert_response :forbidden
713
714       auth_header = bearer_authorization_header moderator_user
715
716       delete api_note_path(open_note_with_comment, :text => "This is a hide comment", :format => "json"), :headers => auth_header
717       assert_response :success
718       js = ActiveSupport::JSON.decode(@response.body)
719       assert_not_nil js
720       assert_equal "Feature", js["type"]
721       assert_equal open_note_with_comment.id, js["properties"]["id"]
722       assert_equal "hidden", js["properties"]["status"]
723       assert_equal 2, js["properties"]["comments"].count
724       assert_equal "hidden", js["properties"]["comments"].last["action"]
725       assert_equal "This is a hide comment", js["properties"]["comments"].last["text"]
726       assert_equal moderator_user.display_name, js["properties"]["comments"].last["user"]
727
728       get api_note_path(open_note_with_comment, :format => "json"), :headers => auth_header
729       assert_response :success
730
731       auth_header = bearer_authorization_header user
732
733       get api_note_path(open_note_with_comment, :format => "json"), :headers => auth_header
734       assert_response :gone
735     end
736
737     def test_destroy_fail
738       user = create(:user)
739       moderator_user = create(:moderator_user)
740
741       delete api_note_path(12345, :format => "json")
742       assert_response :unauthorized
743
744       auth_header = bearer_authorization_header user
745
746       delete api_note_path(12345, :format => "json"), :headers => auth_header
747       assert_response :forbidden
748
749       auth_header = bearer_authorization_header moderator_user
750
751       delete api_note_path(12345, :format => "json"), :headers => auth_header
752       assert_response :not_found
753
754       hidden_note_with_comment = create(:note_with_comments, :status => "hidden")
755
756       delete api_note_path(hidden_note_with_comment, :format => "json"), :headers => auth_header
757       assert_response :gone
758     end
759
760     def test_index_success
761       position = (1.1 * GeoRecord::SCALE).to_i
762       create(:note_with_comments, :latitude => position, :longitude => position)
763       create(:note_with_comments, :latitude => position, :longitude => position)
764
765       get api_notes_path(:bbox => "1,1,1.2,1.2", :format => "rss")
766       assert_response :success
767       assert_equal "application/rss+xml", @response.media_type
768       assert_select "rss", :count => 1 do
769         assert_select "channel", :count => 1 do
770           assert_select "description", :text => /1\.2/, :count => 1
771           assert_select "item", :count => 2
772         end
773       end
774
775       get api_notes_path(:bbox => "1,1,1.2,1.2", :format => "json")
776       assert_response :success
777       assert_equal "application/json", @response.media_type
778       js = ActiveSupport::JSON.decode(@response.body)
779       assert_not_nil js
780       assert_equal "FeatureCollection", js["type"]
781       assert_equal 2, js["features"].count
782
783       get api_notes_path(:bbox => "1,1,1.2,1.2", :format => "xml")
784       assert_response :success
785       assert_equal "application/xml", @response.media_type
786       assert_select "osm", :count => 1 do
787         assert_select "note", :count => 2
788       end
789
790       get api_notes_path(:bbox => "1,1,1.2,1.2", :format => "gpx")
791       assert_response :success
792       assert_equal "application/gpx+xml", @response.media_type
793       assert_select "gpx", :count => 1 do
794         assert_select "wpt", :count => 2
795       end
796     end
797
798     def test_index_limit
799       position = (1.1 * GeoRecord::SCALE).to_i
800       create(:note_with_comments, :latitude => position, :longitude => position)
801       create(:note_with_comments, :latitude => position, :longitude => position)
802
803       get api_notes_path(:bbox => "1,1,1.2,1.2", :limit => 1, :format => "rss")
804       assert_response :success
805       assert_equal "application/rss+xml", @response.media_type
806       assert_select "rss", :count => 1 do
807         assert_select "channel", :count => 1 do
808           assert_select "item", :count => 1
809         end
810       end
811
812       get api_notes_path(:bbox => "1,1,1.2,1.2", :limit => 1, :format => "json")
813       assert_response :success
814       assert_equal "application/json", @response.media_type
815       js = ActiveSupport::JSON.decode(@response.body)
816       assert_not_nil js
817       assert_equal "FeatureCollection", js["type"]
818       assert_equal 1, js["features"].count
819
820       get api_notes_path(:bbox => "1,1,1.2,1.2", :limit => 1, :format => "xml")
821       assert_response :success
822       assert_equal "application/xml", @response.media_type
823       assert_select "osm", :count => 1 do
824         assert_select "note", :count => 1
825       end
826
827       get api_notes_path(:bbox => "1,1,1.2,1.2", :limit => 1, :format => "gpx")
828       assert_response :success
829       assert_equal "application/gpx+xml", @response.media_type
830       assert_select "gpx", :count => 1 do
831         assert_select "wpt", :count => 1
832       end
833
834       get api_notes_path(:bbox => "1,1,1.2,1.2", :limit => Settings.max_note_query_limit, :format => "rss")
835       assert_response :success
836     end
837
838     def test_index_empty_area
839       get api_notes_path(:bbox => "5,5,5.1,5.1", :format => "rss")
840       assert_response :success
841       assert_equal "application/rss+xml", @response.media_type
842       assert_select "rss", :count => 1 do
843         assert_select "channel", :count => 1 do
844           assert_select "item", :count => 0
845         end
846       end
847
848       get api_notes_path(:bbox => "5,5,5.1,5.1", :format => "json")
849       assert_response :success
850       assert_equal "application/json", @response.media_type
851       js = ActiveSupport::JSON.decode(@response.body)
852       assert_not_nil js
853       assert_equal "FeatureCollection", js["type"]
854       assert_equal 0, js["features"].count
855
856       get api_notes_path(:bbox => "5,5,5.1,5.1", :format => "xml")
857       assert_response :success
858       assert_equal "application/xml", @response.media_type
859       assert_select "osm", :count => 1 do
860         assert_select "note", :count => 0
861       end
862
863       get api_notes_path(:bbox => "5,5,5.1,5.1", :format => "gpx")
864       assert_response :success
865       assert_equal "application/gpx+xml", @response.media_type
866       assert_select "gpx", :count => 1 do
867         assert_select "wpt", :count => 0
868       end
869     end
870
871     def test_index_large_area
872       get api_notes_path(:bbox => "-2.5,-2.5,2.5,2.5", :format => :json)
873       assert_response :success
874       assert_equal "application/json", @response.media_type
875
876       get api_notes_path(:l => "-2.5", :b => "-2.5", :r => "2.5", :t => "2.5", :format => :json)
877       assert_response :success
878       assert_equal "application/json", @response.media_type
879
880       get api_notes_path(:bbox => "-10,-10,12,12", :format => :json)
881       assert_response :bad_request
882       assert_equal "text/plain", @response.media_type
883
884       get api_notes_path(:l => "-10", :b => "-10", :r => "12", :t => "12", :format => :json)
885       assert_response :bad_request
886       assert_equal "text/plain", @response.media_type
887     end
888
889     def test_index_closed
890       create(:note_with_comments, :closed, :closed_at => Time.now.utc - 5.days)
891       create(:note_with_comments, :closed, :closed_at => Time.now.utc - 100.days)
892       create(:note_with_comments, :status => "hidden")
893       create(:note_with_comments)
894
895       # Open notes + closed in last 7 days
896       get api_notes_path(:bbox => "1,1,1.7,1.7", :closed => "7", :format => "json")
897       assert_response :success
898       assert_equal "application/json", @response.media_type
899       js = ActiveSupport::JSON.decode(@response.body)
900       assert_not_nil js
901       assert_equal "FeatureCollection", js["type"]
902       assert_equal 2, js["features"].count
903
904       # Only open notes
905       get api_notes_path(:bbox => "1,1,1.7,1.7", :closed => "0", :format => "json")
906       assert_response :success
907       assert_equal "application/json", @response.media_type
908       js = ActiveSupport::JSON.decode(@response.body)
909       assert_not_nil js
910       assert_equal "FeatureCollection", js["type"]
911       assert_equal 1, js["features"].count
912
913       # Open notes + all closed notes
914       get api_notes_path(:bbox => "1,1,1.7,1.7", :closed => "-1", :format => "json")
915       assert_response :success
916       assert_equal "application/json", @response.media_type
917       js = ActiveSupport::JSON.decode(@response.body)
918       assert_not_nil js
919       assert_equal "FeatureCollection", js["type"]
920       assert_equal 3, js["features"].count
921     end
922
923     def test_index_bad_params
924       get api_notes_path
925       assert_response :bad_request
926       assert_equal "The parameter bbox is required", @response.body
927
928       get api_notes_path(:bbox => "-2.5,-2.5,2.5")
929       assert_response :bad_request
930
931       get api_notes_path(:bbox => "-2.5,-2.5,2.5,2.5,2.5")
932       assert_response :bad_request
933
934       get api_notes_path(:b => "-2.5", :r => "2.5", :t => "2.5")
935       assert_response :bad_request
936
937       get api_notes_path(:l => "-2.5", :r => "2.5", :t => "2.5")
938       assert_response :bad_request
939
940       get api_notes_path(:l => "-2.5", :b => "-2.5", :t => "2.5")
941       assert_response :bad_request
942
943       get api_notes_path(:l => "-2.5", :b => "-2.5", :r => "2.5")
944       assert_response :bad_request
945
946       get api_notes_path(:bbox => "1,1,1.7,1.7", :limit => "0", :format => "json")
947       assert_response :bad_request
948
949       get api_notes_path(:bbox => "1,1,1.7,1.7", :limit => Settings.max_note_query_limit + 1, :format => "json")
950       assert_response :bad_request
951     end
952
953     def test_search_success
954       create(:note_with_comments)
955
956       get search_api_notes_path(:q => "note comment", :format => "xml")
957       assert_response :success
958       assert_equal "application/xml", @response.media_type
959       assert_select "osm", :count => 1 do
960         assert_select "note", :count => 1
961       end
962
963       get search_api_notes_path(:q => "note comment", :format => "json")
964       assert_response :success
965       assert_equal "application/json", @response.media_type
966       js = ActiveSupport::JSON.decode(@response.body)
967       assert_not_nil js
968       assert_equal "FeatureCollection", js["type"]
969       assert_equal 1, js["features"].count
970
971       get search_api_notes_path(:q => "note comment", :format => "rss")
972       assert_response :success
973       assert_equal "application/rss+xml", @response.media_type
974       assert_select "rss", :count => 1 do
975         assert_select "channel", :count => 1 do
976           assert_select "item", :count => 1
977         end
978       end
979
980       get search_api_notes_path(:q => "note comment", :format => "gpx")
981       assert_response :success
982       assert_equal "application/gpx+xml", @response.media_type
983       assert_select "gpx", :count => 1 do
984         assert_select "wpt", :count => 1
985       end
986
987       get search_api_notes_path(:q => "note comment", :limit => Settings.max_note_query_limit, :format => "xml")
988       assert_response :success
989     end
990
991     def test_search_by_display_name_success
992       user = create(:user)
993
994       create(:note) do |note|
995         create(:note_comment, :note => note, :author => user)
996       end
997
998       get search_api_notes_path(:display_name => user.display_name, :format => "xml")
999       assert_response :success
1000       assert_equal "application/xml", @response.media_type
1001       assert_select "osm", :count => 1 do
1002         assert_select "note", :count => 1
1003       end
1004
1005       get search_api_notes_path(:display_name => user.display_name, :format => "json")
1006       assert_response :success
1007       assert_equal "application/json", @response.media_type
1008       js = ActiveSupport::JSON.decode(@response.body)
1009       assert_not_nil js
1010       assert_equal "FeatureCollection", js["type"]
1011       assert_equal 1, js["features"].count
1012
1013       get search_api_notes_path(:display_name => user.display_name, :format => "rss")
1014       assert_response :success
1015       assert_equal "application/rss+xml", @response.media_type
1016       assert_select "rss", :count => 1 do
1017         assert_select "channel", :count => 1 do
1018           assert_select "item", :count => 1
1019         end
1020       end
1021
1022       get search_api_notes_path(:display_name => user.display_name, :format => "gpx")
1023       assert_response :success
1024       assert_equal "application/gpx+xml", @response.media_type
1025       assert_select "gpx", :count => 1 do
1026         assert_select "wpt", :count => 1
1027       end
1028     end
1029
1030     def test_search_by_user_success
1031       user = create(:user)
1032
1033       create(:note) do |note|
1034         create(:note_comment, :note => note, :author => user)
1035       end
1036
1037       get search_api_notes_path(:user => user.id, :format => "xml")
1038       assert_response :success
1039       assert_equal "application/xml", @response.media_type
1040       assert_select "osm", :count => 1 do
1041         assert_select "note", :count => 1
1042       end
1043
1044       get search_api_notes_path(:user => user.id, :format => "json")
1045       assert_response :success
1046       assert_equal "application/json", @response.media_type
1047       js = ActiveSupport::JSON.decode(@response.body)
1048       assert_not_nil js
1049       assert_equal "FeatureCollection", js["type"]
1050       assert_equal 1, js["features"].count
1051
1052       get search_api_notes_path(:user => user.id, :format => "rss")
1053       assert_response :success
1054       assert_equal "application/rss+xml", @response.media_type
1055       assert_select "rss", :count => 1 do
1056         assert_select "channel", :count => 1 do
1057           assert_select "item", :count => 1
1058         end
1059       end
1060
1061       get search_api_notes_path(:user => user.id, :format => "gpx")
1062       assert_response :success
1063       assert_equal "application/gpx+xml", @response.media_type
1064       assert_select "gpx", :count => 1 do
1065         assert_select "wpt", :count => 1
1066       end
1067
1068       user2 = create(:user)
1069       get search_api_notes_path(:user => user2.id, :format => "xml")
1070       assert_response :success
1071       assert_equal "application/xml", @response.media_type
1072       assert_select "osm", :count => 1 do
1073         assert_select "note", :count => 0
1074       end
1075     end
1076
1077     def test_search_by_time_success
1078       note1 = create(:note, :created_at => "2020-02-01T00:00:00Z", :updated_at => "2020-04-01T00:00:00Z")
1079       note2 = create(:note, :created_at => "2020-03-01T00:00:00Z", :updated_at => "2020-05-01T00:00:00Z")
1080
1081       get search_api_notes_path(:from => "2020-02-15T00:00:00Z", :to => "2020-04-15T00:00:00Z", :format => "xml")
1082       assert_response :success
1083       assert_equal "application/xml", @response.media_type
1084       assert_select "osm", :count => 1 do
1085         assert_select "note", :count => 1 do
1086           assert_select "id", note2.id.to_s
1087         end
1088       end
1089
1090       get search_api_notes_path(:from => "2020-02-15T00:00:00Z", :to => "2020-04-15T00:00:00Z", :sort => "updated_at", :format => "xml")
1091       assert_response :success
1092       assert_equal "application/xml", @response.media_type
1093       assert_select "osm", :count => 1 do
1094         assert_select "note", :count => 1 do
1095           assert_select "id", note1.id.to_s
1096         end
1097       end
1098     end
1099
1100     def test_search_by_bbox_success
1101       notes = Array.new(5) do |i|
1102         position = ((1.0 + (i * 0.1)) * GeoRecord::SCALE).to_i
1103         create(:note_with_comments, :created_at => Time.parse("2020-01-01T00:00:00Z") + i.day, :latitude => position, :longitude => position)
1104       end
1105
1106       get search_api_notes_path(:bbox => "1.0,1.0,1.6,1.6", :sort => "created_at", :order => "oldest", :format => "xml")
1107       assert_response :success
1108       assert_equal "application/xml", @response.media_type
1109       assert_notes_in_order notes
1110
1111       get search_api_notes_path(:bbox => "1.25,1.25,1.45,1.45", :sort => "created_at", :order => "oldest", :format => "xml")
1112       assert_response :success
1113       assert_equal "application/xml", @response.media_type
1114       assert_notes_in_order [notes[3], notes[4]]
1115
1116       get search_api_notes_path(:bbox => "2.0,2.0,2.5,2.5", :sort => "created_at", :order => "oldest", :format => "xml")
1117       assert_response :success
1118       assert_equal "application/xml", @response.media_type
1119       assert_notes_in_order []
1120     end
1121
1122     def test_search_no_match
1123       create(:note_with_comments)
1124
1125       get search_api_notes_path(:q => "no match", :format => "xml")
1126       assert_response :success
1127       assert_equal "application/xml", @response.media_type
1128       assert_select "osm", :count => 1 do
1129         assert_select "note", :count => 0
1130       end
1131
1132       get search_api_notes_path(:q => "no match", :format => "json")
1133       assert_response :success
1134       assert_equal "application/json", @response.media_type
1135       js = ActiveSupport::JSON.decode(@response.body)
1136       assert_not_nil js
1137       assert_equal "FeatureCollection", js["type"]
1138       assert_equal 0, js["features"].count
1139
1140       get search_api_notes_path(:q => "no match", :format => "rss")
1141       assert_response :success
1142       assert_equal "application/rss+xml", @response.media_type
1143       assert_select "rss", :count => 1 do
1144         assert_select "channel", :count => 1 do
1145           assert_select "item", :count => 0
1146         end
1147       end
1148
1149       get search_api_notes_path(:q => "no match", :format => "gpx")
1150       assert_response :success
1151       assert_equal "application/gpx+xml", @response.media_type
1152       assert_select "gpx", :count => 1 do
1153         assert_select "wpt", :count => 0
1154       end
1155     end
1156
1157     def test_search_by_time_no_match
1158       create(:note_with_comments)
1159
1160       get search_api_notes_path(:from => "01.01.2010", :to => "01.10.2010", :format => "xml")
1161       assert_response :success
1162       assert_equal "application/xml", @response.media_type
1163       assert_select "osm", :count => 1 do
1164         assert_select "note", :count => 0
1165       end
1166
1167       get search_api_notes_path(:from => "01.01.2010", :to => "01.10.2010", :format => "json")
1168       assert_response :success
1169       assert_equal "application/json", @response.media_type
1170       js = ActiveSupport::JSON.decode(@response.body)
1171       assert_not_nil js
1172       assert_equal "FeatureCollection", js["type"]
1173       assert_equal 0, js["features"].count
1174
1175       get search_api_notes_path(:from => "01.01.2010", :to => "01.10.2010", :format => "rss")
1176       assert_response :success
1177       assert_equal "application/rss+xml", @response.media_type
1178       assert_select "rss", :count => 1 do
1179         assert_select "channel", :count => 1 do
1180           assert_select "item", :count => 0
1181         end
1182       end
1183
1184       get search_api_notes_path(:from => "01.01.2010", :to => "01.10.2010", :format => "gpx")
1185       assert_response :success
1186       assert_equal "application/gpx+xml", @response.media_type
1187       assert_select "gpx", :count => 1 do
1188         assert_select "wpt", :count => 0
1189       end
1190     end
1191
1192     def test_search_bad_params
1193       get search_api_notes_path(:q => "no match", :limit => "0", :format => "json")
1194       assert_response :bad_request
1195
1196       get search_api_notes_path(:q => "no match", :limit => Settings.max_note_query_limit + 1, :format => "json")
1197       assert_response :bad_request
1198
1199       get search_api_notes_path(:display_name => "non-existent")
1200       assert_response :bad_request
1201
1202       get search_api_notes_path(:user => "-1")
1203       assert_response :bad_request
1204
1205       get search_api_notes_path(:from => "wrong-date", :to => "wrong-date")
1206       assert_response :bad_request
1207
1208       get search_api_notes_path(:from => "01.01.2010", :to => "2010.01.2010")
1209       assert_response :bad_request
1210     end
1211
1212     def test_feed_success
1213       position = (1.1 * GeoRecord::SCALE).to_i
1214       create(:note_with_comments, :latitude => position, :longitude => position)
1215       create(:note_with_comments, :latitude => position, :longitude => position)
1216       position = (1.5 * GeoRecord::SCALE).to_i
1217       create(:note_with_comments, :latitude => position, :longitude => position)
1218       create(:note_with_comments, :latitude => position, :longitude => position)
1219
1220       get feed_api_notes_path(:format => "rss")
1221       assert_response :success
1222       assert_equal "application/rss+xml", @response.media_type
1223       assert_select "rss", :count => 1 do
1224         assert_select "channel", :count => 1 do
1225           assert_select "item", :count => 4
1226         end
1227       end
1228
1229       get feed_api_notes_path(:bbox => "1,1,1.2,1.2", :format => "rss")
1230       assert_response :success
1231       assert_equal "application/rss+xml", @response.media_type
1232       assert_select "rss", :count => 1 do
1233         assert_select "channel", :count => 1 do
1234           assert_select "description", :text => /1\.2/, :count => 1
1235           assert_select "item", :count => 2
1236         end
1237       end
1238
1239       get feed_api_notes_path(:bbox => "1,1,1.2,1.2", :limit => Settings.max_note_query_limit, :format => "rss")
1240       assert_response :success
1241     end
1242
1243     def test_feed_fail
1244       get feed_api_notes_path(:bbox => "1,1,1.2", :format => "rss")
1245       assert_response :bad_request
1246
1247       get feed_api_notes_path(:bbox => "1,1,1.2,1.2,1.2", :format => "rss")
1248       assert_response :bad_request
1249
1250       get feed_api_notes_path(:bbox => "1,1,1.2,1.2", :limit => "0", :format => "rss")
1251       assert_response :bad_request
1252
1253       get feed_api_notes_path(:bbox => "1,1,1.2,1.2", :limit => Settings.max_note_query_limit + 1, :format => "rss")
1254       assert_response :bad_request
1255     end
1256
1257     private
1258
1259     def assert_notes_in_order(notes)
1260       assert_select "osm>note", notes.size
1261       notes.each_with_index do |note, index|
1262         assert_select "osm>note:nth-child(#{index + 1})>id", :text => note.id.to_s, :count => 1
1263       end
1264     end
1265   end
1266 end