]> git.openstreetmap.org Git - rails.git/blob - test/controllers/changesets_controller_test.rb
Add validation for maximum ID passed to changesets#index
[rails.git] / test / controllers / changesets_controller_test.rb
1 require "test_helper"
2
3 class ChangesetsControllerTest < ActionDispatch::IntegrationTest
4   ##
5   # test all routes which lead to this controller
6   def test_routes
7     assert_routing(
8       { :path => "/changeset/1", :method => :get },
9       { :controller => "changesets", :action => "show", :id => "1" }
10     )
11     assert_routing(
12       { :path => "/user/name/history", :method => :get },
13       { :controller => "changesets", :action => "index", :display_name => "name" }
14     )
15     assert_routing(
16       { :path => "/user/name/history/feed", :method => :get },
17       { :controller => "changesets", :action => "feed", :display_name => "name", :format => :atom }
18     )
19     assert_routing(
20       { :path => "/history/friends", :method => :get },
21       { :controller => "changesets", :action => "index", :friends => true, :format => :html }
22     )
23     assert_routing(
24       { :path => "/history/nearby", :method => :get },
25       { :controller => "changesets", :action => "index", :nearby => true, :format => :html }
26     )
27     assert_routing(
28       { :path => "/history", :method => :get },
29       { :controller => "changesets", :action => "index" }
30     )
31     assert_routing(
32       { :path => "/history/feed", :method => :get },
33       { :controller => "changesets", :action => "feed", :format => :atom }
34     )
35     assert_routing(
36       { :path => "/changeset/1/subscribe", :method => :get },
37       { :controller => "changesets", :action => "subscribe", :id => "1" }
38     )
39     assert_routing(
40       { :path => "/changeset/1/subscribe", :method => :post },
41       { :controller => "changesets", :action => "subscribe", :id => "1" }
42     )
43     assert_routing(
44       { :path => "/changeset/1/unsubscribe", :method => :get },
45       { :controller => "changesets", :action => "unsubscribe", :id => "1" }
46     )
47     assert_routing(
48       { :path => "/changeset/1/unsubscribe", :method => :post },
49       { :controller => "changesets", :action => "unsubscribe", :id => "1" }
50     )
51   end
52
53   ##
54   # This should display the last 20 changesets closed
55   def test_index
56     changesets = create_list(:changeset, 30, :num_changes => 1)
57
58     get history_path(:format => "html")
59     assert_response :success
60     assert_template "history"
61     assert_template :layout => "map"
62     assert_select "h2", :text => "Changesets", :count => 1
63     assert_select "link[rel='alternate'][type='application/atom+xml']", :count => 1 do
64       assert_select "[href=?]", "http://www.example.com/history/feed"
65     end
66
67     get history_path(:format => "html", :list => "1"), :xhr => true
68     assert_response :success
69     assert_template "index"
70
71     check_index_result(changesets.last(20))
72   end
73
74   ##
75   # This should display the last 20 changesets closed
76   def test_index_xhr
77     changesets = create_list(:changeset, 30, :num_changes => 1)
78
79     get history_path(:format => "html"), :xhr => true
80     assert_response :success
81     assert_template "history"
82     assert_template :layout => "xhr"
83     assert_select "h2", :text => "Changesets", :count => 1
84     assert_select "link[rel='alternate'][type='application/atom+xml']", :count => 1 do
85       assert_select "[href=?]", "http://www.example.com/history/feed"
86     end
87
88     get history_path(:format => "html", :list => "1"), :xhr => true
89     assert_response :success
90     assert_template "index"
91
92     check_index_result(changesets.last(20))
93   end
94
95   ##
96   # This should report an error
97   def test_index_invalid_xhr
98     %w[-1 0 fred].each do |id|
99       get history_path(:format => "html", :list => "1", :max_id => id)
100       assert_redirected_to :controller => :errors, :action => :bad_request
101     end
102   end
103
104   ##
105   # This should display the last 20 changesets closed in a specific area
106   def test_index_bbox
107     changesets = create_list(:changeset, 10, :num_changes => 1, :min_lat => 50000000, :max_lat => 50000001, :min_lon => 50000000, :max_lon => 50000001)
108     other_changesets = create_list(:changeset, 10, :num_changes => 1, :min_lat => 0, :max_lat => 1, :min_lon => 0, :max_lon => 1)
109
110     # First check they all show up without a bbox parameter
111     get history_path(:format => "html", :list => "1"), :xhr => true
112     assert_response :success
113     assert_template "index"
114     check_index_result(changesets + other_changesets)
115
116     # Then check with bbox parameter
117     get history_path(:format => "html", :bbox => "4.5,4.5,5.5,5.5")
118     assert_response :success
119     assert_template "history"
120     assert_template :layout => "map"
121     assert_select "h2", :text => "Changesets", :count => 1
122     assert_select "link[rel='alternate'][type='application/atom+xml']", :count => 1 do
123       assert_select "[href=?]", "http://www.example.com/history/feed?bbox=4.5%2C4.5%2C5.5%2C5.5"
124     end
125
126     get history_path(:format => "html", :bbox => "4.5,4.5,5.5,5.5", :list => "1"), :xhr => true
127     assert_response :success
128     assert_template "index"
129
130     check_index_result(changesets)
131   end
132
133   ##
134   # Checks the display of the user changesets listing
135   def test_index_user
136     user = create(:user)
137     create(:changeset, :user => user, :num_changes => 1)
138     create(:changeset, :closed, :user => user, :num_changes => 1)
139     user.reload
140
141     get history_path(:format => "html", :display_name => user.display_name)
142     assert_response :success
143     assert_template "history"
144     assert_template :layout => "map"
145     assert_select "h2", :text => "Changesets by #{user.display_name}", :count => 1 do
146       assert_select "a[href=?]", user_path(user)
147     end
148     assert_select "link[rel='alternate'][type='application/atom+xml']", :count => 1 do
149       assert_select "[href=?]", "http://www.example.com/user/#{ERB::Util.url_encode(user.display_name)}/history/feed"
150     end
151
152     get history_path(:format => "html", :display_name => user.display_name, :list => "1"), :xhr => true
153     assert_response :success
154     assert_template "index"
155
156     check_index_result(user.changesets)
157   end
158
159   ##
160   # Checks the display of the user changesets listing for a private user
161   def test_index_private_user
162     private_user = create(:user, :data_public => false)
163     create(:changeset, :user => private_user)
164     create(:changeset, :closed, :user => private_user)
165
166     get history_path(:format => "html", :display_name => private_user.display_name)
167     assert_response :success
168     assert_template "history"
169
170     get history_path(:format => "html", :display_name => private_user.display_name, :list => "1"), :xhr => true
171     assert_response :success
172     assert_template "index"
173
174     check_index_result([])
175   end
176
177   ##
178   # Check the not found of the index user changesets
179   def test_index_user_not_found
180     get history_path(:format => "html", :display_name => "Some random user")
181     assert_response :not_found
182     assert_template "users/no_such_user"
183
184     get history_path(:format => "html", :display_name => "Some random user", :list => "1"), :xhr => true
185     assert_response :not_found
186     assert_template "users/no_such_user"
187   end
188
189   ##
190   # Checks the display of the friends changesets listing
191   def test_index_friends
192     private_user = create(:user, :data_public => true)
193     friendship = create(:friendship, :befriender => private_user)
194     changeset = create(:changeset, :user => friendship.befriendee, :num_changes => 1)
195     _changeset2 = create(:changeset, :user => create(:user), :num_changes => 1)
196
197     get friend_changesets_path
198     assert_redirected_to login_path(:referer => friend_changesets_path)
199
200     session_for(private_user)
201
202     get friend_changesets_path
203     assert_response :success
204     assert_template "history"
205
206     get friend_changesets_path(:list => "1"), :xhr => true
207     assert_response :success
208     assert_template "index"
209
210     check_index_result([changeset])
211   end
212
213   ##
214   # Checks the display of the nearby user changesets listing
215   def test_index_nearby
216     private_user = create(:user, :data_public => false, :home_lat => 51.1, :home_lon => 1.0)
217     user = create(:user, :home_lat => 51.0, :home_lon => 1.0)
218     far_away_user = create(:user, :home_lat => 51.0, :home_lon => 130)
219     changeset = create(:changeset, :user => user, :num_changes => 1)
220     _changeset2 = create(:changeset, :user => far_away_user, :num_changes => 1)
221
222     get nearby_changesets_path
223     assert_redirected_to login_path(:referer => nearby_changesets_path)
224
225     session_for(private_user)
226
227     get nearby_changesets_path
228     assert_response :success
229     assert_template "history"
230
231     get nearby_changesets_path(:list => "1"), :xhr => true
232     assert_response :success
233     assert_template "index"
234
235     check_index_result([changeset])
236   end
237
238   ##
239   # Check that we can't request later pages of the changesets index
240   def test_index_max_id
241     changeset = create(:changeset, :num_changes => 1)
242     _changeset2 = create(:changeset, :num_changes => 1)
243
244     get history_path(:format => "html", :max_id => changeset.id), :xhr => true
245     assert_response :success
246     assert_template "history"
247     assert_template :layout => "xhr"
248     assert_select "h2", :text => "Changesets", :count => 1
249
250     get history_path(:format => "html", :list => "1", :max_id => changeset.id), :xhr => true
251     assert_response :success
252     assert_template "index"
253
254     check_index_result([changeset])
255   end
256
257   ##
258   # Check that a list with a next page link works
259   def test_index_more
260     create_list(:changeset, 50)
261
262     get history_path(:format => "html")
263     assert_response :success
264
265     get history_path(:format => "html"), :xhr => true
266     assert_response :success
267   end
268
269   def test_show
270     changeset = create(:changeset)
271     create(:changeset_tag, :changeset => changeset, :k => "comment", :v => "tested-changeset-comment")
272     commenting_user = create(:user)
273     changeset_comment = create(:changeset_comment, :changeset => changeset, :author => commenting_user, :body => "Unwanted comment")
274
275     sidebar_browse_check :changeset_path, changeset.id, "changesets/show"
276     assert_dom "h2", :text => "Changeset: #{changeset.id}"
277     assert_dom "p", :text => "tested-changeset-comment"
278     assert_dom "li#c#{changeset_comment.id}" do
279       assert_dom "> small", :text => /^Comment from #{commenting_user.display_name}/
280       assert_dom "a[href='#{user_path(commenting_user)}']"
281     end
282   end
283
284   def test_show_closed_changeset
285     changeset = create(:changeset, :closed)
286
287     sidebar_browse_check :changeset_path, changeset.id, "changesets/show"
288   end
289
290   def test_show_private_changeset
291     user = create(:user)
292     changeset = create(:changeset, :user => create(:user, :data_public => false))
293     create(:changeset, :user => user)
294
295     sidebar_browse_check :changeset_path, changeset.id, "changesets/show"
296   end
297
298   def test_show_element_links
299     changeset = create(:changeset)
300     node = create(:node, :with_history, :changeset => changeset)
301     way = create(:way, :with_history, :changeset => changeset)
302     relation = create(:relation, :with_history, :changeset => changeset)
303
304     sidebar_browse_check :changeset_path, changeset.id, "changesets/show"
305     assert_dom "a[href='#{node_path node}']", :count => 1
306     assert_dom "a[href='#{old_node_path node, 1}']", :count => 1
307     assert_dom "a[href='#{way_path way}']", :count => 1
308     assert_dom "a[href='#{old_way_path way, 1}']", :count => 1
309     assert_dom "a[href='#{relation_path relation}']", :count => 1
310     assert_dom "a[href='#{old_relation_path relation, 1}']", :count => 1
311   end
312
313   def test_show_paginated_element_links
314     page_size = 20
315     changeset = create(:changeset)
316     nodes = create_list(:node, page_size + 1, :with_history, :changeset => changeset)
317     ways = create_list(:way, page_size + 1, :with_history, :changeset => changeset)
318     relations = create_list(:relation, page_size + 1, :with_history, :changeset => changeset)
319
320     sidebar_browse_check :changeset_path, changeset.id, "changesets/show"
321     page_size.times do |i|
322       assert_dom "a[href='#{node_path nodes[i]}']", :count => 1
323       assert_dom "a[href='#{old_node_path nodes[i], 1}']", :count => 1
324       assert_dom "a[href='#{way_path ways[i]}']", :count => 1
325       assert_dom "a[href='#{old_way_path ways[i], 1}']", :count => 1
326       assert_dom "a[href='#{relation_path relations[i]}']", :count => 1
327       assert_dom "a[href='#{old_relation_path relations[i], 1}']", :count => 1
328     end
329   end
330
331   def test_show_adjacent_changesets
332     user = create(:user)
333     changesets = create_list(:changeset, 3, :user => user)
334
335     sidebar_browse_check :changeset_path, changesets[1].id, "changesets/show"
336     assert_dom "a[href='#{changeset_path changesets[0]}']", :count => 1
337     assert_dom "a[href='#{changeset_path changesets[2]}']", :count => 1
338   end
339
340   ##
341   # This should display the last 20 non-empty changesets
342   def test_feed
343     changeset = create(:changeset, :num_changes => 1)
344     create(:changeset_tag, :changeset => changeset)
345     create(:changeset_tag, :changeset => changeset, :k => "website", :v => "http://example.com/")
346     closed_changeset = create(:changeset, :closed, :num_changes => 1)
347     create(:changeset_tag, :changeset => closed_changeset, :k => "website", :v => "https://osm.org/")
348     _empty_changeset = create(:changeset, :num_changes => 0)
349
350     get history_feed_path(:format => :atom)
351     assert_response :success
352     assert_template "index"
353     assert_equal "application/atom+xml", response.media_type
354
355     check_feed_result([closed_changeset, changeset])
356   end
357
358   ##
359   # This should correctly escape XML special characters in the comment
360   def test_feed_with_comment_tag
361     changeset = create(:changeset, :num_changes => 1)
362     create(:changeset_tag, :changeset => changeset, :k => "comment", :v => "tested<changeset>comment")
363
364     get history_feed_path(:format => :atom)
365     assert_response :success
366     assert_template "index"
367     assert_equal "application/atom+xml", response.media_type
368
369     check_feed_result([changeset])
370   end
371
372   ##
373   # This should display the last 20 changesets closed in a specific area
374   def test_feed_bbox
375     changeset = create(:changeset, :num_changes => 1, :min_lat => 5 * GeoRecord::SCALE, :min_lon => 5 * GeoRecord::SCALE, :max_lat => 5 * GeoRecord::SCALE, :max_lon => 5 * GeoRecord::SCALE)
376     create(:changeset_tag, :changeset => changeset)
377     create(:changeset_tag, :changeset => changeset, :k => "website", :v => "http://example.com/")
378     closed_changeset = create(:changeset, :closed, :num_changes => 1, :min_lat => 5 * GeoRecord::SCALE, :min_lon => 5 * GeoRecord::SCALE, :max_lat => 5 * GeoRecord::SCALE, :max_lon => 5 * GeoRecord::SCALE)
379     _elsewhere_changeset = create(:changeset, :num_changes => 1, :min_lat => -5 * GeoRecord::SCALE, :min_lon => -5 * GeoRecord::SCALE, :max_lat => -5 * GeoRecord::SCALE, :max_lon => -5 * GeoRecord::SCALE)
380     _empty_changeset = create(:changeset, :num_changes => 0, :min_lat => -5 * GeoRecord::SCALE, :min_lon => -5 * GeoRecord::SCALE, :max_lat => -5 * GeoRecord::SCALE, :max_lon => -5 * GeoRecord::SCALE)
381
382     get history_feed_path(:format => :atom, :bbox => "4.5,4.5,5.5,5.5")
383     assert_response :success
384     assert_template "index"
385     assert_equal "application/atom+xml", response.media_type
386
387     check_feed_result([closed_changeset, changeset])
388   end
389
390   ##
391   # Checks the display of the user changesets feed
392   def test_feed_user
393     user = create(:user)
394     changesets = create_list(:changeset, 3, :user => user, :num_changes => 4)
395     create(:changeset_tag, :changeset => changesets[1])
396     create(:changeset_tag, :changeset => changesets[1], :k => "website", :v => "http://example.com/")
397     _other_changeset = create(:changeset)
398
399     get history_feed_path(:format => :atom, :display_name => user.display_name)
400
401     assert_response :success
402     assert_template "index"
403     assert_equal "application/atom+xml", response.media_type
404
405     check_feed_result(changesets.reverse)
406   end
407
408   ##
409   # Check the not found of the user changesets feed
410   def test_feed_user_not_found
411     get history_feed_path(:format => "atom", :display_name => "Some random user")
412     assert_response :not_found
413   end
414
415   ##
416   # Check that we can't request later pages of the changesets feed
417   def test_feed_max_id
418     get history_feed_path(:format => "atom", :max_id => 100)
419     assert_redirected_to :action => :feed
420   end
421
422   def test_subscribe_page
423     user = create(:user)
424     other_user = create(:user)
425     changeset = create(:changeset, :user => user)
426     path = subscribe_changeset_path(changeset)
427
428     get path
429     assert_redirected_to login_path(:referer => path)
430
431     session_for(other_user)
432     get path
433     assert_response :success
434     assert_dom ".content-body" do
435       assert_dom "a[href='#{changeset_path(changeset)}']", :text => "Changeset #{changeset.id}"
436       assert_dom "a[href='#{user_path(user)}']", :text => user.display_name
437     end
438   end
439
440   def test_subscribe_success
441     user = create(:user)
442     other_user = create(:user)
443     changeset = create(:changeset, :user => user)
444
445     session_for(other_user)
446     assert_difference "changeset.subscribers.count", 1 do
447       post subscribe_changeset_path(changeset)
448     end
449     assert_redirected_to changeset_path(changeset)
450     assert changeset.reload.subscribed?(other_user)
451   end
452
453   def test_subscribe_fail
454     user = create(:user)
455     other_user = create(:user)
456
457     changeset = create(:changeset, :user => user)
458
459     # not signed in
460     assert_no_difference "changeset.subscribers.count" do
461       post subscribe_changeset_path(changeset)
462     end
463     assert_response :forbidden
464
465     session_for(other_user)
466
467     # bad diary id
468     post subscribe_changeset_path(999111)
469     assert_response :not_found
470
471     # trying to subscribe when already subscribed
472     post subscribe_changeset_path(changeset)
473     assert_no_difference "changeset.subscribers.count" do
474       post subscribe_changeset_path(changeset)
475     end
476   end
477
478   def test_unsubscribe_page
479     user = create(:user)
480     other_user = create(:user)
481     changeset = create(:changeset, :user => user)
482     path = unsubscribe_changeset_path(changeset)
483
484     get path
485     assert_redirected_to login_path(:referer => path)
486
487     session_for(other_user)
488     get path
489     assert_response :success
490     assert_dom ".content-body" do
491       assert_dom "a[href='#{changeset_path(changeset)}']", :text => "Changeset #{changeset.id}"
492       assert_dom "a[href='#{user_path(user)}']", :text => user.display_name
493     end
494   end
495
496   def test_unsubscribe_success
497     user = create(:user)
498     other_user = create(:user)
499
500     changeset = create(:changeset, :user => user)
501     changeset.subscribers.push(other_user)
502
503     session_for(other_user)
504     assert_difference "changeset.subscribers.count", -1 do
505       post unsubscribe_changeset_path(changeset)
506     end
507     assert_redirected_to changeset_path(changeset)
508     assert_not changeset.reload.subscribed?(other_user)
509   end
510
511   def test_unsubscribe_fail
512     user = create(:user)
513     other_user = create(:user)
514
515     changeset = create(:changeset, :user => user)
516
517     # not signed in
518     assert_no_difference "changeset.subscribers.count" do
519       post unsubscribe_changeset_path(changeset)
520     end
521     assert_response :forbidden
522
523     session_for(other_user)
524
525     # bad diary id
526     post unsubscribe_changeset_path(999111)
527     assert_response :not_found
528
529     # trying to unsubscribe when not subscribed
530     assert_no_difference "changeset.subscribers.count" do
531       post unsubscribe_changeset_path(changeset)
532     end
533   end
534
535   private
536
537   ##
538   # check the result of a index
539   def check_index_result(changesets)
540     assert_select "ol.changesets", :count => [changesets.size, 1].min do
541       assert_select "li", :count => changesets.size
542
543       changesets.each do |changeset|
544         assert_select "li#changeset_#{changeset.id}", :count => 1
545       end
546     end
547   end
548
549   ##
550   # check the result of a feed
551   def check_feed_result(changesets)
552     assert_operator changesets.size, :<=, 20
553
554     assert_select "feed", :count => [changesets.size, 1].min do
555       assert_select "> title", :count => 1, :text => /^Changesets/
556       assert_select "> entry", :count => changesets.size do |entries|
557         entries.zip(changesets) do |entry, changeset|
558           assert_select entry, "> id", :text => changeset_url(:id => changeset.id)
559
560           changeset_comment = changeset.tags["comment"]
561           if changeset_comment
562             assert_select entry, "> title", :count => 1, :text => "Changeset #{changeset.id} - #{changeset_comment}"
563           else
564             assert_select entry, "> title", :count => 1, :text => "Changeset #{changeset.id}"
565           end
566
567           assert_select entry, "> content > xhtml|div > xhtml|table" do
568             if changeset.tags.empty?
569               assert_select "> xhtml|tr > xhtml|td > xhtml|table", :count => 0
570             else
571               assert_select "> xhtml|tr > xhtml|td > xhtml|table", :count => 1 do
572                 changeset.tags.each_key do |key|
573                   assert_select "> xhtml|tr > xhtml|td", :text => /^#{key} = /
574                 end
575               end
576             end
577           end
578         end
579       end
580     end
581   end
582 end