Merge remote-tracking branch 'upstream/pull/1561'
[rails.git] / test / controllers / old_relation_controller_test.rb
1 require "test_helper"
2 require "old_relation_controller"
3
4 class OldRelationControllerTest < ActionController::TestCase
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 => "old_relation", :action => "history", :id => "1" }
11     )
12     assert_routing(
13       { :path => "/api/0.6/relation/1/2", :method => :get },
14       { :controller => "old_relation", :action => "version", :id => "1", :version => "2" }
15     )
16     assert_routing(
17       { :path => "/api/0.6/relation/1/2/redact", :method => :post },
18       { :controller => "old_relation", :action => "redact", :id => "1", :version => "2" }
19     )
20   end
21
22   # -------------------------------------
23   # Test reading old relations.
24   # -------------------------------------
25   def test_history
26     # check that a visible relations is returned properly
27     get :history, :params => { :id => create(:relation, :with_history).id }
28     assert_response :success
29
30     # check chat a non-existent relations is not returned
31     get :history, :params => { :id => 0 }
32     assert_response :not_found
33   end
34
35   ##
36   # test the redaction of an old version of a relation, while not being
37   # authorised.
38   def test_redact_relation_unauthorised
39     relation = create(:relation, :with_history, :version => 4)
40     relation_v3 = relation.old_relations.find_by(:version => 3)
41
42     do_redact_relation(relation_v3, create(:redaction))
43     assert_response :unauthorized, "should need to be authenticated to redact."
44   end
45
46   ##
47   # test the redaction of an old version of a relation, while being
48   # authorised as a normal user.
49   def test_redact_relation_normal_user
50     relation = create(:relation, :with_history, :version => 4)
51     relation_v3 = relation.old_relations.find_by(:version => 3)
52
53     basic_authorization(create(:user).email, "test")
54
55     do_redact_relation(relation_v3, create(:redaction))
56     assert_response :forbidden, "should need to be moderator to redact."
57   end
58
59   ##
60   # test that, even as moderator, the current version of a relation
61   # can't be redacted.
62   def test_redact_relation_current_version
63     relation = create(:relation, :with_history, :version => 4)
64     relation_latest = relation.old_relations.last
65
66     basic_authorization(create(:moderator_user).email, "test")
67
68     do_redact_relation(relation_latest, create(:redaction))
69     assert_response :bad_request, "shouldn't be OK to redact current version as moderator."
70   end
71
72   ##
73   # test that redacted relations aren't visible, regardless of
74   # authorisation except as moderator...
75   def test_version_redacted
76     relation = create(:relation, :with_history, :version => 2)
77     relation_v1 = relation.old_relations.find_by(:version => 1)
78     relation_v1.redact!(create(:redaction))
79
80     get :version, :params => { :id => relation_v1.relation_id, :version => relation_v1.version }
81     assert_response :forbidden, "Redacted relation shouldn't be visible via the version API."
82
83     # not even to a logged-in user
84     basic_authorization(create(:user).email, "test")
85     get :version, :params => { :id => relation_v1.relation_id, :version => relation_v1.version }
86     assert_response :forbidden, "Redacted relation shouldn't be visible via the version API, even when logged in."
87   end
88
89   ##
90   # test that redacted relations aren't visible in the history
91   def test_history_redacted
92     relation = create(:relation, :with_history, :version => 2)
93     relation_v1 = relation.old_relations.find_by(:version => 1)
94     relation_v1.redact!(create(:redaction))
95
96     get :history, :params => { :id => relation_v1.relation_id }
97     assert_response :success, "Redaction shouldn't have stopped history working."
98     assert_select "osm relation[id='#{relation_v1.relation_id}'][version='#{relation_v1.version}']", 0, "redacted relation #{relation_v1.relation_id} version #{relation_v1.version} shouldn't be present in the history."
99
100     # not even to a logged-in user
101     basic_authorization(create(:user).email, "test")
102     get :version, :params => { :id => relation_v1.relation_id, :version => relation_v1.version }
103     get :history, :params => { :id => relation_v1.relation_id }
104     assert_response :success, "Redaction shouldn't have stopped history working."
105     assert_select "osm relation[id='#{relation_v1.relation_id}'][version='#{relation_v1.version}']", 0, "redacted relation #{relation_v1.relation_id} version #{relation_v1.version} shouldn't be present in the history, even when logged in."
106   end
107
108   ##
109   # test the redaction of an old version of a relation, while being
110   # authorised as a moderator.
111   def test_redact_relation_moderator
112     relation = create(:relation, :with_history, :version => 4)
113     relation_v3 = relation.old_relations.find_by(:version => 3)
114
115     basic_authorization(create(:moderator_user).email, "test")
116
117     do_redact_relation(relation_v3, create(:redaction))
118     assert_response :success, "should be OK to redact old version as moderator."
119
120     # check moderator can still see the redacted data, when passing
121     # the appropriate flag
122     get :version, :params => { :id => relation_v3.relation_id, :version => relation_v3.version }
123     assert_response :forbidden, "After redaction, relation should be gone for moderator, when flag not passed."
124     get :version, :params => { :id => relation_v3.relation_id, :version => relation_v3.version, :show_redactions => "true" }
125     assert_response :success, "After redaction, relation should not be gone for moderator, when flag passed."
126
127     # and when accessed via history
128     get :history, :params => { :id => relation_v3.relation_id }
129     assert_response :success, "Redaction shouldn't have stopped history working."
130     assert_select "osm relation[id='#{relation_v3.relation_id}'][version='#{relation_v3.version}']", 0, "relation #{relation_v3.relation_id} version #{relation_v3.version} should not be present in the history for moderators when not passing flag."
131     get :history, :params => { :id => relation_v3.relation_id, :show_redactions => "true" }
132     assert_response :success, "Redaction shouldn't have stopped history working."
133     assert_select "osm relation[id='#{relation_v3.relation_id}'][version='#{relation_v3.version}']", 1, "relation #{relation_v3.relation_id} version #{relation_v3.version} should still be present in the history for moderators when passing flag."
134   end
135
136   # testing that if the moderator drops auth, he can't see the
137   # redacted stuff any more.
138   def test_redact_relation_is_redacted
139     relation = create(:relation, :with_history, :version => 4)
140     relation_v3 = relation.old_relations.find_by(:version => 3)
141
142     basic_authorization(create(:moderator_user).email, "test")
143
144     do_redact_relation(relation_v3, create(:redaction))
145     assert_response :success, "should be OK to redact old version as moderator."
146
147     # re-auth as non-moderator
148     basic_authorization(create(:user).email, "test")
149
150     # check can't see the redacted data
151     get :version, :params => { :id => relation_v3.relation_id, :version => relation_v3.version }
152     assert_response :forbidden, "Redacted relation shouldn't be visible via the version API."
153
154     # and when accessed via history
155     get :history, :params => { :id => relation_v3.relation_id }
156     assert_response :success, "Redaction shouldn't have stopped history working."
157     assert_select "osm relation[id='#{relation_v3.relation_id}'][version='#{relation_v3.version}']", 0, "redacted relation #{relation_v3.relation_id} version #{relation_v3.version} shouldn't be present in the history."
158   end
159
160   ##
161   # test the unredaction of an old version of a relation, while not being
162   # authorised.
163   def test_unredact_relation_unauthorised
164     relation = create(:relation, :with_history, :version => 2)
165     relation_v1 = relation.old_relations.find_by(:version => 1)
166     relation_v1.redact!(create(:redaction))
167
168     post :redact, :params => { :id => relation_v1.relation_id, :version => relation_v1.version }
169     assert_response :unauthorized, "should need to be authenticated to unredact."
170   end
171
172   ##
173   # test the unredaction of an old version of a relation, while being
174   # authorised as a normal user.
175   def test_unredact_relation_normal_user
176     relation = create(:relation, :with_history, :version => 2)
177     relation_v1 = relation.old_relations.find_by(:version => 1)
178     relation_v1.redact!(create(:redaction))
179
180     basic_authorization(create(:user).email, "test")
181
182     post :redact, :params => { :id => relation_v1.relation_id, :version => relation_v1.version }
183     assert_response :forbidden, "should need to be moderator to unredact."
184   end
185
186   ##
187   # test the unredaction of an old version of a relation, while being
188   # authorised as a moderator.
189   def test_unredact_relation_moderator
190     relation = create(:relation, :with_history, :version => 2)
191     relation_v1 = relation.old_relations.find_by(:version => 1)
192     relation_v1.redact!(create(:redaction))
193
194     basic_authorization(create(:moderator_user).email, "test")
195
196     post :redact, :params => { :id => relation_v1.relation_id, :version => relation_v1.version }
197     assert_response :success, "should be OK to unredact old version as moderator."
198
199     # check moderator can still see the redacted data, without passing
200     # the appropriate flag
201     get :version, :params => { :id => relation_v1.relation_id, :version => relation_v1.version }
202     assert_response :success, "After unredaction, relation should not be gone for moderator."
203
204     # and when accessed via history
205     get :history, :params => { :id => relation_v1.relation_id }
206     assert_response :success, "Redaction shouldn't have stopped history working."
207     assert_select "osm relation[id='#{relation_v1.relation_id}'][version='#{relation_v1.version}']", 1, "relation #{relation_v1.relation_id} version #{relation_v1.version} should still be present in the history for moderators."
208
209     basic_authorization(create(:user).email, "test")
210
211     # check normal user can now see the redacted data
212     get :version, :params => { :id => relation_v1.relation_id, :version => relation_v1.version }
213     assert_response :success, "After redaction, node should not be gone for normal user."
214
215     # and when accessed via history
216     get :history, :params => { :id => relation_v1.relation_id }
217     assert_response :success, "Redaction shouldn't have stopped history working."
218     assert_select "osm relation[id='#{relation_v1.relation_id}'][version='#{relation_v1.version}']", 1, "relation #{relation_v1.relation_id} version #{relation_v1.version} should still be present in the history for normal users."
219   end
220
221   private
222
223   ##
224   # check that the current version of a relation is equivalent to the
225   # version which we're getting from the versions call.
226   def check_current_version(relation_id)
227     # get the current version
228     current_relation = with_controller(RelationController.new) do
229       get :read, :params => { :id => relation_id }
230       assert_response :success, "can't get current relation #{relation_id}"
231       Relation.from_xml(@response.body)
232     end
233     assert_not_nil current_relation, "getting relation #{relation_id} returned nil"
234
235     # get the "old" version of the relation from the version method
236     get :version, :params => { :id => relation_id, :version => current_relation.version }
237     assert_response :success, "can't get old relation #{relation_id}, v#{current_relation.version}"
238     old_relation = Relation.from_xml(@response.body)
239
240     # check that the relations are identical
241     assert_relations_are_equal current_relation, old_relation
242   end
243
244   ##
245   # look at all the versions of the relation in the history and get each version from
246   # the versions call. check that they're the same.
247   def check_history_equals_versions(relation_id)
248     get :history, :params => { :id => relation_id }
249     assert_response :success, "can't get relation #{relation_id} from API"
250     history_doc = XML::Parser.string(@response.body).parse
251     assert_not_nil history_doc, "parsing relation #{relation_id} history failed"
252
253     history_doc.find("//osm/relation").each do |relation_doc|
254       history_relation = Relation.from_xml_node(relation_doc)
255       assert_not_nil history_relation, "parsing relation #{relation_id} version failed"
256
257       get :version, :params => { :id => relation_id, :version => history_relation.version }
258       assert_response :success, "couldn't get relation #{relation_id}, v#{history_relation.version}"
259       version_relation = Relation.from_xml(@response.body)
260       assert_not_nil version_relation, "failed to parse #{relation_id}, v#{history_relation.version}"
261
262       assert_relations_are_equal history_relation, version_relation
263     end
264   end
265
266   def do_redact_relation(relation, redaction)
267     get :version, :params => { :id => relation.relation_id, :version => relation.version }
268     assert_response :success, "should be able to get version #{relation.version} of relation #{relation.relation_id}."
269
270     # now redact it
271     post :redact, :params => { :id => relation.relation_id, :version => relation.version, :redaction => redaction.id }
272   end
273 end