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