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)