]> git.openstreetmap.org Git - rails.git/blob - test/controllers/traces_controller_test.rb
Merge pull request #4106 from tomhughes/diary-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     assert_select "li.page-item.disabled span.page-link", :text => "Newer Traces", :count => 2
225     assert_select "li.page-item a.page-link", :text => "Older Traces", :count => 2
226
227     # Try and get the second page
228     get css_select("li.page-item a.page-link").last["href"]
229     assert_response :success
230     assert_select "table#trace_list tbody", :count => 1 do
231       assert_select "tr", :count => 20
232     end
233     assert_select "li.page-item a.page-link", :text => "Newer Traces", :count => 2
234     assert_select "li.page-item a.page-link", :text => "Older Traces", :count => 2
235
236     # Try and get the third page
237     get css_select("li.page-item a.page-link").last["href"]
238     assert_response :success
239     assert_select "table#trace_list tbody", :count => 1 do
240       assert_select "tr", :count => 10
241     end
242     assert_select "li.page-item a.page-link", :text => "Newer Traces", :count => 2
243     assert_select "li.page-item.disabled span.page-link", :text => "Older Traces", :count => 2
244
245     # Go back to the second page
246     get css_select("li.page-item a.page-link").first["href"]
247     assert_response :success
248     assert_select "table#trace_list tbody", :count => 1 do
249       assert_select "tr", :count => 20
250     end
251     assert_select "li.page-item a.page-link", :text => "Newer Traces", :count => 2
252     assert_select "li.page-item a.page-link", :text => "Older Traces", :count => 2
253
254     # Go back to the first page
255     get css_select("li.page-item a.page-link").first["href"]
256     assert_response :success
257     assert_select "table#trace_list tbody", :count => 1 do
258       assert_select "tr", :count => 20
259     end
260     assert_select "li.page-item.disabled span.page-link", :text => "Newer Traces", :count => 2
261     assert_select "li.page-item a.page-link", :text => "Older Traces", :count => 2
262   end
263
264   # Check a multi-page index of tagged traces
265   def test_index_tagged_paged
266     # Create several pages worth of traces
267     create_list(:trace, 100) do |trace, index|
268       create(:tracetag, :trace => trace, :tag => "London") if index.even?
269     end
270
271     # Try and get the index
272     get traces_path(:tag => "London")
273     assert_response :success
274     assert_select "table#trace_list tbody", :count => 1 do
275       assert_select "tr", :count => 20
276     end
277     assert_select "li.page-item.disabled span.page-link", :text => "Newer Traces", :count => 2
278     assert_select "li.page-item a.page-link", :text => "Older Traces", :count => 2
279
280     # Try and get the second page
281     get css_select("li.page-item a.page-link").last["href"]
282     assert_response :success
283     assert_select "table#trace_list tbody", :count => 1 do
284       assert_select "tr", :count => 20
285     end
286     assert_select "li.page-item a.page-link", :text => "Newer Traces", :count => 2
287     assert_select "li.page-item a.page-link", :text => "Older Traces", :count => 2
288
289     # Try and get the third page
290     get css_select("li.page-item a.page-link").last["href"]
291     assert_response :success
292     assert_select "table#trace_list tbody", :count => 1 do
293       assert_select "tr", :count => 10
294     end
295     assert_select "li.page-item a.page-link", :text => "Newer Traces", :count => 2
296     assert_select "li.page-item.disabled span.page-link", :text => "Older Traces", :count => 2
297
298     # Go back to the second page
299     get css_select("li.page-item a.page-link").first["href"]
300     assert_response :success
301     assert_select "table#trace_list tbody", :count => 1 do
302       assert_select "tr", :count => 20
303     end
304     assert_select "li.page-item a.page-link", :text => "Newer Traces", :count => 2
305     assert_select "li.page-item a.page-link", :text => "Older Traces", :count => 2
306
307     # Go back to the first page
308     get css_select("li.page-item a.page-link").first["href"]
309     assert_response :success
310     assert_select "table#trace_list tbody", :count => 1 do
311       assert_select "tr", :count => 20
312     end
313     assert_select "li.page-item.disabled span.page-link", :text => "Newer Traces", :count => 2
314     assert_select "li.page-item a.page-link", :text => "Older Traces", :count => 2
315   end
316
317   # Check the RSS feed
318   def test_rss
319     user = create(:user)
320     # The fourth test below is surprisingly sensitive to timestamp ordering when the timestamps are equal.
321     trace_a = create(:trace, :visibility => "public", :timestamp => 4.seconds.ago) do |trace|
322       create(:tracetag, :trace => trace, :tag => "London")
323     end
324     trace_b = create(:trace, :visibility => "public", :timestamp => 3.seconds.ago) do |trace|
325       create(:tracetag, :trace => trace, :tag => "Birmingham")
326     end
327     create(:trace, :visibility => "private", :user => user, :timestamp => 2.seconds.ago) do |trace|
328       create(:tracetag, :trace => trace, :tag => "London")
329     end
330     create(:trace, :visibility => "private", :user => user, :timestamp => 1.second.ago) do |trace|
331       create(:tracetag, :trace => trace, :tag => "Birmingham")
332     end
333
334     # First with the public feed
335     get traces_rss_path
336     check_trace_feed [trace_b, trace_a]
337
338     # Restrict traces to those with a given tag
339     get traces_rss_path(:tag => "London")
340     check_trace_feed [trace_a]
341   end
342
343   # Check the RSS feed for a specific user
344   def test_rss_user
345     user = create(:user)
346     second_user = create(:user)
347     create(:user)
348     create(:trace)
349     trace_b = create(:trace, :visibility => "public", :timestamp => 4.seconds.ago, :user => user)
350     trace_c = create(:trace, :visibility => "public", :timestamp => 3.seconds.ago, :user => user) do |trace|
351       create(:tracetag, :trace => trace, :tag => "London")
352     end
353     create(:trace, :visibility => "private")
354
355     # Test a user with no traces
356     get traces_rss_path(:display_name => second_user.display_name)
357     check_trace_feed []
358
359     # Test the user with the traces - should see only public ones
360     get traces_rss_path(:display_name => user.display_name)
361     check_trace_feed [trace_c, trace_b]
362
363     # Should only see traces with the correct tag when a tag is specified
364     get traces_rss_path(:display_name => user.display_name, :tag => "London")
365     check_trace_feed [trace_c]
366
367     # Should no traces if the user does not exist
368     get traces_rss_path(:display_name => "UnknownUser")
369     check_trace_feed []
370   end
371
372   # Test showing a trace
373   def test_show
374     public_trace_file = create(:trace, :visibility => "public")
375
376     # First with no auth, which should work since the trace is public
377     get show_trace_path(:display_name => public_trace_file.user.display_name, :id => public_trace_file)
378     check_trace_show public_trace_file
379
380     # Now with some other user, which should work since the trace is public
381     session_for(create(:user))
382     get show_trace_path(:display_name => public_trace_file.user.display_name, :id => public_trace_file)
383     check_trace_show public_trace_file
384
385     # And finally we should be able to do it with the owner of the trace
386     session_for(public_trace_file.user)
387     get show_trace_path(:display_name => public_trace_file.user.display_name, :id => public_trace_file)
388     check_trace_show public_trace_file
389   end
390
391   # Check an anonymous trace can't be viewed by another user
392   def test_show_anon
393     anon_trace_file = create(:trace, :visibility => "private")
394
395     # First with no auth
396     get show_trace_path(:display_name => anon_trace_file.user.display_name, :id => anon_trace_file)
397     assert_response :redirect
398     assert_redirected_to :action => :index
399
400     # Now with some other user, which should not work since the trace is anon
401     session_for(create(:user))
402     get show_trace_path(:display_name => anon_trace_file.user.display_name, :id => anon_trace_file)
403     assert_response :redirect
404     assert_redirected_to :action => :index
405
406     # And finally we should be able to do it with the owner of the trace
407     session_for(anon_trace_file.user)
408     get show_trace_path(:display_name => anon_trace_file.user.display_name, :id => anon_trace_file)
409     check_trace_show anon_trace_file
410   end
411
412   # Test showing a trace that doesn't exist
413   def test_show_not_found
414     deleted_trace_file = create(:trace, :deleted)
415
416     # First with a trace that has never existed
417     get show_trace_path(:display_name => create(:user).display_name, :id => 0)
418     assert_response :redirect
419     assert_redirected_to :action => :index
420
421     # Now with a trace that has been deleted
422     session_for(deleted_trace_file.user)
423     get show_trace_path(:display_name => deleted_trace_file.user.display_name, :id => deleted_trace_file)
424     assert_response :redirect
425     assert_redirected_to :action => :index
426   end
427
428   # Test downloading a trace
429   def test_data
430     public_trace_file = create(:trace, :visibility => "public", :fixture => "a")
431
432     # First with no auth, which should work since the trace is public
433     get trace_data_path(:display_name => public_trace_file.user.display_name, :id => public_trace_file)
434     follow_redirect!
435     follow_redirect!
436     check_trace_data public_trace_file, "848caa72f2f456d1bd6a0fdf228aa1b9"
437
438     # Now with some other user, which should work since the trace is public
439     session_for(create(:user))
440     get trace_data_path(:display_name => public_trace_file.user.display_name, :id => public_trace_file)
441     follow_redirect!
442     follow_redirect!
443     check_trace_data public_trace_file, "848caa72f2f456d1bd6a0fdf228aa1b9"
444
445     # And finally we should be able to do it with the owner of the trace
446     session_for(public_trace_file.user)
447     get trace_data_path(:display_name => public_trace_file.user.display_name, :id => public_trace_file)
448     follow_redirect!
449     follow_redirect!
450     check_trace_data public_trace_file, "848caa72f2f456d1bd6a0fdf228aa1b9"
451   end
452
453   # Test downloading a compressed trace
454   def test_data_compressed
455     identifiable_trace_file = create(:trace, :visibility => "identifiable", :fixture => "d")
456
457     # First get the data as is
458     get trace_data_path(:display_name => identifiable_trace_file.user.display_name, :id => identifiable_trace_file)
459     follow_redirect!
460     follow_redirect!
461     check_trace_data identifiable_trace_file, "c6422a3d8750faae49ed70e7e8a51b93", "application/gzip", "gpx.gz"
462
463     # Now ask explicitly for XML format
464     get trace_data_path(:display_name => identifiable_trace_file.user.display_name, :id => identifiable_trace_file.id, :format => "xml")
465     check_trace_data identifiable_trace_file, "abd6675fdf3024a84fc0a1deac147c0d", "application/xml", "xml"
466
467     # Now ask explicitly for GPX format
468     get trace_data_path(:display_name => identifiable_trace_file.user.display_name, :id => identifiable_trace_file.id, :format => "gpx")
469     check_trace_data identifiable_trace_file, "abd6675fdf3024a84fc0a1deac147c0d"
470   end
471
472   # Check an anonymous trace can't be downloaded by another user
473   def test_data_anon
474     anon_trace_file = create(:trace, :visibility => "private", :fixture => "b")
475
476     # First with no auth
477     get trace_data_path(:display_name => anon_trace_file.user.display_name, :id => anon_trace_file)
478     assert_response :not_found
479
480     # Now with some other user, which shouldn't work since the trace is anon
481     session_for(create(:user))
482     get trace_data_path(:display_name => anon_trace_file.user.display_name, :id => anon_trace_file)
483     assert_response :not_found
484
485     # And finally we should be able to do it with the owner of the trace
486     session_for(anon_trace_file.user)
487     get trace_data_path(:display_name => anon_trace_file.user.display_name, :id => anon_trace_file)
488     follow_redirect!
489     follow_redirect!
490     check_trace_data anon_trace_file, "db4cb5ed2d7d2b627b3b504296c4f701"
491   end
492
493   # Test downloading a trace that doesn't exist
494   def test_data_not_found
495     deleted_trace_file = create(:trace, :deleted)
496
497     # First with a trace that has never existed
498     get trace_data_path(:display_name => create(:user).display_name, :id => 0)
499     assert_response :not_found
500
501     # Now with a trace that has been deleted
502     session_for(deleted_trace_file.user)
503     get trace_data_path(:display_name => deleted_trace_file.user.display_name, :id => deleted_trace_file)
504     assert_response :not_found
505   end
506
507   # Test downloading the picture for a trace
508   def test_picture
509     public_trace_file = create(:trace, :visibility => "public", :fixture => "a")
510
511     # First with no auth, which should work since the trace is public
512     get trace_picture_path(:display_name => public_trace_file.user.display_name, :id => public_trace_file)
513     check_trace_picture public_trace_file
514
515     # Now with some other user, which should work since the trace is public
516     session_for(create(:user))
517     get trace_picture_path(:display_name => public_trace_file.user.display_name, :id => public_trace_file)
518     check_trace_picture public_trace_file
519
520     # And finally we should be able to do it with the owner of the trace
521     session_for(public_trace_file.user)
522     get trace_picture_path(:display_name => public_trace_file.user.display_name, :id => public_trace_file)
523     check_trace_picture public_trace_file
524   end
525
526   # Check the picture for an anonymous trace can't be downloaded by another user
527   def test_picture_anon
528     anon_trace_file = create(:trace, :visibility => "private", :fixture => "b")
529
530     # First with no auth
531     get trace_picture_path(:display_name => anon_trace_file.user.display_name, :id => anon_trace_file)
532     assert_response :forbidden
533
534     # Now with some other user, which shouldn't work since the trace is anon
535     session_for(create(:user))
536     get trace_picture_path(:display_name => anon_trace_file.user.display_name, :id => anon_trace_file)
537     assert_response :forbidden
538
539     # And finally we should be able to do it with the owner of the trace
540     session_for(anon_trace_file.user)
541     get trace_picture_path(:display_name => anon_trace_file.user.display_name, :id => anon_trace_file)
542     check_trace_picture anon_trace_file
543   end
544
545   # Test downloading the picture for a trace that doesn't exist
546   def test_picture_not_found
547     deleted_trace_file = create(:trace, :deleted)
548
549     # First with a trace that has never existed
550     get trace_picture_path(:display_name => create(:user).display_name, :id => 0)
551     assert_response :not_found
552
553     # Now with a trace that has been deleted
554     session_for(deleted_trace_file.user)
555     get trace_picture_path(:display_name => deleted_trace_file.user.display_name, :id => deleted_trace_file)
556     assert_response :not_found
557   end
558
559   # Test downloading the icon for a trace
560   def test_icon
561     public_trace_file = create(:trace, :visibility => "public", :fixture => "a")
562
563     # First with no auth, which should work since the trace is public
564     get trace_icon_path(:display_name => public_trace_file.user.display_name, :id => public_trace_file)
565     check_trace_icon public_trace_file
566
567     # Now with some other user, which should work since the trace is public
568     session_for(create(:user))
569     get trace_icon_path(:display_name => public_trace_file.user.display_name, :id => public_trace_file)
570     check_trace_icon public_trace_file
571
572     # And finally we should be able to do it with the owner of the trace
573     session_for(public_trace_file.user)
574     get trace_icon_path(:display_name => public_trace_file.user.display_name, :id => public_trace_file)
575     check_trace_icon public_trace_file
576   end
577
578   # Check the icon for an anonymous trace can't be downloaded by another user
579   def test_icon_anon
580     anon_trace_file = create(:trace, :visibility => "private", :fixture => "b")
581
582     # First with no auth
583     get trace_icon_path(:display_name => anon_trace_file.user.display_name, :id => anon_trace_file)
584     assert_response :forbidden
585
586     # Now with some other user, which shouldn't work since the trace is anon
587     session_for(create(:user))
588     get trace_icon_path(:display_name => anon_trace_file.user.display_name, :id => anon_trace_file)
589     assert_response :forbidden
590
591     # And finally we should be able to do it with the owner of the trace
592     session_for(anon_trace_file.user)
593     get trace_icon_path(:display_name => anon_trace_file.user.display_name, :id => anon_trace_file)
594     check_trace_icon anon_trace_file
595   end
596
597   # Test downloading the icon for a trace that doesn't exist
598   def test_icon_not_found
599     deleted_trace_file = create(:trace, :deleted)
600
601     # First with a trace that has never existed
602     get trace_icon_path(:display_name => create(:user).display_name, :id => 0)
603     assert_response :not_found
604
605     # Now with a trace that has been deleted
606     session_for(deleted_trace_file.user)
607     get trace_icon_path(:display_name => deleted_trace_file.user.display_name, :id => deleted_trace_file)
608     assert_response :not_found
609   end
610
611   # Test fetching the new trace page
612   def test_new_get
613     # First with no auth
614     get new_trace_path
615     assert_response :redirect
616     assert_redirected_to login_path(:referer => new_trace_path)
617
618     # Now authenticated as a user with gps.trace.visibility set
619     user = create(:user)
620     create(:user_preference, :user => user, :k => "gps.trace.visibility", :v => "identifiable")
621     session_for(user)
622     get new_trace_path
623     assert_response :success
624     assert_template :new
625     assert_select "select#trace_visibility option[value=identifiable][selected]", 1
626
627     # Now authenticated as a user with gps.trace.public set
628     second_user = create(:user)
629     create(:user_preference, :user => second_user, :k => "gps.trace.public", :v => "default")
630     session_for(second_user)
631     get new_trace_path
632     assert_response :success
633     assert_template :new
634     assert_select "select#trace_visibility option[value=public][selected]", 1
635
636     # Now authenticated as a user with no preferences
637     third_user = create(:user)
638     session_for(third_user)
639     get new_trace_path
640     assert_response :success
641     assert_template :new
642     assert_select "select#trace_visibility option[value=private][selected]", 1
643   end
644
645   # Test creating a trace
646   def test_create_post
647     # Get file to use
648     fixture = Rails.root.join("test/gpx/fixtures/a.gpx")
649     file = Rack::Test::UploadedFile.new(fixture, "application/gpx+xml")
650     user = create(:user)
651
652     # First with no auth
653     post traces_path(:trace => { :gpx_file => file, :description => "New Trace", :tagstring => "new,trace", :visibility => "trackable" })
654     assert_response :forbidden
655
656     # Rewind the file
657     file.rewind
658
659     # Now authenticated
660     create(:user_preference, :user => user, :k => "gps.trace.visibility", :v => "identifiable")
661     assert_not_equal "trackable", user.preferences.where(:k => "gps.trace.visibility").first.v
662     session_for(user)
663     post traces_path, :params => { :trace => { :gpx_file => file, :description => "New Trace", :tagstring => "new,trace", :visibility => "trackable" } }
664     assert_response :redirect
665     assert_redirected_to :action => :index, :display_name => user.display_name
666     assert_match(/file has been uploaded/, flash[:notice])
667     trace = Trace.order(:id => :desc).first
668     assert_equal "a.gpx", trace.name
669     assert_equal "New Trace", trace.description
670     assert_equal %w[new trace], trace.tags.order(:tag).collect(&:tag)
671     assert_equal "trackable", trace.visibility
672     assert_not trace.inserted
673     assert_equal File.new(fixture).read, trace.file.blob.download
674     trace.destroy
675     assert_equal "trackable", user.preferences.where(:k => "gps.trace.visibility").first.v
676   end
677
678   # Test creating a trace with validation errors
679   def test_create_post_with_validation_errors
680     # Get file to use
681     fixture = Rails.root.join("test/gpx/fixtures/a.gpx")
682     file = Rack::Test::UploadedFile.new(fixture, "application/gpx+xml")
683     user = create(:user)
684
685     # Now authenticated
686     create(:user_preference, :user => user, :k => "gps.trace.visibility", :v => "identifiable")
687     assert_not_equal "trackable", user.preferences.where(:k => "gps.trace.visibility").first.v
688     session_for(user)
689     post traces_path, :params => { :trace => { :gpx_file => file, :description => "", :tagstring => "new,trace", :visibility => "trackable" } }
690     assert_template :new
691     assert_match "is too short (minimum is 1 character)", response.body
692   end
693
694   # Test fetching the edit page for a trace using GET
695   def test_edit_get
696     public_trace_file = create(:trace, :visibility => "public")
697     deleted_trace_file = create(:trace, :deleted)
698
699     # First with no auth
700     get edit_trace_path(:display_name => public_trace_file.user.display_name, :id => public_trace_file)
701     assert_response :redirect
702     assert_redirected_to login_path(:referer => edit_trace_path(:display_name => public_trace_file.user.display_name, :id => public_trace_file.id))
703
704     # Now with some other user, which should fail
705     session_for(create(:user))
706     get edit_trace_path(:display_name => public_trace_file.user.display_name, :id => public_trace_file)
707     assert_response :forbidden
708
709     # Now with a trace which doesn't exist
710     session_for(create(:user))
711     get edit_trace_path(:display_name => create(:user).display_name, :id => 0)
712     assert_response :not_found
713
714     # Now with a trace which has been deleted
715     session_for(deleted_trace_file.user)
716     get edit_trace_path(:display_name => deleted_trace_file.user.display_name, :id => deleted_trace_file)
717     assert_response :not_found
718
719     # Finally with a trace that we are allowed to edit
720     session_for(public_trace_file.user)
721     get edit_trace_path(:display_name => public_trace_file.user.display_name, :id => public_trace_file)
722     assert_response :success
723   end
724
725   # Test saving edits to a trace
726   def test_update
727     public_trace_file = create(:trace, :visibility => "public")
728     deleted_trace_file = create(:trace, :deleted)
729
730     # New details
731     new_details = { :description => "Changed description", :tagstring => "new_tag", :visibility => "private" }
732
733     # First with no auth
734     put trace_path(:display_name => public_trace_file.user.display_name, :id => public_trace_file, :trace => new_details)
735     assert_response :forbidden
736
737     # Now with some other user, which should fail
738     session_for(create(:user))
739     put trace_path(:display_name => public_trace_file.user.display_name, :id => public_trace_file, :trace => new_details)
740     assert_response :forbidden
741
742     # Now with a trace which doesn't exist
743     session_for(create(:user))
744     put trace_path(:display_name => create(:user).display_name, :id => 0, :trace => new_details)
745     assert_response :not_found
746
747     # Now with a trace which has been deleted
748     session_for(deleted_trace_file.user)
749     put trace_path(:display_name => deleted_trace_file.user.display_name, :id => deleted_trace_file, :trace => new_details)
750     assert_response :not_found
751
752     # Finally with a trace that we are allowed to edit
753     session_for(public_trace_file.user)
754     put trace_path(:display_name => public_trace_file.user.display_name, :id => public_trace_file, :trace => new_details)
755     assert_response :redirect
756     assert_redirected_to :action => :show, :display_name => public_trace_file.user.display_name
757     trace = Trace.find(public_trace_file.id)
758     assert_equal new_details[:description], trace.description
759     assert_equal new_details[:tagstring], trace.tagstring
760     assert_equal new_details[:visibility], trace.visibility
761   end
762
763   # Test destroying a trace
764   def test_destroy
765     public_trace_file = create(:trace, :visibility => "public")
766     deleted_trace_file = create(:trace, :deleted)
767
768     # First with no auth
769     delete trace_path(:display_name => public_trace_file.user.display_name, :id => public_trace_file)
770     assert_response :forbidden
771
772     # Now with some other user, which should fail
773     session_for(create(:user))
774     delete trace_path(:display_name => public_trace_file.user.display_name, :id => public_trace_file)
775     assert_response :forbidden
776
777     # Now with a trace which doesn't exist
778     session_for(create(:user))
779     delete trace_path(:display_name => create(:user).display_name, :id => 0)
780     assert_response :not_found
781
782     # Now with a trace has already been deleted
783     session_for(deleted_trace_file.user)
784     delete trace_path(:display_name => deleted_trace_file.user.display_name, :id => deleted_trace_file)
785     assert_response :not_found
786
787     # Now with a trace that we are allowed to delete
788     session_for(public_trace_file.user)
789     delete trace_path(:display_name => public_trace_file.user.display_name, :id => public_trace_file)
790     assert_response :redirect
791     assert_redirected_to :action => :index, :display_name => public_trace_file.user.display_name
792     trace = Trace.find(public_trace_file.id)
793     assert_not trace.visible
794
795     # Finally with a trace that is destroyed by an admin
796     public_trace_file = create(:trace, :visibility => "public")
797     admin = create(:administrator_user)
798     session_for(admin)
799     delete trace_path(:display_name => public_trace_file.user.display_name, :id => public_trace_file)
800     assert_response :redirect
801     assert_redirected_to :action => :index, :display_name => public_trace_file.user.display_name
802     trace = Trace.find(public_trace_file.id)
803     assert_not trace.visible
804   end
805
806   private
807
808   def check_trace_feed(traces)
809     assert_response :success
810     assert_template "georss"
811     assert_equal "application/rss+xml", @response.media_type
812     assert_select "rss", :count => 1 do
813       assert_select "channel", :count => 1 do
814         assert_select "title"
815         assert_select "description"
816         assert_select "link"
817         assert_select "image"
818         assert_select "item", :count => traces.length do |items|
819           traces.zip(items).each do |trace, item|
820             assert_select item, "title", trace.name
821             assert_select item, "link", "http://www.example.com/user/#{ERB::Util.u(trace.user.display_name)}/traces/#{trace.id}"
822             assert_select item, "guid", "http://www.example.com/user/#{ERB::Util.u(trace.user.display_name)}/traces/#{trace.id}"
823             assert_select item, "description"
824             # assert_select item, "dc:creator", trace.user.display_name
825             assert_select item, "pubDate", trace.timestamp.rfc822
826           end
827         end
828       end
829     end
830   end
831
832   def check_trace_index(traces)
833     assert_response :success
834     assert_template "index"
835
836     if traces.empty?
837       assert_select "h2", /Nothing here yet/
838     else
839       assert_select "table#trace_list tbody", :count => 1 do
840         assert_select "tr", :count => traces.length do |rows|
841           traces.zip(rows).each do |trace, row|
842             assert_select row, "a", Regexp.new(Regexp.escape(trace.name))
843             assert_select row, "li", Regexp.new(Regexp.escape("#{trace.size} points")) if trace.inserted?
844             assert_select row, "td", Regexp.new(Regexp.escape(trace.description))
845             assert_select row, "td", Regexp.new(Regexp.escape("by #{trace.user.display_name}"))
846           end
847         end
848       end
849     end
850   end
851
852   def check_trace_show(trace)
853     assert_response :success
854     assert_template "show"
855
856     assert_select "table", :count => 1 do
857       assert_select "td", /^#{Regexp.quote(trace.name)} /
858       assert_select "td", trace.user.display_name
859       assert_select "td", trace.description
860     end
861   end
862
863   def check_trace_data(trace, digest, content_type = "application/gpx+xml", extension = "gpx")
864     assert_equal digest, Digest::MD5.hexdigest(response.body)
865     assert_equal content_type, response.media_type
866     assert_equal "attachment; filename=\"#{trace.id}.#{extension}\"; filename*=UTF-8''#{trace.id}.#{extension}", @response.header["Content-Disposition"]
867   end
868
869   def check_trace_picture(trace)
870     follow_redirect!
871     follow_redirect!
872     assert_response :success
873     assert_equal "image/gif", response.media_type
874     assert_equal trace.large_picture, response.body
875   end
876
877   def check_trace_icon(trace)
878     follow_redirect!
879     follow_redirect!
880     assert_response :success
881     assert_equal "image/gif", response.media_type
882     assert_equal trace.icon_picture, response.body
883   end
884 end