1 require File.dirname(__FILE__) + '/../test_helper'
2 require 'changeset_controller'
4 class ChangesetControllerTest < ActionController::TestCase
7 def basic_authorization(user, pass)
8 @request.env["HTTP_AUTHORIZATION"] = "Basic %s" % Base64.encode64("#{user}:#{pass}")
12 @request.env["RAW_POST_DATA"] = c.to_s
15 # -----------------------
16 # Test simple changeset creation
17 # -----------------------
20 basic_authorization "test@openstreetmap.org", "test"
22 # Create the first user's changeset
23 content "<osm><changeset>" +
24 "<tag k='created_by' v='osm test suite checking changesets'/>" +
28 assert_response :success, "Creation of changeset did not return sucess status"
29 newid = @response.body
32 def test_create_invalid
33 basic_authorization "test@openstreetmap.org", "test"
34 content "<osm><changeset></osm>"
36 assert_response :bad_request, "creating a invalid changeset should fail"
48 # upload something simple, but valid and check that it can
50 def test_upload_simple_valid
51 basic_authorization "test@openstreetmap.org", "test"
53 # simple diff to change a node, way and relation by removing
58 <node id='1' lon='0' lat='0' changeset='1' version='1'/>
59 <way id='1' changeset='1' version='1'>
64 <relation id='1' changeset='1' version='1'>
65 <member type='way' role='some' ref='3'/>
66 <member type='node' role='some' ref='5'/>
67 <member type='relation' role='some' ref='3'/>
75 post :upload, :id => 1
76 assert_response :success,
77 "can't upload a simple valid diff to changeset: #{@response.body}"
79 # check that the changes made it into the database
80 assert_equal 0, Node.find(1).tags.size, "node 1 should now have no tags"
81 assert_equal 0, Way.find(1).tags.size, "way 1 should now have no tags"
82 assert_equal 0, Relation.find(1).tags.size, "relation 1 should now have no tags"
86 # upload something which creates new objects using placeholders
87 def test_upload_create_valid
88 basic_authorization "test@openstreetmap.org", "test"
90 # simple diff to create a node way and relation using placeholders
94 <node id='-1' lon='0' lat='0' changeset='1'>
95 <tag k='foo' v='bar'/>
96 <tag k='baz' v='bat'/>
98 <way id='-1' changeset='1'>
103 <relation id='-1' changeset='1'>
104 <member type='way' role='some' ref='3'/>
105 <member type='node' role='some' ref='5'/>
106 <member type='relation' role='some' ref='3'/>
114 post :upload, :id => 1
115 assert_response :success,
116 "can't upload a simple valid creation to changeset: #{@response.body}"
118 # check the returned payload
119 assert_select "osm[version=#{API_VERSION}][generator=\"OpenStreetMap server\"]", 1
120 assert_select "osm>node", 1
121 assert_select "osm>way", 1
122 assert_select "osm>relation", 1
124 # inspect the response to find out what the new element IDs are
125 doc = XML::Parser.string(@response.body).parse
126 new_node_id = doc.find("//osm/node").first["new_id"].to_i
127 new_way_id = doc.find("//osm/way").first["new_id"].to_i
128 new_rel_id = doc.find("//osm/relation").first["new_id"].to_i
130 # check the old IDs are all present and negative one
131 assert_equal -1, doc.find("//osm/node").first["old_id"].to_i
132 assert_equal -1, doc.find("//osm/way").first["old_id"].to_i
133 assert_equal -1, doc.find("//osm/relation").first["old_id"].to_i
135 # check the versions are present and equal one
136 assert_equal 1, doc.find("//osm/node").first["new_version"].to_i
137 assert_equal 1, doc.find("//osm/way").first["new_version"].to_i
138 assert_equal 1, doc.find("//osm/relation").first["new_version"].to_i
140 # check that the changes made it into the database
141 assert_equal 2, Node.find(new_node_id).tags.size, "new node should have two tags"
142 assert_equal 0, Way.find(new_way_id).tags.size, "new way should have no tags"
143 assert_equal 0, Relation.find(new_rel_id).tags.size, "new relation should have no tags"
147 # test a complex delete where we delete elements which rely on eachother
148 # in the same transaction.
149 def test_upload_delete
150 basic_authorization "test@openstreetmap.org", "test"
152 diff = XML::Document.new
153 diff.root = XML::Node.new "osmChange"
154 delete = XML::Node.new "delete"
156 delete << current_relations(:visible_relation).to_xml_node
157 delete << current_relations(:used_relation).to_xml_node
158 delete << current_ways(:used_way).to_xml_node
159 delete << current_nodes(:node_used_by_relationship).to_xml_node
163 post :upload, :id => 1
164 assert_response :success,
165 "can't upload a deletion diff to changeset: #{@response.body}"
167 # check that everything was deleted
168 assert_equal false, Node.find(current_nodes(:node_used_by_relationship).id).visible
169 assert_equal false, Way.find(current_ways(:used_way).id).visible
170 assert_equal false, Relation.find(current_relations(:visible_relation).id).visible
171 assert_equal false, Relation.find(current_relations(:used_relation).id).visible
175 # test that deleting stuff in a transaction doesn't bypass the checks
176 # to ensure that used elements are not deleted.
177 def test_upload_delete_invalid
178 basic_authorization "test@openstreetmap.org", "test"
180 diff = XML::Document.new
181 diff.root = XML::Node.new "osmChange"
182 delete = XML::Node.new "delete"
184 delete << current_relations(:visible_relation).to_xml_node
185 delete << current_ways(:used_way).to_xml_node
186 delete << current_nodes(:node_used_by_relationship).to_xml_node
190 post :upload, :id => 1
191 assert_response :precondition_failed,
192 "shouldn't be able to upload a invalid deletion diff: #{@response.body}"
194 # check that nothing was, in fact, deleted
195 assert_equal true, Node.find(current_nodes(:node_used_by_relationship).id).visible
196 assert_equal true, Way.find(current_ways(:used_way).id).visible
197 assert_equal true, Relation.find(current_relations(:visible_relation).id).visible
201 # upload something which creates new objects and inserts them into
202 # existing containers using placeholders.
203 def test_upload_complex
204 basic_authorization "test@openstreetmap.org", "test"
206 # simple diff to create a node way and relation using placeholders
210 <node id='-1' lon='0' lat='0' changeset='1'>
211 <tag k='foo' v='bar'/>
212 <tag k='baz' v='bat'/>
216 <way id='1' changeset='1' version='1'>
220 <relation id='1' changeset='1' version='1'>
221 <member type='way' role='some' ref='3'/>
222 <member type='node' role='some' ref='-1'/>
223 <member type='relation' role='some' ref='3'/>
231 post :upload, :id => 1
232 assert_response :success,
233 "can't upload a complex diff to changeset: #{@response.body}"
235 # check the returned payload
236 assert_select "osm[version=#{API_VERSION}][generator=\"OpenStreetMap server\"]", 1
237 assert_select "osm>node", 1
238 assert_select "osm>way", 1
239 assert_select "osm>relation", 1
241 # inspect the response to find out what the new element IDs are
242 doc = XML::Parser.string(@response.body).parse
243 new_node_id = doc.find("//osm/node").first["new_id"].to_i
245 # check that the changes made it into the database
246 assert_equal 2, Node.find(new_node_id).tags.size, "new node should have two tags"
247 assert_equal [new_node_id, 3], Way.find(1).nds, "way nodes should match"
248 Relation.find(1).members.each do |type,id,role|
250 assert_equal new_node_id, id, "relation should contain new node"
256 # create a diff which references several changesets, which should cause
257 # a rollback and none of the diff gets committed
258 def test_upload_invalid_changesets
259 basic_authorization "test@openstreetmap.org", "test"
261 # simple diff to create a node way and relation using placeholders
265 <node id='1' lon='0' lat='0' changeset='1' version='1'/>
266 <way id='1' changeset='1' version='1'>
271 <relation id='1' changeset='1' version='1'>
272 <member type='way' role='some' ref='3'/>
273 <member type='node' role='some' ref='5'/>
274 <member type='relation' role='some' ref='3'/>
278 <node id='-1' changeset='4'>
279 <tag k='foo' v='bar'/>
280 <tag k='baz' v='bat'/>
285 # cache the objects before uploading them
286 node = current_nodes(:visible_node)
287 way = current_ways(:visible_way)
288 rel = current_relations(:visible_relation)
292 post :upload, :id => 1
293 assert_response :conflict,
294 "uploading a diff with multiple changsets should have failed"
296 # check that objects are unmodified
297 assert_nodes_are_equal(node, Node.find(1))
298 assert_ways_are_equal(way, Way.find(1))
302 # upload multiple versions of the same element in the same diff.
303 def test_upload_multiple_valid
304 basic_authorization "test@openstreetmap.org", "test"
306 # change the location of a node multiple times, each time referencing
307 # the last version. doesn't this depend on version numbers being
312 <node id='1' lon='0' lat='0' changeset='1' version='1'/>
313 <node id='1' lon='1' lat='0' changeset='1' version='2'/>
314 <node id='1' lon='1' lat='1' changeset='1' version='3'/>
315 <node id='1' lon='1' lat='2' changeset='1' version='4'/>
316 <node id='1' lon='2' lat='2' changeset='1' version='5'/>
317 <node id='1' lon='3' lat='2' changeset='1' version='6'/>
318 <node id='1' lon='3' lat='3' changeset='1' version='7'/>
319 <node id='1' lon='9' lat='9' changeset='1' version='8'/>
326 post :upload, :id => 1
327 assert_response :success,
328 "can't upload multiple versions of an element in a diff: #{@response.body}"
332 # upload multiple versions of the same element in the same diff, but
333 # keep the version numbers the same.
334 def test_upload_multiple_duplicate
335 basic_authorization "test@openstreetmap.org", "test"
340 <node id='1' lon='0' lat='0' changeset='1' version='1'/>
341 <node id='1' lon='1' lat='1' changeset='1' version='1'/>
348 post :upload, :id => 1
349 assert_response :conflict,
350 "shouldn't be able to upload the same element twice in a diff: #{@response.body}"
354 # try to upload some elements without specifying the version
355 def test_upload_missing_version
356 basic_authorization "test@openstreetmap.org", "test"
361 <node id='1' lon='1' lat='1' changeset='1'/>
368 post :upload, :id => 1
369 assert_response :bad_request,
370 "shouldn't be able to upload an element without version: #{@response.body}"
374 # when we make some simple changes we get the same changes back from the
376 def test_diff_download_simple
377 basic_authorization(users(:normal_user).email, "test")
379 # create a temporary changeset
380 content "<osm><changeset>" +
381 "<tag k='created_by' v='osm test suite checking changesets'/>" +
384 assert_response :success
385 changeset_id = @response.body.to_i
391 <node id='1' lon='0' lat='0' changeset='#{changeset_id}' version='1'/>
392 <node id='1' lon='1' lat='0' changeset='#{changeset_id}' version='2'/>
393 <node id='1' lon='1' lat='1' changeset='#{changeset_id}' version='3'/>
394 <node id='1' lon='1' lat='2' changeset='#{changeset_id}' version='4'/>
395 <node id='1' lon='2' lat='2' changeset='#{changeset_id}' version='5'/>
396 <node id='1' lon='3' lat='2' changeset='#{changeset_id}' version='6'/>
397 <node id='1' lon='3' lat='3' changeset='#{changeset_id}' version='7'/>
398 <node id='1' lon='9' lat='9' changeset='#{changeset_id}' version='8'/>
405 post :upload, :id => changeset_id
406 assert_response :success,
407 "can't upload multiple versions of an element in a diff: #{@response.body}"
409 get :download, :id => changeset_id
410 assert_response :success
412 assert_select "osmChange", 1
413 assert_select "osmChange>modify", 8
414 assert_select "osmChange>modify>node", 8
418 # when we make some complex changes we get the same changes back from the
420 def test_diff_download_complex
421 basic_authorization(users(:normal_user).email, "test")
423 # create a temporary changeset
424 content "<osm><changeset>" +
425 "<tag k='created_by' v='osm test suite checking changesets'/>" +
428 assert_response :success
429 changeset_id = @response.body.to_i
435 <node id='1' lon='0' lat='0' changeset='#{changeset_id}' version='1'/>
438 <node id='-1' lon='9' lat='9' changeset='#{changeset_id}' version='0'/>
439 <node id='-2' lon='8' lat='9' changeset='#{changeset_id}' version='0'/>
440 <node id='-3' lon='7' lat='9' changeset='#{changeset_id}' version='0'/>
443 <node id='3' lon='20' lat='15' changeset='#{changeset_id}' version='1'/>
444 <way id='1' changeset='#{changeset_id}' version='1'>
456 post :upload, :id => changeset_id
457 assert_response :success,
458 "can't upload multiple versions of an element in a diff: #{@response.body}"
460 get :download, :id => changeset_id
461 assert_response :success
463 assert_select "osmChange", 1
464 assert_select "osmChange>create", 3
465 assert_select "osmChange>delete", 1
466 assert_select "osmChange>modify", 2
467 assert_select "osmChange>create>node", 3
468 assert_select "osmChange>delete>node", 1
469 assert_select "osmChange>modify>node", 1
470 assert_select "osmChange>modify>way", 1