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