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