# -----------------------
def test_create
- auth_header = bearer_authorization_header create(:user, :data_public => false)
- # Create the first user's changeset
- xml = "<osm><changeset>" \
- "<tag k='created_by' v='osm test suite checking changesets'/>" \
- "</changeset></osm>"
- post api_changesets_path, :params => xml, :headers => auth_header
- assert_require_public_data
-
- auth_header = bearer_authorization_header
+ user = create(:user)
+ auth_header = bearer_authorization_header user
# Create the first user's changeset
xml = "<osm><changeset>" \
"<tag k='created_by' v='osm test suite checking changesets'/>" \
"</changeset></osm>"
- post api_changesets_path, :params => xml, :headers => auth_header
- assert_response :success, "Creation of changeset did not return success status"
+ assert_difference "Changeset.count", 1 do
+ post api_changesets_path, :params => xml, :headers => auth_header
+ assert_response :success, "Creation of changeset did not return success status"
+ end
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
+ changeset = Changeset.find(newid)
+ duration = changeset.closed_at - changeset.created_at
# the difference can either be a rational, or a floating point number
# of seconds, depending on the code path taken :-(
if duration.instance_of?(Rational)
- assert_equal Rational(1, 24), duration, "initial idle timeout should be an hour (#{cs.created_at} -> #{cs.closed_at})"
+ assert_equal Rational(1, 24), duration, "initial idle timeout should be an hour (#{changeset.created_at} -> #{changeset.closed_at})"
else
# must be number of seconds...
- assert_equal 3600, duration.round, "initial idle timeout should be an hour (#{cs.created_at} -> #{cs.closed_at})"
+ assert_equal 3600, duration.round, "initial idle timeout should be an hour (#{changeset.created_at} -> #{changeset.closed_at})"
end
- # checks if uploader was subscribed
- assert_equal 1, cs.subscribers.length
+ assert_equal [user], changeset.subscribers
end
def test_create_invalid
end
end
- def test_upload_large_changeset
- user = create(:user)
- auth_header = bearer_authorization_header user
-
- # create an old changeset to ensure we have the maximum rate limit
- create(:changeset, :user => user, :created_at => Time.now.utc - 28.days)
-
- # create a changeset
- post api_changesets_path, :params => "<osm><changeset/></osm>", :headers => auth_header
- assert_response :success, "Should be able to create a changeset: #{@response.body}"
- changeset_id = @response.body.to_i
-
- # upload some widely-spaced nodes, spiralling positive and negative
- diff = <<~CHANGESET
- <osmChange>
- <create>
- <node id='-1' lon='-20' lat='-10' changeset='#{changeset_id}'/>
- <node id='-10' lon='20' lat='10' changeset='#{changeset_id}'/>
- <node id='-2' lon='-40' lat='-20' changeset='#{changeset_id}'/>
- <node id='-11' lon='40' lat='20' changeset='#{changeset_id}'/>
- <node id='-3' lon='-60' lat='-30' changeset='#{changeset_id}'/>
- <node id='-12' lon='60' lat='30' changeset='#{changeset_id}'/>
- <node id='-4' lon='-80' lat='-40' changeset='#{changeset_id}'/>
- <node id='-13' lon='80' lat='40' changeset='#{changeset_id}'/>
- <node id='-5' lon='-100' lat='-50' changeset='#{changeset_id}'/>
- <node id='-14' lon='100' lat='50' changeset='#{changeset_id}'/>
- <node id='-6' lon='-120' lat='-60' changeset='#{changeset_id}'/>
- <node id='-15' lon='120' lat='60' changeset='#{changeset_id}'/>
- <node id='-7' lon='-140' lat='-70' changeset='#{changeset_id}'/>
- <node id='-16' lon='140' lat='70' changeset='#{changeset_id}'/>
- <node id='-8' lon='-160' lat='-80' changeset='#{changeset_id}'/>
- <node id='-17' lon='160' lat='80' changeset='#{changeset_id}'/>
- <node id='-9' lon='-179.9' lat='-89.9' changeset='#{changeset_id}'/>
- <node id='-18' lon='179.9' lat='89.9' changeset='#{changeset_id}'/>
- </create>
- </osmChange>
- CHANGESET
-
- # upload it, which used to cause an error like "PGError: ERROR:
- # integer out of range" (bug #2152). but shouldn't any more.
- post api_changeset_upload_path(changeset_id), :params => diff, :headers => auth_header
- assert_response :success,
- "can't upload a spatially-large diff to changeset: #{@response.body}"
-
- # check that the changeset bbox is within bounds
- cs = Changeset.find(changeset_id)
- assert_operator cs.min_lon, :>=, -180 * GeoRecord::SCALE, "Minimum longitude (#{cs.min_lon / GeoRecord::SCALE}) should be >= -180 to be valid."
- assert_operator cs.max_lon, :<=, 180 * GeoRecord::SCALE, "Maximum longitude (#{cs.max_lon / GeoRecord::SCALE}) should be <= 180 to be valid."
- assert_operator cs.min_lat, :>=, -90 * GeoRecord::SCALE, "Minimum latitude (#{cs.min_lat / GeoRecord::SCALE}) should be >= -90 to be valid."
- assert_operator cs.max_lat, :<=, 90 * GeoRecord::SCALE, "Maximum latitude (#{cs.max_lat / GeoRecord::SCALE}) should be <= 90 to be valid."
- end
-
- ##
- # test what happens if a diff is uploaded containing only a node
- # move.
- def test_upload_node_move
- auth_header = bearer_authorization_header
-
- xml = "<osm><changeset>" \
- "<tag k='created_by' v='osm test suite checking changesets'/>" \
- "</changeset></osm>"
- post api_changesets_path, :params => xml, :headers => auth_header
- assert_response :success
- changeset_id = @response.body.to_i
-
- old_node = create(:node, :lat => 1, :lon => 1)
-
- diff = XML::Document.new
- diff.root = XML::Node.new "osmChange"
- modify = XML::Node.new "modify"
- xml_old_node = xml_node_for_node(old_node)
- xml_old_node["lat"] = 2.0.to_s
- xml_old_node["lon"] = 2.0.to_s
- xml_old_node["changeset"] = changeset_id.to_s
- modify << xml_old_node
- diff.root << modify
-
- # upload it
- post api_changeset_upload_path(changeset_id), :params => diff.to_s, :headers => auth_header
- assert_response :success,
- "diff should have uploaded OK"
-
- # check the bbox
- changeset = Changeset.find(changeset_id)
- assert_equal 1 * GeoRecord::SCALE, changeset.min_lon, "min_lon should be 1 degree"
- assert_equal 2 * GeoRecord::SCALE, changeset.max_lon, "max_lon should be 2 degrees"
- assert_equal 1 * GeoRecord::SCALE, changeset.min_lat, "min_lat should be 1 degree"
- assert_equal 2 * GeoRecord::SCALE, changeset.max_lat, "max_lat should be 2 degrees"
- end
-
- ##
- # test what happens if a diff is uploaded adding a node to a way.
- def test_upload_way_extend
- auth_header = bearer_authorization_header
-
- xml = "<osm><changeset>" \
- "<tag k='created_by' v='osm test suite checking changesets'/>" \
- "</changeset></osm>"
- post api_changesets_path, :params => xml, :headers => auth_header
- assert_response :success
- changeset_id = @response.body.to_i
-
- old_way = create(:way)
- create(:way_node, :way => old_way, :node => create(:node, :lat => 0.1, :lon => 0.1))
-
- diff = XML::Document.new
- diff.root = XML::Node.new "osmChange"
- modify = XML::Node.new "modify"
- xml_old_way = xml_node_for_way(old_way)
- nd_ref = XML::Node.new "nd"
- nd_ref["ref"] = create(:node, :lat => 0.3, :lon => 0.3).id.to_s
- xml_old_way << nd_ref
- xml_old_way["changeset"] = changeset_id.to_s
- modify << xml_old_way
- diff.root << modify
-
- # upload it
- post api_changeset_upload_path(changeset_id), :params => diff.to_s, :headers => auth_header
- assert_response :success,
- "diff should have uploaded OK"
-
- # check the bbox
- changeset = Changeset.find(changeset_id)
- assert_equal 0.1 * GeoRecord::SCALE, changeset.min_lon, "min_lon should be 0.1 degree"
- assert_equal 0.3 * GeoRecord::SCALE, changeset.max_lon, "max_lon should be 0.3 degrees"
- assert_equal 0.1 * GeoRecord::SCALE, changeset.min_lat, "min_lat should be 0.1 degree"
- assert_equal 0.3 * GeoRecord::SCALE, changeset.max_lat, "max_lat should be 0.3 degrees"
- end
-
- ##
- # when we make some simple changes we get the same changes back from the
- # diff download.
- def test_diff_download_simple
- node = create(:node)
-
- ## First try with a non-public user, which should get a forbidden
- auth_header = bearer_authorization_header create(:user, :data_public => false)
-
- # create a temporary changeset
- xml = "<osm><changeset>" \
- "<tag k='created_by' v='osm test suite checking changesets'/>" \
- "</changeset></osm>"
- post api_changesets_path, :params => xml, :headers => auth_header
- assert_response :forbidden
-
- ## Now try with a normal user
- auth_header = bearer_authorization_header
-
- # create a temporary changeset
- xml = "<osm><changeset>" \
- "<tag k='created_by' v='osm test suite checking changesets'/>" \
- "</changeset></osm>"
- post api_changesets_path, :params => xml, :headers => auth_header
- assert_response :success
- changeset_id = @response.body.to_i
-
- # add a diff to it
- diff = <<~CHANGESET
- <osmChange>
- <modify>
- <node id='#{node.id}' lon='0.0' lat='0.0' changeset='#{changeset_id}' version='1'/>
- <node id='#{node.id}' lon='0.1' lat='0.0' changeset='#{changeset_id}' version='2'/>
- <node id='#{node.id}' lon='0.1' lat='0.1' changeset='#{changeset_id}' version='3'/>
- <node id='#{node.id}' lon='0.1' lat='0.2' changeset='#{changeset_id}' version='4'/>
- <node id='#{node.id}' lon='0.2' lat='0.2' changeset='#{changeset_id}' version='5'/>
- <node id='#{node.id}' lon='0.3' lat='0.2' changeset='#{changeset_id}' version='6'/>
- <node id='#{node.id}' lon='0.3' lat='0.3' changeset='#{changeset_id}' version='7'/>
- <node id='#{node.id}' lon='0.9' lat='0.9' changeset='#{changeset_id}' version='8'/>
- </modify>
- </osmChange>
- CHANGESET
-
- # upload it
- post api_changeset_upload_path(changeset_id), :params => diff, :headers => auth_header
- assert_response :success,
- "can't upload multiple versions of an element in a diff: #{@response.body}"
-
- get api_changeset_download_path(changeset_id)
- assert_response :success
-
- assert_select "osmChange", 1
- assert_select "osmChange>modify", 8
- 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
- auth_header = bearer_authorization_header
-
- # create a temporary changeset
- xml = "<osm><changeset>" \
- "<tag k='created_by' v='osm test suite checking changesets'/>" \
- "</changeset></osm>"
- post api_changesets_path, :params => xml, :headers => auth_header
- assert_response :success
- changeset_id = @response.body.to_i
-
- diff = <<~OSMFILE
- <osmChange version="0.6" generator="JOSM">
- <create version="0.6" generator="JOSM">
- <node id='-1' visible='true' changeset='#{changeset_id}' lat='51.49619982187321' lon='-0.18722061869438314' />
- <node id='-2' visible='true' changeset='#{changeset_id}' lat='51.496359883909605' lon='-0.18653093576241928' />
- <node id='-3' visible='true' changeset='#{changeset_id}' lat='51.49598132358285' lon='-0.18719613290981638' />
- <node id='-4' visible='true' changeset='#{changeset_id}' lat='51.4961591711078' lon='-0.18629015888084607' />
- <node id='-5' visible='true' changeset='#{changeset_id}' lat='51.49582126021711' lon='-0.18708186591517145' />
- <node id='-6' visible='true' changeset='#{changeset_id}' lat='51.49591018437858' lon='-0.1861432441734455' />
- <node id='-7' visible='true' changeset='#{changeset_id}' lat='51.49560784152179' lon='-0.18694719410005425' />
- <node id='-8' visible='true' changeset='#{changeset_id}' lat='51.49567389979617' lon='-0.1860289771788006' />
- <node id='-9' visible='true' changeset='#{changeset_id}' lat='51.49543761398892' lon='-0.186820684213126' />
- <way id='-10' action='modify' visible='true' changeset='#{changeset_id}'>
- <nd ref='-1' />
- <nd ref='-2' />
- <nd ref='-3' />
- <nd ref='-4' />
- <nd ref='-5' />
- <nd ref='-6' />
- <nd ref='-7' />
- <nd ref='-8' />
- <nd ref='-9' />
- <tag k='highway' v='residential' />
- <tag k='name' v='Foobar Street' />
- </way>
- </create>
- </osmChange>
- OSMFILE
-
- # upload it
- post api_changeset_upload_path(changeset_id), :params => diff, :headers => auth_header
- assert_response :success,
- "can't upload a diff from JOSM: #{@response.body}"
-
- get api_changeset_download_path(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.
- def test_diff_download_complex
- node = create(:node)
- node2 = create(:node)
- way = create(:way)
- auth_header = bearer_authorization_header
-
- # create a temporary changeset
- xml = "<osm><changeset>" \
- "<tag k='created_by' v='osm test suite checking changesets'/>" \
- "</changeset></osm>"
- post api_changesets_path, :params => xml, :headers => auth_header
- assert_response :success
- changeset_id = @response.body.to_i
-
- # add a diff to it
- diff = <<~CHANGESET
- <osmChange>
- <delete>
- <node id='#{node.id}' lon='0.0' lat='0.0' changeset='#{changeset_id}' version='1'/>
- </delete>
- <create>
- <node id='-1' lon='0.9' lat='0.9' changeset='#{changeset_id}' version='0'/>
- <node id='-2' lon='0.8' lat='0.9' changeset='#{changeset_id}' version='0'/>
- <node id='-3' lon='0.7' lat='0.9' changeset='#{changeset_id}' version='0'/>
- </create>
- <modify>
- <node id='#{node2.id}' lon='2.0' lat='1.5' changeset='#{changeset_id}' version='1'/>
- <way id='#{way.id}' changeset='#{changeset_id}' version='1'>
- <nd ref='#{node2.id}'/>
- <nd ref='-1'/>
- <nd ref='-2'/>
- <nd ref='-3'/>
- </way>
- </modify>
- </osmChange>
- CHANGESET
-
- # upload it
- post api_changeset_upload_path(changeset_id), :params => diff, :headers => auth_header
- assert_response :success,
- "can't upload multiple versions of an element in a diff: #{@response.body}"
-
- get api_changeset_download_path(changeset_id)
- assert_response :success
-
- assert_select "osmChange", 1
- assert_select "osmChange>create", 3
- assert_select "osmChange>delete", 1
- assert_select "osmChange>modify", 2
- assert_select "osmChange>create>node", 3
- assert_select "osmChange>delete>node", 1
- assert_select "osmChange>modify>node", 1
- assert_select "osmChange>modify>way", 1
- end
-
- ##
- # check that the bounding box of a changeset gets updated correctly
- # FIXME: This should really be moded to a integration test due to the with_controller
- def test_changeset_bbox
- way = create(:way)
- create(:way_node, :way => way, :node => create(:node, :lat => 0.3, :lon => 0.3))
-
- auth_header = bearer_authorization_header
-
- # create a new changeset
- xml = "<osm><changeset/></osm>"
- post api_changesets_path, :params => xml, :headers => auth_header
- assert_response :success, "Creating of changeset failed."
- changeset_id = @response.body.to_i
-
- # add a single node to it
- with_controller(NodesController.new) do
- xml = "<osm><node lon='0.1' lat='0.2' changeset='#{changeset_id}'/></osm>"
- post api_nodes_path, :params => xml, :headers => auth_header
- assert_response :success, "Couldn't create node."
- end
-
- # get the bounding box back from the changeset
- get api_changeset_path(changeset_id)
- assert_response :success, "Couldn't read back changeset."
- assert_select "osm>changeset[min_lon='0.1000000']", 1
- assert_select "osm>changeset[max_lon='0.1000000']", 1
- assert_select "osm>changeset[min_lat='0.2000000']", 1
- assert_select "osm>changeset[max_lat='0.2000000']", 1
-
- # add another node to it
- with_controller(NodesController.new) do
- xml = "<osm><node lon='0.2' lat='0.1' changeset='#{changeset_id}'/></osm>"
- post api_nodes_path, :params => xml, :headers => auth_header
- assert_response :success, "Couldn't create second node."
- end
-
- # get the bounding box back from the changeset
- get api_changeset_path(changeset_id)
- assert_response :success, "Couldn't read back changeset for the second time."
- assert_select "osm>changeset[min_lon='0.1000000']", 1
- assert_select "osm>changeset[max_lon='0.2000000']", 1
- assert_select "osm>changeset[min_lat='0.1000000']", 1
- assert_select "osm>changeset[max_lat='0.2000000']", 1
-
- # add (delete) a way to it, which contains a point at (3,3)
- with_controller(WaysController.new) do
- xml = update_changeset(xml_for_way(way), changeset_id)
- delete api_way_path(way), :params => xml.to_s, :headers => auth_header
- assert_response :success, "Couldn't delete a way."
- end
-
- # get the bounding box back from the changeset
- get api_changeset_path(changeset_id)
- assert_response :success, "Couldn't read back changeset for the third time."
- assert_select "osm>changeset[min_lon='0.1000000']", 1
- assert_select "osm>changeset[max_lon='0.3000000']", 1
- assert_select "osm>changeset[min_lat='0.1000000']", 1
- assert_select "osm>changeset[max_lat='0.3000000']", 1
- end
-
##
# check updating tags on a changeset
def test_changeset_update
xml = "<osm><changeset/></osm>"
post api_changesets_path, :params => xml, :headers => auth_header
assert_response :success, "can't create a new changeset"
- cs_id = @response.body.to_i
+ changeset_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 = Changeset.find(changeset_id)
changeset.num_changes = Changeset::MAX_ELEMENTS - offset
changeset.save!
with_controller(NodesController.new) do
# create a new node
- xml = "<osm><node changeset='#{cs_id}' lat='0.0' lon='0.0'/></osm>"
+ xml = "<osm><node changeset='#{changeset_id}' lat='0.0' lon='0.0'/></osm>"
post api_nodes_path, :params => xml, :headers => auth_header
assert_response :success, "can't create a new node"
node_id = @response.body.to_i
assert_response :conflict, "final attempt should have failed"
end
- changeset = Changeset.find(cs_id)
+ changeset = Changeset.find(changeset_id)
assert_equal Changeset::MAX_ELEMENTS + 1, changeset.num_changes
# check that the changeset is now closed as well
end
end
- ##
- # update the changeset_id of a way element
- def update_changeset(xml, changeset_id)
- xml_attr_rewrite(xml, "changeset", changeset_id)
- end
-
- ##
- # update an attribute in a way element
- def xml_attr_rewrite(xml, name, value)
- xml.find("//osm/way").first[name] = value.to_s
- xml
- end
-
##
# build XML for changesets
def create_changeset_xml(user: nil, id: nil)
root = XML::Document.new
root.root = XML::Node.new "osm"
- cs = XML::Node.new "changeset"
+ changeset = XML::Node.new "changeset"
if user
- cs["user"] = user.display_name
- cs["uid"] = user.id.to_s
+ changeset["user"] = user.display_name
+ changeset["uid"] = user.id.to_s
end
- cs["id"] = id.to_s if id
- root.root << cs
+ changeset["id"] = id.to_s if id
+ root.root << changeset
root
end
end