X-Git-Url: https://git.openstreetmap.org./rails.git/blobdiff_plain/495bd7f1f077e5cae4428fab8a780f0f479893d0..d3c60874092c63b493818f227f31027327b595e3:/test/functional/changeset_controller_test.rb
diff --git a/test/functional/changeset_controller_test.rb b/test/functional/changeset_controller_test.rb
index 8ccdec889..edc2aee93 100644
--- a/test/functional/changeset_controller_test.rb
+++ b/test/functional/changeset_controller_test.rb
@@ -26,7 +26,19 @@ class ChangesetControllerTest < ActionController::TestCase
put :create
assert_response :success, "Creation of changeset did not return sucess status"
- newid = @response.body
+ newid = @response.body.to_i
+
+ # check end time, should be an hour ahead of creation time
+ cs = Changeset.find(newid)
+ duration = cs.closed_at - cs.created_at
+ # the difference can either be a rational, or a floating point number
+ # of seconds, depending on the code path taken :-(
+ if duration.class == Rational
+ assert_equal Rational(1,24), duration , "initial idle timeout should be an hour (#{cs.created_at} -> #{cs.closed_at})"
+ else
+ # must be number of seconds...
+ assert_equal 3600.0, duration , "initial idle timeout should be an hour (#{cs.created_at} -> #{cs.closed_at})"
+ end
end
def test_create_invalid
@@ -53,8 +65,14 @@ class ChangesetControllerTest < ActionController::TestCase
def test_close
basic_authorization "test@openstreetmap.org", "test"
- put :close, :id => changesets(:normal_user_first_change).id
+ cs_id = changesets(:normal_user_first_change).id
+ put :close, :id => cs_id
assert_response :success
+
+ # test that it really is closed now
+ cs = Changeset.find(cs_id)
+ assert(!cs.is_open?,
+ "changeset should be closed now (#{cs.closed_at} > #{Time.now}.")
end
##
@@ -187,6 +205,11 @@ EOF
assert_response :success,
"can't upload a deletion diff to changeset: #{@response.body}"
+ # check the response is well-formed
+ assert_select "diffResult>node", 1
+ assert_select "diffResult>way", 1
+ assert_select "diffResult>relation", 2
+
# check that everything was deleted
assert_equal false, Node.find(current_nodes(:node_used_by_relationship).id).visible
assert_equal false, Way.find(current_ways(:used_way).id).visible
@@ -194,6 +217,29 @@ EOF
assert_equal false, Relation.find(current_relations(:used_relation).id).visible
end
+ ##
+ # test uploading a delete with no lat/lon, as they are optional in
+ # the osmChange spec.
+ def test_upload_nolatlon_delete
+ basic_authorization "test@openstreetmap.org", "test"
+
+ node = current_nodes(:visible_node)
+ cs = changesets(:normal_user_first_change)
+ diff = ""
+
+ # upload it
+ content diff
+ post :upload, :id => cs.id
+ assert_response :success,
+ "can't upload a deletion diff to changeset: #{@response.body}"
+
+ # check the response is well-formed
+ assert_select "diffResult>node", 1
+
+ # check that everything was deleted
+ assert_equal false, Node.find(node.id).visible
+ end
+
##
# test that deleting stuff in a transaction doesn't bypass the checks
# to ensure that used elements are not deleted.
@@ -298,7 +344,7 @@ EOF
-
+
@@ -349,6 +395,11 @@ EOF
post :upload, :id => 1
assert_response :success,
"can't upload multiple versions of an element in a diff: #{@response.body}"
+
+ # check the response is well-formed. its counter-intuitive, but the
+ # API will return multiple elements with the same ID and different
+ # version numbers for each change we made.
+ assert_select "diffResult>node", 8
end
##
@@ -411,6 +462,115 @@ EOF
assert_equal @response.body, "Unknown action ping, choices are create, modify, delete."
end
+ ##
+ # upload a valid changeset which has a mixture of whitespace
+ # to check a bug reported by ivansanchez (#1565).
+ def test_upload_whitespace_valid
+ basic_authorization "test@openstreetmap.org", "test"
+
+ diff = <
+
+
+
+
+
+
+
+EOF
+
+ # upload it
+ content diff
+ post :upload, :id => 1
+ assert_response :success,
+ "can't upload a valid diff with whitespace variations to changeset: #{@response.body}"
+
+ # check the response is well-formed
+ assert_select "diffResult>node", 2
+ assert_select "diffResult>relation", 1
+
+ # check that the changes made it into the database
+ assert_equal 1, Node.find(1).tags.size, "node 1 should now have one tag"
+ assert_equal 0, Relation.find(1).tags.size, "relation 1 should now have no tags"
+ end
+
+ ##
+ # upload a valid changeset which has a mixture of whitespace
+ # to check a bug reported by ivansanchez.
+ def test_upload_reuse_placeholder_valid
+ basic_authorization "test@openstreetmap.org", "test"
+
+ diff = <
+
+
+
+
+
+
+
+
+
+
+
+
+EOF
+
+ # upload it
+ content diff
+ post :upload, :id => 1
+ assert_response :success,
+ "can't upload a valid diff with re-used placeholders to changeset: #{@response.body}"
+
+ # check the response is well-formed
+ assert_select "diffResult>node", 3
+ assert_select "diffResult>node[old_id=-1]", 3
+ end
+
+ ##
+ # test what happens if a diff upload re-uses placeholder IDs in an
+ # illegal way.
+ def test_upload_placeholder_invalid
+ basic_authorization "test@openstreetmap.org", "test"
+
+ diff = <
+
+
+
+
+
+
+EOF
+
+ # upload it
+ content diff
+ post :upload, :id => 1
+ assert_response :bad_request,
+ "shouldn't be able to re-use placeholder IDs"
+ end
+
+ ##
+ # test for more issues in #1568
+ def test_upload_empty_invalid
+ basic_authorization "test@openstreetmap.org", "test"
+
+ [ "",
+ "",
+ "",
+ ""
+ ].each do |diff|
+ # upload it
+ content diff
+ post :upload, :id => 1
+ assert_response(:success, "should be able to upload " +
+ "empty changeset: " + diff)
+ end
+ end
+
##
# when we make some simple changes we get the same changes back from the
# diff download.
@@ -455,6 +615,67 @@ EOF
assert_select "osmChange>modify>node", 8
end
+ ##
+ # culled this from josm to ensure that nothing in the way that josm
+ # is formatting the request is causing it to fail.
+ #
+ # NOTE: the error turned out to be something else completely!
+ def test_josm_upload
+ basic_authorization(users(:normal_user).email, "test")
+
+ # create a temporary changeset
+ content "" +
+ "" +
+ ""
+ put :create
+ assert_response :success
+ changeset_id = @response.body.to_i
+
+ diff = <
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+OSM
+
+ # upload it
+ content diff
+ post :upload, :id => changeset_id
+ assert_response :success,
+ "can't upload a diff from JOSM: #{@response.body}"
+
+ get :download, :id => changeset_id
+ assert_response :success
+
+ assert_select "osmChange", 1
+ assert_select "osmChange>create>node", 9
+ assert_select "osmChange>create>way", 1
+ assert_select "osmChange>create>way>nd", 9
+ assert_select "osmChange>create>way>tag", 2
+ end
+
##
# when we make some complex changes we get the same changes back from the
# diff download.
@@ -596,7 +817,7 @@ EOF
def test_query
get :query, :bbox => "-10,-10, 10, 10"
assert_response :success, "can't get changesets in bbox"
- assert_changesets [1,4]
+ assert_changesets [1,4,6]
get :query, :bbox => "4.5,4.5,4.6,4.6"
assert_response :success, "can't get changesets in bbox"
@@ -610,7 +831,7 @@ EOF
basic_authorization "test@openstreetmap.org", "test"
get :query, :user => users(:normal_user).id
assert_response :success, "can't get changesets by user"
- assert_changesets [1,3,4]
+ assert_changesets [1,3,4,6]
get :query, :user => users(:normal_user).id, :open => true
assert_response :success, "can't get changesets by user and open"
@@ -618,15 +839,19 @@ EOF
get :query, :time => '2007-12-31'
assert_response :success, "can't get changesets by time-since"
- assert_changesets [2,4,5]
+ assert_changesets [1,2,4,5,6]
get :query, :time => '2008-01-01T12:34Z'
assert_response :success, "can't get changesets by time-since with hour"
- assert_changesets [2]
+ assert_changesets [1,2,4,5,6]
get :query, :time => '2007-12-31T23:59Z,2008-01-01T00:01Z'
assert_response :success, "can't get changesets by time-range"
- assert_changesets [4,5]
+ assert_changesets [1,4,5,6]
+
+ get :query, :open => 'true'
+ assert_response :success, "can't get changesets by open-ness"
+ assert_changesets [1,2,4]
end
##
@@ -664,16 +889,25 @@ EOF
##
# check updating tags on a changeset
def test_changeset_update
- basic_authorization "test@openstreetmap.org", "test"
-
changeset = changesets(:normal_user_first_change)
new_changeset = changeset.to_xml
new_tag = XML::Node.new "tag"
new_tag['k'] = "tagtesting"
new_tag['v'] = "valuetesting"
new_changeset.find("//osm/changeset").first << new_tag
-
content new_changeset
+
+ # try without any authorization
+ put :update, :id => changeset.id
+ assert_response :unauthorized
+
+ # try with the wrong authorization
+ basic_authorization "test@example.com", "test"
+ put :update, :id => changeset.id
+ assert_response :conflict
+
+ # now this should work...
+ basic_authorization "test@openstreetmap.org", "test"
put :update, :id => changeset.id
assert_response :success
@@ -700,6 +934,67 @@ EOF
assert_response :conflict
end
+ ##
+ # check that a changeset can contain a certain max number of changes.
+ def test_changeset_limits
+ basic_authorization "test@openstreetmap.org", "test"
+
+ # open a new changeset
+ content ""
+ put :create
+ assert_response :success, "can't create a new changeset"
+ cs_id = @response.body.to_i
+
+ # start the counter just short of where the changeset should finish.
+ offset = 10
+ # alter the database to set the counter on the changeset directly,
+ # otherwise it takes about 6 minutes to fill all of them.
+ changeset = Changeset.find(cs_id)
+ changeset.num_changes = Changeset::MAX_ELEMENTS - offset
+ changeset.save!
+
+ with_controller(NodeController.new) do
+ # create a new node
+ content ""
+ put :create
+ assert_response :success, "can't create a new node"
+ node_id = @response.body.to_i
+
+ get :read, :id => node_id
+ assert_response :success, "can't read back new node"
+ node_doc = XML::Parser.string(@response.body).parse
+ node_xml = node_doc.find("//osm/node").first
+
+ # loop until we fill the changeset with nodes
+ offset.times do |i|
+ node_xml['lat'] = rand.to_s
+ node_xml['lon'] = rand.to_s
+ node_xml['version'] = (i+1).to_s
+
+ content node_doc
+ put :update, :id => node_id
+ assert_response :success, "attempt #{i} should have succeeded"
+ end
+
+ # trying again should fail
+ node_xml['lat'] = rand.to_s
+ node_xml['lon'] = rand.to_s
+ node_xml['version'] = offset.to_s
+
+ content node_doc
+ put :update, :id => node_id
+ assert_response :conflict, "final attempt should have failed"
+ end
+
+ changeset = Changeset.find(cs_id)
+ assert_equal Changeset::MAX_ELEMENTS + 1, changeset.num_changes
+
+ # check that the changeset is now closed as well
+ assert(!changeset.is_open?,
+ "changeset should have been auto-closed by exceeding " +
+ "element limit.")
+ end
+
#------------------------------------------------------------
# utility functions
#------------------------------------------------------------
@@ -718,7 +1013,7 @@ EOF
# call the include method and assert properties of the bbox
def check_after_include(changeset_id, lon, lat, bbox)
content ""
- post :include, :id => changeset_id
+ post :expand_bbox, :id => changeset_id
assert_response :success, "Setting include of changeset failed: #{@response.body}"
# check exactly one changeset