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