1 require File.dirname(__FILE__) + '/../test_helper'
2 require 'relation_controller'
4 # Re-raise errors caught by the controller.
5 class RelationController; def rescue_action(e) raise e end; end
7 class RelationControllerTest < Test::Unit::TestCase
11 @controller = RelationController.new
12 @request = ActionController::TestRequest.new
13 @response = ActionController::TestResponse.new
16 def basic_authorization(user, pass)
17 @request.env["HTTP_AUTHORIZATION"] = "Basic %s" % Base64.encode64("#{user}:#{pass}")
21 @request.env["RAW_POST_DATA"] = c.to_s
24 # -------------------------------------
25 # Test reading relations.
26 # -------------------------------------
29 # check that a visible relation is returned properly
30 get :read, :id => current_relations(:visible_relation).id
31 assert_response :success
33 # check that an invisible relation is not returned
34 get :read, :id => current_relations(:invisible_relation).id
37 # check chat a non-existent relation is not returned
39 assert_response :not_found
41 # check the "relations for node" mode
42 get :relations_for_node, :id => current_nodes(:node_used_by_relationship).id
43 assert_response :success
44 # FIXME check whether this contains the stuff we want!
45 # see the test_read in way_controller_test.rb for the assert_select
46 assert_select "osm[version=#{API_VERSION}][generator=\"OpenStreetMap server\"]", 1
47 assert_select "osm relation"
52 # check the "relations for way" mode
53 get :relations_for_way, :id => current_ways(:used_way).id
54 assert_response :success
55 # FIXME check whether this contains the stuff we want!
60 # check the "relations for relation" mode
61 get :relations_for_relation, :id => current_relations(:used_relation).id
62 assert_response :success
63 # FIXME check whether this contains the stuff we want!
68 # check the "full" mode
69 get :full, :id => current_relations(:visible_relation).id
70 assert_response :success
71 # FIXME check whether this contains the stuff we want!
77 # -------------------------------------
78 # Test simple relation creation.
79 # -------------------------------------
82 basic_authorization "test@openstreetmap.org", "test"
84 # put the relation in a dummy fixture changset
85 changeset_id = changesets(:normal_user_first_change).id
87 # create an relation without members
88 content "<osm><relation changeset='#{changeset_id}'><tag k='test' v='yes' /></relation></osm>"
91 assert_response :success,
92 "relation upload did not return success status"
93 # read id of created relation and search for it
94 relationid = @response.body
95 checkrelation = Relation.find(relationid)
96 assert_not_nil checkrelation,
97 "uploaded relation not found in data base after upload"
99 assert_equal checkrelation.members.length, 0,
100 "saved relation contains members but should not"
101 assert_equal checkrelation.tags.length, 1,
102 "saved relation does not contain exactly one tag"
103 assert_equal changeset_id, checkrelation.changeset.id,
104 "saved relation does not belong in the changeset it was assigned to"
105 assert_equal users(:normal_user).id, checkrelation.changeset.user_id,
106 "saved relation does not belong to user that created it"
107 assert_equal true, checkrelation.visible,
108 "saved relation is not visible"
109 # ok the relation is there but can we also retrieve it?
110 get :read, :id => relationid
111 assert_response :success
114 # create an relation with a node as member
115 nid = current_nodes(:used_node_1).id
116 content "<osm><relation changeset='#{changeset_id}'>" +
117 "<member type='node' ref='#{nid}' role='some'/>" +
118 "<tag k='test' v='yes' /></relation></osm>"
121 assert_response :success,
122 "relation upload did not return success status"
123 # read id of created relation and search for it
124 relationid = @response.body
125 checkrelation = Relation.find(relationid)
126 assert_not_nil checkrelation,
127 "uploaded relation not found in data base after upload"
129 assert_equal checkrelation.members.length, 1,
130 "saved relation does not contain exactly one member"
131 assert_equal checkrelation.tags.length, 1,
132 "saved relation does not contain exactly one tag"
133 assert_equal changeset_id, checkrelation.changeset.id,
134 "saved relation does not belong in the changeset it was assigned to"
135 assert_equal users(:normal_user).id, checkrelation.changeset.user_id,
136 "saved relation does not belong to user that created it"
137 assert_equal true, checkrelation.visible,
138 "saved relation is not visible"
139 # ok the relation is there but can we also retrieve it?
141 get :read, :id => relationid
142 assert_response :success
144 # create an relation with a way and a node as members
145 nid = current_nodes(:used_node_1).id
146 wid = current_ways(:used_way).id
147 content "<osm><relation changeset='#{changeset_id}'>" +
148 "<member type='node' ref='#{nid}' role='some'/>" +
149 "<member type='way' ref='#{wid}' role='other'/>" +
150 "<tag k='test' v='yes' /></relation></osm>"
153 assert_response :success,
154 "relation upload did not return success status"
155 # read id of created relation and search for it
156 relationid = @response.body
157 checkrelation = Relation.find(relationid)
158 assert_not_nil checkrelation,
159 "uploaded relation not found in data base after upload"
161 assert_equal checkrelation.members.length, 2,
162 "saved relation does not have exactly two members"
163 assert_equal checkrelation.tags.length, 1,
164 "saved relation does not contain exactly one tag"
165 assert_equal changeset_id, checkrelation.changeset.id,
166 "saved relation does not belong in the changeset it was assigned to"
167 assert_equal users(:normal_user).id, checkrelation.changeset.user_id,
168 "saved relation does not belong to user that created it"
169 assert_equal true, checkrelation.visible,
170 "saved relation is not visible"
171 # ok the relation is there but can we also retrieve it?
172 get :read, :id => relationid
173 assert_response :success
177 # -------------------------------------
178 # Test creating some invalid relations.
179 # -------------------------------------
181 def test_create_invalid
182 basic_authorization "test@openstreetmap.org", "test"
184 # put the relation in a dummy fixture changset
185 changeset_id = changesets(:normal_user_first_change).id
187 # create a relation with non-existing node as member
188 content "<osm><relation changeset='#{changeset_id}'>" +
189 "<member type='node' ref='0'/><tag k='test' v='yes' />" +
193 assert_response :precondition_failed,
194 "relation upload with invalid node did not return 'precondition failed'"
197 # -------------------------------------
198 # Test deleting relations.
199 # -------------------------------------
202 # first try to delete relation without auth
203 delete :delete, :id => current_relations(:visible_relation).id
204 assert_response :unauthorized
207 basic_authorization("test@openstreetmap.org", "test");
209 # this shouldn't work, as we should need the payload...
210 delete :delete, :id => current_relations(:visible_relation).id
211 assert_response :bad_request
213 # try to delete without specifying a changeset
214 content "<osm><relation id='#{current_relations(:visible_relation).id}'/></osm>"
215 delete :delete, :id => current_relations(:visible_relation).id
216 assert_response :conflict
218 # try to delete with an invalid (closed) changeset
219 content update_changeset(current_relations(:visible_relation).to_xml,
220 changesets(:normal_user_closed_change).id)
221 delete :delete, :id => current_relations(:visible_relation).id
222 assert_response :conflict
224 # try to delete with an invalid (non-existent) changeset
225 content update_changeset(current_relations(:visible_relation).to_xml,0)
226 delete :delete, :id => current_relations(:visible_relation).id
227 assert_response :conflict
229 # this won't work because the relation is in-use by another relation
230 content(relations(:used_relation).to_xml)
231 delete :delete, :id => current_relations(:used_relation).id
232 assert_response :precondition_failed,
233 "shouldn't be able to delete a relation used in a relation (#{@response.body})"
235 # this should work when we provide the appropriate payload...
236 content(relations(:visible_relation).to_xml)
237 delete :delete, :id => current_relations(:visible_relation).id
238 assert_response :success
240 # valid delete should return the new version number, which should
241 # be greater than the old version number
242 assert @response.body.to_i > current_relations(:visible_relation).version,
243 "delete request should return a new version number for relation"
245 # this won't work since the relation is already deleted
246 content(relations(:invisible_relation).to_xml)
247 delete :delete, :id => current_relations(:invisible_relation).id
248 assert_response :gone
250 # this works now because the relation which was using this one
252 content(relations(:used_relation).to_xml)
253 delete :delete, :id => current_relations(:used_relation).id
254 assert_response :success,
255 "should be able to delete a relation used in an old relation (#{@response.body})"
257 # this won't work since the relation never existed
258 delete :delete, :id => 0
259 assert_response :not_found
263 # update the changeset_id of a node element
264 def update_changeset(xml, changeset_id)
265 xml_attr_rewrite(xml, 'changeset', changeset_id)
269 # update an attribute in the node element
270 def xml_attr_rewrite(xml, name, value)
271 xml.find("//osm/relation").first[name] = value.to_s
278 parser = XML::Parser.new