1 # frozen_string_literal: true
6 class NotesControllerTest < ActionDispatch::IntegrationTest
9 # Stub nominatim response for note locations
10 stub_request(:get, %r{^https://nominatim\.openstreetmap\.org/reverse\?})
11 .to_return(:status => 404)
15 # test all routes which lead to this controller
18 { :path => "/api/0.6/notes", :method => :post },
19 { :controller => "api/notes", :action => "create" }
22 { :path => "/api/0.6/notes/1", :method => :get },
23 { :controller => "api/notes", :action => "show", :id => "1" }
26 { :controller => "api/notes", :action => "show", :id => "1", :format => "xml" },
27 { :path => "/api/0.6/notes/1.xml", :method => :get }
30 { :path => "/api/0.6/notes/1.rss", :method => :get },
31 { :controller => "api/notes", :action => "show", :id => "1", :format => "rss" }
34 { :path => "/api/0.6/notes/1.json", :method => :get },
35 { :controller => "api/notes", :action => "show", :id => "1", :format => "json" }
38 { :path => "/api/0.6/notes/1.gpx", :method => :get },
39 { :controller => "api/notes", :action => "show", :id => "1", :format => "gpx" }
42 { :path => "/api/0.6/notes/1/comment", :method => :post },
43 { :controller => "api/notes", :action => "comment", :id => "1" }
46 { :path => "/api/0.6/notes/1/close", :method => :post },
47 { :controller => "api/notes", :action => "close", :id => "1" }
50 { :path => "/api/0.6/notes/1/reopen", :method => :post },
51 { :controller => "api/notes", :action => "reopen", :id => "1" }
54 { :path => "/api/0.6/notes/1", :method => :delete },
55 { :controller => "api/notes", :action => "destroy", :id => "1" }
59 { :path => "/api/0.6/notes", :method => :get },
60 { :controller => "api/notes", :action => "index" }
63 { :controller => "api/notes", :action => "index", :format => "xml" },
64 { :path => "/api/0.6/notes.xml", :method => :get }
67 { :path => "/api/0.6/notes.rss", :method => :get },
68 { :controller => "api/notes", :action => "index", :format => "rss" }
71 { :path => "/api/0.6/notes.json", :method => :get },
72 { :controller => "api/notes", :action => "index", :format => "json" }
75 { :path => "/api/0.6/notes.gpx", :method => :get },
76 { :controller => "api/notes", :action => "index", :format => "gpx" }
80 { :path => "/api/0.6/notes/search", :method => :get },
81 { :controller => "api/notes", :action => "search" }
84 { :controller => "api/notes", :action => "search", :format => "xml" },
85 { :path => "/api/0.6/notes/search.xml", :method => :get }
88 { :path => "/api/0.6/notes/search.rss", :method => :get },
89 { :controller => "api/notes", :action => "search", :format => "rss" }
92 { :path => "/api/0.6/notes/search.json", :method => :get },
93 { :controller => "api/notes", :action => "search", :format => "json" }
96 { :path => "/api/0.6/notes/search.gpx", :method => :get },
97 { :controller => "api/notes", :action => "search", :format => "gpx" }
101 { :path => "/api/0.6/notes/feed", :method => :get },
102 { :controller => "api/notes", :action => "feed", :format => "rss" }
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")
114 assert_response :success
115 js = ActiveSupport::JSON.decode(@response.body)
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"]
127 get api_note_path(id, :format => "json")
128 assert_response :success
129 js = ActiveSupport::JSON.decode(@response.body)
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"]
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")
148 assert_response :bad_request
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")
155 assert_response :bad_request
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)
162 assert_response :bad_request
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 => "")
169 assert_response :bad_request
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")
176 assert_response :bad_request
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")
183 assert_response :bad_request
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")
190 assert_response :bad_request
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")
197 assert_response :bad_request
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")
204 assert_response :bad_request
207 def test_create_success
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
217 assert_response :success
218 js = ActiveSupport::JSON.decode(@response.body)
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"]
230 subscription = NoteSubscription.last
231 assert_equal user, subscription.user
232 assert_equal note, subscription.note
235 def test_create_no_scope_fail
237 auth_header = bearer_authorization_header user, :scopes => %w[read_prefs]
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
242 assert_response :forbidden
246 def test_comment_success
247 open_note_with_comment = create(:note_with_comments)
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
259 assert_response :success
260 js = ActiveSupport::JSON.decode(@response.body)
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"]
270 subscription = NoteSubscription.last
271 assert_equal user, subscription.user
272 assert_equal open_note_with_comment, subscription.note
274 get api_note_path(open_note_with_comment, :format => "json")
275 assert_response :success
276 js = ActiveSupport::JSON.decode(@response.body)
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"]
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)
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)
298 auth_header = bearer_authorization_header third_user
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
309 assert_response :success
310 js = ActiveSupport::JSON.decode(@response.body)
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"]
320 subscription = NoteSubscription.last
321 assert_equal third_user, subscription.user
322 assert_equal note_with_comments_by_users, subscription.note
324 get api_note_path(note_with_comments_by_users, :format => "json")
325 assert_response :success
326 js = ActiveSupport::JSON.decode(@response.body)
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"]
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)
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)
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)
350 auth_header = bearer_authorization_header third_user
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
361 assert_response :success
362 js = ActiveSupport::JSON.decode(@response.body)
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"]
372 subscription = NoteSubscription.last
373 assert_equal third_user, subscription.user
374 assert_equal note_with_comments_by_users, subscription.note
376 email = ActionMailer::Base.deliveries.find { |e| e.to.first == first_user.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
382 email = ActionMailer::Base.deliveries.find { |e| e.to.first == second_user.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
387 get api_note_path(note_with_comments_by_users, :format => "json")
388 assert_response :success
389 js = ActiveSupport::JSON.decode(@response.body)
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"]
400 def test_comment_twice_success
401 open_note_with_comment = create(:note_with_comments)
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
413 assert_response :success
414 js = ActiveSupport::JSON.decode(@response.body)
416 assert_equal 2, js["properties"]["comments"].count
418 subscription = NoteSubscription.last
419 assert_equal user, subscription.user
420 assert_equal open_note_with_comment, subscription.note
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
431 assert_response :success
432 js = ActiveSupport::JSON.decode(@response.body)
434 assert_equal 3, js["properties"]["comments"].count
437 def test_comment_fail
438 open_note_with_comment = create(:note_with_comments)
442 assert_no_difference "NoteComment.count" do
443 post comment_api_note_path(open_note_with_comment)
444 assert_response :unauthorized
447 auth_header = bearer_authorization_header user
449 assert_no_difference "NoteComment.count" do
450 post comment_api_note_path(open_note_with_comment), :headers => auth_header
452 assert_response :bad_request
454 assert_no_difference "NoteComment.count" do
455 post comment_api_note_path(open_note_with_comment, :text => ""), :headers => auth_header
457 assert_response :bad_request
459 assert_no_difference "NoteComment.count" do
460 post comment_api_note_path(12345, :text => "This is an additional comment"), :headers => auth_header
462 assert_response :not_found
464 hidden_note_with_comment = create(:note_with_comments, :status => "hidden")
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
469 assert_response :gone
471 closed_note_with_comment = create(:note_with_comments, :closed)
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
476 assert_response :conflict
478 assert_no_difference "NoteComment.count" do
479 post comment_api_note_path(open_note_with_comment, :text => "x\u0000y"), :headers => auth_header
481 assert_response :bad_request
484 def test_close_success
485 open_note_with_comment = create(:note_with_comments)
488 post close_api_note_path(open_note_with_comment, :text => "This is a close comment", :format => "json")
489 assert_response :unauthorized
491 auth_header = bearer_authorization_header user
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
496 assert_response :success
497 js = ActiveSupport::JSON.decode(@response.body)
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"]
507 subscription = NoteSubscription.last
508 assert_equal user, subscription.user
509 assert_equal open_note_with_comment, subscription.note
511 get api_note_path(open_note_with_comment.id, :format => "json")
512 assert_response :success
513 js = ActiveSupport::JSON.decode(@response.body)
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"]
525 post close_api_note_path(12345)
526 assert_response :unauthorized
528 auth_header = bearer_authorization_header
530 post close_api_note_path(12345), :headers => auth_header
531 assert_response :not_found
533 hidden_note_with_comment = create(:note_with_comments, :status => "hidden")
535 post close_api_note_path(hidden_note_with_comment), :headers => auth_header
536 assert_response :gone
538 closed_note_with_comment = create(:note_with_comments, :closed)
540 post close_api_note_path(closed_note_with_comment), :headers => auth_header
541 assert_response :conflict
544 def test_reopen_success
545 closed_note_with_comment = create(:note_with_comments, :closed)
548 post reopen_api_note_path(closed_note_with_comment, :text => "This is a reopen comment", :format => "json")
549 assert_response :unauthorized
551 auth_header = bearer_authorization_header user
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
556 assert_response :success
557 js = ActiveSupport::JSON.decode(@response.body)
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"]
567 subscription = NoteSubscription.last
568 assert_equal user, subscription.user
569 assert_equal closed_note_with_comment, subscription.note
571 get api_note_path(closed_note_with_comment, :format => "json")
572 assert_response :success
573 js = ActiveSupport::JSON.decode(@response.body)
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"]
585 hidden_note_with_comment = create(:note_with_comments, :status => "hidden")
587 post reopen_api_note_path(hidden_note_with_comment)
588 assert_response :unauthorized
590 auth_header = bearer_authorization_header
592 post reopen_api_note_path(12345), :headers => auth_header
593 assert_response :not_found
595 post reopen_api_note_path(hidden_note_with_comment), :headers => auth_header
596 assert_response :gone
598 open_note_with_comment = create(:note_with_comments)
600 post reopen_api_note_path(open_note_with_comment), :headers => auth_header
601 assert_response :conflict
604 def test_show_success
605 open_note = create(:note_with_comments)
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
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}"
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)
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"]
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")
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")
682 get api_note_path(note_with_hidden_comment, :format => "json")
683 assert_response :success
684 js = ActiveSupport::JSON.decode(@response.body)
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"]
694 get api_note_path(12345)
695 assert_response :not_found
697 get api_note_path(create(:note, :status => "hidden"))
698 assert_response :gone
701 def test_destroy_success
702 open_note_with_comment = create(:note_with_comments)
704 moderator_user = create(:moderator_user)
706 delete api_note_path(open_note_with_comment, :text => "This is a hide comment", :format => "json")
707 assert_response :unauthorized
709 auth_header = bearer_authorization_header user
711 delete api_note_path(open_note_with_comment, :text => "This is a hide comment", :format => "json"), :headers => auth_header
712 assert_response :forbidden
714 auth_header = bearer_authorization_header moderator_user
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)
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"]
728 get api_note_path(open_note_with_comment, :format => "json"), :headers => auth_header
729 assert_response :success
731 auth_header = bearer_authorization_header user
733 get api_note_path(open_note_with_comment, :format => "json"), :headers => auth_header
734 assert_response :gone
737 def test_destroy_fail
739 moderator_user = create(:moderator_user)
741 delete api_note_path(12345, :format => "json")
742 assert_response :unauthorized
744 auth_header = bearer_authorization_header user
746 delete api_note_path(12345, :format => "json"), :headers => auth_header
747 assert_response :forbidden
749 auth_header = bearer_authorization_header moderator_user
751 delete api_note_path(12345, :format => "json"), :headers => auth_header
752 assert_response :not_found
754 hidden_note_with_comment = create(:note_with_comments, :status => "hidden")
756 delete api_note_path(hidden_note_with_comment, :format => "json"), :headers => auth_header
757 assert_response :gone
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)
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
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)
780 assert_equal "FeatureCollection", js["type"]
781 assert_equal 2, js["features"].count
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
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
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)
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
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)
817 assert_equal "FeatureCollection", js["type"]
818 assert_equal 1, js["features"].count
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
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
834 get api_notes_path(:bbox => "1,1,1.2,1.2", :limit => Settings.max_note_query_limit, :format => "rss")
835 assert_response :success
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
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)
853 assert_equal "FeatureCollection", js["type"]
854 assert_equal 0, js["features"].count
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
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
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
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
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
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
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)
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)
901 assert_equal "FeatureCollection", js["type"]
902 assert_equal 2, js["features"].count
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)
910 assert_equal "FeatureCollection", js["type"]
911 assert_equal 1, js["features"].count
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)
919 assert_equal "FeatureCollection", js["type"]
920 assert_equal 3, js["features"].count
923 def test_index_bad_params
925 assert_response :bad_request
926 assert_equal "The parameter bbox is required", @response.body
928 get api_notes_path(:bbox => "-2.5,-2.5,2.5")
929 assert_response :bad_request
931 get api_notes_path(:bbox => "-2.5,-2.5,2.5,2.5,2.5")
932 assert_response :bad_request
934 get api_notes_path(:b => "-2.5", :r => "2.5", :t => "2.5")
935 assert_response :bad_request
937 get api_notes_path(:l => "-2.5", :r => "2.5", :t => "2.5")
938 assert_response :bad_request
940 get api_notes_path(:l => "-2.5", :b => "-2.5", :t => "2.5")
941 assert_response :bad_request
943 get api_notes_path(:l => "-2.5", :b => "-2.5", :r => "2.5")
944 assert_response :bad_request
946 get api_notes_path(:bbox => "1,1,1.7,1.7", :limit => "0", :format => "json")
947 assert_response :bad_request
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
953 def test_search_success
954 create(:note_with_comments)
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
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)
968 assert_equal "FeatureCollection", js["type"]
969 assert_equal 1, js["features"].count
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
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
987 get search_api_notes_path(:q => "note comment", :limit => Settings.max_note_query_limit, :format => "xml")
988 assert_response :success
991 def test_search_by_display_name_success
994 create(:note) do |note|
995 create(:note_comment, :note => note, :author => user)
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
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)
1010 assert_equal "FeatureCollection", js["type"]
1011 assert_equal 1, js["features"].count
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
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
1030 def test_search_by_user_success
1031 user = create(:user)
1033 create(:note) do |note|
1034 create(:note_comment, :note => note, :author => user)
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
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)
1049 assert_equal "FeatureCollection", js["type"]
1050 assert_equal 1, js["features"].count
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
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
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
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")
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
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
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)
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
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]]
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 []
1122 def test_search_no_match
1123 create(:note_with_comments)
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
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)
1137 assert_equal "FeatureCollection", js["type"]
1138 assert_equal 0, js["features"].count
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
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
1157 def test_search_by_time_no_match
1158 create(:note_with_comments)
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
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)
1172 assert_equal "FeatureCollection", js["type"]
1173 assert_equal 0, js["features"].count
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
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
1192 def test_search_bad_params
1193 get search_api_notes_path(:q => "no match", :limit => "0", :format => "json")
1194 assert_response :bad_request
1196 get search_api_notes_path(:q => "no match", :limit => Settings.max_note_query_limit + 1, :format => "json")
1197 assert_response :bad_request
1199 get search_api_notes_path(:display_name => "non-existent")
1200 assert_response :bad_request
1202 get search_api_notes_path(:user => "-1")
1203 assert_response :bad_request
1205 get search_api_notes_path(:from => "wrong-date", :to => "wrong-date")
1206 assert_response :bad_request
1208 get search_api_notes_path(:from => "01.01.2010", :to => "2010.01.2010")
1209 assert_response :bad_request
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)
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
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
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
1244 get feed_api_notes_path(:bbox => "1,1,1.2", :format => "rss")
1245 assert_response :bad_request
1247 get feed_api_notes_path(:bbox => "1,1,1.2,1.2,1.2", :format => "rss")
1248 assert_response :bad_request
1250 get feed_api_notes_path(:bbox => "1,1,1.2,1.2", :limit => "0", :format => "rss")
1251 assert_response :bad_request
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
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