]> git.openstreetmap.org Git - rails.git/blob - test/functional/relation_controller_test.rb
Fixed fixtures and added new tests for ways and way_nodes.
[rails.git] / test / functional / relation_controller_test.rb
1 require File.dirname(__FILE__) + '/../test_helper'
2 require 'relation_controller'
3
4 # Re-raise errors caught by the controller.
5 class RelationController; def rescue_action(e) raise e end; end
6
7 class RelationControllerTest < Test::Unit::TestCase
8   api_fixtures
9
10   def setup
11     @controller = RelationController.new
12     @request    = ActionController::TestRequest.new
13     @response   = ActionController::TestResponse.new
14   end
15
16   def basic_authorization(user, pass)
17     @request.env["HTTP_AUTHORIZATION"] = "Basic %s" % Base64.encode64("#{user}:#{pass}")
18   end
19
20   def content(c)
21     @request.env["RAW_POST_DATA"] = c.to_s
22   end
23
24   # -------------------------------------
25   # Test reading relations.
26   # -------------------------------------
27
28   def test_read
29     # check that a visible relation is returned properly
30     get :read, :id => current_relations(:visible_relation).id
31     assert_response :success
32
33     # check that an invisible relation is not returned
34     get :read, :id => current_relations(:invisible_relation).id
35     assert_response :gone
36
37     # check chat a non-existent relation is not returned
38     get :read, :id => 0
39     assert_response :not_found
40
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"
48     if $VERBOSE
49         print @response.body
50     end
51
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!
56     if $VERBOSE
57         print @response.body
58     end
59
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!
64     if $VERBOSE
65         print @response.body
66     end
67
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!
72     if $VERBOSE
73         print @response.body
74     end
75   end
76
77   # -------------------------------------
78   # Test simple relation creation.
79   # -------------------------------------
80
81   def test_create
82     basic_authorization "test@openstreetmap.org", "test"
83     
84     # put the relation in a dummy fixture changset
85     changeset_id = changesets(:normal_user_first_change).id
86
87     # create an relation without members
88     content "<osm><relation changeset='#{changeset_id}'><tag k='test' v='yes' /></relation></osm>"
89     put :create
90     # hope for success
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"
98     # compare values
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
112
113
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>"
119     put :create
120     # hope for success
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"
128     # compare values
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?
140     
141     get :read, :id => relationid
142     assert_response :success
143
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>"
151     put :create
152     # hope for success
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"
160     # compare values
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
174
175   end
176
177   # -------------------------------------
178   # Test creating some invalid relations.
179   # -------------------------------------
180
181   def test_create_invalid
182     basic_authorization "test@openstreetmap.org", "test"
183
184     # put the relation in a dummy fixture changset
185     changeset_id = changesets(:normal_user_first_change).id
186
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' />" +
190       "</relation></osm>"
191     put :create
192     # expect failure
193     assert_response :precondition_failed, 
194         "relation upload with invalid node did not return 'precondition failed'"
195   end
196
197   # -------------------------------------
198   # Test deleting relations.
199   # -------------------------------------
200   
201   def test_delete
202     # first try to delete relation without auth
203     delete :delete, :id => current_relations(:visible_relation).id
204     assert_response :unauthorized
205
206     # now set auth
207     basic_authorization("test@openstreetmap.org", "test");  
208
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
212
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
217
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
223
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
228
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})"
234
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
239
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"
244
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
249
250     # this works now because the relation which was using this one 
251     # has been deleted.
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})"
256
257     # this won't work since the relation never existed
258     delete :delete, :id => 0
259     assert_response :not_found
260   end
261
262   ##
263   # update the changeset_id of a node element
264   def update_changeset(xml, changeset_id)
265     xml_attr_rewrite(xml, 'changeset', changeset_id)
266   end
267
268   ##
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
272     return xml
273   end
274
275   ##
276   # parse some xml
277   def xml_parse(xml)
278     parser = XML::Parser.new
279     parser.string = xml
280     parser.parse
281   end
282 end