1 require File.dirname(__FILE__) + '/../test_helper'
2 require 'way_controller'
4 class WayControllerTest < ActionController::TestCase
7 # -------------------------------------
9 # -------------------------------------
12 # check that a visible way is returned properly
13 get :read, :id => current_ways(:visible_way).id
14 assert_response :success
16 # check that an invisible way is not returned
17 get :read, :id => current_ways(:invisible_way).id
20 # check chat a non-existent way is not returned
22 assert_response :not_found
26 # check the "full" mode
28 Way.find(:all).each do |way|
29 get :full, :id => way.id
31 # full call should say "gone" for non-visible ways...
37 # otherwise it should say success
38 assert_response :success
40 # Check the way is correctly returned
41 assert_select "osm way[id=#{way.id}][version=#{way.version}][visible=#{way.visible}]", 1
43 # check that each node in the way appears once in the output as a
44 # reference and as the node element. note the slightly dodgy assumption
45 # that nodes appear only once. this is currently the case with the
46 # fixtures, but it doesn't have to be.
48 assert_select "osm way nd[ref=#{n.id}]", 1
49 assert_select "osm node[id=#{n.id}][version=#{n.version}][lat=#{n.lat}][lon=#{n.lon}]", 1
54 # -------------------------------------
55 # Test simple way creation.
56 # -------------------------------------
59 nid1 = current_nodes(:used_node_1).id
60 nid2 = current_nodes(:used_node_2).id
61 basic_authorization "test@openstreetmap.org", "test"
63 # use the first user's open changeset
64 changeset_id = changesets(:normal_user_first_change).id
66 # create a way with pre-existing nodes
67 content "<osm><way changeset='#{changeset_id}'>" +
68 "<nd ref='#{nid1}'/><nd ref='#{nid2}'/>" +
69 "<tag k='test' v='yes' /></way></osm>"
72 assert_response :success,
73 "way upload did not return success status"
74 # read id of created way and search for it
75 wayid = @response.body
76 checkway = Way.find(wayid)
77 assert_not_nil checkway,
78 "uploaded way not found in data base after upload"
80 assert_equal checkway.nds.length, 2,
81 "saved way does not contain exactly one node"
82 assert_equal checkway.nds[0], nid1,
83 "saved way does not contain the right node on pos 0"
84 assert_equal checkway.nds[1], nid2,
85 "saved way does not contain the right node on pos 1"
86 assert_equal checkway.changeset_id, changeset_id,
87 "saved way does not belong to the correct changeset"
88 assert_equal users(:normal_user).id, checkway.changeset.user_id,
89 "saved way does not belong to user that created it"
90 assert_equal true, checkway.visible,
91 "saved way is not visible"
94 # -------------------------------------
95 # Test creating some invalid ways.
96 # -------------------------------------
98 def test_create_invalid
99 basic_authorization "test@openstreetmap.org", "test"
101 # use the first user's open changeset
102 open_changeset_id = changesets(:normal_user_first_change).id
103 closed_changeset_id = changesets(:normal_user_closed_change).id
104 nid1 = current_nodes(:used_node_1).id
106 # create a way with non-existing node
107 content "<osm><way changeset='#{open_changeset_id}'>" +
108 "<nd ref='0'/><tag k='test' v='yes' /></way></osm>"
111 assert_response :precondition_failed,
112 "way upload with invalid node did not return 'precondition failed'"
114 # create a way with no nodes
115 content "<osm><way changeset='#{open_changeset_id}'>" +
116 "<tag k='test' v='yes' /></way></osm>"
119 assert_response :precondition_failed,
120 "way upload with no node did not return 'precondition failed'"
122 # create a way inside a closed changeset
123 content "<osm><way changeset='#{closed_changeset_id}'>" +
124 "<nd ref='#{nid1}'/></way></osm>"
127 assert_response :conflict,
128 "way upload to closed changeset did not return 'conflict'"
131 # -------------------------------------
132 # Test deleting ways.
133 # -------------------------------------
136 # first try to delete way without auth
137 delete :delete, :id => current_ways(:visible_way).id
138 assert_response :unauthorized
141 basic_authorization("test@openstreetmap.org", "test");
143 # this shouldn't work as with the 0.6 api we need pay load to delete
144 delete :delete, :id => current_ways(:visible_way).id
145 assert_response :bad_request
147 # Now try without having a changeset
148 content "<osm><way id='#{current_ways(:visible_way).id}'></osm>"
149 delete :delete, :id => current_ways(:visible_way).id
150 assert_response :bad_request
152 # try to delete with an invalid (closed) changeset
153 content update_changeset(current_ways(:visible_way).to_xml,
154 changesets(:normal_user_closed_change).id)
155 delete :delete, :id => current_ways(:visible_way).id
156 assert_response :conflict
158 # try to delete with an invalid (non-existent) changeset
159 content update_changeset(current_ways(:visible_way).to_xml,0)
160 delete :delete, :id => current_ways(:visible_way).id
161 assert_response :conflict
163 # Now try with a valid changeset
164 content current_ways(:visible_way).to_xml
165 delete :delete, :id => current_ways(:visible_way).id
166 assert_response :success
168 # check the returned value - should be the new version number
169 # valid delete should return the new version number, which should
170 # be greater than the old version number
171 assert @response.body.to_i > current_ways(:visible_way).version,
172 "delete request should return a new version number for way"
174 # this won't work since the way is already deleted
175 content current_ways(:invisible_way).to_xml
176 delete :delete, :id => current_ways(:invisible_way).id
177 assert_response :gone
179 # this shouldn't work as the way is used in a relation
180 content current_ways(:used_way).to_xml
181 delete :delete, :id => current_ways(:used_way).id
182 assert_response :precondition_failed,
183 "shouldn't be able to delete a way used in a relation (#{@response.body})"
185 # this won't work since the way never existed
186 delete :delete, :id => 0
187 assert_response :not_found
190 # ------------------------------------------------------------
192 # ------------------------------------------------------------
195 # Try adding a duplicate of an existing tag to a way
196 def test_add_duplicate_tags
198 basic_authorization(users(:normal_user).email, "test")
200 # add an identical tag to the way
201 tag_xml = XML::Node.new("tag")
202 tag_xml['k'] = current_way_tags(:t1).k
203 tag_xml['v'] = current_way_tags(:t1).v
205 # add the tag into the existing xml
206 way_xml = current_ways(:visible_way).to_xml
207 way_xml.find("//osm/way").first << tag_xml
211 put :update, :id => current_ways(:visible_way).id
212 assert_response :bad_request,
213 "adding a duplicate tag to a way should fail with 'bad request'"
214 assert_equal "Element way/#{current_ways(:visible_way).id} has duplicate tags with key #{current_way_tags(:t1).k}.", @response.body
218 # Try adding a new duplicate tags to a way
219 def test_new_duplicate_tags
221 basic_authorization(users(:normal_user).email, "test")
223 # create duplicate tag
224 tag_xml = XML::Node.new("tag")
225 tag_xml['k'] = "i_am_a_duplicate"
226 tag_xml['v'] = "foobar"
228 # add the tag into the existing xml
229 way_xml = current_ways(:visible_way).to_xml
231 # add two copies of the tag
232 way_xml.find("//osm/way").first << tag_xml.copy(true) << tag_xml
236 put :update, :id => current_ways(:visible_way).id
237 assert_response :bad_request,
238 "adding new duplicate tags to a way should fail with 'bad request'"
239 assert_equal "Element way/#{current_ways(:visible_way).id} has duplicate tags with key i_am_a_duplicate.", @response.body
243 # Try adding a new duplicate tags to a way.
244 # But be a bit subtle - use unicode decoding ambiguities to use different
245 # binary strings which have the same decoding.
246 def test_invalid_duplicate_tags
248 basic_authorization(users(:normal_user).email, "test")
250 # add the tag into the existing xml
251 way_str = "<osm><way changeset='1'>"
252 way_str << "<tag k='addr:housenumber' v='1'/>"
253 way_str << "<tag k='addr:housenumber' v='2'/>"
254 way_str << "</way></osm>";
259 assert_response :bad_request,
260 "adding new duplicate tags to a way should fail with 'bad request'"
261 assert_equal "Element way/ has duplicate tags with key addr:housenumber.", @response.body
265 # test that a call to ways_for_node returns all ways that contain the node
266 # and none that don't.
267 def test_ways_for_node
268 # in current fixtures ways 1 and 3 all use node 3. ways 2 and 4
269 # *used* to use it but doesn't.
270 get :ways_for_node, :id => current_nodes(:used_node_1).id
271 assert_response :success
272 ways_xml = XML::Parser.string(@response.body).parse
273 assert_not_nil ways_xml, "failed to parse ways_for_node response"
275 # check that the set of IDs match expectations
276 expected_way_ids = [ current_ways(:visible_way).id,
277 current_ways(:used_way).id
279 found_way_ids = ways_xml.find("//osm/way").collect { |w| w["id"].to_i }
280 assert_equal expected_way_ids, found_way_ids,
281 "expected ways for node #{current_nodes(:used_node_1).id} did not match found"
283 # check the full ways to ensure we're not missing anything
284 expected_way_ids.each do |id|
285 way_xml = ways_xml.find("//osm/way[@id=#{id}]").first
286 assert_ways_are_equal(Way.find(id),
287 Way.from_xml_node(way_xml))
292 # update the changeset_id of a node element
293 def update_changeset(xml, changeset_id)
294 xml_attr_rewrite(xml, 'changeset', changeset_id)
298 # update an attribute in the node element
299 def xml_attr_rewrite(xml, name, value)
300 xml.find("//osm/way").first[name] = value.to_s