]> git.openstreetmap.org Git - rails.git/blob - test/javascripts/osm_test.js
Add PWA geo protocol handler
[rails.git] / test / javascripts / osm_test.js
1 //= require jquery
2 //= require js-cookie/dist/js.cookie
3 //= require osm
4 //= require leaflet/dist/leaflet-src
5 //= require leaflet.osm
6 //= require leaflet.map
7
8 describe("OSM", function () {
9   describe(".apiUrl", function () {
10     it("returns a URL for a way", function () {
11       expect(OSM.apiUrl({ type: "way", id: 10 })).to.eq("/api/0.6/way/10/full");
12     });
13
14     it("returns a URL for a node", function () {
15       expect(OSM.apiUrl({ type: "node", id: 10 })).to.eq("/api/0.6/node/10");
16     });
17
18     it("returns a URL for a specific version", function () {
19       expect(OSM.apiUrl({ type: "node", id: 10, version: 2 })).to.eq("/api/0.6/node/10/2");
20     });
21   });
22
23   describe(".mapParams", function () {
24     beforeEach(function () {
25       delete OSM.home;
26       delete OSM.location;
27       location.hash = "";
28       document.cookie = "_osm_location=; expires=Thu, 01 Jan 1970 00:00:00 GMT";
29
30       // Test with another cookie set.
31       document.cookie = "_osm_session=deadbeef";
32     });
33
34     it("parses marker params", function () {
35       const params = OSM.mapParams("?mlat=57.6247&mlon=-3.6845");
36       expect(params).to.have.property("mlat", 57.6247);
37       expect(params).to.have.property("mlon", -3.6845);
38       expect(params).to.have.property("marker", true);
39     });
40
41     it("parses object params", function () {
42       let params = OSM.mapParams("?node=1");
43       expect(params).to.have.property("object");
44       expect(params.object).to.eql({ type: "node", id: 1 });
45
46       params = OSM.mapParams("?way=1");
47       expect(params).to.have.property("object");
48       expect(params.object).to.eql({ type: "way", id: 1 });
49
50       params = OSM.mapParams("?relation=1");
51       expect(params).to.have.property("object");
52       expect(params.object).to.eql({ type: "relation", id: 1 });
53     });
54
55     it("parses bbox params", function () {
56       const expected = L.latLngBounds([57.6247, -3.6845], [57.7247, -3.7845]);
57       let params = OSM.mapParams("?bbox=-3.6845,57.6247,-3.7845,57.7247");
58       expect(params).to.have.property("bounds").deep.equal(expected);
59
60       params = OSM.mapParams("?minlon=-3.6845&minlat=57.6247&maxlon=-3.7845&maxlat=57.7247");
61       expect(params).to.have.property("bounds").deep.equal(expected);
62     });
63
64     it("parses mlat/mlon/zoom params", function () {
65       let params = OSM.mapParams("?mlat=57.6247&mlon=-3.6845");
66       expect(params).to.have.property("lat", 57.6247);
67       expect(params).to.have.property("lon", -3.6845);
68       expect(params).to.have.property("zoom", 12);
69
70       params = OSM.mapParams("?mlat=57.6247&mlon=-3.6845&zoom=16");
71       expect(params).to.have.property("lat", 57.6247);
72       expect(params).to.have.property("lon", -3.6845);
73       expect(params).to.have.property("zoom", 16);
74     });
75
76     it("parses geoURIs", function () {
77       const params = OSM.mapParams("?geouri=geo%3A57.6247%2C-3.6845");
78       expect(params).to.have.property("lat", 57.6247);
79       expect(params).to.have.property("lon", -3.6845);
80       expect(params).to.have.property("mlat", 57.6247);
81       expect(params).to.have.property("mlon", -3.6845);
82       expect(params).to.have.property("zoom", 12);
83     });
84
85     it("parses zoom in geoURIs", function () {
86       const params = OSM.mapParams("?geouri=geo%3A57.6247%2C-3.6845%3Fz%3D16");
87       expect(params).to.have.property("lat", 57.6247);
88       expect(params).to.have.property("lon", -3.6845);
89       expect(params).to.have.property("mlat", 57.6247);
90       expect(params).to.have.property("mlon", -3.6845);
91       expect(params).to.have.property("zoom", 16);
92     });
93
94     it("parses uncertainty in geoURIs", function () {
95       const params = OSM.mapParams("?geouri=geo%3A57.6247%2C-3.6845%3Bu%3D100");
96       const expected = L.latLngBounds([57.62290336944585, -3.6878552857327764], [57.62649663055414, -3.6811447142672233]);
97       expect(params).to.have.property("mlat", 57.6247);
98       expect(params).to.have.property("mlon", -3.6845);
99       expect(params).to.have.property("mrad", 100);
100       expect(params).to.have.property("bounds").deep.equal(expected);
101     });
102
103     it("parses lat/lon/zoom from the hash", function () {
104       location.hash = "#map=16/57.6247/-3.6845";
105       const params = OSM.mapParams("?");
106       expect(params).to.have.property("lat", 57.6247);
107       expect(params).to.have.property("lon", -3.6845);
108       expect(params).to.have.property("zoom", 16);
109     });
110
111     it("sets lat/lon from OSM.home", function () {
112       OSM.home = { lat: 57.6247, lon: -3.6845 };
113       const params = OSM.mapParams("?");
114       expect(params).to.have.property("lat", 57.6247);
115       expect(params).to.have.property("lon", -3.6845);
116     });
117
118     it("sets bbox from OSM.location", function () {
119       OSM.location = { minlon: -3.6845, minlat: 57.6247, maxlon: -3.7845, maxlat: 57.7247 };
120       const expected = L.latLngBounds([57.6247, -3.6845], [57.7247, -3.7845]);
121       const params = OSM.mapParams("?");
122       expect(params).to.have.property("bounds").deep.equal(expected);
123     });
124
125     it("parses params from the _osm_location cookie", function () {
126       document.cookie = "_osm_location=-3.6845|57.6247|5|M";
127       const params = OSM.mapParams("?");
128       expect(params).to.have.property("lat", 57.6247);
129       expect(params).to.have.property("lon", -3.6845);
130       expect(params).to.have.property("zoom", 5);
131       expect(params).to.have.property("layers", "M");
132     });
133
134     it("defaults lat/lon to London", function () {
135       let params = OSM.mapParams("?");
136       expect(params).to.have.property("lat", 51.5);
137       expect(params).to.have.property("lon", -0.1);
138       expect(params).to.have.property("zoom", 5);
139
140       params = OSM.mapParams("?zoom=10");
141       expect(params).to.have.property("lat", 51.5);
142       expect(params).to.have.property("lon", -0.1);
143       expect(params).to.have.property("zoom", 10);
144     });
145
146     it("parses layers param", function () {
147       let params = OSM.mapParams("?");
148       expect(params).to.have.property("layers", "");
149
150       document.cookie = "_osm_location=-3.6845|57.6247|5|C";
151       params = OSM.mapParams("?");
152       expect(params).to.have.property("layers", "C");
153
154       location.hash = "#map=5/57.6247/-3.6845&layers=M";
155       params = OSM.mapParams("?");
156       expect(params).to.have.property("layers", "M");
157     });
158   });
159
160   describe(".parseGeoURI", function () {
161     it("parses basic geoURIs", function () {
162       let params = OSM.parseGeoURI("geo:57.6247,-3.6845");
163       expect(params.coords).to.deep.equal(L.latLng(57.6247, -3.6845));
164       expect(params.zoom).to.be.undefined;
165       expect(params.uncertainty).to.be.undefined;
166       params = OSM.parseGeoURI("GEO:57.6247,-3.6845");
167       expect(params.coords).to.deep.equal(L.latLng(57.6247, -3.6845));
168     });
169     it("parses only geoURIs", function () {
170       let params = OSM.parseGeoURI("latlng:57.6247,-3.6845");
171       expect(params).to.be.undefined;
172       params = OSM.parseGeoURI("geo57.6247,-3.6845");
173       expect(params).to.be.undefined;
174     });
175     it("rejects geoURIs with less than 2 coordinates", function () {
176       const params = OSM.parseGeoURI("geo:57.6247");
177       expect(params).to.be.undefined;
178     });
179     it("parses geoURIs with altitude", function () {
180       const params = OSM.parseGeoURI("geo:57.6247,-3.6845,100");
181       expect(params.coords).to.deep.equal(L.latLng(57.6247, -3.6845, 100));
182     });
183     it("rejects geoURIs with more than 3 coordinates", function () {
184       const params = OSM.parseGeoURI("geo:123,57.6247,-3.6845,100");
185       expect(params).to.be.undefined;
186     });
187     it("ignores non-numeric coordinates", function () {
188       let params = OSM.parseGeoURI("geo:57.6247,-3.6845,abc");
189       expect(params.coords.lat).to.equal(57.6247);
190       expect(params.coords.lng).to.equal(-3.6845);
191       expect(isNaN(params.coords.alt)).to.be.true;
192       params = OSM.parseGeoURI("geo:57.6247,abc");
193       expect(params).to.be.undefined;
194     });
195     it("parses geoURIs with crs", function () {
196       let params = OSM.parseGeoURI("geo:57.6247,-3.6845;crs=wgs84");
197       expect(params.coords).to.deep.equal(L.latLng(57.6247, -3.6845));
198       params = OSM.parseGeoURI("geo:57.6247,-3.6845;CRS=wgs84");
199       expect(params.coords).to.deep.equal(L.latLng(57.6247, -3.6845));
200       params = OSM.parseGeoURI("geo:57.6247,-3.6845;CRS=WGS84");
201       expect(params.coords).to.deep.equal(L.latLng(57.6247, -3.6845));
202     });
203     it("rejects geoURIs with different crs", function () {
204       const params = OSM.parseGeoURI("geo:57.6247,-3.6845;crs=utm");
205       expect(params).to.be.undefined;
206     });
207     it("parses geoURIs with uncertainty", function () {
208       let params = OSM.parseGeoURI("geo:57.6247,-3.6845;u=100");
209       expect(params.uncertainty).to.equal(100);
210       params = OSM.parseGeoURI("geo:57.6247,-3.6845;U=100");
211       expect(params.uncertainty).to.equal(100);
212     });
213     it("ignores negative uncertainty", function () {
214       const params = OSM.parseGeoURI("geo:57.6247,-3.6845;u=-100");
215       expect(params.uncertainty).to.be.undefined;
216     });
217     it("ignores non-numeric uncertainty", function () {
218       const params = OSM.parseGeoURI("geo:57.6247,-3.6845;u=abc");
219       expect(params.uncertainty).to.be.undefined;
220     });
221     it("parses uncertainty 0", function () {
222       const params = OSM.parseGeoURI("geo:57.6247,-3.6845;u=0");
223       expect(params.uncertainty).to.equal(0);
224     });
225     it("ignores uncertainty in the query parameters", function () {
226       const params = OSM.parseGeoURI("geo:57.6247,-3.6845?u=100");
227       expect(params.uncertainty).to.be.undefined;
228     });
229     it("parses geoURIs with zoom", function () {
230       let params = OSM.parseGeoURI("geo:57.6247,-3.6845?z=16");
231       expect(params.zoom).to.equal(16);
232       params = OSM.parseGeoURI("geo:57.6247,-3.6845?Z=16");
233       expect(params.zoom).to.be.undefined;
234     });
235     it("ignores non-numeric zoom", function () {
236       const params = OSM.parseGeoURI("geo:57.6247,-3.6845?z=abc");
237       expect(params.zoom).to.be.undefined;
238     });
239     it("ignores negative zoom", function () {
240       const params = OSM.parseGeoURI("geo:57.6247,-3.6845?z=-100");
241       expect(params.zoom).to.be.undefined;
242     });
243     it("parses geoURIs with zoom level 0", function () {
244       const params = OSM.parseGeoURI("geo:57.6247,-3.6845?z=0");
245       expect(params.zoom).to.equal(0);
246     });
247     it("ignores zoom in the geouri parameters", function () {
248       const params = OSM.parseGeoURI("geo:57.6247,-3.6845;z=16");
249       expect(params.zoom).to.be.undefined;
250     });
251   });
252
253   describe(".parseHash", function () {
254     it("parses lat/lon/zoom params", function () {
255       const args = OSM.parseHash("#map=5/57.6247/-3.6845&layers=M");
256       expect(args).to.have.property("center").deep.equal(L.latLng(57.6247, -3.6845));
257       expect(args).to.have.property("zoom", 5);
258     });
259
260     it("parses layers params", function () {
261       const args = OSM.parseHash("#map=5/57.6247/-3.6845&layers=M");
262       expect(args).to.have.property("layers", "M");
263     });
264   });
265
266   describe(".formatHash", function () {
267     it("formats lat/lon/zoom params", function () {
268       const args = { center: L.latLng(57.6247, -3.6845), zoom: 9 };
269       expect(OSM.formatHash(args)).to.eq("#map=9/57.625/-3.685");
270     });
271
272     it("respects zoomPrecision", function () {
273       let args = { center: L.latLng(57.6247, -3.6845), zoom: 5 };
274       expect(OSM.formatHash(args)).to.eq("#map=5/57.62/-3.68");
275
276
277       args = { center: L.latLng(57.6247, -3.6845), zoom: 9 };
278       expect(OSM.formatHash(args)).to.eq("#map=9/57.625/-3.685");
279
280
281       args = { center: L.latLng(57.6247, -3.6845), zoom: 12 };
282       expect(OSM.formatHash(args)).to.eq("#map=12/57.6247/-3.6845");
283     });
284
285     it("formats layers params", function () {
286       const args = { center: L.latLng(57.6247, -3.6845), zoom: 9, layers: "C" };
287       expect(OSM.formatHash(args)).to.eq("#map=9/57.625/-3.685&layers=C");
288     });
289
290     it("ignores default layers", function () {
291       const args = { center: L.latLng(57.6247, -3.6845), zoom: 9, layers: "M" };
292       expect(OSM.formatHash(args)).to.eq("#map=9/57.625/-3.685");
293     });
294   });
295
296
297   describe(".zoomPrecision", function () {
298     it("suggests 1 digit for z0-2", function () {
299       expect(OSM.zoomPrecision(0)).to.eq(1);
300       expect(OSM.zoomPrecision(1)).to.eq(1);
301       expect(OSM.zoomPrecision(2)).to.eq(1);
302     });
303
304     it("suggests 2 digits for z3-6", function () {
305       expect(OSM.zoomPrecision(3)).to.eq(2);
306       expect(OSM.zoomPrecision(4)).to.eq(2);
307       expect(OSM.zoomPrecision(5)).to.eq(2);
308       expect(OSM.zoomPrecision(6)).to.eq(2);
309     });
310
311     it("suggests 3 digits for z7-9", function () {
312       expect(OSM.zoomPrecision(7)).to.eq(3);
313       expect(OSM.zoomPrecision(8)).to.eq(3);
314       expect(OSM.zoomPrecision(9)).to.eq(3);
315     });
316
317     it("suggests 4 digits for z10-12", function () {
318       expect(OSM.zoomPrecision(10)).to.eq(4);
319       expect(OSM.zoomPrecision(11)).to.eq(4);
320       expect(OSM.zoomPrecision(12)).to.eq(4);
321     });
322
323     it("suggests 5 digits for z13-16", function () {
324       expect(OSM.zoomPrecision(13)).to.eq(5);
325       expect(OSM.zoomPrecision(14)).to.eq(5);
326       expect(OSM.zoomPrecision(15)).to.eq(5);
327       expect(OSM.zoomPrecision(16)).to.eq(5);
328     });
329
330     it("suggests 6 digits for z17-19", function () {
331       expect(OSM.zoomPrecision(17)).to.eq(6);
332       expect(OSM.zoomPrecision(18)).to.eq(6);
333       expect(OSM.zoomPrecision(19)).to.eq(6);
334     });
335
336     it("suggests 7 digits for z20", function () {
337       expect(OSM.zoomPrecision(20)).to.eq(7);
338     });
339   });
340
341   describe(".locationCookie", function () {
342     it("creates a location cookie value", function () {
343       $("body").append("<div id='map'>");
344       const map = new L.OSM.Map("map", { center: [57.6247, -3.6845], zoom: 9 });
345       map.updateLayers("");
346       expect(OSM.locationCookie(map)).to.eq("-3.685|57.625|9|M");
347       $("#map").remove();
348     });
349
350     it("respects zoomPrecision", function () {
351       $("body").append("<div id='map'>");
352       const map = new L.OSM.Map("map", { center: [57.6247, -3.6845], zoom: 9 });
353       map.updateLayers("");
354       expect(OSM.locationCookie(map)).to.eq("-3.685|57.625|9|M");
355       // map.setZoom() doesn't update the zoom level for some reason
356       // using map._zoom here to update the zoom level manually
357       map._zoom = 5;
358       expect(OSM.locationCookie(map)).to.eq("-3.68|57.62|5|M");
359       $("#map").remove();
360     });
361   });
362
363   describe(".distance", function () {
364     it("computes distance between points", function () {
365       const latlng1 = L.latLng(51.76712, -0.00484),
366             latlng2 = L.latLng(51.7675159, -0.0078329);
367
368       expect(OSM.distance(latlng1, latlng2)).to.be.closeTo(210.664, 0.005);
369       expect(OSM.distance(latlng2, latlng1)).to.be.closeTo(210.664, 0.005);
370     });
371   });
372 });