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