Merge remote-tracking branch 'upstream/pull/2167'
[rails.git] / test / models / node_test.rb
1 require "test_helper"
2
3 class NodeTest < ActiveSupport::TestCase
4   def test_node_too_far_north
5     node = build(:node, :latitude => 90.01 * OldNode::SCALE)
6     node.validate
7     assert node.errors.full_messages.include?("Node is not in the world")
8   end
9
10   def test_node_north_limit
11     node = build(:node, :latitude => 90 * OldNode::SCALE)
12     node.validate
13     assert_equal false, node.errors.full_messages.include?("Node is not in the world")
14   end
15
16   def test_node_too_far_south
17     node = build(:node, :latitude => -90.01 * OldNode::SCALE)
18     node.validate
19     assert node.errors.full_messages.include?("Node is not in the world")
20   end
21
22   def test_node_south_limit
23     node = build(:node, :latitude => -90 * OldNode::SCALE)
24     node.validate
25     assert_equal false, node.errors.full_messages.include?("Node is not in the world")
26   end
27
28   def test_node_too_far_west
29     node = build(:node, :longitude => -180.01 * OldNode::SCALE)
30     node.validate
31     assert node.errors.full_messages.include?("Node is not in the world")
32   end
33
34   def test_node_west_limit
35     node = build(:node, :longitude => -180 * OldNode::SCALE)
36     node.validate
37     assert_equal false, node.errors.full_messages.include?("Node is not in the world")
38   end
39
40   def test_node_too_far_east
41     node = build(:node, :longitude => 180.01 * OldNode::SCALE)
42     node.validate
43     assert node.errors.full_messages.include?("Node is not in the world")
44   end
45
46   def test_node_east_limit
47     node = build(:node, :longitude => 180 * OldNode::SCALE)
48     node.validate
49     assert_equal false, node.errors.full_messages.include?("Node is not in the world")
50   end
51
52   def test_totally_wrong
53     node = build(:node, :latitude => 200 * OldNode::SCALE, :longitude => 200 * OldNode::SCALE)
54     node.validate
55     assert node.errors.full_messages.include?("Node is not in the world")
56   end
57
58   def test_lat_lon
59     node = build(:node, :latitude => 12.345 * OldNode::SCALE, :longitude => 34.567 * OldNode::SCALE)
60
61     assert_in_delta 12.345, node.lat, 0.0000001
62     assert_in_delta 34.567, node.lon, 0.0000001
63
64     node.lat = 54.321
65     node.lon = 76.543
66
67     assert_in_delta 54.321 * OldNode::SCALE, node.latitude, 0.000001
68     assert_in_delta 76.543 * OldNode::SCALE, node.longitude, 0.000001
69   end
70
71   # Ensure the lat/lon is formatted as a decimal e.g. not 4.0e-05
72   def test_lat_lon_xml_format
73     node = build(:node, :latitude => 0.00004 * OldNode::SCALE, :longitude => 0.00008 * OldNode::SCALE)
74
75     assert_match(/lat="0.0000400"/, node.to_xml.to_s)
76     assert_match(/lon="0.0000800"/, node.to_xml.to_s)
77   end
78
79   # Check that you can create a node and store it
80   def test_create
81     changeset = create(:changeset)
82     node_template = Node.new(
83       :latitude => 12.3456,
84       :longitude => 65.4321,
85       :changeset_id => changeset.id,
86       :visible => 1,
87       :version => 1
88     )
89     assert node_template.create_with_history(changeset.user)
90
91     node = Node.find(node_template.id)
92     assert_not_nil node
93     assert_equal node_template.latitude, node.latitude
94     assert_equal node_template.longitude, node.longitude
95     assert_equal node_template.changeset_id, node.changeset_id
96     assert_equal node_template.visible, node.visible
97     assert_equal node_template.timestamp.to_i, node.timestamp.to_i
98
99     assert_equal OldNode.where(:node_id => node_template.id).count, 1
100     old_node = OldNode.where(:node_id => node_template.id).first
101     assert_not_nil old_node
102     assert_equal node_template.latitude, old_node.latitude
103     assert_equal node_template.longitude, old_node.longitude
104     assert_equal node_template.changeset_id, old_node.changeset_id
105     assert_equal node_template.visible, old_node.visible
106     assert_equal node_template.tags, old_node.tags
107     assert_equal node_template.timestamp.to_i, old_node.timestamp.to_i
108   end
109
110   def test_update
111     node = create(:node)
112     create(:old_node, :node_id => node.id, :version => 1)
113     node_template = Node.find(node.id)
114
115     assert_not_nil node_template
116     assert_equal OldNode.where(:node_id => node_template.id).count, 1
117     assert_not_nil node
118
119     node_template.latitude = 12.3456
120     node_template.longitude = 65.4321
121     # node_template.tags = "updated=yes"
122     assert node.update_from(node_template, node.changeset.user)
123
124     node = Node.find(node_template.id)
125     assert_not_nil node
126     assert_equal node_template.latitude, node.latitude
127     assert_equal node_template.longitude, node.longitude
128     assert_equal node_template.changeset_id, node.changeset_id
129     assert_equal node_template.visible, node.visible
130     # assert_equal node_template.tags, node.tags
131
132     assert_equal OldNode.where(:node_id => node_template.id).count, 2
133     old_node = OldNode.where(:node_id => node_template.id, :version => 2).first
134     assert_not_nil old_node
135     assert_equal node_template.latitude, old_node.latitude
136     assert_equal node_template.longitude, old_node.longitude
137     assert_equal node_template.changeset_id, old_node.changeset_id
138     assert_equal node_template.visible, old_node.visible
139     # assert_equal node_template.tags, old_node.tags
140   end
141
142   def test_delete
143     node = create(:node)
144     create(:old_node, :node_id => node.id, :version => 1)
145     node_template = Node.find(node.id)
146
147     assert_not_nil node_template
148     assert_equal OldNode.where(:node_id => node_template.id).count, 1
149     assert_not_nil node
150
151     assert node.delete_with_history!(node_template, node.changeset.user)
152
153     node = Node.find(node_template.id)
154     assert_not_nil node
155     assert_equal node_template.latitude, node.latitude
156     assert_equal node_template.longitude, node.longitude
157     assert_equal node_template.changeset_id, node.changeset_id
158     assert_equal false, node.visible
159     # assert_equal node_template.tags, node.tags
160
161     assert_equal OldNode.where(:node_id => node_template.id).count, 2
162     old_node = OldNode.where(:node_id => node_template.id, :version => 2).first
163     assert_not_nil old_node
164     assert_equal node_template.latitude, old_node.latitude
165     assert_equal node_template.longitude, old_node.longitude
166     assert_equal node_template.changeset_id, old_node.changeset_id
167     assert_equal false, old_node.visible
168     # assert_equal node_template.tags, old_node.tags
169   end
170
171   def test_from_xml_no_id
172     lat = 56.7
173     lon = -2.3
174     changeset = 2
175     version = 1
176     noid = "<osm><node lat='#{lat}' lon='#{lon}' changeset='#{changeset}' version='#{version}' /></osm>"
177     # First try a create which doesn't need the id
178     assert_nothing_raised do
179       Node.from_xml(noid, true)
180     end
181     # Now try an update with no id, and make sure that it gives the appropriate exception
182     message = assert_raise(OSM::APIBadXMLError) do
183       Node.from_xml(noid, false)
184     end
185     assert_match(/ID is required when updating./, message.message)
186   end
187
188   def test_from_xml_no_lat
189     nolat = "<osm><node id='1' lon='23.3' changeset='2' version='23' /></osm>"
190     message_create = assert_raise(OSM::APIBadXMLError) do
191       Node.from_xml(nolat, true)
192     end
193     assert_match(/lat missing/, message_create.message)
194     message_update = assert_raise(OSM::APIBadXMLError) do
195       Node.from_xml(nolat, false)
196     end
197     assert_match(/lat missing/, message_update.message)
198   end
199
200   def test_from_xml_no_lon
201     nolon = "<osm><node id='1' lat='23.1' changeset='2' version='23' /></osm>"
202     message_create = assert_raise(OSM::APIBadXMLError) do
203       Node.from_xml(nolon, true)
204     end
205     assert_match(/lon missing/, message_create.message)
206     message_update = assert_raise(OSM::APIBadXMLError) do
207       Node.from_xml(nolon, false)
208     end
209     assert_match(/lon missing/, message_update.message)
210   end
211
212   def test_from_xml_no_changeset_id
213     nocs = "<osm><node id='123' lon='23.23' lat='23.1' version='23' /></osm>"
214     message_create = assert_raise(OSM::APIBadXMLError) do
215       Node.from_xml(nocs, true)
216     end
217     assert_match(/Changeset id is missing/, message_create.message)
218     message_update = assert_raise(OSM::APIBadXMLError) do
219       Node.from_xml(nocs, false)
220     end
221     assert_match(/Changeset id is missing/, message_update.message)
222   end
223
224   def test_from_xml_no_version
225     no_version = "<osm><node id='123' lat='23' lon='23' changeset='23' /></osm>"
226     assert_nothing_raised do
227       Node.from_xml(no_version, true)
228     end
229     message_update = assert_raise(OSM::APIBadXMLError) do
230       Node.from_xml(no_version, false)
231     end
232     assert_match(/Version is required when updating/, message_update.message)
233   end
234
235   def test_from_xml_double_lat
236     nocs = "<osm><node id='123' lon='23.23' lat='23.1' lat='12' changeset='23' version='23' /></osm>"
237     message_create = assert_raise(OSM::APIBadXMLError) do
238       Node.from_xml(nocs, true)
239     end
240     assert_match(/Fatal error: Attribute lat redefined at/, message_create.message)
241     message_update = assert_raise(OSM::APIBadXMLError) do
242       Node.from_xml(nocs, false)
243     end
244     assert_match(/Fatal error: Attribute lat redefined at/, message_update.message)
245   end
246
247   def test_from_xml_id_zero
248     id_list = ["", "0", "00", "0.0", "a"]
249     id_list.each do |id|
250       zero_id = "<osm><node id='#{id}' lat='12.3' lon='12.3' changeset='33' version='23' /></osm>"
251       assert_nothing_raised do
252         Node.from_xml(zero_id, true)
253       end
254       message_update = assert_raise(OSM::APIBadUserInput) do
255         Node.from_xml(zero_id, false)
256       end
257       assert_match(/ID of node cannot be zero when updating/, message_update.message)
258     end
259   end
260
261   def test_from_xml_no_text
262     no_text = ""
263     message_create = assert_raise(OSM::APIBadXMLError) do
264       Node.from_xml(no_text, true)
265     end
266     assert_match(/Must specify a string with one or more characters/, message_create.message)
267     message_update = assert_raise(OSM::APIBadXMLError) do
268       Node.from_xml(no_text, false)
269     end
270     assert_match(/Must specify a string with one or more characters/, message_update.message)
271   end
272
273   def test_from_xml_no_node
274     no_node = "<osm></osm>"
275     message_create = assert_raise(OSM::APIBadXMLError) do
276       Node.from_xml(no_node, true)
277     end
278     assert_match %r{XML doesn't contain an osm/node element}, message_create.message
279     message_update = assert_raise(OSM::APIBadXMLError) do
280       Node.from_xml(no_node, false)
281     end
282     assert_match %r{XML doesn't contain an osm/node element}, message_update.message
283   end
284
285   def test_from_xml_no_k_v
286     nokv = "<osm><node id='23' lat='12.3' lon='23.4' changeset='12' version='23'><tag /></node></osm>"
287     message_create = assert_raise(OSM::APIBadXMLError) do
288       Node.from_xml(nokv, true)
289     end
290     assert_match(/tag is missing key/, message_create.message)
291     message_update = assert_raise(OSM::APIBadXMLError) do
292       Node.from_xml(nokv, false)
293     end
294     assert_match(/tag is missing key/, message_update.message)
295   end
296
297   def test_from_xml_no_v
298     no_v = "<osm><node id='23' lat='23.43' lon='23.32' changeset='23' version='32'><tag k='key' /></node></osm>"
299     message_create = assert_raise(OSM::APIBadXMLError) do
300       Node.from_xml(no_v, true)
301     end
302     assert_match(/tag is missing value/, message_create.message)
303     message_update = assert_raise(OSM::APIBadXMLError) do
304       Node.from_xml(no_v, false)
305     end
306     assert_match(/tag is missing value/, message_update.message)
307   end
308
309   def test_from_xml_duplicate_k
310     dupk = "<osm><node id='23' lat='23.2' lon='23' changeset='34' version='23'><tag k='dup' v='test' /><tag k='dup' v='tester' /></node></osm>"
311     message_create = assert_raise(OSM::APIDuplicateTagsError) do
312       Node.from_xml(dupk, true)
313     end
314     assert_equal "Element node/ has duplicate tags with key dup", message_create.message
315     message_update = assert_raise(OSM::APIDuplicateTagsError) do
316       Node.from_xml(dupk, false)
317     end
318     assert_equal "Element node/23 has duplicate tags with key dup", message_update.message
319   end
320
321   def test_node_tags
322     node = create(:node)
323     taglist = create_list(:node_tag, 2, :node => node)
324     tags = Node.find(node.id).node_tags.order(:k)
325     assert_equal taglist.count, tags.count
326     taglist.sort_by!(&:k).each_index do |i|
327       assert_equal taglist[i].k, tags[i].k
328       assert_equal taglist[i].v, tags[i].v
329     end
330   end
331
332   def test_tags
333     node = create(:node)
334     taglist = create_list(:node_tag, 2, :node => node)
335     tags = Node.find(node.id).tags
336     assert_equal taglist.count, tags.count
337     taglist.each do |tag|
338       assert_equal tag.v, tags[tag.k]
339     end
340   end
341
342   def test_containing_relation_members
343     node = create(:node)
344     relation_member1 = create(:relation_member, :member => node)
345     relation_member2 = create(:relation_member, :member => node)
346     relation_member3 = create(:relation_member, :member => node)
347     crm = Node.find(node.id).containing_relation_members.order(:relation_id)
348     #    assert_equal 3, crm.size
349     assert_equal relation_member1.relation_id, crm.first.relation_id
350     assert_equal "Node", crm.first.member_type
351     assert_equal node.id, crm.first.member_id
352     assert_equal relation_member1.relation_id, crm.first.relation.id
353     assert_equal relation_member2.relation_id, crm.second.relation_id
354     assert_equal "Node", crm.second.member_type
355     assert_equal node.id, crm.second.member_id
356     assert_equal relation_member2.relation_id, crm.second.relation.id
357     assert_equal relation_member3.relation_id, crm.third.relation_id
358     assert_equal "Node", crm.third.member_type
359     assert_equal node.id, crm.third.member_id
360     assert_equal relation_member3.relation_id, crm.third.relation.id
361   end
362
363   def test_containing_relations
364     node = create(:node)
365     relation_member1 = create(:relation_member, :member => node)
366     relation_member2 = create(:relation_member, :member => node)
367     relation_member3 = create(:relation_member, :member => node)
368     cr = Node.find(node.id).containing_relations.order(:id)
369
370     assert_equal 3, cr.size
371     assert_equal relation_member1.relation.id, cr.first.id
372     assert_equal relation_member2.relation.id, cr.second.id
373     assert_equal relation_member3.relation.id, cr.third.id
374   end
375 end