1 require File.dirname(__FILE__) + '/../test_helper'
2 require 'changeset_controller'
4 class ChangesetControllerTest < ActionController::TestCase
8 # test all routes which lead to this controller
11 { :path => "/api/0.6/changeset/create", :method => :put },
12 { :controller => "changeset", :action => "create" }
15 { :path => "/api/0.6/changeset/1/upload", :method => :post },
16 { :controller => "changeset", :action => "upload", :id => "1" }
19 { :path => "/api/0.6/changeset/1/download", :method => :get },
20 { :controller => "changeset", :action => "download", :id => "1" }
23 { :path => "/api/0.6/changeset/1/expand_bbox", :method => :post },
24 { :controller => "changeset", :action => "expand_bbox", :id => "1" }
27 { :path => "/api/0.6/changeset/1", :method => :get },
28 { :controller => "changeset", :action => "read", :id => "1" }
31 { :path => "/api/0.6/changeset/1", :method => :put },
32 { :controller => "changeset", :action => "update", :id => "1" }
35 { :path => "/api/0.6/changeset/1/close", :method => :put },
36 { :controller => "changeset", :action => "close", :id => "1" }
39 { :path => "/api/0.6/changesets", :method => :get },
40 { :controller => "changeset", :action => "query" }
43 { :path => "/user/name/history", :method => :get },
44 { :controller => "changeset", :action => "list", :display_name => "name" }
47 { :path => "/user/name/history/feed", :method => :get },
48 { :controller => "changeset", :action => "feed", :display_name => "name", :format => :atom }
51 { :path => "/history/friends", :method => :get },
52 { :controller => "changeset", :action => "list", :friends => true }
55 { :path => "/history/nearby", :method => :get },
56 { :controller => "changeset", :action => "list", :nearby => true }
59 { :path => "/history", :method => :get },
60 { :controller => "changeset", :action => "list" }
63 { :path => "/history/feed", :method => :get },
64 { :controller => "changeset", :action => "feed", :format => :atom }
68 # -----------------------
69 # Test simple changeset creation
70 # -----------------------
73 basic_authorization users(:normal_user).email, "test"
74 # Create the first user's changeset
75 content "<osm><changeset>" +
76 "<tag k='created_by' v='osm test suite checking changesets'/>" +
79 assert_require_public_data
82 basic_authorization users(:public_user).email, "test"
83 # Create the first user's changeset
84 content "<osm><changeset>" +
85 "<tag k='created_by' v='osm test suite checking changesets'/>" +
89 assert_response :success, "Creation of changeset did not return sucess status"
90 newid = @response.body.to_i
92 # check end time, should be an hour ahead of creation time
93 cs = Changeset.find(newid)
94 duration = cs.closed_at - cs.created_at
95 # the difference can either be a rational, or a floating point number
96 # of seconds, depending on the code path taken :-(
97 if duration.class == Rational
98 assert_equal Rational(1,24), duration , "initial idle timeout should be an hour (#{cs.created_at} -> #{cs.closed_at})"
100 # must be number of seconds...
101 assert_equal 3600, duration.round, "initial idle timeout should be an hour (#{cs.created_at} -> #{cs.closed_at})"
105 def test_create_invalid
106 basic_authorization users(:normal_user).email, "test"
107 content "<osm><changeset></osm>"
109 assert_require_public_data
111 ## Try the public user
112 basic_authorization users(:public_user).email, "test"
113 content "<osm><changeset></osm>"
115 assert_response :bad_request, "creating a invalid changeset should fail"
118 def test_create_invalid_no_content
119 ## First check with no auth
121 assert_response :unauthorized, "shouldn't be able to create a changeset with no auth"
123 ## Now try to with the non-public user
124 basic_authorization users(:normal_user).email, "test"
126 assert_require_public_data
128 ## Try the inactive user
129 basic_authorization users(:inactive_user).email, "test"
133 ## Now try to use the public user
134 basic_authorization users(:public_user).email, "test"
136 assert_response :bad_request, "creating a changeset with no content should fail"
139 def test_create_wrong_method
140 basic_authorization users(:public_user).email, "test"
142 assert_response :method_not_allowed
144 assert_response :method_not_allowed
148 # check that the changeset can be read and returns the correct
149 # document structure.
151 changeset_id = changesets(:normal_user_first_change).id
152 get :read, :id => changeset_id
153 assert_response :success, "cannot get first changeset"
155 assert_select "osm[version=#{API_VERSION}][generator=\"OpenStreetMap server\"]", 1
156 assert_select "osm>changeset[id=#{changeset_id}]", 1
160 # check that a changeset that doesn't exist returns an appropriate message
161 def test_read_not_found
162 [0, -32, 233455644, "afg", "213"].each do |id|
165 assert_response :not_found, "should get a not found"
166 rescue ActionController::UrlGenerationError => ex
167 assert_match /No route matches/, ex.to_s
173 # test that the user who opened a change can close it
175 ## Try without authentication
176 put :close, :id => changesets(:public_user_first_change).id
177 assert_response :unauthorized
180 ## Try using the non-public user
181 basic_authorization users(:normal_user).email, "test"
182 put :close, :id => changesets(:normal_user_first_change).id
183 assert_require_public_data
186 ## The try with the public user
187 basic_authorization users(:public_user).email, "test"
189 cs_id = changesets(:public_user_first_change).id
190 put :close, :id => cs_id
191 assert_response :success
193 # test that it really is closed now
194 cs = Changeset.find(cs_id)
196 "changeset should be closed now (#{cs.closed_at} > #{Time.now.getutc}.")
200 # test that a different user can't close another user's changeset
201 def test_close_invalid
202 basic_authorization users(:public_user).email, "test"
204 put :close, :id => changesets(:normal_user_first_change).id
205 assert_response :conflict
206 assert_equal "The user doesn't own that changeset", @response.body
210 # test that you can't close using another method
211 def test_close_method_invalid
212 basic_authorization users(:public_user).email, "test"
214 cs_id = changesets(:public_user_first_change).id
215 get :close, :id => cs_id
216 assert_response :method_not_allowed
218 post :close, :id => cs_id
219 assert_response :method_not_allowed
223 # check that you can't close a changeset that isn't found
224 def test_close_not_found
225 cs_ids = [0, -132, "123"]
227 # First try to do it with no auth
230 put :close, :id => id
231 assert_response :unauthorized, "Shouldn't be able close the non-existant changeset #{id}, when not authorized"
232 rescue ActionController::UrlGenerationError => ex
233 assert_match /No route matches/, ex.to_s
238 basic_authorization users(:public_user).email, "test"
241 put :close, :id => id
242 assert_response :not_found, "The changeset #{id} doesn't exist, so can't be closed"
243 rescue ActionController::UrlGenerationError => ex
244 assert_match /No route matches/, ex.to_s
250 # upload something simple, but valid and check that it can
252 # Also try without auth and another user.
253 def test_upload_simple_valid
255 changeset_id = changesets(:public_user_first_change).id
257 # simple diff to change a node, way and relation by removing
262 <node id='1' lon='0' lat='0' changeset='#{changeset_id}' version='1'/>
263 <way id='1' changeset='#{changeset_id}' version='1'>
268 <relation id='1' changeset='#{changeset_id}' version='1'>
269 <member type='way' role='some' ref='3'/>
270 <member type='node' role='some' ref='5'/>
271 <member type='relation' role='some' ref='3'/>
279 post :upload, :id => changeset_id
280 assert_response :unauthorized,
281 "shouldnn't be able to upload a simple valid diff to changeset: #{@response.body}"
285 ## Now try with a private user
286 basic_authorization users(:normal_user).email, "test"
287 changeset_id = changesets(:normal_user_first_change).id
289 # simple diff to change a node, way and relation by removing
294 <node id='1' lon='0' lat='0' changeset='#{changeset_id}' version='1'/>
295 <way id='1' changeset='#{changeset_id}' version='1'>
300 <relation id='1' changeset='#{changeset_id}' version='1'>
301 <member type='way' role='some' ref='3'/>
302 <member type='node' role='some' ref='5'/>
303 <member type='relation' role='some' ref='3'/>
311 post :upload, :id => changeset_id
312 assert_response :forbidden,
313 "can't upload a simple valid diff to changeset: #{@response.body}"
317 ## Now try with the public user
318 basic_authorization users(:public_user).email, "test"
319 changeset_id = changesets(:public_user_first_change).id
321 # simple diff to change a node, way and relation by removing
326 <node id='1' lon='0' lat='0' changeset='#{changeset_id}' version='1'/>
327 <way id='1' changeset='#{changeset_id}' version='1'>
332 <relation id='1' changeset='#{changeset_id}' version='1'>
333 <member type='way' role='some' ref='3'/>
334 <member type='node' role='some' ref='5'/>
335 <member type='relation' role='some' ref='3'/>
343 post :upload, :id => changeset_id
344 assert_response :success,
345 "can't upload a simple valid diff to changeset: #{@response.body}"
347 # check that the changes made it into the database
348 assert_equal 0, Node.find(1).tags.size, "node 1 should now have no tags"
349 assert_equal 0, Way.find(1).tags.size, "way 1 should now have no tags"
350 assert_equal 0, Relation.find(1).tags.size, "relation 1 should now have no tags"
354 # upload something which creates new objects using placeholders
355 def test_upload_create_valid
356 basic_authorization users(:public_user).email, "test"
357 cs_id = changesets(:public_user_first_change).id
359 # simple diff to create a node way and relation using placeholders
363 <node id='-1' lon='0' lat='0' changeset='#{cs_id}'>
364 <tag k='foo' v='bar'/>
365 <tag k='baz' v='bat'/>
367 <way id='-1' changeset='#{cs_id}'>
372 <relation id='-1' changeset='#{cs_id}'>
373 <member type='way' role='some' ref='3'/>
374 <member type='node' role='some' ref='5'/>
375 <member type='relation' role='some' ref='3'/>
383 post :upload, :id => cs_id
384 assert_response :success,
385 "can't upload a simple valid creation to changeset: #{@response.body}"
387 # check the returned payload
388 assert_select "diffResult[version=#{API_VERSION}][generator=\"OpenStreetMap server\"]", 1
389 assert_select "diffResult>node", 1
390 assert_select "diffresult>way", 1
391 assert_select "diffResult>relation", 1
393 # inspect the response to find out what the new element IDs are
394 doc = XML::Parser.string(@response.body).parse
395 new_node_id = doc.find("//diffResult/node").first["new_id"].to_i
396 new_way_id = doc.find("//diffResult/way").first["new_id"].to_i
397 new_rel_id = doc.find("//diffResult/relation").first["new_id"].to_i
399 # check the old IDs are all present and negative one
400 assert_equal -1, doc.find("//diffResult/node").first["old_id"].to_i
401 assert_equal -1, doc.find("//diffResult/way").first["old_id"].to_i
402 assert_equal -1, doc.find("//diffResult/relation").first["old_id"].to_i
404 # check the versions are present and equal one
405 assert_equal 1, doc.find("//diffResult/node").first["new_version"].to_i
406 assert_equal 1, doc.find("//diffResult/way").first["new_version"].to_i
407 assert_equal 1, doc.find("//diffResult/relation").first["new_version"].to_i
409 # check that the changes made it into the database
410 assert_equal 2, Node.find(new_node_id).tags.size, "new node should have two tags"
411 assert_equal 0, Way.find(new_way_id).tags.size, "new way should have no tags"
412 assert_equal 0, Relation.find(new_rel_id).tags.size, "new relation should have no tags"
416 # test a complex delete where we delete elements which rely on eachother
417 # in the same transaction.
418 def test_upload_delete
419 basic_authorization users(:public_user).display_name, "test"
421 diff = XML::Document.new
422 diff.root = XML::Node.new "osmChange"
423 delete = XML::Node.new "delete"
425 delete << current_relations(:visible_relation).to_xml_node
426 delete << current_relations(:used_relation).to_xml_node
427 delete << current_ways(:used_way).to_xml_node
428 delete << current_nodes(:node_used_by_relationship).to_xml_node
430 # update the changeset to one that this user owns
431 changeset_id = changesets(:public_user_first_change).id
432 ["node", "way", "relation"].each do |type|
433 delete.find("//osmChange/delete/#{type}").each do |n|
434 n['changeset'] = changeset_id.to_s
440 post :upload, :id => changeset_id
441 assert_response :success,
442 "can't upload a deletion diff to changeset: #{@response.body}"
444 # check the response is well-formed
445 assert_select "diffResult>node", 1
446 assert_select "diffResult>way", 1
447 assert_select "diffResult>relation", 2
449 # check that everything was deleted
450 assert_equal false, Node.find(current_nodes(:node_used_by_relationship).id).visible
451 assert_equal false, Way.find(current_ways(:used_way).id).visible
452 assert_equal false, Relation.find(current_relations(:visible_relation).id).visible
453 assert_equal false, Relation.find(current_relations(:used_relation).id).visible
457 # test uploading a delete with no lat/lon, as they are optional in
458 # the osmChange spec.
459 def test_upload_nolatlon_delete
460 basic_authorization users(:public_user).display_name, "test"
462 node = current_nodes(:public_visible_node)
463 cs = changesets(:public_user_first_change)
464 diff = "<osmChange><delete><node id='#{node.id}' version='#{node.version}' changeset='#{cs.id}'/></delete></osmChange>"
468 post :upload, :id => cs.id
469 assert_response :success,
470 "can't upload a deletion diff to changeset: #{@response.body}"
472 # check the response is well-formed
473 assert_select "diffResult>node", 1
475 # check that everything was deleted
476 assert_equal false, Node.find(node.id).visible
479 def test_repeated_changeset_create
481 basic_authorization users(:public_user).email, "test"
483 # create a temporary changeset
484 content "<osm><changeset>" +
485 "<tag k='created_by' v='osm test suite checking changesets'/>" +
487 assert_difference('Changeset.count', 1) do
490 assert_response :success
491 changeset_id = @response.body.to_i
495 def test_upload_large_changeset
496 basic_authorization users(:public_user).email, "test"
499 content "<osm><changeset/></osm>"
501 assert_response :success, "Should be able to create a changeset: #{@response.body}"
502 changeset_id = @response.body.to_i
504 # upload some widely-spaced nodes, spiralling positive and negative to cause
505 # largest bbox over-expansion possible.
509 <node id='-1' lon='-20' lat='-10' changeset='#{changeset_id}'/>
510 <node id='-10' lon='20' lat='10' changeset='#{changeset_id}'/>
511 <node id='-2' lon='-40' lat='-20' changeset='#{changeset_id}'/>
512 <node id='-11' lon='40' lat='20' changeset='#{changeset_id}'/>
513 <node id='-3' lon='-60' lat='-30' changeset='#{changeset_id}'/>
514 <node id='-12' lon='60' lat='30' changeset='#{changeset_id}'/>
515 <node id='-4' lon='-80' lat='-40' changeset='#{changeset_id}'/>
516 <node id='-13' lon='80' lat='40' changeset='#{changeset_id}'/>
517 <node id='-5' lon='-100' lat='-50' changeset='#{changeset_id}'/>
518 <node id='-14' lon='100' lat='50' changeset='#{changeset_id}'/>
519 <node id='-6' lon='-120' lat='-60' changeset='#{changeset_id}'/>
520 <node id='-15' lon='120' lat='60' changeset='#{changeset_id}'/>
521 <node id='-7' lon='-140' lat='-70' changeset='#{changeset_id}'/>
522 <node id='-16' lon='140' lat='70' changeset='#{changeset_id}'/>
523 <node id='-8' lon='-160' lat='-80' changeset='#{changeset_id}'/>
524 <node id='-17' lon='160' lat='80' changeset='#{changeset_id}'/>
525 <node id='-9' lon='-179.9' lat='-89.9' changeset='#{changeset_id}'/>
526 <node id='-18' lon='179.9' lat='89.9' changeset='#{changeset_id}'/>
531 # upload it, which used to cause an error like "PGError: ERROR:
532 # integer out of range" (bug #2152). but shouldn't any more.
534 post :upload, :id => changeset_id
535 assert_response :success,
536 "can't upload a spatially-large diff to changeset: #{@response.body}"
538 # check that the changeset bbox is within bounds
539 cs = Changeset.find(changeset_id)
540 assert cs.min_lon >= -180 * SCALE, "Minimum longitude (#{cs.min_lon / SCALE}) should be >= -180 to be valid."
541 assert cs.max_lon <= 180 * SCALE, "Maximum longitude (#{cs.max_lon / SCALE}) should be <= 180 to be valid."
542 assert cs.min_lat >= -90 * SCALE, "Minimum latitude (#{cs.min_lat / SCALE}) should be >= -90 to be valid."
543 assert cs.max_lat >= 90 * SCALE, "Maximum latitude (#{cs.max_lat / SCALE}) should be <= 90 to be valid."
547 # test that deleting stuff in a transaction doesn't bypass the checks
548 # to ensure that used elements are not deleted.
549 def test_upload_delete_invalid
550 basic_authorization users(:public_user).email, "test"
552 diff = XML::Document.new
553 diff.root = XML::Node.new "osmChange"
554 delete = XML::Node.new "delete"
556 delete << current_relations(:public_visible_relation).to_xml_node
557 delete << current_ways(:used_way).to_xml_node
558 delete << current_nodes(:node_used_by_relationship).to_xml_node
562 post :upload, :id => 2
563 assert_response :precondition_failed,
564 "shouldn't be able to upload a invalid deletion diff: #{@response.body}"
565 assert_equal "Precondition failed: Way 3 is still used by relations 1.", @response.body
567 # check that nothing was, in fact, deleted
568 assert_equal true, Node.find(current_nodes(:node_used_by_relationship).id).visible
569 assert_equal true, Way.find(current_ways(:used_way).id).visible
570 assert_equal true, Relation.find(current_relations(:visible_relation).id).visible
574 # test that a conditional delete of an in use object works.
575 def test_upload_delete_if_unused
576 basic_authorization users(:public_user).email, "test"
578 diff = XML::Document.new
579 diff.root = XML::Node.new "osmChange"
580 delete = XML::Node.new "delete"
582 delete["if-unused"] = ""
583 delete << current_relations(:public_used_relation).to_xml_node
584 delete << current_ways(:used_way).to_xml_node
585 delete << current_nodes(:node_used_by_relationship).to_xml_node
589 post :upload, :id => 2
590 assert_response :success,
591 "can't do a conditional delete of in use objects: #{@response.body}"
593 # check the returned payload
594 assert_select "diffResult[version=#{API_VERSION}][generator=\"OpenStreetMap server\"]", 1
595 assert_select "diffResult>node", 1
596 assert_select "diffresult>way", 1
597 assert_select "diffResult>relation", 1
600 doc = XML::Parser.string(@response.body).parse
602 # check the old IDs are all present and what we expect
603 assert_equal current_nodes(:node_used_by_relationship).id, doc.find("//diffResult/node").first["old_id"].to_i
604 assert_equal current_ways(:used_way).id, doc.find("//diffResult/way").first["old_id"].to_i
605 assert_equal current_relations(:public_used_relation).id, doc.find("//diffResult/relation").first["old_id"].to_i
607 # check the new IDs are all present and unchanged
608 assert_equal current_nodes(:node_used_by_relationship).id, doc.find("//diffResult/node").first["new_id"].to_i
609 assert_equal current_ways(:used_way).id, doc.find("//diffResult/way").first["new_id"].to_i
610 assert_equal current_relations(:public_used_relation).id, doc.find("//diffResult/relation").first["new_id"].to_i
612 # check the new versions are all present and unchanged
613 assert_equal current_nodes(:node_used_by_relationship).version, doc.find("//diffResult/node").first["new_version"].to_i
614 assert_equal current_ways(:used_way).version, doc.find("//diffResult/way").first["new_version"].to_i
615 assert_equal current_relations(:public_used_relation).version, doc.find("//diffResult/relation").first["new_version"].to_i
617 # check that nothing was, in fact, deleted
618 assert_equal true, Node.find(current_nodes(:node_used_by_relationship).id).visible
619 assert_equal true, Way.find(current_ways(:used_way).id).visible
620 assert_equal true, Relation.find(current_relations(:public_used_relation).id).visible
624 # upload an element with a really long tag value
625 def test_upload_invalid_too_long_tag
626 basic_authorization users(:public_user).email, "test"
627 cs_id = changesets(:public_user_first_change).id
629 # simple diff to create a node way and relation using placeholders
633 <node id='-1' lon='0' lat='0' changeset='#{cs_id}'>
634 <tag k='foo' v='#{"x"*256}'/>
642 post :upload, :id => cs_id
643 assert_response :bad_request,
644 "shoudln't be able to upload too long a tag to changeset: #{@response.body}"
649 # upload something which creates new objects and inserts them into
650 # existing containers using placeholders.
651 def test_upload_complex
652 basic_authorization users(:public_user).email, "test"
653 cs_id = changesets(:public_user_first_change).id
655 # simple diff to create a node way and relation using placeholders
659 <node id='-1' lon='0' lat='0' changeset='#{cs_id}'>
660 <tag k='foo' v='bar'/>
661 <tag k='baz' v='bat'/>
665 <way id='1' changeset='#{cs_id}' version='1'>
669 <relation id='1' changeset='#{cs_id}' version='1'>
670 <member type='way' role='some' ref='3'/>
671 <member type='node' role='some' ref='-1'/>
672 <member type='relation' role='some' ref='3'/>
680 post :upload, :id => cs_id
681 assert_response :success,
682 "can't upload a complex diff to changeset: #{@response.body}"
684 # check the returned payload
685 assert_select "diffResult[version=#{API_VERSION}][generator=\"#{GENERATOR}\"]", 1
686 assert_select "diffResult>node", 1
687 assert_select "diffResult>way", 1
688 assert_select "diffResult>relation", 1
690 # inspect the response to find out what the new element IDs are
691 doc = XML::Parser.string(@response.body).parse
692 new_node_id = doc.find("//diffResult/node").first["new_id"].to_i
694 # check that the changes made it into the database
695 assert_equal 2, Node.find(new_node_id).tags.size, "new node should have two tags"
696 assert_equal [new_node_id, 3], Way.find(1).nds, "way nodes should match"
697 Relation.find(1).members.each do |type,id,role|
699 assert_equal new_node_id, id, "relation should contain new node"
705 # create a diff which references several changesets, which should cause
706 # a rollback and none of the diff gets committed
707 def test_upload_invalid_changesets
708 basic_authorization users(:public_user).email, "test"
709 cs_id = changesets(:public_user_first_change).id
711 # simple diff to create a node way and relation using placeholders
715 <node id='1' lon='0' lat='0' changeset='#{cs_id}' version='1'/>
716 <way id='1' changeset='#{cs_id}' version='1'>
721 <relation id='1' changeset='#{cs_id}' version='1'>
722 <member type='way' role='some' ref='3'/>
723 <member type='node' role='some' ref='5'/>
724 <member type='relation' role='some' ref='3'/>
728 <node id='-1' lon='0' lat='0' changeset='4'>
729 <tag k='foo' v='bar'/>
730 <tag k='baz' v='bat'/>
735 # cache the objects before uploading them
736 node = current_nodes(:visible_node)
737 way = current_ways(:visible_way)
738 rel = current_relations(:visible_relation)
742 post :upload, :id => cs_id
743 assert_response :conflict,
744 "uploading a diff with multiple changsets should have failed"
746 # check that objects are unmodified
747 assert_nodes_are_equal(node, Node.find(1))
748 assert_ways_are_equal(way, Way.find(1))
752 # upload multiple versions of the same element in the same diff.
753 def test_upload_multiple_valid
754 basic_authorization users(:public_user).email, "test"
755 cs_id = changesets(:public_user_first_change).id
757 # change the location of a node multiple times, each time referencing
758 # the last version. doesn't this depend on version numbers being
763 <node id='1' lon='0' lat='0' changeset='#{cs_id}' version='1'/>
764 <node id='1' lon='1' lat='0' changeset='#{cs_id}' version='2'/>
765 <node id='1' lon='1' lat='1' changeset='#{cs_id}' version='3'/>
766 <node id='1' lon='1' lat='2' changeset='#{cs_id}' version='4'/>
767 <node id='1' lon='2' lat='2' changeset='#{cs_id}' version='5'/>
768 <node id='1' lon='3' lat='2' changeset='#{cs_id}' version='6'/>
769 <node id='1' lon='3' lat='3' changeset='#{cs_id}' version='7'/>
770 <node id='1' lon='9' lat='9' changeset='#{cs_id}' version='8'/>
777 post :upload, :id => cs_id
778 assert_response :success,
779 "can't upload multiple versions of an element in a diff: #{@response.body}"
781 # check the response is well-formed. its counter-intuitive, but the
782 # API will return multiple elements with the same ID and different
783 # version numbers for each change we made.
784 assert_select "diffResult>node", 8
788 # upload multiple versions of the same element in the same diff, but
789 # keep the version numbers the same.
790 def test_upload_multiple_duplicate
791 basic_authorization users(:public_user).email, "test"
792 cs_id = changesets(:public_user_first_change).id
797 <node id='1' lon='0' lat='0' changeset='#{cs_id}' version='1'/>
798 <node id='1' lon='1' lat='1' changeset='#{cs_id}' version='1'/>
805 post :upload, :id => cs_id
806 assert_response :conflict,
807 "shouldn't be able to upload the same element twice in a diff: #{@response.body}"
811 # try to upload some elements without specifying the version
812 def test_upload_missing_version
813 basic_authorization users(:public_user).email, "test"
814 cs_id = changesets(:public_user_first_change).id
819 <node id='1' lon='1' lat='1' changeset='cs_id'/>
826 post :upload, :id => cs_id
827 assert_response :bad_request,
828 "shouldn't be able to upload an element without version: #{@response.body}"
832 # try to upload with commands other than create, modify, or delete
833 def test_action_upload_invalid
834 basic_authorization users(:public_user).email, "test"
835 cs_id = changesets(:public_user_first_change).id
840 <node id='1' lon='1' lat='1' changeset='#{cs_id}' />
845 post :upload, :id => cs_id
846 assert_response :bad_request, "Shouldn't be able to upload a diff with the action ping"
847 assert_equal @response.body, "Unknown action ping, choices are create, modify, delete"
851 # upload a valid changeset which has a mixture of whitespace
852 # to check a bug reported by ivansanchez (#1565).
853 def test_upload_whitespace_valid
854 basic_authorization users(:public_user).email, "test"
855 changeset_id = changesets(:public_user_first_change).id
859 <modify><node id='1' lon='0' lat='0' changeset='#{changeset_id}'
861 <node id='1' lon='1' lat='1' changeset='#{changeset_id}' version='2'><tag k='k' v='v'/></node></modify>
863 <relation id='1' changeset='#{changeset_id}' version='1'><member
864 type='way' role='some' ref='3'/><member
865 type='node' role='some' ref='5'/>
866 <member type='relation' role='some' ref='3'/>
868 </modify></osmChange>
873 post :upload, :id => changeset_id
874 assert_response :success,
875 "can't upload a valid diff with whitespace variations to changeset: #{@response.body}"
877 # check the response is well-formed
878 assert_select "diffResult>node", 2
879 assert_select "diffResult>relation", 1
881 # check that the changes made it into the database
882 assert_equal 1, Node.find(1).tags.size, "node 1 should now have one tag"
883 assert_equal 0, Relation.find(1).tags.size, "relation 1 should now have no tags"
887 # upload a valid changeset which has a mixture of whitespace
888 # to check a bug reported by ivansanchez.
889 def test_upload_reuse_placeholder_valid
890 basic_authorization users(:public_user).email, "test"
891 changeset_id = changesets(:public_user_first_change).id
896 <node id='-1' lon='0' lat='0' changeset='#{changeset_id}'>
897 <tag k="foo" v="bar"/>
901 <node id='-1' lon='1' lat='1' changeset='#{changeset_id}' version='1'/>
904 <node id='-1' lon='2' lat='2' changeset='#{changeset_id}' version='2'/>
911 post :upload, :id => changeset_id
912 assert_response :success,
913 "can't upload a valid diff with re-used placeholders to changeset: #{@response.body}"
915 # check the response is well-formed
916 assert_select "diffResult>node", 3
917 assert_select "diffResult>node[old_id=-1]", 3
921 # test what happens if a diff upload re-uses placeholder IDs in an
923 def test_upload_placeholder_invalid
924 basic_authorization users(:public_user).email, "test"
925 changeset_id = changesets(:public_user_first_change).id
930 <node id='-1' lon='0' lat='0' changeset='#{changeset_id}' version='1'/>
931 <node id='-1' lon='1' lat='1' changeset='#{changeset_id}' version='1'/>
932 <node id='-1' lon='2' lat='2' changeset='#{changeset_id}' version='2'/>
939 post :upload, :id => changeset_id
940 assert_response :bad_request,
941 "shouldn't be able to re-use placeholder IDs"
945 # test that uploading a way referencing invalid placeholders gives a
946 # proper error, not a 500.
947 def test_upload_placeholder_invalid_way
948 basic_authorization users(:public_user).email, "test"
949 changeset_id = changesets(:public_user_first_change).id
954 <node id="-1" lon="0" lat="0" changeset="#{changeset_id}" version="1"/>
955 <node id="-2" lon="1" lat="1" changeset="#{changeset_id}" version="1"/>
956 <node id="-3" lon="2" lat="2" changeset="#{changeset_id}" version="1"/>
957 <way id="-1" changeset="#{changeset_id}" version="1">
969 post :upload, :id => changeset_id
970 assert_response :bad_request,
971 "shouldn't be able to use invalid placeholder IDs"
972 assert_equal "Placeholder node not found for reference -4 in way -1", @response.body
974 # the same again, but this time use an existing way
978 <node id="-1" lon="0" lat="0" changeset="#{changeset_id}" version="1"/>
979 <node id="-2" lon="1" lat="1" changeset="#{changeset_id}" version="1"/>
980 <node id="-3" lon="2" lat="2" changeset="#{changeset_id}" version="1"/>
981 <way id="1" changeset="#{changeset_id}" version="1">
993 post :upload, :id => changeset_id
994 assert_response :bad_request,
995 "shouldn't be able to use invalid placeholder IDs"
996 assert_equal "Placeholder node not found for reference -4 in way 1", @response.body
1000 # test that uploading a relation referencing invalid placeholders gives a
1001 # proper error, not a 500.
1002 def test_upload_placeholder_invalid_relation
1003 basic_authorization users(:public_user).email, "test"
1004 changeset_id = changesets(:public_user_first_change).id
1009 <node id="-1" lon="0" lat="0" changeset="#{changeset_id}" version="1"/>
1010 <node id="-2" lon="1" lat="1" changeset="#{changeset_id}" version="1"/>
1011 <node id="-3" lon="2" lat="2" changeset="#{changeset_id}" version="1"/>
1012 <relation id="-1" changeset="#{changeset_id}" version="1">
1013 <member type="node" role="foo" ref="-1"/>
1014 <member type="node" role="foo" ref="-2"/>
1015 <member type="node" role="foo" ref="-3"/>
1016 <member type="node" role="foo" ref="-4"/>
1024 post :upload, :id => changeset_id
1025 assert_response :bad_request,
1026 "shouldn't be able to use invalid placeholder IDs"
1027 assert_equal "Placeholder Node not found for reference -4 in relation -1.", @response.body
1029 # the same again, but this time use an existing way
1033 <node id="-1" lon="0" lat="0" changeset="#{changeset_id}" version="1"/>
1034 <node id="-2" lon="1" lat="1" changeset="#{changeset_id}" version="1"/>
1035 <node id="-3" lon="2" lat="2" changeset="#{changeset_id}" version="1"/>
1036 <relation id="1" changeset="#{changeset_id}" version="1">
1037 <member type="node" role="foo" ref="-1"/>
1038 <member type="node" role="foo" ref="-2"/>
1039 <member type="node" role="foo" ref="-3"/>
1040 <member type="way" role="bar" ref="-1"/>
1048 post :upload, :id => changeset_id
1049 assert_response :bad_request,
1050 "shouldn't be able to use invalid placeholder IDs"
1051 assert_equal "Placeholder Way not found for reference -1 in relation 1.", @response.body
1055 # test what happens if a diff is uploaded containing only a node
1057 def test_upload_node_move
1058 basic_authorization users(:public_user).email, "test"
1060 content "<osm><changeset>" +
1061 "<tag k='created_by' v='osm test suite checking changesets'/>" +
1062 "</changeset></osm>"
1064 assert_response :success
1065 changeset_id = @response.body.to_i
1067 old_node = current_nodes(:visible_node)
1069 diff = XML::Document.new
1070 diff.root = XML::Node.new "osmChange"
1071 modify = XML::Node.new "modify"
1072 xml_old_node = old_node.to_xml_node
1073 xml_old_node["lat"] = (2.0).to_s
1074 xml_old_node["lon"] = (2.0).to_s
1075 xml_old_node["changeset"] = changeset_id.to_s
1076 modify << xml_old_node
1081 post :upload, :id => changeset_id
1082 assert_response :success,
1083 "diff should have uploaded OK"
1086 changeset = Changeset.find(changeset_id)
1087 assert_equal 1*SCALE, changeset.min_lon, "min_lon should be 1 degree"
1088 assert_equal 2*SCALE, changeset.max_lon, "max_lon should be 2 degrees"
1089 assert_equal 1*SCALE, changeset.min_lat, "min_lat should be 1 degree"
1090 assert_equal 2*SCALE, changeset.max_lat, "max_lat should be 2 degrees"
1094 # test what happens if a diff is uploaded adding a node to a way.
1095 def test_upload_way_extend
1096 basic_authorization users(:public_user).email, "test"
1098 content "<osm><changeset>" +
1099 "<tag k='created_by' v='osm test suite checking changesets'/>" +
1100 "</changeset></osm>"
1102 assert_response :success
1103 changeset_id = @response.body.to_i
1105 old_way = current_ways(:visible_way)
1107 diff = XML::Document.new
1108 diff.root = XML::Node.new "osmChange"
1109 modify = XML::Node.new "modify"
1110 xml_old_way = old_way.to_xml_node
1111 nd_ref = XML::Node.new "nd"
1112 nd_ref["ref"] = current_nodes(:visible_node).id.to_s
1113 xml_old_way << nd_ref
1114 xml_old_way["changeset"] = changeset_id.to_s
1115 modify << xml_old_way
1120 post :upload, :id => changeset_id
1121 assert_response :success,
1122 "diff should have uploaded OK"
1125 changeset = Changeset.find(changeset_id)
1126 assert_equal 1*SCALE, changeset.min_lon, "min_lon should be 1 degree"
1127 assert_equal 3*SCALE, changeset.max_lon, "max_lon should be 3 degrees"
1128 assert_equal 1*SCALE, changeset.min_lat, "min_lat should be 1 degree"
1129 assert_equal 3*SCALE, changeset.max_lat, "max_lat should be 3 degrees"
1133 # test for more issues in #1568
1134 def test_upload_empty_invalid
1135 basic_authorization users(:public_user).email, "test"
1138 "<osmChange></osmChange>",
1139 "<osmChange><modify/></osmChange>",
1140 "<osmChange><modify></modify></osmChange>"
1144 post :upload, :id => changesets(:public_user_first_change).id
1145 assert_response(:success, "should be able to upload " +
1146 "empty changeset: " + diff)
1151 # test that the X-Error-Format header works to request XML errors
1152 def test_upload_xml_errors
1153 basic_authorization users(:public_user).email, "test"
1155 # try and delete a node that is in use
1156 diff = XML::Document.new
1157 diff.root = XML::Node.new "osmChange"
1158 delete = XML::Node.new "delete"
1160 delete << current_nodes(:node_used_by_relationship).to_xml_node
1165 post :upload, :id => 2
1166 assert_response :success,
1167 "failed to return error in XML format"
1169 # check the returned payload
1170 assert_select "osmError[version=#{API_VERSION}][generator=\"OpenStreetMap server\"]", 1
1171 assert_select "osmError>status", 1
1172 assert_select "osmError>message", 1
1177 # when we make some simple changes we get the same changes back from the
1179 def test_diff_download_simple
1180 ## First try with the normal user, which should get a forbidden
1181 basic_authorization(users(:normal_user).email, "test")
1183 # create a temporary changeset
1184 content "<osm><changeset>" +
1185 "<tag k='created_by' v='osm test suite checking changesets'/>" +
1186 "</changeset></osm>"
1188 assert_response :forbidden
1192 ## Now try with the public user
1193 basic_authorization(users(:public_user).email, "test")
1195 # create a temporary changeset
1196 content "<osm><changeset>" +
1197 "<tag k='created_by' v='osm test suite checking changesets'/>" +
1198 "</changeset></osm>"
1200 assert_response :success
1201 changeset_id = @response.body.to_i
1207 <node id='1' lon='0' lat='0' changeset='#{changeset_id}' version='1'/>
1208 <node id='1' lon='1' lat='0' changeset='#{changeset_id}' version='2'/>
1209 <node id='1' lon='1' lat='1' changeset='#{changeset_id}' version='3'/>
1210 <node id='1' lon='1' lat='2' changeset='#{changeset_id}' version='4'/>
1211 <node id='1' lon='2' lat='2' changeset='#{changeset_id}' version='5'/>
1212 <node id='1' lon='3' lat='2' changeset='#{changeset_id}' version='6'/>
1213 <node id='1' lon='3' lat='3' changeset='#{changeset_id}' version='7'/>
1214 <node id='1' lon='9' lat='9' changeset='#{changeset_id}' version='8'/>
1221 post :upload, :id => changeset_id
1222 assert_response :success,
1223 "can't upload multiple versions of an element in a diff: #{@response.body}"
1225 get :download, :id => changeset_id
1226 assert_response :success
1228 assert_select "osmChange", 1
1229 assert_select "osmChange>modify", 8
1230 assert_select "osmChange>modify>node", 8
1234 # culled this from josm to ensure that nothing in the way that josm
1235 # is formatting the request is causing it to fail.
1237 # NOTE: the error turned out to be something else completely!
1238 def test_josm_upload
1239 basic_authorization(users(:public_user).email, "test")
1241 # create a temporary changeset
1242 content "<osm><changeset>" +
1243 "<tag k='created_by' v='osm test suite checking changesets'/>" +
1244 "</changeset></osm>"
1246 assert_response :success
1247 changeset_id = @response.body.to_i
1250 <osmChange version="0.6" generator="JOSM">
1251 <create version="0.6" generator="JOSM">
1252 <node id='-1' visible='true' changeset='#{changeset_id}' lat='51.49619982187321' lon='-0.18722061869438314' />
1253 <node id='-2' visible='true' changeset='#{changeset_id}' lat='51.496359883909605' lon='-0.18653093576241928' />
1254 <node id='-3' visible='true' changeset='#{changeset_id}' lat='51.49598132358285' lon='-0.18719613290981638' />
1255 <node id='-4' visible='true' changeset='#{changeset_id}' lat='51.4961591711078' lon='-0.18629015888084607' />
1256 <node id='-5' visible='true' changeset='#{changeset_id}' lat='51.49582126021711' lon='-0.18708186591517145' />
1257 <node id='-6' visible='true' changeset='#{changeset_id}' lat='51.49591018437858' lon='-0.1861432441734455' />
1258 <node id='-7' visible='true' changeset='#{changeset_id}' lat='51.49560784152179' lon='-0.18694719410005425' />
1259 <node id='-8' visible='true' changeset='#{changeset_id}' lat='51.49567389979617' lon='-0.1860289771788006' />
1260 <node id='-9' visible='true' changeset='#{changeset_id}' lat='51.49543761398892' lon='-0.186820684213126' />
1261 <way id='-10' action='modiy' visible='true' changeset='#{changeset_id}'>
1271 <tag k='highway' v='residential' />
1272 <tag k='name' v='Foobar Street' />
1280 post :upload, :id => changeset_id
1281 assert_response :success,
1282 "can't upload a diff from JOSM: #{@response.body}"
1284 get :download, :id => changeset_id
1285 assert_response :success
1287 assert_select "osmChange", 1
1288 assert_select "osmChange>create>node", 9
1289 assert_select "osmChange>create>way", 1
1290 assert_select "osmChange>create>way>nd", 9
1291 assert_select "osmChange>create>way>tag", 2
1295 # when we make some complex changes we get the same changes back from the
1297 def test_diff_download_complex
1298 basic_authorization(users(:public_user).email, "test")
1300 # create a temporary changeset
1301 content "<osm><changeset>" +
1302 "<tag k='created_by' v='osm test suite checking changesets'/>" +
1303 "</changeset></osm>"
1305 assert_response :success
1306 changeset_id = @response.body.to_i
1312 <node id='1' lon='0' lat='0' changeset='#{changeset_id}' version='1'/>
1315 <node id='-1' lon='9' lat='9' changeset='#{changeset_id}' version='0'/>
1316 <node id='-2' lon='8' lat='9' changeset='#{changeset_id}' version='0'/>
1317 <node id='-3' lon='7' lat='9' changeset='#{changeset_id}' version='0'/>
1320 <node id='3' lon='20' lat='15' changeset='#{changeset_id}' version='1'/>
1321 <way id='1' changeset='#{changeset_id}' version='1'>
1333 post :upload, :id => changeset_id
1334 assert_response :success,
1335 "can't upload multiple versions of an element in a diff: #{@response.body}"
1337 get :download, :id => changeset_id
1338 assert_response :success
1340 assert_select "osmChange", 1
1341 assert_select "osmChange>create", 3
1342 assert_select "osmChange>delete", 1
1343 assert_select "osmChange>modify", 2
1344 assert_select "osmChange>create>node", 3
1345 assert_select "osmChange>delete>node", 1
1346 assert_select "osmChange>modify>node", 1
1347 assert_select "osmChange>modify>way", 1
1350 def test_changeset_download
1351 get :download, :id => changesets(:normal_user_first_change).id
1352 assert_response :success
1354 #print @response.body
1355 # FIXME needs more assert_select tests
1356 assert_select "osmChange[version='#{API_VERSION}'][generator='#{GENERATOR}']" do
1357 assert_select "create", :count => 5
1358 assert_select "create>node[id=#{nodes(:used_node_2).node_id}][visible=#{nodes(:used_node_2).visible?}][version=#{nodes(:used_node_2).version}]" do
1359 assert_select "tag[k=#{node_tags(:t3).k}][v=#{node_tags(:t3).v}]"
1361 assert_select "create>node[id=#{nodes(:visible_node).node_id}]"
1366 # check that the bounding box of a changeset gets updated correctly
1367 ## FIXME: This should really be moded to a integration test due to the with_controller
1368 def test_changeset_bbox
1369 basic_authorization users(:public_user).email, "test"
1371 # create a new changeset
1372 content "<osm><changeset/></osm>"
1374 assert_response :success, "Creating of changeset failed."
1375 changeset_id = @response.body.to_i
1377 # add a single node to it
1378 with_controller(NodeController.new) do
1379 content "<osm><node lon='1' lat='2' changeset='#{changeset_id}'/></osm>"
1381 assert_response :success, "Couldn't create node."
1384 # get the bounding box back from the changeset
1385 get :read, :id => changeset_id
1386 assert_response :success, "Couldn't read back changeset."
1387 assert_select "osm>changeset[min_lon=1.0]", 1
1388 assert_select "osm>changeset[max_lon=1.0]", 1
1389 assert_select "osm>changeset[min_lat=2.0]", 1
1390 assert_select "osm>changeset[max_lat=2.0]", 1
1392 # add another node to it
1393 with_controller(NodeController.new) do
1394 content "<osm><node lon='2' lat='1' changeset='#{changeset_id}'/></osm>"
1396 assert_response :success, "Couldn't create second node."
1399 # get the bounding box back from the changeset
1400 get :read, :id => changeset_id
1401 assert_response :success, "Couldn't read back changeset for the second time."
1402 assert_select "osm>changeset[min_lon=1.0]", 1
1403 assert_select "osm>changeset[max_lon=2.0]", 1
1404 assert_select "osm>changeset[min_lat=1.0]", 1
1405 assert_select "osm>changeset[max_lat=2.0]", 1
1407 # add (delete) a way to it, which contains a point at (3,3)
1408 with_controller(WayController.new) do
1409 content update_changeset(current_ways(:visible_way).to_xml,
1411 put :delete, :id => current_ways(:visible_way).id
1412 assert_response :success, "Couldn't delete a way."
1415 # get the bounding box back from the changeset
1416 get :read, :id => changeset_id
1417 assert_response :success, "Couldn't read back changeset for the third time."
1418 # note that the 3.1 here is because of the bbox overexpansion
1419 assert_select "osm>changeset[min_lon=1.0]", 1
1420 assert_select "osm>changeset[max_lon=3.1]", 1
1421 assert_select "osm>changeset[min_lat=1.0]", 1
1422 assert_select "osm>changeset[max_lat=3.1]", 1
1426 # test that the changeset :include method works as it should
1427 def test_changeset_include
1428 basic_authorization users(:public_user).display_name, "test"
1430 # create a new changeset
1431 content "<osm><changeset/></osm>"
1433 assert_response :success, "Creating of changeset failed."
1434 changeset_id = @response.body.to_i
1436 # NOTE: the include method doesn't over-expand, like inserting
1437 # a real method does. this is because we expect the client to
1438 # know what it is doing!
1439 check_after_include(changeset_id, 1, 1, [ 1, 1, 1, 1])
1440 check_after_include(changeset_id, 3, 3, [ 1, 1, 3, 3])
1441 check_after_include(changeset_id, 4, 2, [ 1, 1, 4, 3])
1442 check_after_include(changeset_id, 2, 2, [ 1, 1, 4, 3])
1443 check_after_include(changeset_id, -1, -1, [-1, -1, 4, 3])
1444 check_after_include(changeset_id, -2, 5, [-2, -1, 4, 5])
1448 # test that a not found, wrong method with the expand bbox works as expected
1449 def test_changeset_expand_bbox_error
1450 basic_authorization users(:public_user).display_name, "test"
1452 # create a new changeset
1453 content "<osm><changeset/></osm>"
1455 assert_response :success, "Creating of changeset failed."
1456 changeset_id = @response.body.to_i
1462 content "<osm><node lon='#{lon}' lat='#{lat}'/></osm>"
1463 put :expand_bbox, :id => changeset_id
1464 assert_response :method_not_allowed, "shouldn't be able to put a bbox expand"
1466 # Try to get the update
1467 content "<osm><node lon='#{lon}' lat='#{lat}'/></osm>"
1468 get :expand_bbox, :id => changeset_id
1469 assert_response :method_not_allowed, "shouldn't be able to get a bbox expand"
1471 # Try to use a hopefully missing changeset
1472 content "<osm><node lon='#{lon}' lat='#{lat}'/></osm>"
1473 post :expand_bbox, :id => changeset_id+13245
1474 assert_response :not_found, "shouldn't be able to do a bbox expand on a nonexistant changeset"
1479 # test the query functionality of changesets
1481 get :query, :bbox => "-10,-10, 10, 10"
1482 assert_response :success, "can't get changesets in bbox"
1483 assert_changesets [1,4,6]
1485 get :query, :bbox => "4.5,4.5,4.6,4.6"
1486 assert_response :success, "can't get changesets in bbox"
1487 assert_changesets [1]
1489 # not found when looking for changesets of non-existing users
1490 get :query, :user => User.maximum(:id) + 1
1491 assert_response :not_found
1492 get :query, :display_name => " "
1493 assert_response :not_found
1495 # can't get changesets of user 1 without authenticating
1496 get :query, :user => users(:normal_user).id
1497 assert_response :not_found, "shouldn't be able to get changesets by non-public user (ID)"
1498 get :query, :display_name => users(:normal_user).display_name
1499 assert_response :not_found, "shouldn't be able to get changesets by non-public user (name)"
1501 # but this should work
1502 basic_authorization "test@openstreetmap.org", "test"
1503 get :query, :user => users(:normal_user).id
1504 assert_response :success, "can't get changesets by user ID"
1505 assert_changesets [1,3,6]
1507 get :query, :display_name => users(:normal_user).display_name
1508 assert_response :success, "can't get changesets by user name"
1509 assert_changesets [1,3,6]
1511 # check that the correct error is given when we provide both UID and name
1512 get :query, :user => users(:normal_user).id, :display_name => users(:normal_user).display_name
1513 assert_response :bad_request, "should be a bad request to have both ID and name specified"
1515 get :query, :user => users(:normal_user).id, :open => true
1516 assert_response :success, "can't get changesets by user and open"
1517 assert_changesets [1]
1519 get :query, :time => '2007-12-31'
1520 assert_response :success, "can't get changesets by time-since"
1521 assert_changesets [1,2,4,5,6]
1523 get :query, :time => '2008-01-01T12:34Z'
1524 assert_response :success, "can't get changesets by time-since with hour"
1525 assert_changesets [1,2,4,5,6]
1527 get :query, :time => '2007-12-31T23:59Z,2008-01-01T00:01Z'
1528 assert_response :success, "can't get changesets by time-range"
1529 assert_changesets [1,5,6]
1531 get :query, :open => 'true'
1532 assert_response :success, "can't get changesets by open-ness"
1533 assert_changesets [1,2,4]
1535 get :query, :closed => 'true'
1536 assert_response :success, "can't get changesets by closed-ness"
1537 assert_changesets [3,5,6,7]
1539 get :query, :closed => 'true', :user => users(:normal_user).id
1540 assert_response :success, "can't get changesets by closed-ness and user"
1541 assert_changesets [3,6]
1543 get :query, :closed => 'true', :user => users(:public_user).id
1544 assert_response :success, "can't get changesets by closed-ness and user"
1545 assert_changesets [7]
1547 get :query, :changesets => '1,2,3'
1548 assert_response :success, "can't get changesets by id (as comma-separated string)"
1549 assert_changesets [1,2,3]
1551 get :query, :changesets => ''
1552 assert_response :bad_request, "should be a bad request since changesets is empty"
1556 # check that errors are returned if garbage is inserted
1557 # into query strings
1558 def test_query_invalid
1561 ";drop table users;"
1563 get :query, :bbox => bbox
1564 assert_response :bad_request, "'#{bbox}' isn't a bbox"
1569 ";drop table users;",
1573 get :query, :time => time
1574 assert_response :bad_request, "'#{time}' isn't a valid time range"
1582 get :query, :user => uid
1583 assert_response :bad_request, "'#{uid}' isn't a valid user ID"
1588 # check updating tags on a changeset
1589 def test_changeset_update
1590 ## First try with the non-public user
1591 changeset = changesets(:normal_user_first_change)
1592 new_changeset = changeset.to_xml
1593 new_tag = XML::Node.new "tag"
1594 new_tag['k'] = "tagtesting"
1595 new_tag['v'] = "valuetesting"
1596 new_changeset.find("//osm/changeset").first << new_tag
1597 content new_changeset
1599 # try without any authorization
1600 put :update, :id => changeset.id
1601 assert_response :unauthorized
1603 # try with the wrong authorization
1604 basic_authorization users(:public_user).email, "test"
1605 put :update, :id => changeset.id
1606 assert_response :conflict
1608 # now this should get an unauthorized
1609 basic_authorization users(:normal_user).email, "test"
1610 put :update, :id => changeset.id
1611 assert_require_public_data "user with their data non-public, shouldn't be able to edit their changeset"
1614 ## Now try with the public user
1615 changeset = changesets(:public_user_first_change)
1616 new_changeset = changeset.to_xml
1617 new_tag = XML::Node.new "tag"
1618 new_tag['k'] = "tagtesting"
1619 new_tag['v'] = "valuetesting"
1620 new_changeset.find("//osm/changeset").first << new_tag
1621 content new_changeset
1623 # try without any authorization
1624 @request.env["HTTP_AUTHORIZATION"] = nil
1625 put :update, :id => changeset.id
1626 assert_response :unauthorized
1628 # try with the wrong authorization
1629 basic_authorization users(:second_public_user).email, "test"
1630 put :update, :id => changeset.id
1631 assert_response :conflict
1633 # now this should work...
1634 basic_authorization users(:public_user).email, "test"
1635 put :update, :id => changeset.id
1636 assert_response :success
1638 assert_select "osm>changeset[id=#{changeset.id}]", 1
1639 assert_select "osm>changeset>tag", 2
1640 assert_select "osm>changeset>tag[k=tagtesting][v=valuetesting]", 1
1644 # check that a user different from the one who opened the changeset
1646 def test_changeset_update_invalid
1647 basic_authorization users(:public_user).email, "test"
1649 changeset = changesets(:normal_user_first_change)
1650 new_changeset = changeset.to_xml
1651 new_tag = XML::Node.new "tag"
1652 new_tag['k'] = "testing"
1653 new_tag['v'] = "testing"
1654 new_changeset.find("//osm/changeset").first << new_tag
1656 content new_changeset
1657 put :update, :id => changeset.id
1658 assert_response :conflict
1662 # check that a changeset can contain a certain max number of changes.
1663 ## FIXME should be changed to an integration test due to the with_controller
1664 def test_changeset_limits
1665 basic_authorization users(:public_user).email, "test"
1667 # open a new changeset
1668 content "<osm><changeset/></osm>"
1670 assert_response :success, "can't create a new changeset"
1671 cs_id = @response.body.to_i
1673 # start the counter just short of where the changeset should finish.
1675 # alter the database to set the counter on the changeset directly,
1676 # otherwise it takes about 6 minutes to fill all of them.
1677 changeset = Changeset.find(cs_id)
1678 changeset.num_changes = Changeset::MAX_ELEMENTS - offset
1681 with_controller(NodeController.new) do
1683 content "<osm><node changeset='#{cs_id}' lat='0.0' lon='0.0'/></osm>"
1685 assert_response :success, "can't create a new node"
1686 node_id = @response.body.to_i
1688 get :read, :id => node_id
1689 assert_response :success, "can't read back new node"
1690 node_doc = XML::Parser.string(@response.body).parse
1691 node_xml = node_doc.find("//osm/node").first
1693 # loop until we fill the changeset with nodes
1695 node_xml['lat'] = rand.to_s
1696 node_xml['lon'] = rand.to_s
1697 node_xml['version'] = (i+1).to_s
1700 put :update, :id => node_id
1701 assert_response :success, "attempt #{i} should have succeeded"
1704 # trying again should fail
1705 node_xml['lat'] = rand.to_s
1706 node_xml['lon'] = rand.to_s
1707 node_xml['version'] = offset.to_s
1710 put :update, :id => node_id
1711 assert_response :conflict, "final attempt should have failed"
1714 changeset = Changeset.find(cs_id)
1715 assert_equal Changeset::MAX_ELEMENTS + 1, changeset.num_changes
1717 # check that the changeset is now closed as well
1718 assert(!changeset.is_open?,
1719 "changeset should have been auto-closed by exceeding " +
1724 # This should display the last 20 changesets closed.
1726 get :list, {:format => "html"}
1727 assert_response :success
1728 assert_template "history"
1729 assert_template :layout => "map"
1730 assert_select "h2", :text => "Changesets", :count => 1
1732 get :list, {:format => "html", :list => '1', :bbox => '-180,-90,90,180'}
1733 assert_response :success
1734 assert_template "list"
1736 changesets = Changeset.
1737 where("num_changes > 0 and min_lon is not null").
1738 order(:created_at => :desc).
1740 assert changesets.size <= 20
1742 # Now check that all 20 (or however many were returned) changesets are in the html
1743 assert_select "li", :count => changesets.size
1744 changesets.each do |changeset|
1745 # FIXME this test needs rewriting - test for table contents
1750 # This should display the last 20 changesets closed.
1752 xhr :get, :list, {:format => "html"}
1753 assert_response :success
1754 assert_template "history"
1755 assert_template :layout => "xhr"
1756 assert_select "h2", :text => "Changesets", :count => 1
1758 get :list, {:format => "html", :list => '1', :bbox => '-180,-90,90,180'}
1759 assert_response :success
1760 assert_template "list"
1762 changesets = Changeset.
1763 where("num_changes > 0 and min_lon is not null").
1764 order(:created_at => :desc).
1766 assert changesets.size <= 20
1768 # Now check that all 20 (or however many were returned) changesets are in the html
1769 assert_select "li", :count => changesets.size
1770 changesets.each do |changeset|
1771 # FIXME this test needs rewriting - test for table contents
1776 # Checks the display of the user changesets listing
1778 user = users(:public_user)
1779 get :list, {:format => "html", :display_name => user.display_name}
1780 assert_response :success
1781 assert_template "history"
1782 ## FIXME need to add more checks to see which if edits are actually shown if your data is public
1786 # Check the not found of the list user changesets
1787 def test_list_user_not_found
1788 get :list, {:format => "html", :display_name => "Some random user"}
1789 assert_response :not_found
1790 assert_template 'user/no_such_user'
1794 # This should display the last 20 changesets closed.
1796 changesets = Changeset.where("num_changes > 0").order(:created_at => :desc).limit(20)
1797 assert changesets.size <= 20
1798 get :feed, {:format => "atom"}
1799 assert_response :success
1800 assert_template "list"
1801 # Now check that all 20 (or however many were returned) changesets are in the html
1802 assert_select "feed", :count => 1
1803 assert_select "entry", :count => changesets.size
1804 changesets.each do |changeset|
1805 # FIXME this test needs rewriting - test for feed contents
1810 # Checks the display of the user changesets feed
1812 user = users(:public_user)
1813 get :feed, {:format => "atom", :display_name => user.display_name}
1814 assert_response :success
1815 assert_template "list"
1816 assert_equal "application/atom+xml", response.content_type
1817 ## FIXME need to add more checks to see which if edits are actually shown if your data is public
1821 # Check the not found of the user changesets feed
1822 def test_feed_user_not_found
1823 get :feed, {:format => "atom", :display_name => "Some random user"}
1824 assert_response :not_found
1828 # check that the changeset download for a changeset with a redacted
1829 # element in it doesn't contain that element.
1830 def test_diff_download_redacted
1831 changeset_id = changesets(:public_user_first_change).id
1833 get :download, :id => changeset_id
1834 assert_response :success
1836 assert_select "osmChange", 1
1837 # this changeset contains node 17 in versions 1 & 2, but 1 should
1839 assert_select "osmChange node[id=17]", 1
1840 assert_select "osmChange node[id=17][version=1]", 0
1843 #------------------------------------------------------------
1845 #------------------------------------------------------------
1848 # boilerplate for checking that certain changesets exist in the
1850 def assert_changesets(ids)
1851 assert_select "osm>changeset", ids.size
1853 assert_select "osm>changeset[id=#{id}]", 1
1858 # call the include method and assert properties of the bbox
1859 def check_after_include(changeset_id, lon, lat, bbox)
1860 content "<osm><node lon='#{lon}' lat='#{lat}'/></osm>"
1861 post :expand_bbox, :id => changeset_id
1862 assert_response :success, "Setting include of changeset failed: #{@response.body}"
1864 # check exactly one changeset
1865 assert_select "osm>changeset", 1
1866 assert_select "osm>changeset[id=#{changeset_id}]", 1
1869 doc = XML::Parser.string(@response.body).parse
1870 changeset = doc.find("//osm/changeset").first
1871 assert_equal bbox[0], changeset['min_lon'].to_f, "min lon"
1872 assert_equal bbox[1], changeset['min_lat'].to_f, "min lat"
1873 assert_equal bbox[2], changeset['max_lon'].to_f, "max lon"
1874 assert_equal bbox[3], changeset['max_lat'].to_f, "max lat"
1878 # update the changeset_id of a way element
1879 def update_changeset(xml, changeset_id)
1880 xml_attr_rewrite(xml, 'changeset', changeset_id)
1884 # update an attribute in a way element
1885 def xml_attr_rewrite(xml, name, value)
1886 xml.find("//osm/way").first[name] = value.to_s