1 # frozen_string_literal: true
 
   5 class RelationTest < ActiveSupport::TestCase
 
   6   def test_from_xml_no_id
 
   7     noid = "<osm><relation version='12' changeset='23' /></osm>"
 
   8     assert_nothing_raised do
 
   9       Relation.from_xml(noid, :create => true)
 
  11     message = assert_raise(OSM::APIBadXMLError) do
 
  12       Relation.from_xml(noid, :create => false)
 
  14     assert_match(/ID is required when updating/, message.message)
 
  17   def test_from_xml_no_changeset_id
 
  18     nocs = "<osm><relation id='123' version='12' /></osm>"
 
  19     message_create = assert_raise(OSM::APIBadXMLError) do
 
  20       Relation.from_xml(nocs, :create => true)
 
  22     assert_match(/Changeset id is missing/, message_create.message)
 
  23     message_update = assert_raise(OSM::APIBadXMLError) do
 
  24       Relation.from_xml(nocs, :create => false)
 
  26     assert_match(/Changeset id is missing/, message_update.message)
 
  29   def test_from_xml_no_version
 
  30     no_version = "<osm><relation id='123' changeset='23' /></osm>"
 
  31     assert_nothing_raised do
 
  32       Relation.from_xml(no_version, :create => true)
 
  34     message_update = assert_raise(OSM::APIBadXMLError) do
 
  35       Relation.from_xml(no_version, :create => false)
 
  37     assert_match(/Version is required when updating/, message_update.message)
 
  40   def test_from_xml_id_zero
 
  41     id_list = ["", "0", "00", "0.0", "a"]
 
  43       zero_id = "<osm><relation id='#{id}' changeset='332' version='23' /></osm>"
 
  44       assert_nothing_raised do
 
  45         Relation.from_xml(zero_id, :create => true)
 
  47       message_update = assert_raise(OSM::APIBadUserInput) do
 
  48         Relation.from_xml(zero_id, :create => false)
 
  50       assert_match(/ID of relation cannot be zero when updating/, message_update.message)
 
  54   def test_from_xml_no_text
 
  56     message_create = assert_raise(OSM::APIBadXMLError) do
 
  57       Relation.from_xml(no_text, :create => true)
 
  59     assert_match(/Must specify a string with one or more characters/, message_create.message)
 
  60     message_update = assert_raise(OSM::APIBadXMLError) do
 
  61       Relation.from_xml(no_text, :create => false)
 
  63     assert_match(/Must specify a string with one or more characters/, message_update.message)
 
  66   def test_from_xml_no_k_v
 
  67     nokv = "<osm><relation id='23' changeset='23' version='23'><tag /></relation></osm>"
 
  68     message_create = assert_raise(OSM::APIBadXMLError) do
 
  69       Relation.from_xml(nokv, :create => true)
 
  71     assert_match(/tag is missing key/, message_create.message)
 
  72     message_update = assert_raise(OSM::APIBadXMLError) do
 
  73       Relation.from_xml(nokv, :create => false)
 
  75     assert_match(/tag is missing key/, message_update.message)
 
  78   def test_from_xml_no_v
 
  79     no_v = "<osm><relation id='23' changeset='23' version='23'><tag k='key' /></relation></osm>"
 
  80     message_create = assert_raise(OSM::APIBadXMLError) do
 
  81       Relation.from_xml(no_v, :create => true)
 
  83     assert_match(/tag is missing value/, message_create.message)
 
  84     message_update = assert_raise(OSM::APIBadXMLError) do
 
  85       Relation.from_xml(no_v, :create => false)
 
  87     assert_match(/tag is missing value/, message_update.message)
 
  90   def test_from_xml_duplicate_k
 
  91     dupk = "<osm><relation id='23' changeset='23' version='23'><tag k='dup' v='test'/><tag k='dup' v='tester'/></relation></osm>"
 
  92     message_create = assert_raise(OSM::APIDuplicateTagsError) do
 
  93       Relation.from_xml(dupk, :create => true)
 
  95     assert_equal "Element relation/ has duplicate tags with key dup", message_create.message
 
  96     message_update = assert_raise(OSM::APIDuplicateTagsError) do
 
  97       Relation.from_xml(dupk, :create => false)
 
  99     assert_equal "Element relation/23 has duplicate tags with key dup", message_update.message
 
 102   def test_relation_members
 
 103     relation = create(:relation)
 
 106     other_relation = create(:relation)
 
 107     create(:relation_member, :relation => relation, :member => node, :member_role => "some node")
 
 108     create(:relation_member, :relation => relation, :member => way, :member_role => "some way")
 
 109     create(:relation_member, :relation => relation, :member => other_relation, :member_role => "some relation")
 
 111     members = Relation.find(relation.id).relation_members
 
 112     assert_equal 3, members.count
 
 113     assert_equal "some node", members[0].member_role
 
 114     assert_equal "Node", members[0].member_type
 
 115     assert_equal node.id, members[0].member_id
 
 116     assert_equal "some way", members[1].member_role
 
 117     assert_equal "Way", members[1].member_type
 
 118     assert_equal way.id, members[1].member_id
 
 119     assert_equal "some relation", members[2].member_role
 
 120     assert_equal "Relation", members[2].member_type
 
 121     assert_equal other_relation.id, members[2].member_id
 
 125     relation = create(:relation)
 
 128     other_relation = create(:relation)
 
 129     create(:relation_member, :relation => relation, :member => node, :member_role => "some node")
 
 130     create(:relation_member, :relation => relation, :member => way, :member_role => "some way")
 
 131     create(:relation_member, :relation => relation, :member => other_relation, :member_role => "some relation")
 
 133     members = Relation.find(relation.id).members
 
 134     assert_equal 3, members.count
 
 135     assert_equal ["Node", node.id, "some node"], members[0]
 
 136     assert_equal ["Way", way.id, "some way"], members[1]
 
 137     assert_equal ["Relation", other_relation.id, "some relation"], members[2]
 
 140   def test_element_tags
 
 141     relation = create(:relation)
 
 142     taglist = create_list(:relation_tag, 2, :relation => relation)
 
 144     tags = Relation.find(relation.id).element_tags.order(:k)
 
 145     assert_equal taglist.count, tags.count
 
 146     taglist.sort_by!(&:k).each_index do |i|
 
 147       assert_equal taglist[i].k, tags[i].k
 
 148       assert_equal taglist[i].v, tags[i].v
 
 153     relation = create(:relation)
 
 154     taglist = create_list(:relation_tag, 2, :relation => relation)
 
 156     tags = Relation.find(relation.id).tags
 
 157     assert_equal taglist.count, tags.count
 
 158     taglist.each do |tag|
 
 159       assert_equal tag.v, tags[tag.k]
 
 163   def test_containing_relation_members
 
 164     relation = create(:relation)
 
 165     super_relation = create(:relation)
 
 166     create(:relation_member, :relation => super_relation, :member => relation)
 
 168     crm = Relation.find(relation.id).containing_relation_members.order(:relation_id)
 
 169     #    assert_equal 1, crm.size
 
 170     assert_equal super_relation.id, crm.first.relation_id
 
 171     assert_equal "Relation", crm.first.member_type
 
 172     assert_equal relation.id, crm.first.member_id
 
 173     assert_equal super_relation.id, crm.first.relation.id
 
 176   def test_containing_relations
 
 177     relation = create(:relation)
 
 178     super_relation = create(:relation)
 
 179     create(:relation_member, :relation => super_relation, :member => relation)
 
 181     cr = Relation.find(relation.id).containing_relations.order(:id)
 
 182     assert_equal 1, cr.size
 
 183     assert_equal super_relation.id, cr.first.id
 
 186   def test_update_changeset_bbox_any_relation
 
 187     relation = create(:relation)
 
 188     super_relation = create(:relation)
 
 189     node = create(:node, :longitude => 116, :latitude => 39)
 
 190     create(:relation_member, :relation => super_relation, :member_type => "Relation", :member_id => relation.id)
 
 191     node_member = create(:relation_member, :relation => super_relation, :member_type => "Node", :member_id => node.id)
 
 193     changeset = create(:changeset, :user => user)
 
 194     assert_nil changeset.min_lon
 
 195     assert_nil changeset.max_lon
 
 196     assert_nil changeset.max_lat
 
 197     assert_nil changeset.min_lat
 
 198     new_relation = build(:relation, :id => super_relation.id,
 
 199                                     :version => super_relation.version,
 
 200                                     :changeset => changeset)
 
 201     new_relation.add_member node_member.member_type, node_member.member_id, node_member.member_role
 
 202     # one member(relation type) was removed, so any_relation flag is expected to be true.
 
 203     super_relation.update_from(new_relation, user)
 
 205     # changeset updated by node member, representing any_relation flag true.
 
 206     assert_equal 116, changeset.min_lon
 
 207     assert_equal 116, changeset.max_lon
 
 208     assert_equal 39, changeset.min_lat
 
 209     assert_equal 39, changeset.max_lat
 
 212   def test_changeset_bbox_delete_relation
 
 213     orig_relation = create(:relation)
 
 214     node1 = create(:node, :longitude => 116, :latitude => 39)
 
 215     node2 = create(:node, :longitude => 39, :latitude => 116)
 
 216     create(:relation_member, :relation => orig_relation, :member_type => "Node", :member_id => node1.id)
 
 217     create(:relation_member, :relation => orig_relation, :member_type => "Node", :member_id => node2.id)
 
 219     changeset = create(:changeset, :user => user)
 
 220     assert_nil changeset.min_lon
 
 221     assert_nil changeset.max_lon
 
 222     assert_nil changeset.max_lat
 
 223     assert_nil changeset.min_lat
 
 225     new_relation = build(:relation, :id => orig_relation.id,
 
 226                                     :version => orig_relation.version,
 
 227                                     :changeset_id => changeset.id)
 
 228     orig_relation.delete_with_history!(new_relation, user)
 
 230     assert_equal 39, changeset.min_lon
 
 231     assert_equal 116, changeset.max_lon
 
 232     assert_equal 39, changeset.min_lat
 
 233     assert_equal 116, changeset.max_lat
 
 236   # Check that the preconditions fail when you are over the defined limit of
 
 237   # the maximum number of members in a relation.
 
 238   def test_max_members_per_relation_limit
 
 239     # Speed up unit test by using a small relation member limit
 
 240     with_settings(:max_number_of_relation_members => 20) do
 
 242       changeset = create(:changeset, :user => user)
 
 243       relation = create(:relation, :changeset => changeset)
 
 244       node = create(:node, :longitude => 116, :latitude => 39)
 
 245       # Create relation which exceeds the relation member limit by one
 
 246       0.upto(Settings.max_number_of_relation_members) do |i|
 
 247         create(:relation_member, :relation => relation, :member_type => "Node", :member_id => node.id, :sequence_id => i)
 
 250       assert_raise OSM::APITooManyRelationMembersError do
 
 251         relation.create_with_history user
 
 256   test "raises missing changeset exception when creating" do
 
 258     relation = Relation.new
 
 259     assert_raises OSM::APIChangesetMissingError do
 
 260       relation.create_with_history(user)
 
 264   test "raises user-changeset mismatch exception when creating" do
 
 266     changeset = create(:changeset)
 
 267     relation = Relation.new(:changeset => changeset)
 
 268     assert_raises OSM::APIUserChangesetMismatchError do
 
 269       relation.create_with_history(user)
 
 273   test "raises already closed changeset exception when creating" do
 
 275     changeset = create(:changeset, :closed, :user => user)
 
 276     relation = Relation.new(:changeset => changeset)
 
 277     assert_raises OSM::APIChangesetAlreadyClosedError do
 
 278       relation.create_with_history(user)
 
 282   test "raises id precondition exception when updating" do
 
 284     relation = Relation.new(:id => 23)
 
 285     new_relation = Relation.new(:id => 42)
 
 286     assert_raises OSM::APIPreconditionFailedError do
 
 287       relation.update_from(new_relation, user)
 
 291   test "raises version mismatch exception when updating" do
 
 293     relation = Relation.new(:id => 42, :version => 7)
 
 294     new_relation = Relation.new(:id => 42, :version => 12)
 
 295     assert_raises OSM::APIVersionMismatchError do
 
 296       relation.update_from(new_relation, user)
 
 300   test "raises missing changeset exception when updating" do
 
 302     relation = Relation.new(:id => 42, :version => 12)
 
 303     new_relation = Relation.new(:id => 42, :version => 12)
 
 304     assert_raises OSM::APIChangesetMissingError do
 
 305       relation.update_from(new_relation, user)
 
 309   test "raises user-changeset mismatch exception when updating" do
 
 311     changeset = create(:changeset)
 
 312     relation = Relation.new(:id => 42, :version => 12)
 
 313     new_relation = Relation.new(:id => 42, :version => 12, :changeset => changeset)
 
 314     assert_raises OSM::APIUserChangesetMismatchError do
 
 315       relation.update_from(new_relation, user)
 
 319   test "raises already closed changeset exception when updating" do
 
 321     changeset = create(:changeset, :closed, :user => user)
 
 322     relation = Relation.new(:id => 42, :version => 12)
 
 323     new_relation = Relation.new(:id => 42, :version => 12, :changeset => changeset)
 
 324     assert_raises OSM::APIChangesetAlreadyClosedError do
 
 325       relation.update_from(new_relation, user)
 
 329   test "raises id precondition exception when deleting" do
 
 331     relation = Relation.new(:id => 23, :visible => true)
 
 332     new_relation = Relation.new(:id => 42, :visible => false)
 
 333     assert_raises OSM::APIPreconditionFailedError do
 
 334       relation.delete_with_history!(new_relation, user)