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