d5b1163e1795eab75b35ec61c462b437b8de8aa5
[rails.git] / test / functional / api_controller_test.rb
1 require File.dirname(__FILE__) + '/../test_helper'
2 require 'api_controller'
3
4 class ApiControllerTest < ActionController::TestCase
5   api_fixtures
6   
7   def setup
8     super
9     @badbigbbox = %w{ -0.1,-0.1,1.1,1.1  10,10,11,11 }
10     @badmalformedbbox = %w{ -0.1  hello 
11     10N2W10.1N2.1W }
12     @badlatmixedbbox = %w{ 0,0.1,0.1,0  -0.1,80,0.1,70  0.24,54.34,0.25,54.33 }
13     @badlonmixedbbox = %w{ 80,-0.1,70,0.1  54.34,0.24,54.33,0.25 }  
14     #@badlatlonoutboundsbbox = %w{ 191,-0.1,193,0.1  -190.1,89.9,-190,90 }
15     @goodbbox = %w{ -0.1,-0.1,0.1,0.1  51.1,-0.1,51.2,0 
16     -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}
17     # That last item in the goodbbox really shouldn't be there, as the API should
18     # reall reject it, however this is to test to see if the api changes.
19   end
20
21   # -------------------------------------
22   # Test reading a bounding box.
23   # -------------------------------------
24
25   def test_map
26     node = current_nodes(:used_node_1)
27     # Need to split the min/max lat/lon out into their own variables here
28     # so that we can test they are returned later.
29     minlon = node.lon-0.1
30     minlat = node.lat-0.1
31     maxlon = node.lon+0.1
32     maxlat = node.lat+0.1
33     bbox = "#{minlon},#{minlat},#{maxlon},#{maxlat}"
34     get :map, :bbox => bbox
35     if $VERBOSE
36       print @request.to_yaml
37       print @response.body
38     end
39     assert_response :success, "Expected scucess with the map call"
40     assert_select "osm[version='#{API_VERSION}'][generator='#{GENERATOR}']:root", :count => 1 do
41       assert_select "bounds[minlon=#{minlon}][minlat=#{minlat}][maxlon=#{maxlon}][maxlat=#{maxlat}]", :count => 1
42       assert_select "node[id=#{node.id}][lat=#{node.lat}][lon=#{node.lon}][version=#{node.version}][changeset=#{node.changeset_id}][visible=#{node.visible}][timestamp=#{node.timestamp.xmlschema}]", :count => 1 do
43         # This should really be more generic
44         assert_select "tag[k='test'][v='yes']"
45       end
46       # Should also test for the ways and relation
47     end
48   end
49   
50   # This differs from the above test in that we are making the bbox exactly
51   # the same as the node we are looking at
52   def test_map_inclusive
53     node = current_nodes(:used_node_1)
54     bbox = "#{node.lon},#{node.lat},#{node.lon},#{node.lat}"
55     get :map, :bbox => bbox
56     assert_response :success, "The map call should have succeeded"
57     assert_select "osm[version='#{API_VERSION}'][generator='#{GENERATOR}']:root", :count => 1 do
58       assert_select "bounds[minlon=#{node.lon}][minlat=#{node.lat}][maxlon=#{node.lon}][maxlat=#{node.lat}]", :count => 1
59       assert_select "node[id=#{node.id}][lat=#{node.lat}][lon=#{node.lon}][version=#{node.version}][changeset=#{node.changeset_id}][visible=#{node.visible}][timestamp=#{node.timestamp.xmlschema}]", :count => 1 do
60         # This should really be more generic
61         assert_select "tag[k='test'][v='yes']"
62       end
63       # Should also test for the ways and relation
64     end
65   end
66   
67   def test_tracepoints
68     point = gpx_files(:public_trace_file)
69     minlon = point.longitude-0.001
70     minlat = point.latitude-0.001
71     maxlon = point.longitude+0.001
72     maxlat = point.latitude+0.001
73     bbox = "#{minlon},#{minlat},#{maxlon},#{maxlat}"
74     get :trackpoints, :bbox => bbox
75     assert_response :success
76     assert_select "gpx[version=1.0][creator=OpenStreetMap.org][xmlns=http://www.topografix.com/GPX/1/0]:root", :count => 1 do
77       assert_select "trk" do
78         assert_select "trkseg"
79       end
80     end
81   end
82   
83   def test_tracepoints_trackable
84     point = gpx_files(:trackable_trace_file)
85     minlon = point.longitude-0.002
86     minlat = point.latitude-0.002
87     maxlon = point.longitude+0.002
88     maxlat = point.latitude+0.002
89     bbox = "#{minlon},#{minlat},#{maxlon},#{maxlat}"
90     get :trackpoints, :bbox => bbox
91     assert_response :success
92     assert_select "gpx[version=1.0][creator=OpenStreetMap.org][xmlns=http://www.topografix.com/GPX/1/0]:root", :count => 1 do
93       assert_select "trk", :count => 1 do
94         assert_select "trk > trkseg", :count => 2 do |trksegs|
95           trksegs.each do |trkseg|
96             assert_select trkseg, "trkpt", :count => 1 do |trkpt|
97               assert_select trkpt[0], "time", :count => 1
98             end
99           end
100         end
101       end
102     end
103   end
104   
105   def test_tracepoints_identifiable
106     point = gpx_files(:identifiable_trace_file)
107     minlon = point.longitude-0.002
108     minlat = point.latitude-0.002
109     maxlon = point.longitude+0.002
110     maxlat = point.latitude+0.002
111     bbox = "#{minlon},#{minlat},#{maxlon},#{maxlat}"
112     get :trackpoints, :bbox => bbox
113     assert_response :success
114     assert_select "gpx[version=1.0][creator=OpenStreetMap.org][xmlns=http://www.topografix.com/GPX/1/0]:root", :count => 1 do
115       assert_select "trk", :count => 1 do
116         assert_select "trk>name", :count => 1
117         assert_select "trk>desc", :count => 1
118         assert_select "trk>url", :count => 1
119         assert_select "trkseg", :count => 1 do
120           assert_select "trkpt", :count => 1 do
121             assert_select "time", :count => 1
122           end
123         end
124       end
125     end
126   end
127   
128   def test_map_without_bbox
129     ["trackpoints", "map"].each do |tq|
130       get tq
131       assert_response :bad_request
132       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"
133     end
134   end
135   
136   def test_traces_page_less_than_0
137     -10.upto(-1) do |i|
138       get :trackpoints, :page => i, :bbox => "-0.1,-0.1,0.1,0.1"
139       assert_response :bad_request
140       assert_equal "Page number must be greater than or equal to 0", @response.body, "The page number was #{i}"
141     end
142     0.upto(10) do |i|
143       get :trackpoints, :page => i, :bbox => "-0.1,-0.1,0.1,0.1"
144       assert_response :success, "The page number was #{i} and should have been accepted"
145     end
146   end
147   
148   def test_bbox_too_big
149     @badbigbbox.each do |bbox|
150       [ "trackpoints", "map" ].each do |tq|
151         get tq, :bbox => bbox
152         assert_response :bad_request, "The bbox:#{bbox} was expected to be too big"
153         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}"
154       end
155     end
156   end
157   
158   def test_bbox_malformed
159     @badmalformedbbox.each do |bbox|
160       [ "trackpoints", "map" ].each do |tq|
161         get tq, :bbox => bbox
162         assert_response :bad_request, "The bbox:#{bbox} was expected to be malformed"
163         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}"
164       end
165     end
166   end
167   
168   def test_bbox_lon_mixedup
169     @badlonmixedbbox.each do |bbox|
170       [ "trackpoints", "map" ].each do |tq|
171         get tq, :bbox => bbox
172         assert_response :bad_request, "The bbox:#{bbox} was expected to have the longitude mixed up"
173         assert_equal "The minimum longitude must be less than the maximum longitude, but it wasn't", @response.body, "bbox: #{bbox}"
174       end
175     end
176   end
177   
178   def test_bbox_lat_mixedup
179     @badlatmixedbbox.each do |bbox|
180       ["trackpoints", "map"].each do |tq|
181         get tq, :bbox => bbox
182         assert_response :bad_request, "The bbox:#{bbox} was expected to have the latitude mixed up"
183         assert_equal "The minimum latitude must be less than the maximum latitude, but it wasn't", @response.body, "bbox: #{bbox}"
184       end
185     end
186   end
187   
188   # We can't actually get an out of bounds error, as the bbox is sanitised.
189   #def test_latlon_outofbounds
190   #  @badlatlonoutboundsbbox.each do |bbox|
191   #    [ "trackpoints", "map" ].each do |tq|
192   #      get tq, :bbox => bbox
193   #      #print @request.to_yaml
194   #      assert_response :bad_request, "The bbox #{bbox} was expected to be out of range"
195   #      assert_equal "The latitudes must be between -90 an 90, and longitudes between -180 and 180", @response.body, "bbox: #{bbox}"
196   #    end
197   #  end
198   #end
199   
200   # MySQL and Postgres require that the C based functions are installed for 
201   # this test to work. More information is available from:
202   # http://wiki.openstreetmap.org/wiki/Rails#Installing_the_quadtile_functions
203   # or by looking at the readme in db/README
204   def test_changes_simple
205     Timecop.freeze(Time.parse('2010-04-03 10:55:00'))
206     get :changes
207     assert_response :success
208     #print @response.body
209     # As we have loaded the fixtures, we can assume that there are no 
210     # changes at the time we have frozen at
211     now = Time.now.getutc
212     hourago = now - 1.hour
213     assert_select "osm[version='#{API_VERSION}'][generator='#{GENERATOR}']:root", :count => 1 do
214       assert_select "changes[starttime='#{hourago.xmlschema}'][endtime='#{now.xmlschema}']", :count => 1
215     end
216     Timecop.return
217   end
218   
219   def test_changes_zoom_invalid
220     zoom_to_test = %w{ p -1 0 17 one two }
221     zoom_to_test.each do |zoom|
222       get :changes, :zoom => zoom
223       assert_response :bad_request
224       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"
225     end
226   end
227   
228   def test_changes_zoom_valid
229     1.upto(16) do |zoom|
230       get :changes, :zoom => zoom
231       assert_response :success
232       # NOTE: there was a test here for the timing, but it was too sensitive to be a good test
233       # and it was annoying.
234       assert_select "osm[version='#{API_VERSION}'][generator='#{GENERATOR}']:root", :count => 1 do
235         assert_select "changes", :count => 1
236       end
237     end
238   end
239   
240   def test_start_end_time_invalid
241     
242   end
243   
244   def test_start_end_time_invalid
245     
246   end
247   
248   def test_hours_invalid
249     invalid = %w{ -21 335 -1 0 25 26 100 one two three ping pong : }
250     invalid.each do |hour|
251       get :changes, :hours => hour
252       assert_response :bad_request, "Problem with the hour: #{hour}"
253       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}."
254     end
255   end
256   
257   def test_hours_valid
258     1.upto(24) do |hour|
259       get :changes, :hours => hour
260       assert_response :success
261     end
262   end
263   
264   def test_capabilities
265     get :capabilities
266     assert_response :success
267     assert_select "osm:root[version='#{API_VERSION}'][generator='#{GENERATOR}']", :count => 1 do
268       assert_select "api", :count => 1 do
269         assert_select "version[minimum=#{API_VERSION}][maximum=#{API_VERSION}]", :count => 1
270         assert_select "area[maximum=#{MAX_REQUEST_AREA}]", :count => 1
271         assert_select "tracepoints[per_page=#{TRACEPOINTS_PER_PAGE}]", :count => 1
272         assert_select "changesets[maximum_elements=#{Changeset::MAX_ELEMENTS}]", :count => 1
273       end
274     end
275   end
276 end