3 class NodeVersionsTest < ActionDispatch::IntegrationTest
 
   5   # test the version call by submitting several revisions of a new node
 
   6   # to the API and ensuring that later calls to version return the
 
   7   # matching versions of the object.
 
   9     private_user = create(:user, :data_public => false)
 
  10     private_node = create(:node, :with_history, :version => 4, :lat => 0, :lon => 0, :changeset => create(:changeset, :user => private_user))
 
  12     node = create(:node, :with_history, :version => 4, :lat => 0, :lon => 0, :changeset => create(:changeset, :user => user))
 
  13     create_list(:node_tag, 2, :node => node)
 
  14     # Ensure that the current tags are propagated to the history too
 
  15     propagate_tags(node, node.old_nodes.last)
 
  17     ## First try this with a non-public user
 
  18     auth_header = request_headers private_user
 
  20     # setup a simple XML node
 
  21     xml_doc = xml_for_node(private_node)
 
  22     xml_node = xml_doc.find("//osm/node").first
 
  23     node_id = private_node.id
 
  25     # keep a hash of the versions => string, as we'll need something
 
  26     # to test against later
 
  29     # save a version for later checking
 
  30     versions[xml_node["version"]] = xml_doc.to_s
 
  32     # randomly move the node about
 
  34       # move the node somewhere else
 
  35       xml_node["lat"] = precision(rand - 0.5).to_s
 
  36       xml_node["lon"] = precision(rand - 0.5).to_s
 
  37       with_controller(NodesController.new) do
 
  38         put api_node_path(node_id), :params => xml_doc.to_s, :headers => auth_header
 
  39         assert_response :forbidden, "Should have rejected node update"
 
  40         xml_node["version"] = @response.body.to_s
 
  42       # save a version for later checking
 
  43       versions[xml_node["version"]] = xml_doc.to_s
 
  46     # add a bunch of random tags
 
  48       xml_tag = XML::Node.new("tag")
 
  49       xml_tag["k"] = random_string
 
  50       xml_tag["v"] = random_string
 
  52       with_controller(NodesController.new) do
 
  53         put api_node_path(node_id), :params => xml_doc.to_s, :headers => auth_header
 
  54         assert_response :forbidden,
 
  55                         "should have rejected node #{node_id} (#{@response.body}) with forbidden"
 
  56         xml_node["version"] = @response.body.to_s
 
  58       # save a version for later checking
 
  59       versions[xml_node["version"]] = xml_doc.to_s
 
  62     # probably should check that they didn't get written to the database
 
  64     ## Now do it with the public user
 
  65     auth_header = request_headers user
 
  67     # setup a simple XML node
 
  69     xml_doc = xml_for_node(node)
 
  70     xml_node = xml_doc.find("//osm/node").first
 
  73     # keep a hash of the versions => string, as we'll need something
 
  74     # to test against later
 
  77     # save a version for later checking
 
  78     versions[xml_node["version"]] = xml_doc.to_s
 
  80     # randomly move the node about
 
  82       # move the node somewhere else
 
  83       xml_node["lat"] = precision(rand - 0.5).to_s
 
  84       xml_node["lon"] = precision(rand - 0.5).to_s
 
  85       with_controller(NodesController.new) do
 
  86         put api_node_path(node_id), :params => xml_doc.to_s, :headers => auth_header
 
  87         assert_response :success
 
  88         xml_node["version"] = @response.body.to_s
 
  90       # save a version for later checking
 
  91       versions[xml_node["version"]] = xml_doc.to_s
 
  94     # add a bunch of random tags
 
  96       xml_tag = XML::Node.new("tag")
 
  97       xml_tag["k"] = random_string
 
  98       xml_tag["v"] = random_string
 
 100       with_controller(NodesController.new) do
 
 101         put api_node_path(node_id), :params => xml_doc.to_s, :headers => auth_header
 
 102         assert_response :success,
 
 103                         "couldn't update node #{node_id} (#{@response.body})"
 
 104         xml_node["version"] = @response.body.to_s
 
 106       # save a version for later checking
 
 107       versions[xml_node["version"]] = xml_doc.to_s
 
 110     # check all the versions
 
 111     versions.each_key do |key|
 
 112       get api_node_version_path(node_id, key.to_i)
 
 114       assert_response :success,
 
 115                       "couldn't get version #{key.to_i} of node #{node_id}"
 
 117       check_node = Node.from_xml(versions[key])
 
 118       api_node = Node.from_xml(@response.body.to_s)
 
 120       assert_nodes_are_equal check_node, api_node
 
 125   # Test that getting the current version is identical to picking
 
 126   # that version with the version URI call.
 
 127   def test_current_version
 
 128     node = create(:node, :with_history)
 
 129     used_node = create(:node, :with_history)
 
 130     create(:way_node, :node => used_node)
 
 131     node_used_by_relationship = create(:node, :with_history)
 
 132     create(:relation_member, :member => node_used_by_relationship)
 
 133     node_with_versions = create(:node, :with_history, :version => 4)
 
 135     create(:node_tag, :node => node)
 
 136     create(:node_tag, :node => used_node)
 
 137     create(:node_tag, :node => node_used_by_relationship)
 
 138     create(:node_tag, :node => node_with_versions)
 
 139     propagate_tags(node, node.old_nodes.last)
 
 140     propagate_tags(used_node, used_node.old_nodes.last)
 
 141     propagate_tags(node_used_by_relationship, node_used_by_relationship.old_nodes.last)
 
 142     propagate_tags(node_with_versions, node_with_versions.old_nodes.last)
 
 144     check_current_version(node)
 
 145     check_current_version(used_node)
 
 146     check_current_version(node_used_by_relationship)
 
 147     check_current_version(node_with_versions)
 
 152   def check_current_version(node_id)
 
 153     # get the current version of the node
 
 154     current_node = with_controller(NodesController.new) do
 
 155       get api_node_path(node_id)
 
 156       assert_response :success, "cant get current node #{node_id}"
 
 157       Node.from_xml(@response.body)
 
 159     assert_not_nil current_node, "getting node #{node_id} returned nil"
 
 161     # get the "old" version of the node from the old_node interface
 
 162     get api_node_version_path(node_id, current_node.version)
 
 163     assert_response :success, "cant get old node #{node_id}, v#{current_node.version}"
 
 164     old_node = Node.from_xml(@response.body)
 
 166     # check the nodes are the same
 
 167     assert_nodes_are_equal current_node, old_node
 
 171   # returns a 16 character long string with some nasty characters in it.
 
 172   # this ought to stress-test the tag handling as well as the versioning.
 
 174     letters = [["!", '"', "$", "&", ";", "@"],
 
 177                ("0".."9").to_a].flatten
 
 178     (1..16).map { letters[rand(letters.length)] }.join
 
 182   # truncate a floating point number to the scale that it is stored in
 
 183   # the database. otherwise rounding errors can produce failing unit
 
 184   # tests when they shouldn't.
 
 186     (f * GeoRecord::SCALE).round.to_f / GeoRecord::SCALE
 
 189   def propagate_tags(node, old_node)
 
 190     node.tags.each do |k, v|
 
 191       create(:old_node_tag, :old_node => old_node, :k => k, :v => v)
 
 195   def request_headers(user)
 
 196     bearer_authorization_header(user).merge("Content-Type" => "application/xml")