]> git.openstreetmap.org Git - rails.git/blob - test/controllers/traces_controller_test.rb
Merge pull request #4089 from tomhughes/trace-paging
[rails.git] / test / controllers / traces_controller_test.rb
1 require "test_helper"
2
3 class TracesControllerTest < ActionDispatch::IntegrationTest
4   ##
5   # test all routes which lead to this controller
6   def test_routes
7     assert_routing(
8       { :path => "/traces", :method => :get },
9       { :controller => "traces", :action => "index" }
10     )
11     assert_routing(
12       { :path => "/traces/tag/tagname", :method => :get },
13       { :controller => "traces", :action => "index", :tag => "tagname" }
14     )
15     assert_routing(
16       { :path => "/user/username/traces", :method => :get },
17       { :controller => "traces", :action => "index", :display_name => "username" }
18     )
19     assert_routing(
20       { :path => "/user/username/traces/tag/tagname", :method => :get },
21       { :controller => "traces", :action => "index", :display_name => "username", :tag => "tagname" }
22     )
23
24     assert_routing(
25       { :path => "/traces/mine", :method => :get },
26       { :controller => "traces", :action => "mine" }
27     )
28     assert_routing(
29       { :path => "/traces/mine/tag/tagname", :method => :get },
30       { :controller => "traces", :action => "mine", :tag => "tagname" }
31     )
32
33     assert_routing(
34       { :path => "/traces/rss", :method => :get },
35       { :controller => "traces", :action => "georss", :format => :rss }
36     )
37     assert_routing(
38       { :path => "/traces/tag/tagname/rss", :method => :get },
39       { :controller => "traces", :action => "georss", :tag => "tagname", :format => :rss }
40     )
41     assert_routing(
42       { :path => "/user/username/traces/rss", :method => :get },
43       { :controller => "traces", :action => "georss", :display_name => "username", :format => :rss }
44     )
45     assert_routing(
46       { :path => "/user/username/traces/tag/tagname/rss", :method => :get },
47       { :controller => "traces", :action => "georss", :display_name => "username", :tag => "tagname", :format => :rss }
48     )
49
50     assert_routing(
51       { :path => "/user/username/traces/1", :method => :get },
52       { :controller => "traces", :action => "show", :display_name => "username", :id => "1" }
53     )
54     assert_routing(
55       { :path => "/user/username/traces/1/picture", :method => :get },
56       { :controller => "traces", :action => "picture", :display_name => "username", :id => "1" }
57     )
58     assert_routing(
59       { :path => "/user/username/traces/1/icon", :method => :get },
60       { :controller => "traces", :action => "icon", :display_name => "username", :id => "1" }
61     )
62
63     assert_routing(
64       { :path => "/traces/new", :method => :get },
65       { :controller => "traces", :action => "new" }
66     )
67     assert_routing(
68       { :path => "/traces", :method => :post },
69       { :controller => "traces", :action => "create" }
70     )
71     assert_routing(
72       { :path => "/trace/1/data", :method => :get },
73       { :controller => "traces", :action => "data", :id => "1" }
74     )
75     assert_routing(
76       { :path => "/trace/1/data.xml", :method => :get },
77       { :controller => "traces", :action => "data", :id => "1", :format => "xml" }
78     )
79     assert_routing(
80       { :path => "/traces/1/edit", :method => :get },
81       { :controller => "traces", :action => "edit", :id => "1" }
82     )
83     assert_routing(
84       { :path => "/traces/1", :method => :put },
85       { :controller => "traces", :action => "update", :id => "1" }
86     )
87     assert_routing(
88       { :path => "/traces/1", :method => :delete },
89       { :controller => "traces", :action => "destroy", :id => "1" }
90     )
91
92     get "/traces/page/1"
93     assert_redirected_to "/traces"
94
95     get "/traces/tag/tagname/page/1"
96     assert_redirected_to "/traces/tag/tagname"
97
98     get "/user/username/traces/page/1"
99     assert_redirected_to "/user/username/traces"
100
101     get "/user/username/traces/tag/tagname/page/1"
102     assert_redirected_to "/user/username/traces/tag/tagname"
103
104     get "/traces/mine/page/1"
105     assert_redirected_to "/traces/mine"
106
107     get "/traces/mine/tag/tagname/page/1"
108     assert_redirected_to "/traces/mine/tag/tagname"
109   end
110
111   # Check that the index of traces is displayed
112   def test_index
113     user = create(:user)
114     # The fourth test below is surprisingly sensitive to timestamp ordering when the timestamps are equal.
115     trace_a = create(:trace, :visibility => "public", :timestamp => 4.seconds.ago) do |trace|
116       create(:tracetag, :trace => trace, :tag => "London")
117     end
118     trace_b = create(:trace, :visibility => "public", :timestamp => 3.seconds.ago) do |trace|
119       create(:tracetag, :trace => trace, :tag => "Birmingham")
120     end
121     trace_c = create(:trace, :visibility => "private", :user => user, :timestamp => 2.seconds.ago) do |trace|
122       create(:tracetag, :trace => trace, :tag => "London")
123     end
124     trace_d = create(:trace, :visibility => "private", :user => user, :timestamp => 1.second.ago) do |trace|
125       create(:tracetag, :trace => trace, :tag => "Birmingham")
126     end
127
128     # First with the public index
129     get traces_path
130     check_trace_index [trace_b, trace_a]
131
132     # Restrict traces to those with a given tag
133     get traces_path(:tag => "London")
134     check_trace_index [trace_a]
135
136     session_for(user)
137
138     # Should see more when we are logged in
139     get traces_path
140     check_trace_index [trace_d, trace_c, trace_b, trace_a]
141
142     # Again, we should see more when we are logged in
143     get traces_path(:tag => "London")
144     check_trace_index [trace_c, trace_a]
145   end
146
147   # Check that I can get mine
148   def test_index_mine
149     user = create(:user)
150     create(:trace, :visibility => "public") do |trace|
151       create(:tracetag, :trace => trace, :tag => "Birmingham")
152     end
153     trace_b = create(:trace, :visibility => "private", :user => user) do |trace|
154       create(:tracetag, :trace => trace, :tag => "London")
155     end
156
157     # First try to get it when not logged in
158     get traces_mine_path
159     assert_redirected_to login_path(:referer => "/traces/mine")
160
161     session_for(user)
162
163     # Now try when logged in
164     get traces_mine_path
165     assert_redirected_to :action => "index", :display_name => user.display_name
166
167     # Fetch the actual index
168     get traces_path(:display_name => user.display_name)
169     check_trace_index [trace_b]
170   end
171
172   # Check the index of traces for a specific user
173   def test_index_user
174     user = create(:user)
175     second_user = create(:user)
176     third_user = create(:user)
177     create(:trace)
178     trace_b = create(:trace, :visibility => "public", :user => user)
179     trace_c = create(:trace, :visibility => "private", :user => user) do |trace|
180       create(:tracetag, :trace => trace, :tag => "London")
181     end
182
183     # Test a user with no traces
184     get traces_path(:display_name => second_user.display_name)
185     check_trace_index []
186
187     # Test the user with the traces - should see only public ones
188     get traces_path(:display_name => user.display_name)
189     check_trace_index [trace_b]
190
191     session_for(third_user)
192
193     # Should still see only public ones when authenticated as another user
194     get traces_path(:display_name => user.display_name)
195     check_trace_index [trace_b]
196
197     session_for(user)
198
199     # Should see all traces when authenticated as the target user
200     get traces_path(:display_name => user.display_name)
201     check_trace_index [trace_c, trace_b]
202
203     # Should only see traces with the correct tag when a tag is specified
204     get traces_path(:display_name => user.display_name, :tag => "London")
205     check_trace_index [trace_c]
206
207     # Should get an error if the user does not exist
208     get traces_path(:display_name => "UnknownUser")
209     assert_response :not_found
210     assert_template "users/no_such_user"
211   end
212
213   # Check a multi-page index
214   def test_index_paged
215     # Create several pages worth of traces
216     create_list(:trace, 50)
217
218     # Try and get the index
219     get traces_path
220     assert_response :success
221     assert_select "table#trace_list tbody", :count => 1 do
222       assert_select "tr", :count => 20
223     end
224
225     # Try and get the second page
226     get traces_path(:page => 2)
227     assert_response :success
228     assert_select "table#trace_list tbody", :count => 1 do
229       assert_select "tr", :count => 20
230     end
231   end
232
233   # Check the RSS feed
234   def test_rss
235     user = create(:user)
236     # The fourth test below is surprisingly sensitive to timestamp ordering when the timestamps are equal.
237     trace_a = create(:trace, :visibility => "public", :timestamp => 4.seconds.ago) do |trace|
238       create(:tracetag, :trace => trace, :tag => "London")
239     end
240     trace_b = create(:trace, :visibility => "public", :timestamp => 3.seconds.ago) do |trace|
241       create(:tracetag, :trace => trace, :tag => "Birmingham")
242     end
243     create(:trace, :visibility => "private", :user => user, :timestamp => 2.seconds.ago) do |trace|
244       create(:tracetag, :trace => trace, :tag => "London")
245     end
246     create(:trace, :visibility => "private", :user => user, :timestamp => 1.second.ago) do |trace|
247       create(:tracetag, :trace => trace, :tag => "Birmingham")
248     end
249
250     # First with the public feed
251     get traces_rss_path
252     check_trace_feed [trace_b, trace_a]
253
254     # Restrict traces to those with a given tag
255     get traces_rss_path(:tag => "London")
256     check_trace_feed [trace_a]
257   end
258
259   # Check the RSS feed for a specific user
260   def test_rss_user
261     user = create(:user)
262     second_user = create(:user)
263     create(:user)
264     create(:trace)
265     trace_b = create(:trace, :visibility => "public", :timestamp => 4.seconds.ago, :user => user)
266     trace_c = create(:trace, :visibility => "public", :timestamp => 3.seconds.ago, :user => user) do |trace|
267       create(:tracetag, :trace => trace, :tag => "London")
268     end
269     create(:trace, :visibility => "private")
270
271     # Test a user with no traces
272     get traces_rss_path(:display_name => second_user.display_name)
273     check_trace_feed []
274
275     # Test the user with the traces - should see only public ones
276     get traces_rss_path(:display_name => user.display_name)
277     check_trace_feed [trace_c, trace_b]
278
279     # Should only see traces with the correct tag when a tag is specified
280     get traces_rss_path(:display_name => user.display_name, :tag => "London")
281     check_trace_feed [trace_c]
282
283     # Should no traces if the user does not exist
284     get traces_rss_path(:display_name => "UnknownUser")
285     check_trace_feed []
286   end
287
288   # Test showing a trace
289   def test_show
290     public_trace_file = create(:trace, :visibility => "public")
291
292     # First with no auth, which should work since the trace is public
293     get show_trace_path(:display_name => public_trace_file.user.display_name, :id => public_trace_file)
294     check_trace_show public_trace_file
295
296     # Now with some other user, which should work since the trace is public
297     session_for(create(:user))
298     get show_trace_path(:display_name => public_trace_file.user.display_name, :id => public_trace_file)
299     check_trace_show public_trace_file
300
301     # And finally we should be able to do it with the owner of the trace
302     session_for(public_trace_file.user)
303     get show_trace_path(:display_name => public_trace_file.user.display_name, :id => public_trace_file)
304     check_trace_show public_trace_file
305   end
306
307   # Check an anonymous trace can't be viewed by another user
308   def test_show_anon
309     anon_trace_file = create(:trace, :visibility => "private")
310
311     # First with no auth
312     get show_trace_path(:display_name => anon_trace_file.user.display_name, :id => anon_trace_file)
313     assert_response :redirect
314     assert_redirected_to :action => :index
315
316     # Now with some other user, which should not work since the trace is anon
317     session_for(create(:user))
318     get show_trace_path(:display_name => anon_trace_file.user.display_name, :id => anon_trace_file)
319     assert_response :redirect
320     assert_redirected_to :action => :index
321
322     # And finally we should be able to do it with the owner of the trace
323     session_for(anon_trace_file.user)
324     get show_trace_path(:display_name => anon_trace_file.user.display_name, :id => anon_trace_file)
325     check_trace_show anon_trace_file
326   end
327
328   # Test showing a trace that doesn't exist
329   def test_show_not_found
330     deleted_trace_file = create(:trace, :deleted)
331
332     # First with a trace that has never existed
333     get show_trace_path(:display_name => create(:user).display_name, :id => 0)
334     assert_response :redirect
335     assert_redirected_to :action => :index
336
337     # Now with a trace that has been deleted
338     session_for(deleted_trace_file.user)
339     get show_trace_path(:display_name => deleted_trace_file.user.display_name, :id => deleted_trace_file)
340     assert_response :redirect
341     assert_redirected_to :action => :index
342   end
343
344   # Test downloading a trace
345   def test_data
346     public_trace_file = create(:trace, :visibility => "public", :fixture => "a")
347
348     # First with no auth, which should work since the trace is public
349     get trace_data_path(:display_name => public_trace_file.user.display_name, :id => public_trace_file)
350     follow_redirect!
351     follow_redirect!
352     check_trace_data public_trace_file, "848caa72f2f456d1bd6a0fdf228aa1b9"
353
354     # Now with some other user, which should work since the trace is public
355     session_for(create(:user))
356     get trace_data_path(:display_name => public_trace_file.user.display_name, :id => public_trace_file)
357     follow_redirect!
358     follow_redirect!
359     check_trace_data public_trace_file, "848caa72f2f456d1bd6a0fdf228aa1b9"
360
361     # And finally we should be able to do it with the owner of the trace
362     session_for(public_trace_file.user)
363     get trace_data_path(:display_name => public_trace_file.user.display_name, :id => public_trace_file)
364     follow_redirect!
365     follow_redirect!
366     check_trace_data public_trace_file, "848caa72f2f456d1bd6a0fdf228aa1b9"
367   end
368
369   # Test downloading a compressed trace
370   def test_data_compressed
371     identifiable_trace_file = create(:trace, :visibility => "identifiable", :fixture => "d")
372
373     # First get the data as is
374     get trace_data_path(:display_name => identifiable_trace_file.user.display_name, :id => identifiable_trace_file)
375     follow_redirect!
376     follow_redirect!
377     check_trace_data identifiable_trace_file, "c6422a3d8750faae49ed70e7e8a51b93", "application/gzip", "gpx.gz"
378
379     # Now ask explicitly for XML format
380     get trace_data_path(:display_name => identifiable_trace_file.user.display_name, :id => identifiable_trace_file.id, :format => "xml")
381     check_trace_data identifiable_trace_file, "abd6675fdf3024a84fc0a1deac147c0d", "application/xml", "xml"
382
383     # Now ask explicitly for GPX format
384     get trace_data_path(:display_name => identifiable_trace_file.user.display_name, :id => identifiable_trace_file.id, :format => "gpx")
385     check_trace_data identifiable_trace_file, "abd6675fdf3024a84fc0a1deac147c0d"
386   end
387
388   # Check an anonymous trace can't be downloaded by another user
389   def test_data_anon
390     anon_trace_file = create(:trace, :visibility => "private", :fixture => "b")
391
392     # First with no auth
393     get trace_data_path(:display_name => anon_trace_file.user.display_name, :id => anon_trace_file)
394     assert_response :not_found
395
396     # Now with some other user, which shouldn't work since the trace is anon
397     session_for(create(:user))
398     get trace_data_path(:display_name => anon_trace_file.user.display_name, :id => anon_trace_file)
399     assert_response :not_found
400
401     # And finally we should be able to do it with the owner of the trace
402     session_for(anon_trace_file.user)
403     get trace_data_path(:display_name => anon_trace_file.user.display_name, :id => anon_trace_file)
404     follow_redirect!
405     follow_redirect!
406     check_trace_data anon_trace_file, "db4cb5ed2d7d2b627b3b504296c4f701"
407   end
408
409   # Test downloading a trace that doesn't exist
410   def test_data_not_found
411     deleted_trace_file = create(:trace, :deleted)
412
413     # First with a trace that has never existed
414     get trace_data_path(:display_name => create(:user).display_name, :id => 0)
415     assert_response :not_found
416
417     # Now with a trace that has been deleted
418     session_for(deleted_trace_file.user)
419     get trace_data_path(:display_name => deleted_trace_file.user.display_name, :id => deleted_trace_file)
420     assert_response :not_found
421   end
422
423   # Test downloading the picture for a trace
424   def test_picture
425     public_trace_file = create(:trace, :visibility => "public", :fixture => "a")
426
427     # First with no auth, which should work since the trace is public
428     get trace_picture_path(:display_name => public_trace_file.user.display_name, :id => public_trace_file)
429     check_trace_picture public_trace_file
430
431     # Now with some other user, which should work since the trace is public
432     session_for(create(:user))
433     get trace_picture_path(:display_name => public_trace_file.user.display_name, :id => public_trace_file)
434     check_trace_picture public_trace_file
435
436     # And finally we should be able to do it with the owner of the trace
437     session_for(public_trace_file.user)
438     get trace_picture_path(:display_name => public_trace_file.user.display_name, :id => public_trace_file)
439     check_trace_picture public_trace_file
440   end
441
442   # Check the picture for an anonymous trace can't be downloaded by another user
443   def test_picture_anon
444     anon_trace_file = create(:trace, :visibility => "private", :fixture => "b")
445
446     # First with no auth
447     get trace_picture_path(:display_name => anon_trace_file.user.display_name, :id => anon_trace_file)
448     assert_response :forbidden
449
450     # Now with some other user, which shouldn't work since the trace is anon
451     session_for(create(:user))
452     get trace_picture_path(:display_name => anon_trace_file.user.display_name, :id => anon_trace_file)
453     assert_response :forbidden
454
455     # And finally we should be able to do it with the owner of the trace
456     session_for(anon_trace_file.user)
457     get trace_picture_path(:display_name => anon_trace_file.user.display_name, :id => anon_trace_file)
458     check_trace_picture anon_trace_file
459   end
460
461   # Test downloading the picture for a trace that doesn't exist
462   def test_picture_not_found
463     deleted_trace_file = create(:trace, :deleted)
464
465     # First with a trace that has never existed
466     get trace_picture_path(:display_name => create(:user).display_name, :id => 0)
467     assert_response :not_found
468
469     # Now with a trace that has been deleted
470     session_for(deleted_trace_file.user)
471     get trace_picture_path(:display_name => deleted_trace_file.user.display_name, :id => deleted_trace_file)
472     assert_response :not_found
473   end
474
475   # Test downloading the icon for a trace
476   def test_icon
477     public_trace_file = create(:trace, :visibility => "public", :fixture => "a")
478
479     # First with no auth, which should work since the trace is public
480     get trace_icon_path(:display_name => public_trace_file.user.display_name, :id => public_trace_file)
481     check_trace_icon public_trace_file
482
483     # Now with some other user, which should work since the trace is public
484     session_for(create(:user))
485     get trace_icon_path(:display_name => public_trace_file.user.display_name, :id => public_trace_file)
486     check_trace_icon public_trace_file
487
488     # And finally we should be able to do it with the owner of the trace
489     session_for(public_trace_file.user)
490     get trace_icon_path(:display_name => public_trace_file.user.display_name, :id => public_trace_file)
491     check_trace_icon public_trace_file
492   end
493
494   # Check the icon for an anonymous trace can't be downloaded by another user
495   def test_icon_anon
496     anon_trace_file = create(:trace, :visibility => "private", :fixture => "b")
497
498     # First with no auth
499     get trace_icon_path(:display_name => anon_trace_file.user.display_name, :id => anon_trace_file)
500     assert_response :forbidden
501
502     # Now with some other user, which shouldn't work since the trace is anon
503     session_for(create(:user))
504     get trace_icon_path(:display_name => anon_trace_file.user.display_name, :id => anon_trace_file)
505     assert_response :forbidden
506
507     # And finally we should be able to do it with the owner of the trace
508     session_for(anon_trace_file.user)
509     get trace_icon_path(:display_name => anon_trace_file.user.display_name, :id => anon_trace_file)
510     check_trace_icon anon_trace_file
511   end
512
513   # Test downloading the icon for a trace that doesn't exist
514   def test_icon_not_found
515     deleted_trace_file = create(:trace, :deleted)
516
517     # First with a trace that has never existed
518     get trace_icon_path(:display_name => create(:user).display_name, :id => 0)
519     assert_response :not_found
520
521     # Now with a trace that has been deleted
522     session_for(deleted_trace_file.user)
523     get trace_icon_path(:display_name => deleted_trace_file.user.display_name, :id => deleted_trace_file)
524     assert_response :not_found
525   end
526
527   # Test fetching the new trace page
528   def test_new_get
529     # First with no auth
530     get new_trace_path
531     assert_response :redirect
532     assert_redirected_to login_path(:referer => new_trace_path)
533
534     # Now authenticated as a user with gps.trace.visibility set
535     user = create(:user)
536     create(:user_preference, :user => user, :k => "gps.trace.visibility", :v => "identifiable")
537     session_for(user)
538     get new_trace_path
539     assert_response :success
540     assert_template :new
541     assert_select "select#trace_visibility option[value=identifiable][selected]", 1
542
543     # Now authenticated as a user with gps.trace.public set
544     second_user = create(:user)
545     create(:user_preference, :user => second_user, :k => "gps.trace.public", :v => "default")
546     session_for(second_user)
547     get new_trace_path
548     assert_response :success
549     assert_template :new
550     assert_select "select#trace_visibility option[value=public][selected]", 1
551
552     # Now authenticated as a user with no preferences
553     third_user = create(:user)
554     session_for(third_user)
555     get new_trace_path
556     assert_response :success
557     assert_template :new
558     assert_select "select#trace_visibility option[value=private][selected]", 1
559   end
560
561   # Test creating a trace
562   def test_create_post
563     # Get file to use
564     fixture = Rails.root.join("test/gpx/fixtures/a.gpx")
565     file = Rack::Test::UploadedFile.new(fixture, "application/gpx+xml")
566     user = create(:user)
567
568     # First with no auth
569     post traces_path(:trace => { :gpx_file => file, :description => "New Trace", :tagstring => "new,trace", :visibility => "trackable" })
570     assert_response :forbidden
571
572     # Rewind the file
573     file.rewind
574
575     # Now authenticated
576     create(:user_preference, :user => user, :k => "gps.trace.visibility", :v => "identifiable")
577     assert_not_equal "trackable", user.preferences.where(:k => "gps.trace.visibility").first.v
578     session_for(user)
579     post traces_path, :params => { :trace => { :gpx_file => file, :description => "New Trace", :tagstring => "new,trace", :visibility => "trackable" } }
580     assert_response :redirect
581     assert_redirected_to :action => :index, :display_name => user.display_name
582     assert_match(/file has been uploaded/, flash[:notice])
583     trace = Trace.order(:id => :desc).first
584     assert_equal "a.gpx", trace.name
585     assert_equal "New Trace", trace.description
586     assert_equal %w[new trace], trace.tags.order(:tag).collect(&:tag)
587     assert_equal "trackable", trace.visibility
588     assert_not trace.inserted
589     assert_equal File.new(fixture).read, trace.file.blob.download
590     trace.destroy
591     assert_equal "trackable", user.preferences.where(:k => "gps.trace.visibility").first.v
592   end
593
594   # Test creating a trace with validation errors
595   def test_create_post_with_validation_errors
596     # Get file to use
597     fixture = Rails.root.join("test/gpx/fixtures/a.gpx")
598     file = Rack::Test::UploadedFile.new(fixture, "application/gpx+xml")
599     user = create(:user)
600
601     # Now authenticated
602     create(:user_preference, :user => user, :k => "gps.trace.visibility", :v => "identifiable")
603     assert_not_equal "trackable", user.preferences.where(:k => "gps.trace.visibility").first.v
604     session_for(user)
605     post traces_path, :params => { :trace => { :gpx_file => file, :description => "", :tagstring => "new,trace", :visibility => "trackable" } }
606     assert_template :new
607     assert_match "is too short (minimum is 1 character)", response.body
608   end
609
610   # Test fetching the edit page for a trace using GET
611   def test_edit_get
612     public_trace_file = create(:trace, :visibility => "public")
613     deleted_trace_file = create(:trace, :deleted)
614
615     # First with no auth
616     get edit_trace_path(:display_name => public_trace_file.user.display_name, :id => public_trace_file)
617     assert_response :redirect
618     assert_redirected_to login_path(:referer => edit_trace_path(:display_name => public_trace_file.user.display_name, :id => public_trace_file.id))
619
620     # Now with some other user, which should fail
621     session_for(create(:user))
622     get edit_trace_path(:display_name => public_trace_file.user.display_name, :id => public_trace_file)
623     assert_response :forbidden
624
625     # Now with a trace which doesn't exist
626     session_for(create(:user))
627     get edit_trace_path(:display_name => create(:user).display_name, :id => 0)
628     assert_response :not_found
629
630     # Now with a trace which has been deleted
631     session_for(deleted_trace_file.user)
632     get edit_trace_path(:display_name => deleted_trace_file.user.display_name, :id => deleted_trace_file)
633     assert_response :not_found
634
635     # Finally with a trace that we are allowed to edit
636     session_for(public_trace_file.user)
637     get edit_trace_path(:display_name => public_trace_file.user.display_name, :id => public_trace_file)
638     assert_response :success
639   end
640
641   # Test saving edits to a trace
642   def test_update
643     public_trace_file = create(:trace, :visibility => "public")
644     deleted_trace_file = create(:trace, :deleted)
645
646     # New details
647     new_details = { :description => "Changed description", :tagstring => "new_tag", :visibility => "private" }
648
649     # First with no auth
650     put trace_path(:display_name => public_trace_file.user.display_name, :id => public_trace_file, :trace => new_details)
651     assert_response :forbidden
652
653     # Now with some other user, which should fail
654     session_for(create(:user))
655     put trace_path(:display_name => public_trace_file.user.display_name, :id => public_trace_file, :trace => new_details)
656     assert_response :forbidden
657
658     # Now with a trace which doesn't exist
659     session_for(create(:user))
660     put trace_path(:display_name => create(:user).display_name, :id => 0, :trace => new_details)
661     assert_response :not_found
662
663     # Now with a trace which has been deleted
664     session_for(deleted_trace_file.user)
665     put trace_path(:display_name => deleted_trace_file.user.display_name, :id => deleted_trace_file, :trace => new_details)
666     assert_response :not_found
667
668     # Finally with a trace that we are allowed to edit
669     session_for(public_trace_file.user)
670     put trace_path(:display_name => public_trace_file.user.display_name, :id => public_trace_file, :trace => new_details)
671     assert_response :redirect
672     assert_redirected_to :action => :show, :display_name => public_trace_file.user.display_name
673     trace = Trace.find(public_trace_file.id)
674     assert_equal new_details[:description], trace.description
675     assert_equal new_details[:tagstring], trace.tagstring
676     assert_equal new_details[:visibility], trace.visibility
677   end
678
679   # Test destroying a trace
680   def test_destroy
681     public_trace_file = create(:trace, :visibility => "public")
682     deleted_trace_file = create(:trace, :deleted)
683
684     # First with no auth
685     delete trace_path(:display_name => public_trace_file.user.display_name, :id => public_trace_file)
686     assert_response :forbidden
687
688     # Now with some other user, which should fail
689     session_for(create(:user))
690     delete trace_path(:display_name => public_trace_file.user.display_name, :id => public_trace_file)
691     assert_response :forbidden
692
693     # Now with a trace which doesn't exist
694     session_for(create(:user))
695     delete trace_path(:display_name => create(:user).display_name, :id => 0)
696     assert_response :not_found
697
698     # Now with a trace has already been deleted
699     session_for(deleted_trace_file.user)
700     delete trace_path(:display_name => deleted_trace_file.user.display_name, :id => deleted_trace_file)
701     assert_response :not_found
702
703     # Now with a trace that we are allowed to delete
704     session_for(public_trace_file.user)
705     delete trace_path(:display_name => public_trace_file.user.display_name, :id => public_trace_file)
706     assert_response :redirect
707     assert_redirected_to :action => :index, :display_name => public_trace_file.user.display_name
708     trace = Trace.find(public_trace_file.id)
709     assert_not trace.visible
710
711     # Finally with a trace that is destroyed by an admin
712     public_trace_file = create(:trace, :visibility => "public")
713     admin = create(:administrator_user)
714     session_for(admin)
715     delete trace_path(:display_name => public_trace_file.user.display_name, :id => public_trace_file)
716     assert_response :redirect
717     assert_redirected_to :action => :index, :display_name => public_trace_file.user.display_name
718     trace = Trace.find(public_trace_file.id)
719     assert_not trace.visible
720   end
721
722   private
723
724   def check_trace_feed(traces)
725     assert_response :success
726     assert_template "georss"
727     assert_equal "application/rss+xml", @response.media_type
728     assert_select "rss", :count => 1 do
729       assert_select "channel", :count => 1 do
730         assert_select "title"
731         assert_select "description"
732         assert_select "link"
733         assert_select "image"
734         assert_select "item", :count => traces.length do |items|
735           traces.zip(items).each do |trace, item|
736             assert_select item, "title", trace.name
737             assert_select item, "link", "http://www.example.com/user/#{ERB::Util.u(trace.user.display_name)}/traces/#{trace.id}"
738             assert_select item, "guid", "http://www.example.com/user/#{ERB::Util.u(trace.user.display_name)}/traces/#{trace.id}"
739             assert_select item, "description"
740             # assert_select item, "dc:creator", trace.user.display_name
741             assert_select item, "pubDate", trace.timestamp.rfc822
742           end
743         end
744       end
745     end
746   end
747
748   def check_trace_index(traces)
749     assert_response :success
750     assert_template "index"
751
752     if traces.empty?
753       assert_select "h2", /Nothing here yet/
754     else
755       assert_select "table#trace_list tbody", :count => 1 do
756         assert_select "tr", :count => traces.length do |rows|
757           traces.zip(rows).each do |trace, row|
758             assert_select row, "a", Regexp.new(Regexp.escape(trace.name))
759             assert_select row, "li", Regexp.new(Regexp.escape("#{trace.size} points")) if trace.inserted?
760             assert_select row, "td", Regexp.new(Regexp.escape(trace.description))
761             assert_select row, "td", Regexp.new(Regexp.escape("by #{trace.user.display_name}"))
762           end
763         end
764       end
765     end
766   end
767
768   def check_trace_show(trace)
769     assert_response :success
770     assert_template "show"
771
772     assert_select "table", :count => 1 do
773       assert_select "td", /^#{Regexp.quote(trace.name)} /
774       assert_select "td", trace.user.display_name
775       assert_select "td", trace.description
776     end
777   end
778
779   def check_trace_data(trace, digest, content_type = "application/gpx+xml", extension = "gpx")
780     assert_equal digest, Digest::MD5.hexdigest(response.body)
781     assert_equal content_type, response.media_type
782     assert_equal "attachment; filename=\"#{trace.id}.#{extension}\"; filename*=UTF-8''#{trace.id}.#{extension}", @response.header["Content-Disposition"]
783   end
784
785   def check_trace_picture(trace)
786     follow_redirect!
787     follow_redirect!
788     assert_response :success
789     assert_equal "image/gif", response.media_type
790     assert_equal trace.large_picture, response.body
791   end
792
793   def check_trace_icon(trace)
794     follow_redirect!
795     follow_redirect!
796     assert_response :success
797     assert_equal "image/gif", response.media_type
798     assert_equal trace.icon_picture, response.body
799   end
800 end