]> git.openstreetmap.org Git - rails.git/blob - test/controllers/api/old_relations_controller_test.rb
Split api old element redacted index tests
[rails.git] / test / controllers / api / old_relations_controller_test.rb
1 require "test_helper"
2
3 module Api
4   class OldRelationsControllerTest < ActionDispatch::IntegrationTest
5     ##
6     # test all routes which lead to this controller
7     def test_routes
8       assert_routing(
9         { :path => "/api/0.6/relation/1/history", :method => :get },
10         { :controller => "api/old_relations", :action => "index", :relation_id => "1" }
11       )
12       assert_routing(
13         { :path => "/api/0.6/relation/1/history.json", :method => :get },
14         { :controller => "api/old_relations", :action => "index", :relation_id => "1", :format => "json" }
15       )
16       assert_routing(
17         { :path => "/api/0.6/relation/1/2", :method => :get },
18         { :controller => "api/old_relations", :action => "show", :relation_id => "1", :version => "2" }
19       )
20       assert_routing(
21         { :path => "/api/0.6/relation/1/2.json", :method => :get },
22         { :controller => "api/old_relations", :action => "show", :relation_id => "1", :version => "2", :format => "json" }
23       )
24       assert_routing(
25         { :path => "/api/0.6/relation/1/2/redact", :method => :post },
26         { :controller => "api/old_relations", :action => "redact", :relation_id => "1", :version => "2" }
27       )
28     end
29
30     ##
31     # check that a visible relations is returned properly
32     def test_index
33       relation = create(:relation, :with_history, :version => 2)
34
35       get api_relation_versions_path(relation)
36
37       assert_response :success
38       assert_dom "osm:root", 1 do
39         assert_dom "> relation", 2 do |dom_relations|
40           assert_dom dom_relations[0], "> @id", relation.id.to_s
41           assert_dom dom_relations[0], "> @version", "1"
42
43           assert_dom dom_relations[1], "> @id", relation.id.to_s
44           assert_dom dom_relations[1], "> @version", "2"
45         end
46       end
47     end
48
49     ##
50     # check that a non-existent relations is not returned
51     def test_index_invalid
52       get api_relation_versions_path(0)
53       assert_response :not_found
54     end
55
56     ##
57     # test that redacted relations aren't visible in the history
58     def test_index_redacted_unauthorised
59       relation = create(:relation, :with_history, :version => 2)
60       relation.old_relations.find_by(:version => 1).redact!(create(:redaction))
61
62       get api_relation_versions_path(relation)
63
64       assert_response :success, "Redaction shouldn't have stopped history working."
65       assert_dom "osm relation[id='#{relation.id}'][version='1']", 0,
66                  "redacted relation #{relation.id} version 1 shouldn't be present in the history."
67     end
68
69     def test_index_redacted_normal_user
70       relation = create(:relation, :with_history, :version => 2)
71       relation.old_relations.find_by(:version => 1).redact!(create(:redaction))
72
73       get api_relation_versions_path(relation), :headers => bearer_authorization_header
74
75       assert_response :success, "Redaction shouldn't have stopped history working."
76       assert_dom "osm relation[id='#{relation.id}'][version='1']", 0,
77                  "redacted relation #{relation.id} version 1 shouldn't be present in the history, even when logged in."
78     end
79
80     def test_show
81       relation = create(:relation, :with_history, :version => 2)
82       create(:old_relation_tag, :old_relation => relation.old_relations[0], :k => "k1", :v => "v1")
83       create(:old_relation_tag, :old_relation => relation.old_relations[1], :k => "k2", :v => "v2")
84
85       get api_relation_version_path(relation, 1)
86
87       assert_response :success
88       assert_dom "osm:root", 1 do
89         assert_dom "> relation", 1 do
90           assert_dom "> @id", relation.id.to_s
91           assert_dom "> @version", "1"
92           assert_dom "> tag", 1 do
93             assert_dom "> @k", "k1"
94             assert_dom "> @v", "v1"
95           end
96         end
97       end
98
99       get api_relation_version_path(relation, 2)
100
101       assert_response :success
102       assert_dom "osm:root", 1 do
103         assert_dom "> relation", 1 do
104           assert_dom "> @id", relation.id.to_s
105           assert_dom "> @version", "2"
106           assert_dom "> tag", 1 do
107             assert_dom "> @k", "k2"
108             assert_dom "> @v", "v2"
109           end
110         end
111       end
112     end
113
114     ##
115     # test that redacted relations aren't visible, regardless of
116     # authorisation except as moderator...
117     def test_show_redacted
118       relation = create(:relation, :with_history, :version => 2)
119       relation_v1 = relation.old_relations.find_by(:version => 1)
120       relation_v1.redact!(create(:redaction))
121
122       get api_relation_version_path(relation_v1.relation_id, relation_v1.version)
123       assert_response :forbidden, "Redacted relation shouldn't be visible via the version API."
124
125       # not even to a logged-in user
126       auth_header = bearer_authorization_header
127       get api_relation_version_path(relation_v1.relation_id, relation_v1.version), :headers => auth_header
128       assert_response :forbidden, "Redacted relation shouldn't be visible via the version API, even when logged in."
129     end
130
131     ##
132     # test the redaction of an old version of a relation, while not being
133     # authorised.
134     def test_redact_relation_unauthorised
135       relation = create(:relation, :with_history, :version => 4)
136       relation_v3 = relation.old_relations.find_by(:version => 3)
137
138       do_redact_relation(relation_v3, create(:redaction))
139       assert_response :unauthorized, "should need to be authenticated to redact."
140     end
141
142     ##
143     # test the redaction of an old version of a relation, while being
144     # authorised as a normal user.
145     def test_redact_relation_normal_user
146       relation = create(:relation, :with_history, :version => 4)
147       relation_v3 = relation.old_relations.find_by(:version => 3)
148
149       auth_header = bearer_authorization_header
150
151       do_redact_relation(relation_v3, create(:redaction), auth_header)
152       assert_response :forbidden, "should need to be moderator to redact."
153     end
154
155     ##
156     # test that, even as moderator, the current version of a relation
157     # can't be redacted.
158     def test_redact_relation_current_version
159       relation = create(:relation, :with_history, :version => 4)
160       relation_latest = relation.old_relations.last
161
162       auth_header = bearer_authorization_header create(:moderator_user)
163
164       do_redact_relation(relation_latest, create(:redaction), auth_header)
165       assert_response :bad_request, "shouldn't be OK to redact current version as moderator."
166     end
167
168     def test_redact_relation_by_regular_without_write_redactions_scope
169       auth_header = bearer_authorization_header(create(:user), :scopes => %w[read_prefs write_api])
170       do_redact_redactable_relation(auth_header)
171       assert_response :forbidden, "should need to be moderator to redact."
172     end
173
174     def test_redact_relation_by_regular_with_write_redactions_scope
175       auth_header = bearer_authorization_header(create(:user), :scopes => %w[write_redactions])
176       do_redact_redactable_relation(auth_header)
177       assert_response :forbidden, "should need to be moderator to redact."
178     end
179
180     def test_redact_relation_by_moderator_without_write_redactions_scope
181       auth_header = bearer_authorization_header(create(:moderator_user), :scopes => %w[read_prefs write_api])
182       do_redact_redactable_relation(auth_header)
183       assert_response :forbidden, "should need to have write_redactions scope to redact."
184     end
185
186     def test_redact_relation_by_moderator_with_write_redactions_scope
187       auth_header = bearer_authorization_header(create(:moderator_user), :scopes => %w[write_redactions])
188       do_redact_redactable_relation(auth_header)
189       assert_response :success, "should be OK to redact old version as moderator with write_redactions scope."
190     end
191
192     ##
193     # test the redaction of an old version of a relation, while being
194     # authorised as a moderator.
195     def test_redact_relation_moderator
196       relation = create(:relation, :with_history, :version => 4)
197       relation_v3 = relation.old_relations.find_by(:version => 3)
198
199       auth_header = bearer_authorization_header create(:moderator_user)
200
201       do_redact_relation(relation_v3, create(:redaction), auth_header)
202       assert_response :success, "should be OK to redact old version as moderator."
203
204       # check moderator can still see the redacted data, when passing
205       # the appropriate flag
206       get api_relation_version_path(relation_v3.relation_id, relation_v3.version), :headers => auth_header
207       assert_response :forbidden, "After redaction, relation should be gone for moderator, when flag not passed."
208       get api_relation_version_path(relation_v3.relation_id, relation_v3.version, :show_redactions => "true"), :headers => auth_header
209       assert_response :success, "After redaction, relation should not be gone for moderator, when flag passed."
210
211       # and when accessed via history
212       get api_relation_versions_path(relation), :headers => auth_header
213       assert_response :success, "Redaction shouldn't have stopped history working."
214       assert_select "osm relation[id='#{relation_v3.relation_id}'][version='#{relation_v3.version}']", 0,
215                     "relation #{relation_v3.relation_id} version #{relation_v3.version} should not be present in the history for moderators when not passing flag."
216       get api_relation_versions_path(relation, :show_redactions => "true"), :headers => auth_header
217       assert_response :success, "Redaction shouldn't have stopped history working."
218       assert_select "osm relation[id='#{relation_v3.relation_id}'][version='#{relation_v3.version}']", 1,
219                     "relation #{relation_v3.relation_id} version #{relation_v3.version} should still be present in the history for moderators when passing flag."
220     end
221
222     # testing that if the moderator drops auth, he can't see the
223     # redacted stuff any more.
224     def test_redact_relation_is_redacted
225       relation = create(:relation, :with_history, :version => 4)
226       relation_v3 = relation.old_relations.find_by(:version => 3)
227
228       auth_header = bearer_authorization_header create(:moderator_user)
229
230       do_redact_relation(relation_v3, create(:redaction), auth_header)
231       assert_response :success, "should be OK to redact old version as moderator."
232
233       # re-auth as non-moderator
234       auth_header = bearer_authorization_header
235
236       # check can't see the redacted data
237       get api_relation_version_path(relation_v3.relation_id, relation_v3.version), :headers => auth_header
238       assert_response :forbidden, "Redacted relation shouldn't be visible via the version API."
239
240       # and when accessed via history
241       get api_relation_versions_path(relation), :headers => auth_header
242       assert_response :success, "Redaction shouldn't have stopped history working."
243       assert_select "osm relation[id='#{relation_v3.relation_id}'][version='#{relation_v3.version}']", 0,
244                     "redacted relation #{relation_v3.relation_id} version #{relation_v3.version} shouldn't be present in the history."
245     end
246
247     ##
248     # test the unredaction of an old version of a relation, while not being
249     # authorised.
250     def test_unredact_relation_unauthorised
251       relation = create(:relation, :with_history, :version => 2)
252       relation_v1 = relation.old_relations.find_by(:version => 1)
253       relation_v1.redact!(create(:redaction))
254
255       post relation_version_redact_path(relation_v1.relation_id, relation_v1.version)
256       assert_response :unauthorized, "should need to be authenticated to unredact."
257     end
258
259     ##
260     # test the unredaction of an old version of a relation, while being
261     # authorised as a normal user.
262     def test_unredact_relation_normal_user
263       relation = create(:relation, :with_history, :version => 2)
264       relation_v1 = relation.old_relations.find_by(:version => 1)
265       relation_v1.redact!(create(:redaction))
266
267       auth_header = bearer_authorization_header
268
269       post relation_version_redact_path(relation_v1.relation_id, relation_v1.version), :headers => auth_header
270       assert_response :forbidden, "should need to be moderator to unredact."
271     end
272
273     ##
274     # test the unredaction of an old version of a relation, while being
275     # authorised as a moderator.
276     def test_unredact_relation_moderator
277       relation = create(:relation, :with_history, :version => 2)
278       relation_v1 = relation.old_relations.find_by(:version => 1)
279       relation_v1.redact!(create(:redaction))
280
281       auth_header = bearer_authorization_header create(:moderator_user)
282
283       post relation_version_redact_path(relation_v1.relation_id, relation_v1.version), :headers => auth_header
284       assert_response :success, "should be OK to unredact old version as moderator."
285
286       # check moderator can still see the redacted data, without passing
287       # the appropriate flag
288       get api_relation_version_path(relation_v1.relation_id, relation_v1.version), :headers => auth_header
289       assert_response :success, "After unredaction, relation should not be gone for moderator."
290
291       # and when accessed via history
292       get api_relation_versions_path(relation), :headers => auth_header
293       assert_response :success, "Redaction shouldn't have stopped history working."
294       assert_select "osm relation[id='#{relation_v1.relation_id}'][version='#{relation_v1.version}']", 1,
295                     "relation #{relation_v1.relation_id} version #{relation_v1.version} should still be present in the history for moderators."
296
297       auth_header = bearer_authorization_header
298
299       # check normal user can now see the redacted data
300       get api_relation_version_path(relation_v1.relation_id, relation_v1.version), :headers => auth_header
301       assert_response :success, "After redaction, node should not be gone for normal user."
302
303       # and when accessed via history
304       get api_relation_versions_path(relation), :headers => auth_header
305       assert_response :success, "Redaction shouldn't have stopped history working."
306       assert_select "osm relation[id='#{relation_v1.relation_id}'][version='#{relation_v1.version}']", 1,
307                     "relation #{relation_v1.relation_id} version #{relation_v1.version} should still be present in the history for normal users."
308     end
309
310     private
311
312     def do_redact_redactable_relation(headers = {})
313       relation = create(:relation, :with_history, :version => 4)
314       relation_v3 = relation.old_relations.find_by(:version => 3)
315       do_redact_relation(relation_v3, create(:redaction), headers)
316     end
317
318     def do_redact_relation(relation, redaction, headers = {})
319       get api_relation_version_path(relation.relation_id, relation.version)
320       assert_response :success, "should be able to get version #{relation.version} of relation #{relation.relation_id}."
321
322       # now redact it
323       post relation_version_redact_path(relation.relation_id, relation.version), :params => { :redaction => redaction.id }, :headers => headers
324     end
325   end
326 end