]> git.openstreetmap.org Git - rails.git/blob - test/controllers/api/notes_controller_test.rb
Rename api_notes resource to avoid conflict with non-API 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
103       assert_recognizes(
104         { :controller => "api/notes", :action => "create" },
105         { :path => "/api/0.6/notes/addPOIexec", :method => :post }
106       )
107       assert_recognizes(
108         { :controller => "api/notes", :action => "close" },
109         { :path => "/api/0.6/notes/closePOIexec", :method => :post }
110       )
111       assert_recognizes(
112         { :controller => "api/notes", :action => "comment" },
113         { :path => "/api/0.6/notes/editPOIexec", :method => :post }
114       )
115       assert_recognizes(
116         { :controller => "api/notes", :action => "index", :format => "gpx" },
117         { :path => "/api/0.6/notes/getGPX", :method => :get }
118       )
119       assert_recognizes(
120         { :controller => "api/notes", :action => "feed", :format => "rss" },
121         { :path => "/api/0.6/notes/getRSSfeed", :method => :get }
122       )
123     end
124
125     def test_create_success
126       assert_difference "Note.count", 1 do
127         assert_difference "NoteComment.count", 1 do
128           post api_notes_path(:lat => -1.0, :lon => -1.0, :text => "This is a comment", :format => "json")
129         end
130       end
131       assert_response :success
132       js = ActiveSupport::JSON.decode(@response.body)
133       assert_not_nil js
134       assert_equal "Feature", js["type"]
135       assert_equal "Point", js["geometry"]["type"]
136       assert_equal [-1.0, -1.0], js["geometry"]["coordinates"]
137       assert_equal "open", js["properties"]["status"]
138       assert_equal 1, js["properties"]["comments"].count
139       assert_equal "opened", js["properties"]["comments"].last["action"]
140       assert_equal "This is a comment", js["properties"]["comments"].last["text"]
141       assert_nil js["properties"]["comments"].last["user"]
142       id = js["properties"]["id"]
143
144       get api_note_path(:id => id, :format => "json")
145       assert_response :success
146       js = ActiveSupport::JSON.decode(@response.body)
147       assert_not_nil js
148       assert_equal "Feature", js["type"]
149       assert_equal "Point", js["geometry"]["type"]
150       assert_equal [-1.0, -1.0], js["geometry"]["coordinates"]
151       assert_equal id, js["properties"]["id"]
152       assert_equal "open", js["properties"]["status"]
153       assert_equal 1, js["properties"]["comments"].count
154       assert_equal "opened", js["properties"]["comments"].last["action"]
155       assert_equal "This is a comment", js["properties"]["comments"].last["text"]
156       assert_nil js["properties"]["comments"].last["user"]
157     end
158
159     def test_create_fail
160       assert_no_difference "Note.count" do
161         assert_no_difference "NoteComment.count" do
162           post api_notes_path(:lon => -1.0, :text => "This is a comment")
163         end
164       end
165       assert_response :bad_request
166
167       assert_no_difference "Note.count" do
168         assert_no_difference "NoteComment.count" do
169           post api_notes_path(:lat => -1.0, :text => "This is a comment")
170         end
171       end
172       assert_response :bad_request
173
174       assert_no_difference "Note.count" do
175         assert_no_difference "NoteComment.count" do
176           post api_notes_path(:lat => -1.0, :lon => -1.0)
177         end
178       end
179       assert_response :bad_request
180
181       assert_no_difference "Note.count" do
182         assert_no_difference "NoteComment.count" do
183           post api_notes_path(:lat => -1.0, :lon => -1.0, :text => "")
184         end
185       end
186       assert_response :bad_request
187
188       assert_no_difference "Note.count" do
189         assert_no_difference "NoteComment.count" do
190           post api_notes_path(:lat => -100.0, :lon => -1.0, :text => "This is a comment")
191         end
192       end
193       assert_response :bad_request
194
195       assert_no_difference "Note.count" do
196         assert_no_difference "NoteComment.count" do
197           post api_notes_path(:lat => -1.0, :lon => -200.0, :text => "This is a comment")
198         end
199       end
200       assert_response :bad_request
201
202       assert_no_difference "Note.count" do
203         assert_no_difference "NoteComment.count" do
204           post api_notes_path(:lat => "abc", :lon => -1.0, :text => "This is a comment")
205         end
206       end
207       assert_response :bad_request
208
209       assert_no_difference "Note.count" do
210         assert_no_difference "NoteComment.count" do
211           post api_notes_path(:lat => -1.0, :lon => "abc", :text => "This is a comment")
212         end
213       end
214       assert_response :bad_request
215
216       assert_no_difference "Note.count" do
217         assert_no_difference "NoteComment.count" do
218           post api_notes_path(:lat => -1.0, :lon => -1.0, :text => "x\u0000y")
219         end
220       end
221       assert_response :bad_request
222     end
223
224     def test_comment_success
225       open_note_with_comment = create(:note_with_comments)
226       user = create(:user)
227       auth_header = basic_authorization_header user.email, "test"
228       assert_difference "NoteComment.count", 1 do
229         assert_no_difference "ActionMailer::Base.deliveries.size" do
230           perform_enqueued_jobs do
231             post comment_api_note_path(:id => open_note_with_comment, :text => "This is an additional comment", :format => "json"), :headers => auth_header
232           end
233         end
234       end
235       assert_response :success
236       js = ActiveSupport::JSON.decode(@response.body)
237       assert_not_nil js
238       assert_equal "Feature", js["type"]
239       assert_equal open_note_with_comment.id, js["properties"]["id"]
240       assert_equal "open", js["properties"]["status"]
241       assert_equal 2, js["properties"]["comments"].count
242       assert_equal "commented", js["properties"]["comments"].last["action"]
243       assert_equal "This is an additional comment", js["properties"]["comments"].last["text"]
244       assert_equal user.display_name, js["properties"]["comments"].last["user"]
245
246       get api_note_path(:id => open_note_with_comment, :format => "json")
247       assert_response :success
248       js = ActiveSupport::JSON.decode(@response.body)
249       assert_not_nil js
250       assert_equal "Feature", js["type"]
251       assert_equal open_note_with_comment.id, js["properties"]["id"]
252       assert_equal "open", js["properties"]["status"]
253       assert_equal 2, js["properties"]["comments"].count
254       assert_equal "commented", js["properties"]["comments"].last["action"]
255       assert_equal "This is an additional comment", js["properties"]["comments"].last["text"]
256       assert_equal user.display_name, js["properties"]["comments"].last["user"]
257
258       # Ensure that emails are sent to users
259       first_user = create(:user)
260       second_user = create(:user)
261       third_user = create(:user)
262
263       note_with_comments_by_users = create(:note) do |note|
264         create(:note_comment, :note => note, :author => first_user)
265         create(:note_comment, :note => note, :author => second_user)
266       end
267
268       auth_header = basic_authorization_header third_user.email, "test"
269
270       assert_difference "NoteComment.count", 1 do
271         assert_difference "ActionMailer::Base.deliveries.size", 2 do
272           perform_enqueued_jobs do
273             post comment_api_note_path(:id => note_with_comments_by_users, :text => "This is an additional comment", :format => "json"), :headers => auth_header
274           end
275         end
276       end
277       assert_response :success
278       js = ActiveSupport::JSON.decode(@response.body)
279       assert_not_nil js
280       assert_equal "Feature", js["type"]
281       assert_equal note_with_comments_by_users.id, js["properties"]["id"]
282       assert_equal "open", js["properties"]["status"]
283       assert_equal 3, js["properties"]["comments"].count
284       assert_equal "commented", js["properties"]["comments"].last["action"]
285       assert_equal "This is an additional comment", js["properties"]["comments"].last["text"]
286       assert_equal third_user.display_name, js["properties"]["comments"].last["user"]
287
288       email = ActionMailer::Base.deliveries.find { |e| e.to.first == first_user.email }
289       assert_not_nil email
290       assert_equal 1, email.to.length
291       assert_equal "[OpenStreetMap] #{third_user.display_name} has commented on one of your notes", email.subject
292       assert_equal first_user.email, email.to.first
293
294       email = ActionMailer::Base.deliveries.find { |e| e.to.first == second_user.email }
295       assert_not_nil email
296       assert_equal 1, email.to.length
297       assert_equal "[OpenStreetMap] #{third_user.display_name} has commented on a note you are interested in", email.subject
298
299       get api_note_path(:id => note_with_comments_by_users, :format => "json")
300       assert_response :success
301       js = ActiveSupport::JSON.decode(@response.body)
302       assert_not_nil js
303       assert_equal "Feature", js["type"]
304       assert_equal note_with_comments_by_users.id, js["properties"]["id"]
305       assert_equal "open", js["properties"]["status"]
306       assert_equal 3, js["properties"]["comments"].count
307       assert_equal "commented", js["properties"]["comments"].last["action"]
308       assert_equal "This is an additional comment", js["properties"]["comments"].last["text"]
309       assert_equal third_user.display_name, js["properties"]["comments"].last["user"]
310
311       ActionMailer::Base.deliveries.clear
312     end
313
314     def test_comment_fail
315       open_note_with_comment = create(:note_with_comments)
316
317       user = create(:user)
318
319       assert_no_difference "NoteComment.count" do
320         post comment_api_note_path(:id => open_note_with_comment)
321         assert_response :unauthorized
322       end
323
324       auth_header = basic_authorization_header user.email, "test"
325
326       assert_no_difference "NoteComment.count" do
327         post comment_api_note_path(:id => open_note_with_comment), :headers => auth_header
328       end
329       assert_response :bad_request
330
331       assert_no_difference "NoteComment.count" do
332         post comment_api_note_path(:id => open_note_with_comment, :text => ""), :headers => auth_header
333       end
334       assert_response :bad_request
335
336       assert_no_difference "NoteComment.count" do
337         post comment_api_note_path(:id => 12345, :text => "This is an additional comment"), :headers => auth_header
338       end
339       assert_response :not_found
340
341       hidden_note_with_comment = create(:note_with_comments, :status => "hidden")
342
343       assert_no_difference "NoteComment.count" do
344         post comment_api_note_path(:id => hidden_note_with_comment, :text => "This is an additional comment"), :headers => auth_header
345       end
346       assert_response :gone
347
348       closed_note_with_comment = create(:note_with_comments, :status => "closed", :closed_at => Time.now.utc)
349
350       assert_no_difference "NoteComment.count" do
351         post comment_api_note_path(:id => closed_note_with_comment, :text => "This is an additional comment"), :headers => auth_header
352       end
353       assert_response :conflict
354
355       assert_no_difference "NoteComment.count" do
356         post comment_api_note_path(:id => open_note_with_comment, :text => "x\u0000y"), :headers => auth_header
357       end
358       assert_response :bad_request
359     end
360
361     def test_close_success
362       open_note_with_comment = create(:note_with_comments)
363       user = create(:user)
364
365       post close_api_note_path(:id => open_note_with_comment, :text => "This is a close comment", :format => "json")
366       assert_response :unauthorized
367
368       auth_header = basic_authorization_header user.email, "test"
369
370       post close_api_note_path(:id => open_note_with_comment, :text => "This is a close comment", :format => "json"), :headers => auth_header
371       assert_response :success
372       js = ActiveSupport::JSON.decode(@response.body)
373       assert_not_nil js
374       assert_equal "Feature", js["type"]
375       assert_equal open_note_with_comment.id, js["properties"]["id"]
376       assert_equal "closed", js["properties"]["status"]
377       assert_equal 2, js["properties"]["comments"].count
378       assert_equal "closed", js["properties"]["comments"].last["action"]
379       assert_equal "This is a close comment", js["properties"]["comments"].last["text"]
380       assert_equal user.display_name, js["properties"]["comments"].last["user"]
381
382       get api_note_path(:id => open_note_with_comment.id, :format => "json")
383       assert_response :success
384       js = ActiveSupport::JSON.decode(@response.body)
385       assert_not_nil js
386       assert_equal "Feature", js["type"]
387       assert_equal open_note_with_comment.id, js["properties"]["id"]
388       assert_equal "closed", js["properties"]["status"]
389       assert_equal 2, js["properties"]["comments"].count
390       assert_equal "closed", js["properties"]["comments"].last["action"]
391       assert_equal "This is a close comment", js["properties"]["comments"].last["text"]
392       assert_equal user.display_name, js["properties"]["comments"].last["user"]
393     end
394
395     def test_close_fail
396       post close_api_note_path(:id => 12345)
397       assert_response :unauthorized
398
399       auth_header = basic_authorization_header create(:user).email, "test"
400
401       post close_api_note_path(:id => 12345), :headers => auth_header
402       assert_response :not_found
403
404       hidden_note_with_comment = create(:note_with_comments, :status => "hidden")
405
406       post close_api_note_path(:id => hidden_note_with_comment), :headers => auth_header
407       assert_response :gone
408
409       closed_note_with_comment = create(:note_with_comments, :status => "closed", :closed_at => Time.now.utc)
410
411       post close_api_note_path(:id => closed_note_with_comment), :headers => auth_header
412       assert_response :conflict
413     end
414
415     def test_reopen_success
416       closed_note_with_comment = create(:note_with_comments, :status => "closed", :closed_at => Time.now.utc)
417       user = create(:user)
418
419       post reopen_api_note_path(:id => closed_note_with_comment, :text => "This is a reopen comment", :format => "json")
420       assert_response :unauthorized
421
422       auth_header = basic_authorization_header user.email, "test"
423
424       post reopen_api_note_path(:id => closed_note_with_comment, :text => "This is a reopen comment", :format => "json"), :headers => auth_header
425       assert_response :success
426       js = ActiveSupport::JSON.decode(@response.body)
427       assert_not_nil js
428       assert_equal "Feature", js["type"]
429       assert_equal closed_note_with_comment.id, js["properties"]["id"]
430       assert_equal "open", js["properties"]["status"]
431       assert_equal 2, js["properties"]["comments"].count
432       assert_equal "reopened", js["properties"]["comments"].last["action"]
433       assert_equal "This is a reopen comment", js["properties"]["comments"].last["text"]
434       assert_equal user.display_name, js["properties"]["comments"].last["user"]
435
436       get api_note_path(:id => closed_note_with_comment, :format => "json")
437       assert_response :success
438       js = ActiveSupport::JSON.decode(@response.body)
439       assert_not_nil js
440       assert_equal "Feature", js["type"]
441       assert_equal closed_note_with_comment.id, js["properties"]["id"]
442       assert_equal "open", js["properties"]["status"]
443       assert_equal 2, js["properties"]["comments"].count
444       assert_equal "reopened", js["properties"]["comments"].last["action"]
445       assert_equal "This is a reopen comment", js["properties"]["comments"].last["text"]
446       assert_equal user.display_name, js["properties"]["comments"].last["user"]
447     end
448
449     def test_reopen_fail
450       hidden_note_with_comment = create(:note_with_comments, :status => "hidden")
451
452       post reopen_api_note_path(:id => hidden_note_with_comment)
453       assert_response :unauthorized
454
455       auth_header = basic_authorization_header create(:user).email, "test"
456
457       post reopen_api_note_path(:id => 12345), :headers => auth_header
458       assert_response :not_found
459
460       post reopen_api_note_path(:id => hidden_note_with_comment), :headers => auth_header
461       assert_response :gone
462
463       open_note_with_comment = create(:note_with_comments)
464
465       post reopen_api_note_path(:id => open_note_with_comment), :headers => auth_header
466       assert_response :conflict
467     end
468
469     def test_show_success
470       open_note = create(:note_with_comments)
471
472       get api_note_path(:id => open_note, :format => "xml")
473       assert_response :success
474       assert_equal "application/xml", @response.media_type
475       assert_select "osm", :count => 1 do
476         assert_select "note[lat='#{open_note.lat}'][lon='#{open_note.lon}']", :count => 1 do
477           assert_select "id", open_note.id.to_s
478           assert_select "url", api_note_url(open_note, :format => "xml")
479           assert_select "comment_url", comment_api_note_url(open_note, :format => "xml")
480           assert_select "close_url", close_api_note_url(open_note, :format => "xml")
481           assert_select "date_created", open_note.created_at.to_s
482           assert_select "status", open_note.status
483           assert_select "comments", :count => 1 do
484             assert_select "comment", :count => 1
485           end
486         end
487       end
488
489       get api_note_path(:id => open_note, :format => "rss")
490       assert_response :success
491       assert_equal "application/rss+xml", @response.media_type
492       assert_select "rss", :count => 1 do
493         assert_select "channel", :count => 1 do
494           assert_select "item", :count => 1 do
495             assert_select "link", browse_note_url(open_note)
496             assert_select "guid", api_note_url(open_note)
497             assert_select "pubDate", open_note.created_at.to_fs(:rfc822)
498             assert_select "geo|lat", open_note.lat.to_s
499             assert_select "geo|long", open_note.lon.to_s
500             assert_select "georss|point", "#{open_note.lon} #{open_note.lon}"
501           end
502         end
503       end
504
505       get api_note_path(:id => open_note, :format => "json")
506       assert_response :success
507       assert_equal "application/json", @response.media_type
508       js = ActiveSupport::JSON.decode(@response.body)
509       assert_not_nil js
510       assert_equal "Feature", js["type"]
511       assert_equal "Point", js["geometry"]["type"]
512       assert_equal open_note.lat, js["geometry"]["coordinates"][0]
513       assert_equal open_note.lon, js["geometry"]["coordinates"][1]
514       assert_equal open_note.id, js["properties"]["id"]
515       assert_equal api_note_url(open_note, :format => "json"), js["properties"]["url"]
516       assert_equal comment_api_note_url(open_note, :format => "json"), js["properties"]["comment_url"]
517       assert_equal close_api_note_url(open_note, :format => "json"), js["properties"]["close_url"]
518       assert_equal open_note.created_at.to_s, js["properties"]["date_created"]
519       assert_equal open_note.status, js["properties"]["status"]
520
521       get api_note_path(:id => open_note, :format => "gpx")
522       assert_response :success
523       assert_equal "application/gpx+xml", @response.media_type
524       assert_select "gpx", :count => 1 do
525         assert_select "wpt[lat='#{open_note.lat}'][lon='#{open_note.lon}']", :count => 1 do
526           assert_select "time", :count => 1
527           assert_select "name", "Note: #{open_note.id}"
528           assert_select "desc", :count => 1
529           assert_select "link[href='http://www.example.com/note/#{open_note.id}']", :count => 1
530           assert_select "extensions", :count => 1 do
531             assert_select "id", open_note.id.to_s
532             assert_select "url", api_note_url(open_note, :format => "gpx")
533             assert_select "comment_url", comment_api_note_url(open_note, :format => "gpx")
534             assert_select "close_url", close_api_note_url(open_note, :format => "gpx")
535           end
536         end
537       end
538     end
539
540     def test_show_hidden_comment
541       note_with_hidden_comment = create(:note) do |note|
542         create(:note_comment, :note => note, :body => "Valid comment for hidden note")
543         create(:note_comment, :note => note, :visible => false)
544         create(:note_comment, :note => note, :body => "Another valid comment for hidden note")
545       end
546
547       get api_note_path(:id => note_with_hidden_comment, :format => "json")
548       assert_response :success
549       js = ActiveSupport::JSON.decode(@response.body)
550       assert_not_nil js
551       assert_equal "Feature", js["type"]
552       assert_equal note_with_hidden_comment.id, js["properties"]["id"]
553       assert_equal 2, js["properties"]["comments"].count
554       assert_equal "Valid comment for hidden note", js["properties"]["comments"][0]["text"]
555       assert_equal "Another valid comment for hidden note", js["properties"]["comments"][1]["text"]
556     end
557
558     def test_show_fail
559       get api_note_path(:id => 12345)
560       assert_response :not_found
561
562       get api_note_path(:id => create(:note, :status => "hidden"))
563       assert_response :gone
564     end
565
566     def test_destroy_success
567       open_note_with_comment = create(:note_with_comments)
568       user = create(:user)
569       moderator_user = create(:moderator_user)
570
571       delete api_note_path(:id => open_note_with_comment, :text => "This is a hide comment", :format => "json")
572       assert_response :unauthorized
573
574       auth_header = basic_authorization_header user.email, "test"
575
576       delete api_note_path(:id => open_note_with_comment, :text => "This is a hide comment", :format => "json"), :headers => auth_header
577       assert_response :forbidden
578
579       auth_header = basic_authorization_header moderator_user.email, "test"
580
581       delete api_note_path(:id => open_note_with_comment, :text => "This is a hide comment", :format => "json"), :headers => auth_header
582       assert_response :success
583       js = ActiveSupport::JSON.decode(@response.body)
584       assert_not_nil js
585       assert_equal "Feature", js["type"]
586       assert_equal open_note_with_comment.id, js["properties"]["id"]
587       assert_equal "hidden", js["properties"]["status"]
588       assert_equal 2, js["properties"]["comments"].count
589       assert_equal "hidden", js["properties"]["comments"].last["action"]
590       assert_equal "This is a hide comment", js["properties"]["comments"].last["text"]
591       assert_equal moderator_user.display_name, js["properties"]["comments"].last["user"]
592
593       get api_note_path(:id => open_note_with_comment, :format => "json"), :headers => auth_header
594       assert_response :success
595
596       auth_header = basic_authorization_header user.email, "test"
597
598       get api_note_path(:id => open_note_with_comment, :format => "json"), :headers => auth_header
599       assert_response :gone
600     end
601
602     def test_destroy_fail
603       user = create(:user)
604       moderator_user = create(:moderator_user)
605
606       delete api_note_path(:id => 12345, :format => "json")
607       assert_response :unauthorized
608
609       auth_header = basic_authorization_header user.email, "test"
610
611       delete api_note_path(:id => 12345, :format => "json"), :headers => auth_header
612       assert_response :forbidden
613
614       auth_header = basic_authorization_header moderator_user.email, "test"
615
616       delete api_note_path(:id => 12345, :format => "json"), :headers => auth_header
617       assert_response :not_found
618
619       hidden_note_with_comment = create(:note_with_comments, :status => "hidden")
620
621       delete api_note_path(:id => hidden_note_with_comment, :format => "json"), :headers => auth_header
622       assert_response :gone
623     end
624
625     def test_index_success
626       position = (1.1 * GeoRecord::SCALE).to_i
627       create(:note_with_comments, :latitude => position, :longitude => position)
628       create(:note_with_comments, :latitude => position, :longitude => position)
629
630       get api_notes_path(:bbox => "1,1,1.2,1.2", :format => "rss")
631       assert_response :success
632       assert_equal "application/rss+xml", @response.media_type
633       assert_select "rss", :count => 1 do
634         assert_select "channel", :count => 1 do
635           assert_select "description", :text => /1\.2/, :count => 1
636           assert_select "item", :count => 2
637         end
638       end
639
640       get api_notes_path(:bbox => "1,1,1.2,1.2", :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 "FeatureCollection", js["type"]
646       assert_equal 2, js["features"].count
647
648       get api_notes_path(:bbox => "1,1,1.2,1.2", :format => "xml")
649       assert_response :success
650       assert_equal "application/xml", @response.media_type
651       assert_select "osm", :count => 1 do
652         assert_select "note", :count => 2
653       end
654
655       get api_notes_path(:bbox => "1,1,1.2,1.2", :format => "gpx")
656       assert_response :success
657       assert_equal "application/gpx+xml", @response.media_type
658       assert_select "gpx", :count => 1 do
659         assert_select "wpt", :count => 2
660       end
661     end
662
663     def test_index_limit
664       position = (1.1 * GeoRecord::SCALE).to_i
665       create(:note_with_comments, :latitude => position, :longitude => position)
666       create(:note_with_comments, :latitude => position, :longitude => position)
667
668       get api_notes_path(:bbox => "1,1,1.2,1.2", :limit => 1, :format => "rss")
669       assert_response :success
670       assert_equal "application/rss+xml", @response.media_type
671       assert_select "rss", :count => 1 do
672         assert_select "channel", :count => 1 do
673           assert_select "item", :count => 1
674         end
675       end
676
677       get api_notes_path(:bbox => "1,1,1.2,1.2", :limit => 1, :format => "json")
678       assert_response :success
679       assert_equal "application/json", @response.media_type
680       js = ActiveSupport::JSON.decode(@response.body)
681       assert_not_nil js
682       assert_equal "FeatureCollection", js["type"]
683       assert_equal 1, js["features"].count
684
685       get api_notes_path(:bbox => "1,1,1.2,1.2", :limit => 1, :format => "xml")
686       assert_response :success
687       assert_equal "application/xml", @response.media_type
688       assert_select "osm", :count => 1 do
689         assert_select "note", :count => 1
690       end
691
692       get api_notes_path(:bbox => "1,1,1.2,1.2", :limit => 1, :format => "gpx")
693       assert_response :success
694       assert_equal "application/gpx+xml", @response.media_type
695       assert_select "gpx", :count => 1 do
696         assert_select "wpt", :count => 1
697       end
698     end
699
700     def test_index_empty_area
701       get api_notes_path(:bbox => "5,5,5.1,5.1", :format => "rss")
702       assert_response :success
703       assert_equal "application/rss+xml", @response.media_type
704       assert_select "rss", :count => 1 do
705         assert_select "channel", :count => 1 do
706           assert_select "item", :count => 0
707         end
708       end
709
710       get api_notes_path(:bbox => "5,5,5.1,5.1", :format => "json")
711       assert_response :success
712       assert_equal "application/json", @response.media_type
713       js = ActiveSupport::JSON.decode(@response.body)
714       assert_not_nil js
715       assert_equal "FeatureCollection", js["type"]
716       assert_equal 0, js["features"].count
717
718       get api_notes_path(:bbox => "5,5,5.1,5.1", :format => "xml")
719       assert_response :success
720       assert_equal "application/xml", @response.media_type
721       assert_select "osm", :count => 1 do
722         assert_select "note", :count => 0
723       end
724
725       get api_notes_path(:bbox => "5,5,5.1,5.1", :format => "gpx")
726       assert_response :success
727       assert_equal "application/gpx+xml", @response.media_type
728       assert_select "gpx", :count => 1 do
729         assert_select "wpt", :count => 0
730       end
731     end
732
733     def test_index_large_area
734       get api_notes_path(:bbox => "-2.5,-2.5,2.5,2.5", :format => :json)
735       assert_response :success
736       assert_equal "application/json", @response.media_type
737
738       get api_notes_path(:l => "-2.5", :b => "-2.5", :r => "2.5", :t => "2.5", :format => :json)
739       assert_response :success
740       assert_equal "application/json", @response.media_type
741
742       get api_notes_path(:bbox => "-10,-10,12,12", :format => :json)
743       assert_response :bad_request
744       assert_equal "text/plain", @response.media_type
745
746       get api_notes_path(:l => "-10", :b => "-10", :r => "12", :t => "12", :format => :json)
747       assert_response :bad_request
748       assert_equal "text/plain", @response.media_type
749     end
750
751     def test_index_closed
752       create(:note_with_comments, :status => "closed", :closed_at => Time.now.utc - 5.days)
753       create(:note_with_comments, :status => "closed", :closed_at => Time.now.utc - 100.days)
754       create(:note_with_comments, :status => "hidden")
755       create(:note_with_comments)
756
757       # Open notes + closed in last 7 days
758       get api_notes_path(:bbox => "1,1,1.7,1.7", :closed => "7", :format => "json")
759       assert_response :success
760       assert_equal "application/json", @response.media_type
761       js = ActiveSupport::JSON.decode(@response.body)
762       assert_not_nil js
763       assert_equal "FeatureCollection", js["type"]
764       assert_equal 2, js["features"].count
765
766       # Only open notes
767       get api_notes_path(:bbox => "1,1,1.7,1.7", :closed => "0", :format => "json")
768       assert_response :success
769       assert_equal "application/json", @response.media_type
770       js = ActiveSupport::JSON.decode(@response.body)
771       assert_not_nil js
772       assert_equal "FeatureCollection", js["type"]
773       assert_equal 1, js["features"].count
774
775       # Open notes + all closed notes
776       get api_notes_path(:bbox => "1,1,1.7,1.7", :closed => "-1", :format => "json")
777       assert_response :success
778       assert_equal "application/json", @response.media_type
779       js = ActiveSupport::JSON.decode(@response.body)
780       assert_not_nil js
781       assert_equal "FeatureCollection", js["type"]
782       assert_equal 3, js["features"].count
783     end
784
785     def test_index_bad_params
786       get api_notes_path(:bbox => "-2.5,-2.5,2.5")
787       assert_response :bad_request
788
789       get api_notes_path(:bbox => "-2.5,-2.5,2.5,2.5,2.5")
790       assert_response :bad_request
791
792       get api_notes_path(:b => "-2.5", :r => "2.5", :t => "2.5")
793       assert_response :bad_request
794
795       get api_notes_path(:l => "-2.5", :r => "2.5", :t => "2.5")
796       assert_response :bad_request
797
798       get api_notes_path(:l => "-2.5", :b => "-2.5", :t => "2.5")
799       assert_response :bad_request
800
801       get api_notes_path(:l => "-2.5", :b => "-2.5", :r => "2.5")
802       assert_response :bad_request
803
804       get api_notes_path(:bbox => "1,1,1.7,1.7", :limit => "0", :format => "json")
805       assert_response :bad_request
806
807       get api_notes_path(:bbox => "1,1,1.7,1.7", :limit => "10001", :format => "json")
808       assert_response :bad_request
809     end
810
811     def test_search_success
812       create(:note_with_comments)
813
814       get search_api_notes_path(:q => "note comment", :format => "xml")
815       assert_response :success
816       assert_equal "application/xml", @response.media_type
817       assert_select "osm", :count => 1 do
818         assert_select "note", :count => 1
819       end
820
821       get search_api_notes_path(:q => "note comment", :format => "json")
822       assert_response :success
823       assert_equal "application/json", @response.media_type
824       js = ActiveSupport::JSON.decode(@response.body)
825       assert_not_nil js
826       assert_equal "FeatureCollection", js["type"]
827       assert_equal 1, js["features"].count
828
829       get search_api_notes_path(:q => "note comment", :format => "rss")
830       assert_response :success
831       assert_equal "application/rss+xml", @response.media_type
832       assert_select "rss", :count => 1 do
833         assert_select "channel", :count => 1 do
834           assert_select "item", :count => 1
835         end
836       end
837
838       get search_api_notes_path(:q => "note comment", :format => "gpx")
839       assert_response :success
840       assert_equal "application/gpx+xml", @response.media_type
841       assert_select "gpx", :count => 1 do
842         assert_select "wpt", :count => 1
843       end
844     end
845
846     def test_search_by_display_name_success
847       user = create(:user)
848
849       create(:note) do |note|
850         create(:note_comment, :note => note, :author => user)
851       end
852
853       get search_api_notes_path(:display_name => user.display_name, :format => "xml")
854       assert_response :success
855       assert_equal "application/xml", @response.media_type
856       assert_select "osm", :count => 1 do
857         assert_select "note", :count => 1
858       end
859
860       get search_api_notes_path(:display_name => user.display_name, :format => "json")
861       assert_response :success
862       assert_equal "application/json", @response.media_type
863       js = ActiveSupport::JSON.decode(@response.body)
864       assert_not_nil js
865       assert_equal "FeatureCollection", js["type"]
866       assert_equal 1, js["features"].count
867
868       get search_api_notes_path(:display_name => user.display_name, :format => "rss")
869       assert_response :success
870       assert_equal "application/rss+xml", @response.media_type
871       assert_select "rss", :count => 1 do
872         assert_select "channel", :count => 1 do
873           assert_select "item", :count => 1
874         end
875       end
876
877       get search_api_notes_path(:display_name => user.display_name, :format => "gpx")
878       assert_response :success
879       assert_equal "application/gpx+xml", @response.media_type
880       assert_select "gpx", :count => 1 do
881         assert_select "wpt", :count => 1
882       end
883     end
884
885     def test_search_by_user_success
886       user = create(:user)
887
888       create(:note) do |note|
889         create(:note_comment, :note => note, :author => user)
890       end
891
892       get search_api_notes_path(:user => user.id, :format => "xml")
893       assert_response :success
894       assert_equal "application/xml", @response.media_type
895       assert_select "osm", :count => 1 do
896         assert_select "note", :count => 1
897       end
898
899       get search_api_notes_path(:user => user.id, :format => "json")
900       assert_response :success
901       assert_equal "application/json", @response.media_type
902       js = ActiveSupport::JSON.decode(@response.body)
903       assert_not_nil js
904       assert_equal "FeatureCollection", js["type"]
905       assert_equal 1, js["features"].count
906
907       get search_api_notes_path(:user => user.id, :format => "rss")
908       assert_response :success
909       assert_equal "application/rss+xml", @response.media_type
910       assert_select "rss", :count => 1 do
911         assert_select "channel", :count => 1 do
912           assert_select "item", :count => 1
913         end
914       end
915
916       get search_api_notes_path(:user => user.id, :format => "gpx")
917       assert_response :success
918       assert_equal "application/gpx+xml", @response.media_type
919       assert_select "gpx", :count => 1 do
920         assert_select "wpt", :count => 1
921       end
922     end
923
924     def test_search_no_match
925       create(:note_with_comments)
926
927       get search_api_notes_path(:q => "no match", :format => "xml")
928       assert_response :success
929       assert_equal "application/xml", @response.media_type
930       assert_select "osm", :count => 1 do
931         assert_select "note", :count => 0
932       end
933
934       get search_api_notes_path(:q => "no match", :format => "json")
935       assert_response :success
936       assert_equal "application/json", @response.media_type
937       js = ActiveSupport::JSON.decode(@response.body)
938       assert_not_nil js
939       assert_equal "FeatureCollection", js["type"]
940       assert_equal 0, js["features"].count
941
942       get search_api_notes_path(:q => "no match", :format => "rss")
943       assert_response :success
944       assert_equal "application/rss+xml", @response.media_type
945       assert_select "rss", :count => 1 do
946         assert_select "channel", :count => 1 do
947           assert_select "item", :count => 0
948         end
949       end
950
951       get search_api_notes_path(:q => "no match", :format => "gpx")
952       assert_response :success
953       assert_equal "application/gpx+xml", @response.media_type
954       assert_select "gpx", :count => 1 do
955         assert_select "wpt", :count => 0
956       end
957     end
958
959     def test_search_by_time_no_match
960       create(:note_with_comments)
961
962       get search_api_notes_path(:from => "01.01.2010", :to => "01.10.2010", :format => "xml")
963       assert_response :success
964       assert_equal "application/xml", @response.media_type
965       assert_select "osm", :count => 1 do
966         assert_select "note", :count => 0
967       end
968
969       get search_api_notes_path(:from => "01.01.2010", :to => "01.10.2010", :format => "json")
970       assert_response :success
971       assert_equal "application/json", @response.media_type
972       js = ActiveSupport::JSON.decode(@response.body)
973       assert_not_nil js
974       assert_equal "FeatureCollection", js["type"]
975       assert_equal 0, js["features"].count
976
977       get search_api_notes_path(:from => "01.01.2010", :to => "01.10.2010", :format => "rss")
978       assert_response :success
979       assert_equal "application/rss+xml", @response.media_type
980       assert_select "rss", :count => 1 do
981         assert_select "channel", :count => 1 do
982           assert_select "item", :count => 0
983         end
984       end
985
986       get search_api_notes_path(:from => "01.01.2010", :to => "01.10.2010", :format => "gpx")
987       assert_response :success
988       assert_equal "application/gpx+xml", @response.media_type
989       assert_select "gpx", :count => 1 do
990         assert_select "wpt", :count => 0
991       end
992     end
993
994     def test_search_bad_params
995       get search_api_notes_path(:q => "no match", :limit => "0", :format => "json")
996       assert_response :bad_request
997
998       get search_api_notes_path(:q => "no match", :limit => "10001", :format => "json")
999       assert_response :bad_request
1000
1001       get search_api_notes_path(:display_name => "non-existent")
1002       assert_response :bad_request
1003
1004       get search_api_notes_path(:user => "-1")
1005       assert_response :bad_request
1006
1007       get search_api_notes_path(:from => "wrong-date", :to => "wrong-date")
1008       assert_response :bad_request
1009
1010       get search_api_notes_path(:from => "01.01.2010", :to => "2010.01.2010")
1011       assert_response :bad_request
1012     end
1013
1014     def test_feed_success
1015       position = (1.1 * GeoRecord::SCALE).to_i
1016       create(:note_with_comments, :latitude => position, :longitude => position)
1017       create(:note_with_comments, :latitude => position, :longitude => position)
1018       position = (1.5 * GeoRecord::SCALE).to_i
1019       create(:note_with_comments, :latitude => position, :longitude => position)
1020       create(:note_with_comments, :latitude => position, :longitude => position)
1021
1022       get feed_api_notes_path(:format => "rss")
1023       assert_response :success
1024       assert_equal "application/rss+xml", @response.media_type
1025       assert_select "rss", :count => 1 do
1026         assert_select "channel", :count => 1 do
1027           assert_select "item", :count => 4
1028         end
1029       end
1030
1031       get feed_api_notes_path(:bbox => "1,1,1.2,1.2", :format => "rss")
1032       assert_response :success
1033       assert_equal "application/rss+xml", @response.media_type
1034       assert_select "rss", :count => 1 do
1035         assert_select "channel", :count => 1 do
1036           assert_select "description", :text => /1\.2/, :count => 1
1037           assert_select "item", :count => 2
1038         end
1039       end
1040     end
1041
1042     def test_feed_fail
1043       get feed_api_notes_path(:bbox => "1,1,1.2", :format => "rss")
1044       assert_response :bad_request
1045
1046       get feed_api_notes_path(:bbox => "1,1,1.2,1.2,1.2", :format => "rss")
1047       assert_response :bad_request
1048
1049       get feed_api_notes_path(:bbox => "1,1,1.2,1.2", :limit => "0", :format => "rss")
1050       assert_response :bad_request
1051
1052       get feed_api_notes_path(:bbox => "1,1,1.2,1.2", :limit => "10001", :format => "rss")
1053       assert_response :bad_request
1054     end
1055   end
1056 end