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