+
+ def test_changeset_download
+ get :download, :id => changesets(:normal_user_first_change).id
+ assert_response :success
+ assert_template nil
+ #print @response.body
+ # FIXME needs more assert_select tests
+ assert_select "osmChange[version='#{API_VERSION}'][generator='#{GENERATOR}']" do
+ assert_select "create", :count => 5
+ assert_select "create>node[id=#{nodes(:used_node_2).id}][visible=#{nodes(:used_node_2).visible?}][version=#{nodes(:used_node_2).version}]" do
+ assert_select "tag[k=#{node_tags(:t3).k}][v=#{node_tags(:t3).v}]"
+ end
+ assert_select "create>node[id=#{nodes(:visible_node).id}]"
+ end
+ 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
+ basic_authorization users(:public_user).email, "test"
+
+ # create a new changeset
+ content "<osm><changeset/></osm>"
+ put :create
+ assert_response :success, "Creating of changeset failed."
+ changeset_id = @response.body.to_i
+
+ # add a single node to it
+ with_controller(NodeController.new) do
+ content "<osm><node lon='1' lat='2' changeset='#{changeset_id}'/></osm>"
+ put :create
+ assert_response :success, "Couldn't create node."
+ end
+
+ # get the bounding box back from the changeset
+ get :read, :id => changeset_id
+ assert_response :success, "Couldn't read back changeset."
+ assert_select "osm>changeset[min_lon=1.0]", 1
+ assert_select "osm>changeset[max_lon=1.0]", 1
+ assert_select "osm>changeset[min_lat=2.0]", 1
+ assert_select "osm>changeset[max_lat=2.0]", 1
+
+ # add another node to it
+ with_controller(NodeController.new) do
+ content "<osm><node lon='2' lat='1' changeset='#{changeset_id}'/></osm>"
+ put :create
+ assert_response :success, "Couldn't create second node."
+ end
+
+ # get the bounding box back from the changeset
+ get :read, :id => changeset_id
+ assert_response :success, "Couldn't read back changeset for the second time."
+ assert_select "osm>changeset[min_lon=1.0]", 1
+ assert_select "osm>changeset[max_lon=2.0]", 1
+ assert_select "osm>changeset[min_lat=1.0]", 1
+ assert_select "osm>changeset[max_lat=2.0]", 1
+
+ # add (delete) a way to it, which contains a point at (3,3)
+ with_controller(WayController.new) do
+ content update_changeset(current_ways(:visible_way).to_xml,
+ changeset_id)
+ put :delete, :id => current_ways(:visible_way).id
+ assert_response :success, "Couldn't delete a way."
+ end
+
+ # get the bounding box back from the changeset
+ get :read, :id => changeset_id
+ assert_response :success, "Couldn't read back changeset for the third time."
+ # note that the 3.1 here is because of the bbox overexpansion
+ assert_select "osm>changeset[min_lon=1.0]", 1
+ assert_select "osm>changeset[max_lon=3.1]", 1
+ assert_select "osm>changeset[min_lat=1.0]", 1
+ assert_select "osm>changeset[max_lat=3.1]", 1
+ end
+
+ ##
+ # test that the changeset :include method works as it should
+ def test_changeset_include
+ basic_authorization users(:public_user).display_name, "test"
+
+ # create a new changeset
+ content "<osm><changeset/></osm>"
+ put :create
+ assert_response :success, "Creating of changeset failed."
+ changeset_id = @response.body.to_i
+
+ # NOTE: the include method doesn't over-expand, like inserting
+ # a real method does. this is because we expect the client to
+ # know what it is doing!
+ check_after_include(changeset_id, 1, 1, [ 1, 1, 1, 1])
+ check_after_include(changeset_id, 3, 3, [ 1, 1, 3, 3])
+ check_after_include(changeset_id, 4, 2, [ 1, 1, 4, 3])
+ check_after_include(changeset_id, 2, 2, [ 1, 1, 4, 3])
+ check_after_include(changeset_id, -1, -1, [-1, -1, 4, 3])
+ check_after_include(changeset_id, -2, 5, [-2, -1, 4, 5])
+ end
+
+ ##
+ # test that a not found, wrong method with the expand bbox works as expected
+ def test_changeset_expand_bbox_error
+ basic_authorization users(:public_user).display_name, "test"
+
+ # create a new changeset
+ content "<osm><changeset/></osm>"
+ put :create
+ assert_response :success, "Creating of changeset failed."
+ changeset_id = @response.body.to_i
+
+ lon=58.2
+ lat=-0.45
+
+ # Try and put
+ content "<osm><node lon='#{lon}' lat='#{lat}'/></osm>"
+ put :expand_bbox, :id => changeset_id
+ assert_response :method_not_allowed, "shouldn't be able to put a bbox expand"
+
+ # Try to get the update
+ content "<osm><node lon='#{lon}' lat='#{lat}'/></osm>"
+ get :expand_bbox, :id => changeset_id
+ assert_response :method_not_allowed, "shouldn't be able to get a bbox expand"
+
+ # Try to use a hopefully missing changeset
+ content "<osm><node lon='#{lon}' lat='#{lat}'/></osm>"
+ post :expand_bbox, :id => changeset_id+13245
+ assert_response :not_found, "shouldn't be able to do a bbox expand on a nonexistant changeset"
+
+ end
+
+ ##
+ # test the query functionality of changesets
+ def test_query
+ get :query, :bbox => "-10,-10, 10, 10"
+ assert_response :success, "can't get changesets in bbox"
+ 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"
+ assert_changesets [1]
+
+ # not found when looking for changesets of non-existing users
+ get :query, :user => User.maximum(:id) + 1
+ assert_response :not_found
+ get :query, :display_name => " "
+ assert_response :not_found
+
+ # can't get changesets of user 1 without authenticating
+ get :query, :user => users(:normal_user).id
+ assert_response :not_found, "shouldn't be able to get changesets by non-public user (ID)"
+ get :query, :display_name => users(:normal_user).display_name
+ assert_response :not_found, "shouldn't be able to get changesets by non-public user (name)"
+
+ # but this should work
+ basic_authorization "test@openstreetmap.org", "test"
+ get :query, :user => users(:normal_user).id
+ assert_response :success, "can't get changesets by user ID"
+ assert_changesets [1,3,6]
+
+ get :query, :display_name => users(:normal_user).display_name
+ assert_response :success, "can't get changesets by user name"
+ assert_changesets [1,3,6]
+
+ # check that the correct error is given when we provide both UID and name
+ get :query, :user => users(:normal_user).id, :display_name => users(:normal_user).display_name
+ assert_response :bad_request, "should be a bad request to have both ID and name specified"
+
+ get :query, :user => users(:normal_user).id, :open => true
+ assert_response :success, "can't get changesets by user and open"
+ assert_changesets [1]
+
+ get :query, :time => '2007-12-31'
+ assert_response :success, "can't get changesets by time-since"
+ 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 [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 [1,5,6]
+
+ get :query, :open => 'true'
+ assert_response :success, "can't get changesets by open-ness"
+ assert_changesets [1,2,4]
+
+ get :query, :closed => 'true'
+ assert_response :success, "can't get changesets by closed-ness"
+ assert_changesets [3,5,6,7]
+ end
+
+ ##
+ # check that errors are returned if garbage is inserted
+ # into query strings
+ def test_query_invalid
+ [ "abracadabra!",
+ "1,2,3,F",
+ ";drop table users;"
+ ].each do |bbox|
+ get :query, :bbox => bbox
+ assert_response :bad_request, "'#{bbox}' isn't a bbox"
+ end
+
+ [ "now()",
+ "00-00-00",
+ ";drop table users;",
+ ",",
+ "-,-"
+ ].each do |time|
+ get :query, :time => time
+ assert_response :bad_request, "'#{time}' isn't a valid time range"
+ end
+
+ [ "me",
+ "foobar",
+ "-1",
+ "0"
+ ].each do |uid|
+ get :query, :user => uid
+ assert_response :bad_request, "'#{uid}' isn't a valid user ID"
+ end
+ end
+
+ ##
+ # check updating tags on a changeset
+ def test_changeset_update
+ ## First try with the non-public user
+ 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 users(:public_user).email, "test"
+ put :update, :id => changeset.id
+ assert_response :conflict
+
+ # now this should get an unauthorized
+ basic_authorization users(:normal_user).email, "test"
+ put :update, :id => changeset.id
+ assert_require_public_data "user with their data non-public, shouldn't be able to edit their changeset"
+
+
+ ## Now try with the public user
+ changeset = changesets(:public_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
+ @request.env["HTTP_AUTHORIZATION"] = nil
+ put :update, :id => changeset.id
+ assert_response :unauthorized
+
+ # try with the wrong authorization
+ basic_authorization users(:second_public_user).email, "test"
+ put :update, :id => changeset.id
+ assert_response :conflict
+
+ # now this should work...
+ basic_authorization users(:public_user).email, "test"
+ put :update, :id => changeset.id
+ assert_response :success
+
+ assert_select "osm>changeset[id=#{changeset.id}]", 1
+ assert_select "osm>changeset>tag", 2
+ assert_select "osm>changeset>tag[k=tagtesting][v=valuetesting]", 1
+ end