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 assert_email_received first_user.email, "[OpenStreetMap] #{third_user.display_name} has commented on one of your notes"
377 assert_email_received second_user.email, "[OpenStreetMap] #{third_user.display_name} has commented on a note you are interested in"
379 get api_note_path(note_with_comments_by_users, :format => "json")
380 assert_response :success
381 js = ActiveSupport::JSON.decode(@response.body)
383 assert_equal "Feature", js["type"]
384 assert_equal note_with_comments_by_users.id, js["properties"]["id"]
385 assert_equal "open", js["properties"]["status"]
386 assert_equal 3, js["properties"]["comments"].count
387 assert_equal "commented", js["properties"]["comments"].last["action"]
388 assert_equal "This is an additional comment", js["properties"]["comments"].last["text"]
389 assert_equal third_user.display_name, js["properties"]["comments"].last["user"]
392 def test_comment_twice_success
393 open_note_with_comment = create(:note_with_comments)
395 auth_header = bearer_authorization_header user
396 assert_difference "NoteComment.count", 1 do
397 assert_difference "NoteSubscription.count", 1 do
398 assert_no_difference "ActionMailer::Base.deliveries.size" do
399 perform_enqueued_jobs do
400 post comment_api_note_path(open_note_with_comment, :text => "This is an additional comment", :format => "json"), :headers => auth_header
405 assert_response :success
406 js = ActiveSupport::JSON.decode(@response.body)
408 assert_equal 2, js["properties"]["comments"].count
410 subscription = NoteSubscription.last
411 assert_equal user, subscription.user
412 assert_equal open_note_with_comment, subscription.note
414 assert_difference "NoteComment.count", 1 do
415 assert_no_difference "NoteSubscription.count" do
416 assert_no_difference "ActionMailer::Base.deliveries.size" do
417 perform_enqueued_jobs do
418 post comment_api_note_path(open_note_with_comment, :text => "This is a second additional comment", :format => "json"), :headers => auth_header
423 assert_response :success
424 js = ActiveSupport::JSON.decode(@response.body)
426 assert_equal 3, js["properties"]["comments"].count
429 def test_comment_fail
430 open_note_with_comment = create(:note_with_comments)
434 assert_no_difference "NoteComment.count" do
435 post comment_api_note_path(open_note_with_comment)
436 assert_response :unauthorized
439 auth_header = bearer_authorization_header user
441 assert_no_difference "NoteComment.count" do
442 post comment_api_note_path(open_note_with_comment), :headers => auth_header
444 assert_response :bad_request
446 assert_no_difference "NoteComment.count" do
447 post comment_api_note_path(open_note_with_comment, :text => ""), :headers => auth_header
449 assert_response :bad_request
451 assert_no_difference "NoteComment.count" do
452 post comment_api_note_path(12345, :text => "This is an additional comment"), :headers => auth_header
454 assert_response :not_found
456 hidden_note_with_comment = create(:note_with_comments, :status => "hidden")
458 assert_no_difference "NoteComment.count" do
459 post comment_api_note_path(hidden_note_with_comment, :text => "This is an additional comment"), :headers => auth_header
461 assert_response :gone
463 closed_note_with_comment = create(:note_with_comments, :closed)
465 assert_no_difference "NoteComment.count" do
466 post comment_api_note_path(closed_note_with_comment, :text => "This is an additional comment"), :headers => auth_header
468 assert_response :conflict
470 assert_no_difference "NoteComment.count" do
471 post comment_api_note_path(open_note_with_comment, :text => "x\u0000y"), :headers => auth_header
473 assert_response :bad_request
476 def test_close_success
477 open_note_with_comment = create(:note_with_comments)
480 post close_api_note_path(open_note_with_comment, :text => "This is a close comment", :format => "json")
481 assert_response :unauthorized
483 auth_header = bearer_authorization_header user
485 assert_difference "NoteSubscription.count", 1 do
486 post close_api_note_path(open_note_with_comment, :text => "This is a close comment", :format => "json"), :headers => auth_header
488 assert_response :success
489 js = ActiveSupport::JSON.decode(@response.body)
491 assert_equal "Feature", js["type"]
492 assert_equal open_note_with_comment.id, js["properties"]["id"]
493 assert_equal "closed", js["properties"]["status"]
494 assert_equal 2, js["properties"]["comments"].count
495 assert_equal "closed", js["properties"]["comments"].last["action"]
496 assert_equal "This is a close comment", js["properties"]["comments"].last["text"]
497 assert_equal user.display_name, js["properties"]["comments"].last["user"]
499 subscription = NoteSubscription.last
500 assert_equal user, subscription.user
501 assert_equal open_note_with_comment, subscription.note
503 get api_note_path(open_note_with_comment.id, :format => "json")
504 assert_response :success
505 js = ActiveSupport::JSON.decode(@response.body)
507 assert_equal "Feature", js["type"]
508 assert_equal open_note_with_comment.id, js["properties"]["id"]
509 assert_equal "closed", js["properties"]["status"]
510 assert_equal 2, js["properties"]["comments"].count
511 assert_equal "closed", js["properties"]["comments"].last["action"]
512 assert_equal "This is a close comment", js["properties"]["comments"].last["text"]
513 assert_equal user.display_name, js["properties"]["comments"].last["user"]
517 post close_api_note_path(12345)
518 assert_response :unauthorized
520 auth_header = bearer_authorization_header
522 post close_api_note_path(12345), :headers => auth_header
523 assert_response :not_found
525 hidden_note_with_comment = create(:note_with_comments, :status => "hidden")
527 post close_api_note_path(hidden_note_with_comment), :headers => auth_header
528 assert_response :gone
530 closed_note_with_comment = create(:note_with_comments, :closed)
532 post close_api_note_path(closed_note_with_comment), :headers => auth_header
533 assert_response :conflict
536 def test_reopen_success
537 closed_note_with_comment = create(:note_with_comments, :closed)
540 post reopen_api_note_path(closed_note_with_comment, :text => "This is a reopen comment", :format => "json")
541 assert_response :unauthorized
543 auth_header = bearer_authorization_header user
545 assert_difference "NoteSubscription.count", 1 do
546 post reopen_api_note_path(closed_note_with_comment, :text => "This is a reopen comment", :format => "json"), :headers => auth_header
548 assert_response :success
549 js = ActiveSupport::JSON.decode(@response.body)
551 assert_equal "Feature", js["type"]
552 assert_equal closed_note_with_comment.id, js["properties"]["id"]
553 assert_equal "open", js["properties"]["status"]
554 assert_equal 3, js["properties"]["comments"].count
555 assert_equal "reopened", js["properties"]["comments"].last["action"]
556 assert_equal "This is a reopen comment", js["properties"]["comments"].last["text"]
557 assert_equal user.display_name, js["properties"]["comments"].last["user"]
559 subscription = NoteSubscription.last
560 assert_equal user, subscription.user
561 assert_equal closed_note_with_comment, subscription.note
563 get api_note_path(closed_note_with_comment, :format => "json")
564 assert_response :success
565 js = ActiveSupport::JSON.decode(@response.body)
567 assert_equal "Feature", js["type"]
568 assert_equal closed_note_with_comment.id, js["properties"]["id"]
569 assert_equal "open", js["properties"]["status"]
570 assert_equal 3, js["properties"]["comments"].count
571 assert_equal "reopened", js["properties"]["comments"].last["action"]
572 assert_equal "This is a reopen comment", js["properties"]["comments"].last["text"]
573 assert_equal user.display_name, js["properties"]["comments"].last["user"]
577 hidden_note_with_comment = create(:note_with_comments, :status => "hidden")
579 post reopen_api_note_path(hidden_note_with_comment)
580 assert_response :unauthorized
582 auth_header = bearer_authorization_header
584 post reopen_api_note_path(12345), :headers => auth_header
585 assert_response :not_found
587 post reopen_api_note_path(hidden_note_with_comment), :headers => auth_header
588 assert_response :gone
590 open_note_with_comment = create(:note_with_comments)
592 post reopen_api_note_path(open_note_with_comment), :headers => auth_header
593 assert_response :conflict
596 def test_show_success
597 open_note = create(:note_with_comments)
599 get api_note_path(open_note, :format => "xml")
600 assert_response :success
601 assert_equal "application/xml", @response.media_type
602 assert_select "osm", :count => 1 do
603 assert_select "note[lat='#{open_note.lat}'][lon='#{open_note.lon}']", :count => 1 do
604 assert_select "id", open_note.id.to_s
605 assert_select "url", api_note_url(open_note, :format => "xml")
606 assert_select "comment_url", comment_api_note_url(open_note, :format => "xml")
607 assert_select "close_url", close_api_note_url(open_note, :format => "xml")
608 assert_select "date_created", open_note.created_at.to_s
609 assert_select "status", open_note.status
610 assert_select "comments", :count => 1 do
611 assert_select "comment", :count => 1
616 get api_note_path(open_note, :format => "rss")
617 assert_response :success
618 assert_equal "application/rss+xml", @response.media_type
619 assert_select "rss", :count => 1 do
620 assert_select "channel", :count => 1 do
621 assert_select "item", :count => 1 do
622 assert_select "link", note_url(open_note)
623 assert_select "guid", api_note_url(open_note)
624 assert_select "pubDate", open_note.created_at.to_fs(:rfc822)
625 assert_select "geo|lat", open_note.lat.to_s
626 assert_select "geo|long", open_note.lon.to_s
627 assert_select "georss|point", "#{open_note.lon} #{open_note.lon}"
632 get api_note_path(open_note, :format => "json")
633 assert_response :success
634 assert_equal "application/json", @response.media_type
635 js = ActiveSupport::JSON.decode(@response.body)
637 assert_equal "Feature", js["type"]
638 assert_equal "Point", js["geometry"]["type"]
639 assert_equal open_note.lat, js["geometry"]["coordinates"][0]
640 assert_equal open_note.lon, js["geometry"]["coordinates"][1]
641 assert_equal open_note.id, js["properties"]["id"]
642 assert_equal api_note_url(open_note, :format => "json"), js["properties"]["url"]
643 assert_equal comment_api_note_url(open_note, :format => "json"), js["properties"]["comment_url"]
644 assert_equal close_api_note_url(open_note, :format => "json"), js["properties"]["close_url"]
645 assert_equal open_note.created_at.to_s, js["properties"]["date_created"]
646 assert_equal open_note.status, js["properties"]["status"]
648 get api_note_path(open_note, :format => "gpx")
649 assert_response :success
650 assert_equal "application/gpx+xml", @response.media_type
651 assert_select "gpx", :count => 1 do
652 assert_select "wpt[lat='#{open_note.lat}'][lon='#{open_note.lon}']", :count => 1 do
653 assert_select "time", :count => 1
654 assert_select "name", "Note: #{open_note.id}"
655 assert_select "desc", :count => 1
656 assert_select "link[href='http://www.example.com/note/#{open_note.id}']", :count => 1
657 assert_select "extensions", :count => 1 do
658 assert_select "id", open_note.id.to_s
659 assert_select "url", api_note_url(open_note, :format => "gpx")
660 assert_select "comment_url", comment_api_note_url(open_note, :format => "gpx")
661 assert_select "close_url", close_api_note_url(open_note, :format => "gpx")
667 def test_show_hidden_comment
668 note_with_hidden_comment = create(:note) do |note|
669 create(:note_comment, :note => note, :body => "Valid comment for hidden note")
670 create(:note_comment, :note => note, :visible => false)
671 create(:note_comment, :note => note, :body => "Another valid comment for hidden note")
674 get api_note_path(note_with_hidden_comment, :format => "json")
675 assert_response :success
676 js = ActiveSupport::JSON.decode(@response.body)
678 assert_equal "Feature", js["type"]
679 assert_equal note_with_hidden_comment.id, js["properties"]["id"]
680 assert_equal 2, js["properties"]["comments"].count
681 assert_equal "Valid comment for hidden note", js["properties"]["comments"][0]["text"]
682 assert_equal "Another valid comment for hidden note", js["properties"]["comments"][1]["text"]
686 get api_note_path(12345)
687 assert_response :not_found
689 get api_note_path(create(:note, :status => "hidden"))
690 assert_response :gone
693 def test_destroy_success
694 open_note_with_comment = create(:note_with_comments)
696 moderator_user = create(:moderator_user)
698 delete api_note_path(open_note_with_comment, :text => "This is a hide comment", :format => "json")
699 assert_response :unauthorized
701 auth_header = bearer_authorization_header user
703 delete api_note_path(open_note_with_comment, :text => "This is a hide comment", :format => "json"), :headers => auth_header
704 assert_response :forbidden
706 auth_header = bearer_authorization_header moderator_user
708 delete api_note_path(open_note_with_comment, :text => "This is a hide comment", :format => "json"), :headers => auth_header
709 assert_response :success
710 js = ActiveSupport::JSON.decode(@response.body)
712 assert_equal "Feature", js["type"]
713 assert_equal open_note_with_comment.id, js["properties"]["id"]
714 assert_equal "hidden", js["properties"]["status"]
715 assert_equal 2, js["properties"]["comments"].count
716 assert_equal "hidden", js["properties"]["comments"].last["action"]
717 assert_equal "This is a hide comment", js["properties"]["comments"].last["text"]
718 assert_equal moderator_user.display_name, js["properties"]["comments"].last["user"]
720 get api_note_path(open_note_with_comment, :format => "json"), :headers => auth_header
721 assert_response :success
723 auth_header = bearer_authorization_header user
725 get api_note_path(open_note_with_comment, :format => "json"), :headers => auth_header
726 assert_response :gone
729 def test_destroy_fail
731 moderator_user = create(:moderator_user)
733 delete api_note_path(12345, :format => "json")
734 assert_response :unauthorized
736 auth_header = bearer_authorization_header user
738 delete api_note_path(12345, :format => "json"), :headers => auth_header
739 assert_response :forbidden
741 auth_header = bearer_authorization_header moderator_user
743 delete api_note_path(12345, :format => "json"), :headers => auth_header
744 assert_response :not_found
746 hidden_note_with_comment = create(:note_with_comments, :status => "hidden")
748 delete api_note_path(hidden_note_with_comment, :format => "json"), :headers => auth_header
749 assert_response :gone
752 def test_index_success
753 position = (1.1 * GeoRecord::SCALE).to_i
754 create(:note_with_comments, :latitude => position, :longitude => position)
755 create(:note_with_comments, :latitude => position, :longitude => position)
757 get api_notes_path(:bbox => "1,1,1.2,1.2", :format => "rss")
758 assert_response :success
759 assert_equal "application/rss+xml", @response.media_type
760 assert_select "rss", :count => 1 do
761 assert_select "channel", :count => 1 do
762 assert_select "description", :text => /1\.2/, :count => 1
763 assert_select "item", :count => 2
767 get api_notes_path(:bbox => "1,1,1.2,1.2", :format => "json")
768 assert_response :success
769 assert_equal "application/json", @response.media_type
770 js = ActiveSupport::JSON.decode(@response.body)
772 assert_equal "FeatureCollection", js["type"]
773 assert_equal 2, js["features"].count
775 get api_notes_path(:bbox => "1,1,1.2,1.2", :format => "xml")
776 assert_response :success
777 assert_equal "application/xml", @response.media_type
778 assert_select "osm", :count => 1 do
779 assert_select "note", :count => 2
782 get api_notes_path(:bbox => "1,1,1.2,1.2", :format => "gpx")
783 assert_response :success
784 assert_equal "application/gpx+xml", @response.media_type
785 assert_select "gpx", :count => 1 do
786 assert_select "wpt", :count => 2
791 position = (1.1 * GeoRecord::SCALE).to_i
792 create(:note_with_comments, :latitude => position, :longitude => position)
793 create(:note_with_comments, :latitude => position, :longitude => position)
795 get api_notes_path(:bbox => "1,1,1.2,1.2", :limit => 1, :format => "rss")
796 assert_response :success
797 assert_equal "application/rss+xml", @response.media_type
798 assert_select "rss", :count => 1 do
799 assert_select "channel", :count => 1 do
800 assert_select "item", :count => 1
804 get api_notes_path(:bbox => "1,1,1.2,1.2", :limit => 1, :format => "json")
805 assert_response :success
806 assert_equal "application/json", @response.media_type
807 js = ActiveSupport::JSON.decode(@response.body)
809 assert_equal "FeatureCollection", js["type"]
810 assert_equal 1, js["features"].count
812 get api_notes_path(:bbox => "1,1,1.2,1.2", :limit => 1, :format => "xml")
813 assert_response :success
814 assert_equal "application/xml", @response.media_type
815 assert_select "osm", :count => 1 do
816 assert_select "note", :count => 1
819 get api_notes_path(:bbox => "1,1,1.2,1.2", :limit => 1, :format => "gpx")
820 assert_response :success
821 assert_equal "application/gpx+xml", @response.media_type
822 assert_select "gpx", :count => 1 do
823 assert_select "wpt", :count => 1
826 get api_notes_path(:bbox => "1,1,1.2,1.2", :limit => Settings.max_note_query_limit, :format => "rss")
827 assert_response :success
830 def test_index_empty_area
831 get api_notes_path(:bbox => "5,5,5.1,5.1", :format => "rss")
832 assert_response :success
833 assert_equal "application/rss+xml", @response.media_type
834 assert_select "rss", :count => 1 do
835 assert_select "channel", :count => 1 do
836 assert_select "item", :count => 0
840 get api_notes_path(:bbox => "5,5,5.1,5.1", :format => "json")
841 assert_response :success
842 assert_equal "application/json", @response.media_type
843 js = ActiveSupport::JSON.decode(@response.body)
845 assert_equal "FeatureCollection", js["type"]
846 assert_equal 0, js["features"].count
848 get api_notes_path(:bbox => "5,5,5.1,5.1", :format => "xml")
849 assert_response :success
850 assert_equal "application/xml", @response.media_type
851 assert_select "osm", :count => 1 do
852 assert_select "note", :count => 0
855 get api_notes_path(:bbox => "5,5,5.1,5.1", :format => "gpx")
856 assert_response :success
857 assert_equal "application/gpx+xml", @response.media_type
858 assert_select "gpx", :count => 1 do
859 assert_select "wpt", :count => 0
863 def test_index_large_area
864 get api_notes_path(:bbox => "-2.5,-2.5,2.5,2.5", :format => :json)
865 assert_response :success
866 assert_equal "application/json", @response.media_type
868 get api_notes_path(:l => "-2.5", :b => "-2.5", :r => "2.5", :t => "2.5", :format => :json)
869 assert_response :success
870 assert_equal "application/json", @response.media_type
872 get api_notes_path(:bbox => "-10,-10,12,12", :format => :json)
873 assert_response :bad_request
874 assert_equal "text/plain", @response.media_type
876 get api_notes_path(:l => "-10", :b => "-10", :r => "12", :t => "12", :format => :json)
877 assert_response :bad_request
878 assert_equal "text/plain", @response.media_type
881 def test_index_closed
882 create(:note_with_comments, :closed, :closed_at => Time.now.utc - 5.days)
883 create(:note_with_comments, :closed, :closed_at => Time.now.utc - 100.days)
884 create(:note_with_comments, :status => "hidden")
885 create(:note_with_comments)
887 # Open notes + closed in last 7 days
888 get api_notes_path(:bbox => "1,1,1.7,1.7", :closed => "7", :format => "json")
889 assert_response :success
890 assert_equal "application/json", @response.media_type
891 js = ActiveSupport::JSON.decode(@response.body)
893 assert_equal "FeatureCollection", js["type"]
894 assert_equal 2, js["features"].count
897 get api_notes_path(:bbox => "1,1,1.7,1.7", :closed => "0", :format => "json")
898 assert_response :success
899 assert_equal "application/json", @response.media_type
900 js = ActiveSupport::JSON.decode(@response.body)
902 assert_equal "FeatureCollection", js["type"]
903 assert_equal 1, js["features"].count
905 # Open notes + all closed notes
906 get api_notes_path(:bbox => "1,1,1.7,1.7", :closed => "-1", :format => "json")
907 assert_response :success
908 assert_equal "application/json", @response.media_type
909 js = ActiveSupport::JSON.decode(@response.body)
911 assert_equal "FeatureCollection", js["type"]
912 assert_equal 3, js["features"].count
915 def test_index_bad_params
917 assert_response :bad_request
918 assert_equal "The parameter bbox is required", @response.body
920 get api_notes_path(:bbox => "-2.5,-2.5,2.5")
921 assert_response :bad_request
923 get api_notes_path(:bbox => "-2.5,-2.5,2.5,2.5,2.5")
924 assert_response :bad_request
926 get api_notes_path(:b => "-2.5", :r => "2.5", :t => "2.5")
927 assert_response :bad_request
929 get api_notes_path(:l => "-2.5", :r => "2.5", :t => "2.5")
930 assert_response :bad_request
932 get api_notes_path(:l => "-2.5", :b => "-2.5", :t => "2.5")
933 assert_response :bad_request
935 get api_notes_path(:l => "-2.5", :b => "-2.5", :r => "2.5")
936 assert_response :bad_request
938 get api_notes_path(:bbox => "1,1,1.7,1.7", :limit => "0", :format => "json")
939 assert_response :bad_request
941 get api_notes_path(:bbox => "1,1,1.7,1.7", :limit => Settings.max_note_query_limit + 1, :format => "json")
942 assert_response :bad_request
945 def test_search_success
946 create(:note_with_comments)
948 get search_api_notes_path(:q => "note comment", :format => "xml")
949 assert_response :success
950 assert_equal "application/xml", @response.media_type
951 assert_select "osm", :count => 1 do
952 assert_select "note", :count => 1
955 get search_api_notes_path(:q => "note comment", :format => "json")
956 assert_response :success
957 assert_equal "application/json", @response.media_type
958 js = ActiveSupport::JSON.decode(@response.body)
960 assert_equal "FeatureCollection", js["type"]
961 assert_equal 1, js["features"].count
963 get search_api_notes_path(:q => "note comment", :format => "rss")
964 assert_response :success
965 assert_equal "application/rss+xml", @response.media_type
966 assert_select "rss", :count => 1 do
967 assert_select "channel", :count => 1 do
968 assert_select "item", :count => 1
972 get search_api_notes_path(:q => "note comment", :format => "gpx")
973 assert_response :success
974 assert_equal "application/gpx+xml", @response.media_type
975 assert_select "gpx", :count => 1 do
976 assert_select "wpt", :count => 1
979 get search_api_notes_path(:q => "note comment", :limit => Settings.max_note_query_limit, :format => "xml")
980 assert_response :success
983 def test_search_by_display_name_success
986 create(:note) do |note|
987 create(:note_comment, :note => note, :author => user)
990 get search_api_notes_path(:display_name => user.display_name, :format => "xml")
991 assert_response :success
992 assert_equal "application/xml", @response.media_type
993 assert_select "osm", :count => 1 do
994 assert_select "note", :count => 1
997 get search_api_notes_path(:display_name => user.display_name, :format => "json")
998 assert_response :success
999 assert_equal "application/json", @response.media_type
1000 js = ActiveSupport::JSON.decode(@response.body)
1002 assert_equal "FeatureCollection", js["type"]
1003 assert_equal 1, js["features"].count
1005 get search_api_notes_path(:display_name => user.display_name, :format => "rss")
1006 assert_response :success
1007 assert_equal "application/rss+xml", @response.media_type
1008 assert_select "rss", :count => 1 do
1009 assert_select "channel", :count => 1 do
1010 assert_select "item", :count => 1
1014 get search_api_notes_path(:display_name => user.display_name, :format => "gpx")
1015 assert_response :success
1016 assert_equal "application/gpx+xml", @response.media_type
1017 assert_select "gpx", :count => 1 do
1018 assert_select "wpt", :count => 1
1022 def test_search_by_user_success
1023 user = create(:user)
1025 create(:note) do |note|
1026 create(:note_comment, :note => note, :author => user)
1029 get search_api_notes_path(:user => user.id, :format => "xml")
1030 assert_response :success
1031 assert_equal "application/xml", @response.media_type
1032 assert_select "osm", :count => 1 do
1033 assert_select "note", :count => 1
1036 get search_api_notes_path(:user => user.id, :format => "json")
1037 assert_response :success
1038 assert_equal "application/json", @response.media_type
1039 js = ActiveSupport::JSON.decode(@response.body)
1041 assert_equal "FeatureCollection", js["type"]
1042 assert_equal 1, js["features"].count
1044 get search_api_notes_path(:user => user.id, :format => "rss")
1045 assert_response :success
1046 assert_equal "application/rss+xml", @response.media_type
1047 assert_select "rss", :count => 1 do
1048 assert_select "channel", :count => 1 do
1049 assert_select "item", :count => 1
1053 get search_api_notes_path(:user => user.id, :format => "gpx")
1054 assert_response :success
1055 assert_equal "application/gpx+xml", @response.media_type
1056 assert_select "gpx", :count => 1 do
1057 assert_select "wpt", :count => 1
1060 user2 = create(:user)
1061 get search_api_notes_path(:user => user2.id, :format => "xml")
1062 assert_response :success
1063 assert_equal "application/xml", @response.media_type
1064 assert_select "osm", :count => 1 do
1065 assert_select "note", :count => 0
1069 def test_search_by_time_success
1070 note1 = create(:note, :created_at => "2020-02-01T00:00:00Z", :updated_at => "2020-04-01T00:00:00Z")
1071 note2 = create(:note, :created_at => "2020-03-01T00:00:00Z", :updated_at => "2020-05-01T00:00:00Z")
1073 get search_api_notes_path(:from => "2020-02-15T00:00:00Z", :to => "2020-04-15T00:00:00Z", :format => "xml")
1074 assert_response :success
1075 assert_equal "application/xml", @response.media_type
1076 assert_select "osm", :count => 1 do
1077 assert_select "note", :count => 1 do
1078 assert_select "id", note2.id.to_s
1082 get search_api_notes_path(:from => "2020-02-15T00:00:00Z", :to => "2020-04-15T00:00:00Z", :sort => "updated_at", :format => "xml")
1083 assert_response :success
1084 assert_equal "application/xml", @response.media_type
1085 assert_select "osm", :count => 1 do
1086 assert_select "note", :count => 1 do
1087 assert_select "id", note1.id.to_s
1092 def test_search_by_bbox_success
1093 notes = Array.new(5) do |i|
1094 position = ((1.0 + (i * 0.1)) * GeoRecord::SCALE).to_i
1095 create(:note_with_comments, :created_at => Time.parse("2020-01-01T00:00:00Z") + i.day, :latitude => position, :longitude => position)
1098 get search_api_notes_path(:bbox => "1.0,1.0,1.6,1.6", :sort => "created_at", :order => "oldest", :format => "xml")
1099 assert_response :success
1100 assert_equal "application/xml", @response.media_type
1101 assert_notes_in_order notes
1103 get search_api_notes_path(:bbox => "1.25,1.25,1.45,1.45", :sort => "created_at", :order => "oldest", :format => "xml")
1104 assert_response :success
1105 assert_equal "application/xml", @response.media_type
1106 assert_notes_in_order [notes[3], notes[4]]
1108 get search_api_notes_path(:bbox => "2.0,2.0,2.5,2.5", :sort => "created_at", :order => "oldest", :format => "xml")
1109 assert_response :success
1110 assert_equal "application/xml", @response.media_type
1111 assert_notes_in_order []
1114 def test_search_no_match
1115 create(:note_with_comments)
1117 get search_api_notes_path(:q => "no match", :format => "xml")
1118 assert_response :success
1119 assert_equal "application/xml", @response.media_type
1120 assert_select "osm", :count => 1 do
1121 assert_select "note", :count => 0
1124 get search_api_notes_path(:q => "no match", :format => "json")
1125 assert_response :success
1126 assert_equal "application/json", @response.media_type
1127 js = ActiveSupport::JSON.decode(@response.body)
1129 assert_equal "FeatureCollection", js["type"]
1130 assert_equal 0, js["features"].count
1132 get search_api_notes_path(:q => "no match", :format => "rss")
1133 assert_response :success
1134 assert_equal "application/rss+xml", @response.media_type
1135 assert_select "rss", :count => 1 do
1136 assert_select "channel", :count => 1 do
1137 assert_select "item", :count => 0
1141 get search_api_notes_path(:q => "no match", :format => "gpx")
1142 assert_response :success
1143 assert_equal "application/gpx+xml", @response.media_type
1144 assert_select "gpx", :count => 1 do
1145 assert_select "wpt", :count => 0
1149 def test_search_by_time_no_match
1150 create(:note_with_comments)
1152 get search_api_notes_path(:from => "01.01.2010", :to => "01.10.2010", :format => "xml")
1153 assert_response :success
1154 assert_equal "application/xml", @response.media_type
1155 assert_select "osm", :count => 1 do
1156 assert_select "note", :count => 0
1159 get search_api_notes_path(:from => "01.01.2010", :to => "01.10.2010", :format => "json")
1160 assert_response :success
1161 assert_equal "application/json", @response.media_type
1162 js = ActiveSupport::JSON.decode(@response.body)
1164 assert_equal "FeatureCollection", js["type"]
1165 assert_equal 0, js["features"].count
1167 get search_api_notes_path(:from => "01.01.2010", :to => "01.10.2010", :format => "rss")
1168 assert_response :success
1169 assert_equal "application/rss+xml", @response.media_type
1170 assert_select "rss", :count => 1 do
1171 assert_select "channel", :count => 1 do
1172 assert_select "item", :count => 0
1176 get search_api_notes_path(:from => "01.01.2010", :to => "01.10.2010", :format => "gpx")
1177 assert_response :success
1178 assert_equal "application/gpx+xml", @response.media_type
1179 assert_select "gpx", :count => 1 do
1180 assert_select "wpt", :count => 0
1184 def test_search_bad_params
1185 get search_api_notes_path(:q => "no match", :limit => "0", :format => "json")
1186 assert_response :bad_request
1188 get search_api_notes_path(:q => "no match", :limit => Settings.max_note_query_limit + 1, :format => "json")
1189 assert_response :bad_request
1191 get search_api_notes_path(:display_name => "non-existent")
1192 assert_response :bad_request
1194 get search_api_notes_path(:user => "-1")
1195 assert_response :bad_request
1197 get search_api_notes_path(:from => "wrong-date", :to => "wrong-date")
1198 assert_response :bad_request
1200 get search_api_notes_path(:from => "01.01.2010", :to => "2010.01.2010")
1201 assert_response :bad_request
1204 def test_feed_success
1205 position = (1.1 * GeoRecord::SCALE).to_i
1206 create(:note_with_comments, :latitude => position, :longitude => position)
1207 create(:note_with_comments, :latitude => position, :longitude => position)
1208 position = (1.5 * GeoRecord::SCALE).to_i
1209 create(:note_with_comments, :latitude => position, :longitude => position)
1210 create(:note_with_comments, :latitude => position, :longitude => position)
1212 get feed_api_notes_path(:format => "rss")
1213 assert_response :success
1214 assert_equal "application/rss+xml", @response.media_type
1215 assert_select "rss", :count => 1 do
1216 assert_select "channel", :count => 1 do
1217 assert_select "item", :count => 4
1221 get feed_api_notes_path(:bbox => "1,1,1.2,1.2", :format => "rss")
1222 assert_response :success
1223 assert_equal "application/rss+xml", @response.media_type
1224 assert_select "rss", :count => 1 do
1225 assert_select "channel", :count => 1 do
1226 assert_select "description", :text => /1\.2/, :count => 1
1227 assert_select "item", :count => 2
1231 get feed_api_notes_path(:bbox => "1,1,1.2,1.2", :limit => Settings.max_note_query_limit, :format => "rss")
1232 assert_response :success
1236 get feed_api_notes_path(:bbox => "1,1,1.2", :format => "rss")
1237 assert_response :bad_request
1239 get feed_api_notes_path(:bbox => "1,1,1.2,1.2,1.2", :format => "rss")
1240 assert_response :bad_request
1242 get feed_api_notes_path(:bbox => "1,1,1.2,1.2", :limit => "0", :format => "rss")
1243 assert_response :bad_request
1245 get feed_api_notes_path(:bbox => "1,1,1.2,1.2", :limit => Settings.max_note_query_limit + 1, :format => "rss")
1246 assert_response :bad_request
1251 def assert_notes_in_order(notes)
1252 assert_select "osm>note", notes.size
1253 notes.each_with_index do |note, index|
1254 assert_select "osm>note:nth-child(#{index + 1})>id", :text => note.id.to_s, :count => 1