]> git.openstreetmap.org Git - rails.git/blob - test/controllers/api_controller_test.rb
Move the permissions call out of api_controller
[rails.git] / test / controllers / api_controller_test.rb
1 require "test_helper"
2
3 class ApiControllerTest < ActionController::TestCase
4   def setup
5     super
6     @badbigbbox = %w[-0.1,-0.1,1.1,1.1 10,10,11,11]
7     @badmalformedbbox = %w[-0.1 hello
8                            10N2W10.1N2.1W]
9     @badlatmixedbbox = %w[0,0.1,0.1,0 -0.1,80,0.1,70 0.24,54.34,0.25,54.33]
10     @badlonmixedbbox = %w[80,-0.1,70,0.1 54.34,0.24,54.33,0.25]
11     # @badlatlonoutboundsbbox = %w{ 191,-0.1,193,0.1  -190.1,89.9,-190,90 }
12     @goodbbox = %w[-0.1,-0.1,0.1,0.1 51.1,-0.1,51.2,0
13                    -0.1,%20-0.1,%200.1,%200.1 -0.1edcd,-0.1d,0.1,0.1 -0.1E,-0.1E,0.1S,0.1N S0.1,W0.1,N0.1,E0.1]
14     # That last item in the goodbbox really shouldn't be there, as the API should
15     # reall reject it, however this is to test to see if the api changes.
16   end
17
18   ##
19   # test all routes which lead to this controller
20   def test_routes
21     assert_routing(
22       { :path => "/api/0.6/map", :method => :get },
23       { :controller => "api", :action => "map" }
24     )
25     assert_routing(
26       { :path => "/api/0.6/changes", :method => :get },
27       { :controller => "api", :action => "changes" }
28     )
29   end
30
31   # -------------------------------------
32   # Test reading a bounding box.
33   # -------------------------------------
34
35   def test_map
36     node = create(:node, :lat => 7, :lon => 7)
37     tag = create(:node_tag, :node => node)
38     way1 = create(:way_node, :node => node).way
39     way2 = create(:way_node, :node => node).way
40     relation = create(:relation_member, :member => node).relation
41
42     # Need to split the min/max lat/lon out into their own variables here
43     # so that we can test they are returned later.
44     minlon = node.lon - 0.1
45     minlat = node.lat - 0.1
46     maxlon = node.lon + 0.1
47     maxlat = node.lat + 0.1
48     bbox = "#{minlon},#{minlat},#{maxlon},#{maxlat}"
49     get :map, :params => { :bbox => bbox }
50     if $VERBOSE
51       print @request.to_yaml
52       print @response.body
53     end
54     assert_response :success, "Expected scucess with the map call"
55     assert_select "osm[version='#{API_VERSION}'][generator='#{GENERATOR}']", :count => 1 do
56       assert_select "bounds[minlon='#{format('%.7f', minlon)}'][minlat='#{format('%.7f', minlat)}'][maxlon='#{format('%.7f', maxlon)}'][maxlat='#{format('%.7f', maxlat)}']", :count => 1
57       assert_select "node[id='#{node.id}'][lat='#{format('%.7f', node.lat)}'][lon='#{format('%.7f', node.lon)}'][version='#{node.version}'][changeset='#{node.changeset_id}'][visible='#{node.visible}'][timestamp='#{node.timestamp.xmlschema}']", :count => 1 do
58         # This should really be more generic
59         assert_select "tag[k='#{tag.k}'][v='#{tag.v}']"
60       end
61       assert_select "way", :count => 2
62       assert_select "way[id='#{way1.id}']", :count => 1
63       assert_select "way[id='#{way2.id}']", :count => 1
64       assert_select "relation", :count => 1
65       assert_select "relation[id='#{relation.id}']", :count => 1
66     end
67   end
68
69   # This differs from the above test in that we are making the bbox exactly
70   # the same as the node we are looking at
71   def test_map_inclusive
72     node = create(:node, :lat => 7, :lon => 7)
73     tag = create(:node_tag, :node => node)
74     way1 = create(:way_node, :node => node).way
75     way2 = create(:way_node, :node => node).way
76     relation = create(:relation_member, :member => node).relation
77
78     bbox = "#{node.lon},#{node.lat},#{node.lon},#{node.lat}"
79     get :map, :params => { :bbox => bbox }
80     assert_response :success, "The map call should have succeeded"
81     assert_select "osm[version='#{API_VERSION}'][generator='#{GENERATOR}']", :count => 1 do
82       assert_select "bounds[minlon='#{node.lon}'][minlat='#{node.lat}'][maxlon='#{node.lon}'][maxlat='#{node.lat}']", :count => 1
83       assert_select "node[id='#{node.id}'][lat='#{format('%.7f', node.lat)}'][lon='#{format('%.7f', node.lon)}'][version='#{node.version}'][changeset='#{node.changeset_id}'][visible='#{node.visible}'][timestamp='#{node.timestamp.xmlschema}']", :count => 1 do
84         # This should really be more generic
85         assert_select "tag[k='#{tag.k}'][v='#{tag.v}']"
86       end
87       assert_select "way", :count => 2
88       assert_select "way[id='#{way1.id}']", :count => 1
89       assert_select "way[id='#{way2.id}']", :count => 1
90       assert_select "relation", :count => 1
91       assert_select "relation[id='#{relation.id}']", :count => 1
92     end
93   end
94
95   def test_map_complete_way
96     node = create(:node, :lat => 7, :lon => 7)
97     # create a couple of nodes well outside of the bbox
98     node2 = create(:node, :lat => 45, :lon => 45)
99     node3 = create(:node, :lat => 10, :lon => 10)
100     way1 = create(:way_node, :node => node).way
101     create(:way_node, :way => way1, :node => node2, :sequence_id => 2)
102     way2 = create(:way_node, :node => node).way
103     create(:way_node, :way => way2, :node => node3, :sequence_id => 2)
104     relation = create(:relation_member, :member => way1).relation
105
106     bbox = "#{node.lon},#{node.lat},#{node.lon},#{node.lat}"
107     get :map, :params => { :bbox => bbox }
108     assert_response :success, "The map call should have succeeded"
109     assert_select "osm[version='#{API_VERSION}'][generator='#{GENERATOR}']", :count => 1 do
110       assert_select "bounds[minlon='#{node.lon}'][minlat='#{node.lat}'][maxlon='#{node.lon}'][maxlat='#{node.lat}']", :count => 1
111       assert_select "node", :count => 3
112       assert_select "node[id='#{node.id}']", :count => 1
113       assert_select "node[id='#{node2.id}']", :count => 1
114       assert_select "node[id='#{node3.id}']", :count => 1
115       assert_select "way", :count => 2
116       assert_select "way[id='#{way1.id}']", :count => 1
117       assert_select "way[id='#{way2.id}']", :count => 1
118       assert_select "relation", :count => 1
119       assert_select "relation[id='#{relation.id}']", :count => 1
120     end
121   end
122
123   def test_map_empty
124     get :map, :params => { :bbox => "179.998,89.998,179.999.1,89.999" }
125     assert_response :success, "The map call should have succeeded"
126     assert_select "osm[version='#{API_VERSION}'][generator='#{GENERATOR}']", :count => 1 do
127       assert_select "bounds[minlon='179.9980000'][minlat='89.9980000'][maxlon='179.9990000'][maxlat='89.9990000']", :count => 1
128       assert_select "node", :count => 0
129       assert_select "way", :count => 0
130       assert_select "relation", :count => 0
131     end
132   end
133
134   def test_map_without_bbox
135     get :map
136     assert_response :bad_request
137     assert_equal "The parameter bbox is required, and must be of the form min_lon,min_lat,max_lon,max_lat", @response.body, "A bbox param was expected"
138   end
139
140   def test_bbox_too_big
141     @badbigbbox.each do |bbox|
142       get :map, :params => { :bbox => bbox }
143       assert_response :bad_request, "The bbox:#{bbox} was expected to be too big"
144       assert_equal "The maximum bbox size is #{MAX_REQUEST_AREA}, and your request was too large. Either request a smaller area, or use planet.osm", @response.body, "bbox: #{bbox}"
145     end
146   end
147
148   def test_bbox_malformed
149     @badmalformedbbox.each do |bbox|
150       get :map, :params => { :bbox => bbox }
151       assert_response :bad_request, "The bbox:#{bbox} was expected to be malformed"
152       assert_equal "The parameter bbox is required, and must be of the form min_lon,min_lat,max_lon,max_lat", @response.body, "bbox: #{bbox}"
153     end
154   end
155
156   def test_bbox_lon_mixedup
157     @badlonmixedbbox.each do |bbox|
158       get :map, :params => { :bbox => bbox }
159       assert_response :bad_request, "The bbox:#{bbox} was expected to have the longitude mixed up"
160       assert_equal "The minimum longitude must be less than the maximum longitude, but it wasn't", @response.body, "bbox: #{bbox}"
161     end
162   end
163
164   def test_bbox_lat_mixedup
165     @badlatmixedbbox.each do |bbox|
166       get :map, :params => { :bbox => bbox }
167       assert_response :bad_request, "The bbox:#{bbox} was expected to have the latitude mixed up"
168       assert_equal "The minimum latitude must be less than the maximum latitude, but it wasn't", @response.body, "bbox: #{bbox}"
169     end
170   end
171
172   # We can't actually get an out of bounds error, as the bbox is sanitised.
173   # def test_latlon_outofbounds
174   #  @badlatlonoutboundsbbox.each do |bbox|
175   #    [ "trackpoints", "map" ].each do |tq|
176   #      get tq, :bbox => bbox
177   #      #print @request.to_yaml
178   #      assert_response :bad_request, "The bbox #{bbox} was expected to be out of range"
179   #      assert_equal "The latitudes must be between -90 an 90, and longitudes between -180 and 180", @response.body, "bbox: #{bbox}"
180   #    end
181   #  end
182   # end
183
184   # MySQL and Postgres require that the C based functions are installed for
185   # this test to work. More information is available from:
186   # http://wiki.openstreetmap.org/wiki/Rails#Installing_the_quadtile_functions
187   # or by looking at the readme in db/README
188   def test_changes_simple
189     # create a selection of nodes
190     (1..5).each do |n|
191       create(:node, :timestamp => Time.utc(2007, 1, 1, 0, 0, 0), :lat => n, :lon => n)
192     end
193     # deleted nodes should also be counted
194     create(:node, :deleted, :timestamp => Time.utc(2007, 1, 1, 0, 0, 0), :lat => 6, :lon => 6)
195     # nodes in the same tile won't change the total
196     create(:node, :timestamp => Time.utc(2007, 1, 1, 0, 0, 0), :lat => 6, :lon => 6)
197     # nodes with a different timestamp should be ignored
198     create(:node, :timestamp => Time.utc(2008, 1, 1, 0, 0, 0), :lat => 7, :lon => 7)
199
200     travel_to Time.utc(2010, 4, 3, 10, 55, 0) do
201       get :changes
202       assert_response :success
203       now = Time.now.getutc
204       hourago = now - 1.hour
205       assert_select "osm[version='#{API_VERSION}'][generator='#{GENERATOR}']", :count => 1 do
206         assert_select "changes[starttime='#{hourago.xmlschema}'][endtime='#{now.xmlschema}']", :count => 1 do
207           assert_select "tile", :count => 0
208         end
209       end
210     end
211
212     travel_to Time.utc(2007, 1, 1, 0, 30, 0) do
213       get :changes
214       assert_response :success
215       # print @response.body
216       # As we have loaded the fixtures, we can assume that there are some
217       # changes at the time we have frozen at
218       now = Time.now.getutc
219       hourago = now - 1.hour
220       assert_select "osm[version='#{API_VERSION}'][generator='#{GENERATOR}']", :count => 1 do
221         assert_select "changes[starttime='#{hourago.xmlschema}'][endtime='#{now.xmlschema}']", :count => 1 do
222           assert_select "tile", :count => 6
223         end
224       end
225     end
226   end
227
228   def test_changes_zoom_invalid
229     zoom_to_test = %w[p -1 0 17 one two]
230     zoom_to_test.each do |zoom|
231       get :changes, :params => { :zoom => zoom }
232       assert_response :bad_request
233       assert_equal @response.body, "Requested zoom is invalid, or the supplied start is after the end time, or the start duration is more than 24 hours"
234     end
235   end
236
237   def test_changes_zoom_valid
238     1.upto(16) do |zoom|
239       get :changes, :params => { :zoom => zoom }
240       assert_response :success
241       # NOTE: there was a test here for the timing, but it was too sensitive to be a good test
242       # and it was annoying.
243       assert_select "osm[version='#{API_VERSION}'][generator='#{GENERATOR}']", :count => 1 do
244         assert_select "changes", :count => 1
245       end
246     end
247   end
248
249   def test_changes_hours_invalid
250     invalid = %w[-21 335 -1 0 25 26 100 one two three ping pong :]
251     invalid.each do |hour|
252       get :changes, :params => { :hours => hour }
253       assert_response :bad_request, "Problem with the hour: #{hour}"
254       assert_equal @response.body, "Requested zoom is invalid, or the supplied start is after the end time, or the start duration is more than 24 hours", "Problem with the hour: #{hour}."
255     end
256   end
257
258   def test_changes_hours_valid
259     1.upto(24) do |hour|
260       get :changes, :params => { :hours => hour }
261       assert_response :success
262     end
263   end
264
265   def test_changes_start_end_invalid
266     get :changes, :params => { :start => "2010-04-03 10:55:00", :end => "2010-04-03 09:55:00" }
267     assert_response :bad_request
268     assert_equal @response.body, "Requested zoom is invalid, or the supplied start is after the end time, or the start duration is more than 24 hours"
269   end
270
271   def test_changes_start_end_valid
272     get :changes, :params => { :start => "2010-04-03 09:55:00", :end => "2010-04-03 10:55:00" }
273     assert_response :success
274   end
275 end