]> git.openstreetmap.org Git - rails.git/blob - test/controllers/api/old_ways_controller_test.rb
Merge branch 'pull/3146'
[rails.git] / test / controllers / api / old_ways_controller_test.rb
1 require "test_helper"
2
3 module Api
4   class OldWaysControllerTest < ActionDispatch::IntegrationTest
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 api_way_history_path(create(:way, :with_history))
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 api_way_history_path(create(:way, :with_history, :deleted))
43       assert_response :success
44     end
45
46     def test_history_invalid
47       # check chat a non-existent way is not returned
48       get api_way_history_path(: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       auth_header = basic_authorization_header 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), auth_header)
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       auth_header = basic_authorization_header 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), auth_header)
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 way_version_path(: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       auth_header = basic_authorization_header create(:user).email, "test"
134       get way_version_path(:id => way_v1.way_id, :version => way_v1.version), :headers => auth_header
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 api_way_history_path(: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,
148                     "redacted way #{way_v1.way_id} version #{way_v1.version} shouldn't be present in the history."
149
150       # not even to a logged-in user
151       auth_header = basic_authorization_header create(:user).email, "test"
152       get way_version_path(:id => way_v1.way_id, :version => way_v1.version), :headers => auth_header
153       get api_way_history_path(:id => way_v1.way_id), :headers => auth_header
154       assert_response :success, "Redaction shouldn't have stopped history working."
155       assert_select "osm way[id='#{way_v1.way_id}'][version='#{way_v1.version}']", 0,
156                     "redacted node #{way_v1.way_id} version #{way_v1.version} shouldn't be present in the history, even when logged in."
157     end
158
159     ##
160     # test the redaction of an old version of a way, while being
161     # authorised as a moderator.
162     def test_redact_way_moderator
163       way = create(:way, :with_history, :version => 4)
164       way_v3 = way.old_ways.find_by(:version => 3)
165       auth_header = basic_authorization_header create(:moderator_user).email, "test"
166
167       do_redact_way(way_v3, create(:redaction), auth_header)
168       assert_response :success, "should be OK to redact old version as moderator."
169
170       # check moderator can still see the redacted data, when passing
171       # the appropriate flag
172       get way_version_path(:id => way_v3.way_id, :version => way_v3.version), :headers => auth_header
173       assert_response :forbidden, "After redaction, node should be gone for moderator, when flag not passed."
174       get way_version_path(:id => way_v3.way_id, :version => way_v3.version), :params => { :show_redactions => "true" }, :headers => auth_header
175       assert_response :success, "After redaction, node should not be gone for moderator, when flag passed."
176
177       # and when accessed via history
178       get api_way_history_path(:id => way_v3.way_id), :headers => auth_header
179       assert_response :success, "Redaction shouldn't have stopped history working."
180       assert_select "osm way[id='#{way_v3.way_id}'][version='#{way_v3.version}']", 0,
181                     "way #{way_v3.way_id} version #{way_v3.version} should not be present in the history for moderators when not passing flag."
182       get api_way_history_path(:id => way_v3.way_id), :params => { :show_redactions => "true" }, :headers => auth_header
183       assert_response :success, "Redaction shouldn't have stopped history working."
184       assert_select "osm way[id='#{way_v3.way_id}'][version='#{way_v3.version}']", 1,
185                     "way #{way_v3.way_id} version #{way_v3.version} should still be present in the history for moderators when passing flag."
186     end
187
188     # testing that if the moderator drops auth, he can't see the
189     # redacted stuff any more.
190     def test_redact_way_is_redacted
191       way = create(:way, :with_history, :version => 4)
192       way_v3 = way.old_ways.find_by(:version => 3)
193       auth_header = basic_authorization_header create(:moderator_user).email, "test"
194
195       do_redact_way(way_v3, create(:redaction), auth_header)
196       assert_response :success, "should be OK to redact old version as moderator."
197
198       # re-auth as non-moderator
199       auth_header = basic_authorization_header create(:user).email, "test"
200
201       # check can't see the redacted data
202       get way_version_path(:id => way_v3.way_id, :version => way_v3.version), :headers => auth_header
203       assert_response :forbidden, "Redacted node shouldn't be visible via the version API."
204
205       # and when accessed via history
206       get api_way_history_path(:id => way_v3.way_id), :headers => auth_header
207       assert_response :success, "Redaction shouldn't have stopped history working."
208       assert_select "osm way[id='#{way_v3.way_id}'][version='#{way_v3.version}']", 0,
209                     "redacted way #{way_v3.way_id} version #{way_v3.version} shouldn't be present in the history."
210     end
211
212     ##
213     # test the unredaction of an old version of a way, while not being
214     # authorised.
215     def test_unredact_way_unauthorised
216       way = create(:way, :with_history, :version => 2)
217       way_v1 = way.old_ways.find_by(:version => 1)
218       way_v1.redact!(create(:redaction))
219
220       post way_version_redact_path(:id => way_v1.way_id, :version => way_v1.version)
221       assert_response :unauthorized, "should need to be authenticated to unredact."
222     end
223
224     ##
225     # test the unredaction of an old version of a way, while being
226     # authorised as a normal user.
227     def test_unredact_way_normal_user
228       way = create(:way, :with_history, :version => 2)
229       way_v1 = way.old_ways.find_by(:version => 1)
230       way_v1.redact!(create(:redaction))
231
232       auth_header = basic_authorization_header create(:user).email, "test"
233
234       post way_version_redact_path(:id => way_v1.way_id, :version => way_v1.version), :headers => auth_header
235       assert_response :forbidden, "should need to be moderator to unredact."
236     end
237
238     ##
239     # test the unredaction of an old version of a way, while being
240     # authorised as a moderator.
241     def test_unredact_way_moderator
242       moderator_user = create(:moderator_user)
243       way = create(:way, :with_history, :version => 2)
244       way_v1 = way.old_ways.find_by(:version => 1)
245       way_v1.redact!(create(:redaction))
246
247       auth_header = basic_authorization_header moderator_user.email, "test"
248
249       post way_version_redact_path(:id => way_v1.way_id, :version => way_v1.version), :headers => auth_header
250       assert_response :success, "should be OK to unredact old version as moderator."
251
252       # check moderator can still see the unredacted data, without passing
253       # the appropriate flag
254       get way_version_path(:id => way_v1.way_id, :version => way_v1.version), :headers => auth_header
255       assert_response :success, "After unredaction, node should not be gone for moderator."
256
257       # and when accessed via history
258       get api_way_history_path(:id => way_v1.way_id), :headers => auth_header
259       assert_response :success, "Unredaction shouldn't have stopped history working."
260       assert_select "osm way[id='#{way_v1.way_id}'][version='#{way_v1.version}']", 1,
261                     "way #{way_v1.way_id} version #{way_v1.version} should still be present in the history for moderators."
262
263       auth_header = basic_authorization_header create(:user).email, "test"
264
265       # check normal user can now see the unredacted data
266       get way_version_path(:id => way_v1.way_id, :version => way_v1.version), :headers => auth_header
267       assert_response :success, "After redaction, node should not be gone for moderator, when flag passed."
268
269       # and when accessed via history
270       get api_way_history_path(:id => way_v1.way_id), :headers => auth_header
271       assert_response :success, "Redaction shouldn't have stopped history working."
272       assert_select "osm way[id='#{way_v1.way_id}'][version='#{way_v1.version}']", 1,
273                     "way #{way_v1.way_id} version #{way_v1.version} should still be present in the history for normal users."
274     end
275
276     private
277
278     ##
279     # check that the current version of a way is equivalent to the
280     # version which we're getting from the versions call.
281     def check_current_version(way_id)
282       # get the current version
283       current_way = with_controller(WaysController.new) do
284         get api_way_path(way_id)
285         assert_response :success, "can't get current way #{way_id}"
286         Way.from_xml(@response.body)
287       end
288       assert_not_nil current_way, "getting way #{way_id} returned nil"
289
290       # get the "old" version of the way from the version method
291       get way_version_path(:id => way_id, :version => current_way.version)
292       assert_response :success, "can't get old way #{way_id}, v#{current_way.version}"
293       old_way = Way.from_xml(@response.body)
294
295       # check that the ways are identical
296       assert_ways_are_equal current_way, old_way
297     end
298
299     ##
300     # look at all the versions of the way in the history and get each version from
301     # the versions call. check that they're the same.
302     def check_history_equals_versions(way_id)
303       get api_way_history_path(:id => way_id)
304       assert_response :success, "can't get way #{way_id} from API"
305       history_doc = XML::Parser.string(@response.body).parse
306       assert_not_nil history_doc, "parsing way #{way_id} history failed"
307
308       history_doc.find("//osm/way").each do |way_doc|
309         history_way = Way.from_xml_node(way_doc)
310         assert_not_nil history_way, "parsing way #{way_id} version failed"
311
312         get way_version_path(:id => way_id, :version => history_way.version)
313         assert_response :success, "couldn't get way #{way_id}, v#{history_way.version}"
314         version_way = Way.from_xml(@response.body)
315         assert_not_nil version_way, "failed to parse #{way_id}, v#{history_way.version}"
316
317         assert_ways_are_equal history_way, version_way
318       end
319     end
320
321     def do_redact_way(way, redaction, headers = {})
322       get way_version_path(:id => way.way_id, :version => way.version)
323       assert_response :success, "should be able to get version #{way.version} of way #{way.way_id}."
324
325       # now redact it
326       post way_version_redact_path(:id => way.way_id, :version => way.version), :params => { :redaction => redaction.id }, :headers => headers
327     end
328
329     def propagate_tags(way, old_way)
330       way.tags.each do |k, v|
331         create(:old_way_tag, :old_way => old_way, :k => k, :v => v)
332       end
333     end
334   end
335 end