X-Git-Url: https://git.openstreetmap.org/rails.git/blobdiff_plain/721dd9c27d299455b9159457a095716f797389f1..0b76693672b8dd86bc8efd565491d8d2d0fcbb8a:/test/functional/relation_controller_test.rb diff --git a/test/functional/relation_controller_test.rb b/test/functional/relation_controller_test.rb index 4ace316a4..9ecac826c 100644 --- a/test/functional/relation_controller_test.rb +++ b/test/functional/relation_controller_test.rb @@ -4,14 +4,6 @@ require 'relation_controller' class RelationControllerTest < ActionController::TestCase api_fixtures - def basic_authorization(user, pass) - @request.env["HTTP_AUTHORIZATION"] = "Basic %s" % Base64.encode64("#{user}:#{pass}") - end - - def content(c) - @request.env["RAW_POST_DATA"] = c.to_s - end - # ------------------------------------- # Test reading relations. # ------------------------------------- @@ -216,6 +208,68 @@ class RelationControllerTest < ActionController::TestCase end + # ------------------------------------ + # Test updating relations + # ------------------------------------ + + ## + # test that, when tags are updated on a relation, the correct things + # happen to the correct tables and the API gives sensible results. + # this is to test a case that gregory marler noticed and posted to + # josm-dev. + def test_update_relation_tags + basic_authorization "test@example.com", "test" + rel_id = current_relations(:multi_tag_relation).id + cs_id = changesets(:public_user_first_change).id + + with_relation(rel_id) do |rel| + # alter one of the tags + tag = rel.find("//osm/relation/tag").first + tag['v'] = 'some changed value' + update_changeset(rel, cs_id) + + # check that the downloaded tags are the same as the uploaded tags... + new_version = with_update(rel) do |new_rel| + assert_tags_equal rel, new_rel + end + + # check the original one in the current_* table again + with_relation(rel_id) { |r| assert_tags_equal rel, r } + + # now check the version in the history + with_relation(rel_id, new_version) { |r| assert_tags_equal rel, r } + end + end + + ## + # test that, when tags are updated on a relation when using the diff + # upload function, the correct things happen to the correct tables + # and the API gives sensible results. this is to test a case that + # gregory marler noticed and posted to josm-dev. + def test_update_relation_tags_via_upload + basic_authorization "test@example.com", "test" + rel_id = current_relations(:multi_tag_relation).id + cs_id = changesets(:public_user_first_change).id + + with_relation(rel_id) do |rel| + # alter one of the tags + tag = rel.find("//osm/relation/tag").first + tag['v'] = 'some changed value' + update_changeset(rel, cs_id) + + # check that the downloaded tags are the same as the uploaded tags... + new_version = with_update_diff(rel) do |new_rel| + assert_tags_equal rel, new_rel + end + + # check the original one in the current_* table again + with_relation(rel_id) { |r| assert_tags_equal rel, r } + + # now check the version in the history + with_relation(rel_id, new_version) { |r| assert_tags_equal rel, r } + end + end + # ------------------------------------- # Test creating some invalid relations. # ------------------------------------- @@ -524,6 +578,101 @@ OSM end end + ## + # yields the relation with the given +id+ (and optional +version+ + # to read from the history tables) into the block. the parsed XML + # doc is returned. + def with_relation(id, ver = nil) + if ver.nil? + get :read, :id => id + else + with_controller(OldRelationController.new) do + get :version, :id => id, :version => ver + end + end + assert_response :success + yield xml_parse(@response.body) + end + + ## + # updates the relation (XML) +rel+ and + # yields the new version of that relation into the block. + # the parsed XML doc is retured. + def with_update(rel) + rel_id = rel.find("//osm/relation").first["id"].to_i + content rel + put :update, :id => rel_id + assert_response :success, "can't update relation: #{@response.body}" + version = @response.body.to_i + + # now get the new version + get :read, :id => rel_id + assert_response :success + new_rel = xml_parse(@response.body) + + yield new_rel + + return version + end + + ## + # updates the relation (XML) +rel+ via the diff-upload API and + # yields the new version of that relation into the block. + # the parsed XML doc is retured. + def with_update_diff(rel) + rel_id = rel.find("//osm/relation").first["id"].to_i + cs_id = rel.find("//osm/relation").first['changeset'].to_i + version = nil + + with_controller(ChangesetController.new) do + doc = OSM::API.new.get_xml_doc + change = XML::Node.new 'osmChange' + doc.root = change + modify = XML::Node.new 'modify' + change << modify + modify << doc.import(rel.find("//osm/relation").first) + + content doc.to_s + post :upload, :id => cs_id + assert_response :success, "can't upload diff relation: #{@response.body}" + version = xml_parse(@response.body).find("//diffResult/relation").first["new_version"].to_i + end + + # now get the new version + get :read, :id => rel_id + assert_response :success + new_rel = xml_parse(@response.body) + + yield new_rel + + return version + end + + ## + # returns a k->v hash of tags from an xml doc + def get_tags_as_hash(a) + a.find("//osm/relation/tag").inject({}) do |h,v| + h[v['k']] = v['v'] + h + end + end + + ## + # assert that all tags on relation documents +a+ and +b+ + # are equal + def assert_tags_equal(a, b) + # turn the XML doc into tags hashes + a_tags = get_tags_as_hash(a) + b_tags = get_tags_as_hash(b) + + assert_equal a_tags.keys, b_tags.keys, "Tag keys should be identical." + a_tags.each do |k, v| + assert_equal v, b_tags[k], + "Tags which were not altered should be the same. " + + "#{a_tags.inspect} != #{b_tags.inspect}" + end + end + ## # update the changeset_id of a node element def update_changeset(xml, changeset_id) @@ -540,8 +689,7 @@ OSM ## # parse some xml def xml_parse(xml) - parser = XML::Parser.new - parser.string = xml + parser = XML::Parser.string(xml) parser.parse end end