Use jquery
[rails.git] / test / controllers / api / old_ways_controller_test.rb
1 require "test_helper"
2
3 module Api
4   class OldWaysControllerTest < ActionController::TestCase
5     ##
6     # test all routes which lead to this controller
7     def test_routes
8       assert_routing(
9         { :path => "/api/0.6/way/1/history", :method => :get },
10         { :controller => "api/old_ways", :action => "history", :id => "1" }
11       )
12       assert_routing(
13         { :path => "/api/0.6/way/1/2", :method => :get },
14         { :controller => "api/old_ways", :action => "version", :id => "1", :version => "2" }
15       )
16       assert_routing(
17         { :path => "/api/0.6/way/1/2/redact", :method => :post },
18         { :controller => "api/old_ways", :action => "redact", :id => "1", :version => "2" }
19       )
20     end
21
22     # -------------------------------------
23     # Test reading old ways.
24     # -------------------------------------
25
26     def test_history_visible
27       # check that a visible way is returned properly
28       get :history, :params => { :id => create(:way, :with_history).id }
29       assert_response :success
30     end
31
32     def test_history_invisible
33       # check that an invisible way's history is returned properly
34       get :history, :params => { :id => create(:way, :with_history, :deleted).id }
35       assert_response :success
36     end
37
38     def test_history_invalid
39       # check chat a non-existent way is not returned
40       get :history, :params => { :id => 0 }
41       assert_response :not_found
42     end
43
44     ##
45     # check that we can retrieve versions of a way
46     def test_version
47       way = create(:way, :with_history)
48       used_way = create(:way, :with_history)
49       create(:relation_member, :member => used_way)
50       way_with_versions = create(:way, :with_history, :version => 4)
51
52       create(:way_tag, :way => way)
53       create(:way_tag, :way => used_way)
54       create(:way_tag, :way => way_with_versions)
55       propagate_tags(way, way.old_ways.last)
56       propagate_tags(used_way, used_way.old_ways.last)
57       propagate_tags(way_with_versions, way_with_versions.old_ways.last)
58
59       check_current_version(way.id)
60       check_current_version(used_way.id)
61       check_current_version(way_with_versions.id)
62     end
63
64     ##
65     # check that returned history is the same as getting all
66     # versions of a way from the api.
67     def test_history_equals_versions
68       way = create(:way, :with_history)
69       used_way = create(:way, :with_history)
70       create(:relation_member, :member => used_way)
71       way_with_versions = create(:way, :with_history, :version => 4)
72
73       check_history_equals_versions(way.id)
74       check_history_equals_versions(used_way.id)
75       check_history_equals_versions(way_with_versions.id)
76     end
77
78     ##
79     # test the redaction of an old version of a way, while not being
80     # authorised.
81     def test_redact_way_unauthorised
82       way = create(:way, :with_history, :version => 4)
83       way_v3 = way.old_ways.find_by(:version => 3)
84
85       do_redact_way(way_v3, create(:redaction))
86       assert_response :unauthorized, "should need to be authenticated to redact."
87     end
88
89     ##
90     # test the redaction of an old version of a way, while being
91     # authorised as a normal user.
92     def test_redact_way_normal_user
93       basic_authorization create(:user).email, "test"
94       way = create(:way, :with_history, :version => 4)
95       way_v3 = way.old_ways.find_by(:version => 3)
96
97       do_redact_way(way_v3, create(:redaction))
98       assert_response :forbidden, "should need to be moderator to redact."
99     end
100
101     ##
102     # test that, even as moderator, the current version of a way
103     # can't be redacted.
104     def test_redact_way_current_version
105       basic_authorization create(:moderator_user).email, "test"
106       way = create(:way, :with_history, :version => 4)
107       way_latest = way.old_ways.last
108
109       do_redact_way(way_latest, create(:redaction))
110       assert_response :bad_request, "shouldn't be OK to redact current version as moderator."
111     end
112
113     ##
114     # test that redacted ways aren't visible, regardless of
115     # authorisation except as moderator...
116     def test_version_redacted
117       way = create(:way, :with_history, :version => 2)
118       way_v1 = way.old_ways.find_by(:version => 1)
119       way_v1.redact!(create(:redaction))
120
121       get :version, :params => { :id => way_v1.way_id, :version => way_v1.version }
122       assert_response :forbidden, "Redacted way shouldn't be visible via the version API."
123
124       # not even to a logged-in user
125       basic_authorization create(:user).email, "test"
126       get :version, :params => { :id => way_v1.way_id, :version => way_v1.version }
127       assert_response :forbidden, "Redacted way shouldn't be visible via the version API, even when logged in."
128     end
129
130     ##
131     # test that redacted ways aren't visible in the history
132     def test_history_redacted
133       way = create(:way, :with_history, :version => 2)
134       way_v1 = way.old_ways.find_by(:version => 1)
135       way_v1.redact!(create(:redaction))
136
137       get :history, :params => { :id => way_v1.way_id }
138       assert_response :success, "Redaction shouldn't have stopped history working."
139       assert_select "osm way[id='#{way_v1.way_id}'][version='#{way_v1.version}']", 0, "redacted way #{way_v1.way_id} version #{way_v1.version} shouldn't be present in the history."
140
141       # not even to a logged-in user
142       basic_authorization create(:user).email, "test"
143       get :version, :params => { :id => way_v1.way_id, :version => way_v1.version }
144       get :history, :params => { :id => way_v1.way_id }
145       assert_response :success, "Redaction shouldn't have stopped history working."
146       assert_select "osm way[id='#{way_v1.way_id}'][version='#{way_v1.version}']", 0, "redacted node #{way_v1.way_id} version #{way_v1.version} shouldn't be present in the history, even when logged in."
147     end
148
149     ##
150     # test the redaction of an old version of a way, while being
151     # authorised as a moderator.
152     def test_redact_way_moderator
153       way = create(:way, :with_history, :version => 4)
154       way_v3 = way.old_ways.find_by(:version => 3)
155       basic_authorization create(:moderator_user).email, "test"
156
157       do_redact_way(way_v3, create(:redaction))
158       assert_response :success, "should be OK to redact old version as moderator."
159
160       # check moderator can still see the redacted data, when passing
161       # the appropriate flag
162       get :version, :params => { :id => way_v3.way_id, :version => way_v3.version }
163       assert_response :forbidden, "After redaction, node should be gone for moderator, when flag not passed."
164       get :version, :params => { :id => way_v3.way_id, :version => way_v3.version, :show_redactions => "true" }
165       assert_response :success, "After redaction, node should not be gone for moderator, when flag passed."
166
167       # and when accessed via history
168       get :history, :params => { :id => way_v3.way_id }
169       assert_response :success, "Redaction shouldn't have stopped history working."
170       assert_select "osm way[id='#{way_v3.way_id}'][version='#{way_v3.version}']", 0, "way #{way_v3.way_id} version #{way_v3.version} should not be present in the history for moderators when not passing flag."
171       get :history, :params => { :id => way_v3.way_id, :show_redactions => "true" }
172       assert_response :success, "Redaction shouldn't have stopped history working."
173       assert_select "osm way[id='#{way_v3.way_id}'][version='#{way_v3.version}']", 1, "way #{way_v3.way_id} version #{way_v3.version} should still be present in the history for moderators when passing flag."
174     end
175
176     # testing that if the moderator drops auth, he can't see the
177     # redacted stuff any more.
178     def test_redact_way_is_redacted
179       way = create(:way, :with_history, :version => 4)
180       way_v3 = way.old_ways.find_by(:version => 3)
181       basic_authorization create(:moderator_user).email, "test"
182
183       do_redact_way(way_v3, create(:redaction))
184       assert_response :success, "should be OK to redact old version as moderator."
185
186       # re-auth as non-moderator
187       basic_authorization create(:user).email, "test"
188
189       # check can't see the redacted data
190       get :version, :params => { :id => way_v3.way_id, :version => way_v3.version }
191       assert_response :forbidden, "Redacted node shouldn't be visible via the version API."
192
193       # and when accessed via history
194       get :history, :params => { :id => way_v3.way_id }
195       assert_response :success, "Redaction shouldn't have stopped history working."
196       assert_select "osm way[id='#{way_v3.way_id}'][version='#{way_v3.version}']", 0, "redacted way #{way_v3.way_id} version #{way_v3.version} shouldn't be present in the history."
197     end
198
199     ##
200     # test the unredaction of an old version of a way, while not being
201     # authorised.
202     def test_unredact_way_unauthorised
203       way = create(:way, :with_history, :version => 2)
204       way_v1 = way.old_ways.find_by(:version => 1)
205       way_v1.redact!(create(:redaction))
206
207       post :redact, :params => { :id => way_v1.way_id, :version => way_v1.version }
208       assert_response :unauthorized, "should need to be authenticated to unredact."
209     end
210
211     ##
212     # test the unredaction of an old version of a way, while being
213     # authorised as a normal user.
214     def test_unredact_way_normal_user
215       way = create(:way, :with_history, :version => 2)
216       way_v1 = way.old_ways.find_by(:version => 1)
217       way_v1.redact!(create(:redaction))
218
219       basic_authorization create(:user).email, "test"
220
221       post :redact, :params => { :id => way_v1.way_id, :version => way_v1.version }
222       assert_response :forbidden, "should need to be moderator to unredact."
223     end
224
225     ##
226     # test the unredaction of an old version of a way, while being
227     # authorised as a moderator.
228     def test_unredact_way_moderator
229       moderator_user = create(:moderator_user)
230       way = create(:way, :with_history, :version => 2)
231       way_v1 = way.old_ways.find_by(:version => 1)
232       way_v1.redact!(create(:redaction))
233
234       basic_authorization moderator_user.email, "test"
235
236       post :redact, :params => { :id => way_v1.way_id, :version => way_v1.version }
237       assert_response :success, "should be OK to unredact old version as moderator."
238
239       # check moderator can still see the unredacted data, without passing
240       # the appropriate flag
241       get :version, :params => { :id => way_v1.way_id, :version => way_v1.version }
242       assert_response :success, "After unredaction, node should not be gone for moderator."
243
244       # and when accessed via history
245       get :history, :params => { :id => way_v1.way_id }
246       assert_response :success, "Unredaction shouldn't have stopped history working."
247       assert_select "osm way[id='#{way_v1.way_id}'][version='#{way_v1.version}']", 1, "way #{way_v1.way_id} version #{way_v1.version} should still be present in the history for moderators."
248
249       basic_authorization create(:user).email, "test"
250
251       # check normal user can now see the unredacted data
252       get :version, :params => { :id => way_v1.way_id, :version => way_v1.version }
253       assert_response :success, "After redaction, node should not be gone for moderator, when flag passed."
254
255       # and when accessed via history
256       get :history, :params => { :id => way_v1.way_id }
257       assert_response :success, "Redaction shouldn't have stopped history working."
258       assert_select "osm way[id='#{way_v1.way_id}'][version='#{way_v1.version}']", 1, "way #{way_v1.way_id} version #{way_v1.version} should still be present in the history for normal users."
259     end
260
261     private
262
263     ##
264     # check that the current version of a way is equivalent to the
265     # version which we're getting from the versions call.
266     def check_current_version(way_id)
267       # get the current version
268       current_way = with_controller(WaysController.new) do
269         get :show, :params => { :id => way_id }
270         assert_response :success, "can't get current way #{way_id}"
271         Way.from_xml(@response.body)
272       end
273       assert_not_nil current_way, "getting way #{way_id} returned nil"
274
275       # get the "old" version of the way from the version method
276       get :version, :params => { :id => way_id, :version => current_way.version }
277       assert_response :success, "can't get old way #{way_id}, v#{current_way.version}"
278       old_way = Way.from_xml(@response.body)
279
280       # check that the ways are identical
281       assert_ways_are_equal current_way, old_way
282     end
283
284     ##
285     # look at all the versions of the way in the history and get each version from
286     # the versions call. check that they're the same.
287     def check_history_equals_versions(way_id)
288       get :history, :params => { :id => way_id }
289       assert_response :success, "can't get way #{way_id} from API"
290       history_doc = XML::Parser.string(@response.body).parse
291       assert_not_nil history_doc, "parsing way #{way_id} history failed"
292
293       history_doc.find("//osm/way").each do |way_doc|
294         history_way = Way.from_xml_node(way_doc)
295         assert_not_nil history_way, "parsing way #{way_id} version failed"
296
297         get :version, :params => { :id => way_id, :version => history_way.version }
298         assert_response :success, "couldn't get way #{way_id}, v#{history_way.version}"
299         version_way = Way.from_xml(@response.body)
300         assert_not_nil version_way, "failed to parse #{way_id}, v#{history_way.version}"
301
302         assert_ways_are_equal history_way, version_way
303       end
304     end
305
306     def do_redact_way(way, redaction)
307       get :version, :params => { :id => way.way_id, :version => way.version }
308       assert_response :success, "should be able to get version #{way.version} of way #{way.way_id}."
309
310       # now redact it
311       post :redact, :params => { :id => way.way_id, :version => way.version, :redaction => redaction.id }
312     end
313
314     def propagate_tags(way, old_way)
315       way.tags.each do |k, v|
316         create(:old_way_tag, :old_way => old_way, :k => k, :v => v)
317       end
318     end
319   end
320 end