@panoramax/web-viewer 4.0.1 → 4.0.2-develop-9d664bb8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +31 -3
- package/build/index.css +1 -1
- package/build/index.css.map +1 -1
- package/build/index.js +150 -51
- package/build/index.js.map +1 -1
- package/config/jest/mocks.js +2 -1
- package/docs/03_URL_settings.md +1 -1
- package/docs/09_Develop.md +5 -1
- package/docs/reference/components/core/Viewer.md +1 -1
- package/docs/reference/components/ui/CopyButton.md +1 -0
- package/docs/reference/components/ui/Map.md +13 -0
- package/docs/reference/components/ui/MapMore.md +13 -0
- package/docs/reference/components/ui/Photo.md +1 -1
- package/docs/reference/components/ui/widgets/CopyCoordinates.md +32 -0
- package/docs/reference/components/ui/widgets/GeoSearch.md +5 -1
- package/docs/reference/utils/API.md +1 -1
- package/docs/reference.md +1 -0
- package/docs/tutorials/migrate_v4.md +1 -1
- package/docs/tutorials/synced_coverage.md +1 -1
- package/mkdocs.yml +1 -0
- package/package.json +1 -1
- package/src/components/core/CoverageMap.js +2 -2
- package/src/components/core/PhotoViewer.js +5 -1
- package/src/components/core/Viewer.js +10 -5
- package/src/components/menus/PictureLegend.js +7 -4
- package/src/components/menus/PictureMetadata.js +23 -2
- package/src/components/styles.js +61 -0
- package/src/components/ui/ButtonGroup.css +2 -0
- package/src/components/ui/CopyButton.js +3 -1
- package/src/components/ui/Map.js +35 -4
- package/src/components/ui/Photo.js +4 -2
- package/src/components/ui/TogglableGroup.js +1 -1
- package/src/components/ui/widgets/CopyCoordinates.js +75 -0
- package/src/components/ui/widgets/GeoSearch.js +13 -5
- package/src/components/ui/widgets/Legend.js +1 -1
- package/src/components/ui/widgets/OSMEditors.js +2 -2
- package/src/components/ui/widgets/PictureLegendActions.js +1 -1
- package/src/components/ui/widgets/Player.js +1 -0
- package/src/components/ui/widgets/index.js +1 -0
- package/src/translations/en.json +6 -2
- package/src/translations/fr.json +6 -2
- package/src/translations/it.json +3 -1
- package/src/translations/ti.json +9 -0
- package/src/utils/API.js +1 -1
- package/src/utils/InitParameters.js +2 -2
- package/src/utils/geocoder.js +155 -67
- package/src/utils/index.js +2 -1
- package/src/utils/picture.js +6 -1
- package/src/utils/services.js +57 -0
- package/src/utils/utils.js +18 -5
- package/tests/components/ui/Map.test.js +7 -3
- package/tests/utils/InitParameters.test.js +15 -15
- package/tests/utils/__snapshots__/geocoder.test.js.snap +0 -6
- package/tests/utils/geocoder.test.js +1 -1
- package/tests/utils/utils.test.js +136 -109
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Settings that may be useful to change for special cases (e.g. offline implementation).
|
|
3
|
+
* Most users will be fine with the defaults.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* OpenStreetMap iD editor URL
|
|
9
|
+
* @returns {string} The editor URL
|
|
10
|
+
*/
|
|
11
|
+
export function IdEditorURL() {
|
|
12
|
+
return "https://www.openstreetmap.org/edit?editor=id";
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
/* -----------------------------------------------------
|
|
17
|
+
* Internet speed tests
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Get the threshold fast internet speed value.
|
|
22
|
+
*
|
|
23
|
+
* @returns {number} the minimum speed in MBps for internet to be considered "fast"
|
|
24
|
+
*/
|
|
25
|
+
export function InternetFastThreshold() {
|
|
26
|
+
return 10;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Get the fast internet speed test file.
|
|
31
|
+
*
|
|
32
|
+
* @returns {string} URL for the file to use for internet speed testing.
|
|
33
|
+
*/
|
|
34
|
+
export function InternetFastTestFile() {
|
|
35
|
+
return "https://panoramax.openstreetmap.fr/images/05/ca/2c/98/0111-4baf-b6f3-587bb8847d2e.jpg";
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
/* -----------------------------------------------------
|
|
40
|
+
* Geocoding-related settings
|
|
41
|
+
*/
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Get the Base Adresse Nationale URL for geocoding API.
|
|
45
|
+
* @returns {string} The Base Adresse Nationale URL (must support /search calls).
|
|
46
|
+
*/
|
|
47
|
+
export function AdresseDataGouvBaseURL() {
|
|
48
|
+
return "https://data.geopf.fr/geocodage/search";
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Get the Nominatim base URL for geocoding API.
|
|
53
|
+
* @returns {string} The Nominatim URL (must support /search & /reverse calls).
|
|
54
|
+
*/
|
|
55
|
+
export function NominatimBaseUrl() {
|
|
56
|
+
return "https://nominatim.openstreetmap.org";
|
|
57
|
+
}
|
package/src/utils/utils.js
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { InternetFastTestFile, InternetFastThreshold } from "./services";
|
|
2
|
+
|
|
1
3
|
export const BASE_PANORAMA_ID = "geovisio-fake-id-0";
|
|
2
4
|
|
|
3
5
|
export const COLORS = {
|
|
@@ -209,6 +211,19 @@ export function xyzToPosition(x, y, z) {
|
|
|
209
211
|
};
|
|
210
212
|
}
|
|
211
213
|
|
|
214
|
+
/**
|
|
215
|
+
* Transforms decimal degrees into degrees/minutes/seconds format.
|
|
216
|
+
* @param {number} degrees The decimal degrees value
|
|
217
|
+
* @returns {object} Coordinate as {d,m,s} object
|
|
218
|
+
*/
|
|
219
|
+
export function degToDms(degrees) {
|
|
220
|
+
const d = degrees < 0 ? Math.ceil(degrees) : Math.floor(degrees);
|
|
221
|
+
const rm = Math.abs(degrees - d) * 60;
|
|
222
|
+
const m = Math.floor(rm);
|
|
223
|
+
const s = parseFloat(((rm - m) * 60).toFixed(3));
|
|
224
|
+
return { d, m, s };
|
|
225
|
+
}
|
|
226
|
+
|
|
212
227
|
/**
|
|
213
228
|
* Get the query string for JOSM to load current picture area
|
|
214
229
|
* @returns {string} The query string, or null if not available
|
|
@@ -245,9 +260,7 @@ export function isInIframe() {
|
|
|
245
260
|
}
|
|
246
261
|
|
|
247
262
|
|
|
248
|
-
const INTERNET_FAST_THRESHOLD = 10; // MBit/s
|
|
249
263
|
const INTERNET_FAST_STORAGE = "pnx-internet-fast";
|
|
250
|
-
const INTERNET_FAST_TESTFILE = "https://panoramax.openstreetmap.fr/images/05/ca/2c/98/0111-4baf-b6f3-587bb8847d2e.jpg";
|
|
251
264
|
|
|
252
265
|
/**
|
|
253
266
|
* Check if Internet connection is high-speed or not.
|
|
@@ -258,7 +271,7 @@ export function isInternetFast() {
|
|
|
258
271
|
// Check if downlink property is available
|
|
259
272
|
try {
|
|
260
273
|
const speed = navigator.connection.downlink; // MBit/s
|
|
261
|
-
return Promise.resolve(speed >=
|
|
274
|
+
return Promise.resolve(speed >= InternetFastThreshold());
|
|
262
275
|
}
|
|
263
276
|
// Fallback for other browsers
|
|
264
277
|
catch(e) {
|
|
@@ -271,14 +284,14 @@ export function isInternetFast() {
|
|
|
271
284
|
|
|
272
285
|
// Run download testing
|
|
273
286
|
const startTime = (new Date()).getTime();
|
|
274
|
-
return fetch(
|
|
287
|
+
return fetch(`${InternetFastTestFile()}?nocache=${startTime}`)
|
|
275
288
|
.then(async res => [res, await res.blob()])
|
|
276
289
|
.then(([res, blob]) => {
|
|
277
290
|
const size = parseInt(res.headers.get("Content-Length") || blob.size); // Bytes
|
|
278
291
|
const endTime = (new Date()).getTime();
|
|
279
292
|
const duration = (endTime - startTime) / 1000; // Transfer time in seconds
|
|
280
293
|
const speed = (size * 8 / 1024 / 1024) / duration; // MBits/s
|
|
281
|
-
const isFast = speed >=
|
|
294
|
+
const isFast = speed >= InternetFastThreshold();
|
|
282
295
|
sessionStorage.setItem(INTERNET_FAST_STORAGE, isFast ? "true" : "false");
|
|
283
296
|
return isFast;
|
|
284
297
|
})
|
|
@@ -81,6 +81,7 @@ describe("getBackground", () => {
|
|
|
81
81
|
const p = createParent();
|
|
82
82
|
const c = document.createElement("div");
|
|
83
83
|
const m = new Map(p, c);
|
|
84
|
+
m.getLayer = () => undefined;
|
|
84
85
|
expect(m.getBackground()).toBe("streets");
|
|
85
86
|
});
|
|
86
87
|
});
|
|
@@ -99,7 +100,7 @@ describe("setBackground", () => {
|
|
|
99
100
|
resolve();
|
|
100
101
|
});
|
|
101
102
|
m.setBackground("aerial");
|
|
102
|
-
})
|
|
103
|
+
});
|
|
103
104
|
});
|
|
104
105
|
|
|
105
106
|
it("skips if setting streets and no raster available", () => {
|
|
@@ -107,6 +108,7 @@ describe("setBackground", () => {
|
|
|
107
108
|
const c = document.createElement("div");
|
|
108
109
|
const m = new Map(p, c);
|
|
109
110
|
m.setLayoutProperty = jest.fn();
|
|
111
|
+
m.getLayer = () => undefined;
|
|
110
112
|
m.setBackground("streets");
|
|
111
113
|
expect(m.setLayoutProperty.mock.calls.length).toBe(0);
|
|
112
114
|
});
|
|
@@ -115,6 +117,7 @@ describe("setBackground", () => {
|
|
|
115
117
|
const p = createParent();
|
|
116
118
|
const c = document.createElement("div");
|
|
117
119
|
const m = new Map(p, c);
|
|
120
|
+
m.getLayer = () => undefined;
|
|
118
121
|
expect(() => m.setBackground("aerial")).toThrowError("No aerial imagery available");
|
|
119
122
|
});
|
|
120
123
|
});
|
|
@@ -138,9 +141,10 @@ describe("setVisibleUsers", () => {
|
|
|
138
141
|
const c = document.createElement("div");
|
|
139
142
|
const m = new Map(p, c);
|
|
140
143
|
m._createPicturesTilesLayer = (url, id) => m._userLayers.add(id);
|
|
141
|
-
m.
|
|
144
|
+
m._addedLayers = [];
|
|
145
|
+
m.addLayer = jest.fn();
|
|
142
146
|
await m.setVisibleUsers(["blabla"]);
|
|
143
|
-
expect(m.
|
|
147
|
+
expect(m.addLayer.mock.calls).toMatchSnapshot();
|
|
144
148
|
expect(p.dispatchEvent.mock.calls).toMatchSnapshot();
|
|
145
149
|
});
|
|
146
150
|
|
|
@@ -372,47 +372,47 @@ describe("alterMapState", () => {
|
|
|
372
372
|
|
|
373
373
|
afterEach(() => jest.clearAllMocks());
|
|
374
374
|
|
|
375
|
-
it("should jump to map position when map param is provided", () => {
|
|
375
|
+
it("should jump to map position when map param is provided", async () => {
|
|
376
376
|
const params = { map: "10/20/30" };
|
|
377
377
|
const mapOpts = { center: [30,20], zoom: 10, pitch: 0 };
|
|
378
378
|
|
|
379
|
-
alterMapState(map, params);
|
|
379
|
+
await alterMapState(map, params);
|
|
380
380
|
expect(map.jumpTo).toHaveBeenCalledWith(mapOpts);
|
|
381
381
|
});
|
|
382
382
|
|
|
383
|
-
it("should set visible users when users param is provided", () => {
|
|
383
|
+
it("should set visible users when users param is provided", async () => {
|
|
384
384
|
const params = { users: "user1,user2" };
|
|
385
|
-
alterMapState(map, params);
|
|
385
|
+
await alterMapState(map, params);
|
|
386
386
|
expect(map.setVisibleUsers).toHaveBeenCalledWith(["user1", "user2"]);
|
|
387
387
|
});
|
|
388
388
|
|
|
389
|
-
it("should set default visible user when users param is empty", () => {
|
|
389
|
+
it("should set default visible user when users param is empty", async () => {
|
|
390
390
|
const params = { users: "" };
|
|
391
|
-
alterMapState(map, params);
|
|
391
|
+
await alterMapState(map, params);
|
|
392
392
|
expect(map.setVisibleUsers).toHaveBeenCalledWith(["geovisio"]);
|
|
393
393
|
});
|
|
394
394
|
|
|
395
|
-
it("should set map filters when params are provided", () => {
|
|
395
|
+
it("should set map filters when params are provided", async () => {
|
|
396
396
|
const params = { "date_from": "2024-01-01", "pic_score": "ABC" };
|
|
397
397
|
const filters = { "minDate": "2024-01-01", "qualityscore": [5,4,3] };
|
|
398
|
-
|
|
399
|
-
alterMapState(map, params);
|
|
398
|
+
await alterMapState(map, params);
|
|
400
399
|
expect(map.setFilters).toHaveBeenCalledWith(filters);
|
|
401
400
|
});
|
|
402
401
|
|
|
403
|
-
it("should set map background when background param is valid", () => {
|
|
402
|
+
it("should set map background when background param is valid", async () => {
|
|
404
403
|
const params = { background: "aerial" };
|
|
405
|
-
|
|
404
|
+
map.setVisibleUsers = () => Promise.resolve();
|
|
405
|
+
await alterMapState(map, params);
|
|
406
406
|
expect(map.setBackground).toHaveBeenCalledWith("aerial");
|
|
407
407
|
});
|
|
408
408
|
|
|
409
|
-
it("should not set map background when background param is invalid", () => {
|
|
409
|
+
it("should not set map background when background param is invalid", async () => {
|
|
410
410
|
const params = { background: "invalid" };
|
|
411
|
-
alterMapState(map, params);
|
|
411
|
+
await alterMapState(map, params);
|
|
412
412
|
expect(map.setBackground).not.toHaveBeenCalled();
|
|
413
413
|
});
|
|
414
414
|
|
|
415
|
-
it("should handle multiple params correctly", () => {
|
|
415
|
+
it("should handle multiple params correctly", async () => {
|
|
416
416
|
const params = {
|
|
417
417
|
map: "15/7/6",
|
|
418
418
|
users: "user1,user2",
|
|
@@ -422,7 +422,7 @@ describe("alterMapState", () => {
|
|
|
422
422
|
const mapOpts = { center: [6, 7], zoom: 15, pitch: 0 };
|
|
423
423
|
const filters = { camera: "value1" };
|
|
424
424
|
|
|
425
|
-
alterMapState(map, params);
|
|
425
|
+
await alterMapState(map, params);
|
|
426
426
|
expect(map.jumpTo).toHaveBeenCalledWith(mapOpts);
|
|
427
427
|
expect(map.setVisibleUsers).toHaveBeenCalledWith(["user1", "user2"]);
|
|
428
428
|
expect(map.setFilters).toHaveBeenCalledWith(filters);
|
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
exports[`forwardGeocodingBAN works 1`] = `
|
|
4
4
|
Object {
|
|
5
|
-
"attribution": "BAN",
|
|
6
5
|
"features": Array [
|
|
7
6
|
Object {
|
|
8
7
|
"center": Object {
|
|
@@ -16,11 +15,6 @@ Object {
|
|
|
16
15
|
"zoom": 20,
|
|
17
16
|
},
|
|
18
17
|
],
|
|
19
|
-
"licence": "ODbL 1.0",
|
|
20
|
-
"limit": 1,
|
|
21
|
-
"query": "8 bd du port",
|
|
22
|
-
"type": "FeatureCollection",
|
|
23
|
-
"version": "draft",
|
|
24
18
|
}
|
|
25
19
|
`;
|
|
26
20
|
|
|
@@ -30,7 +30,7 @@ describe("forwardGeocodingBAN", () => {
|
|
|
30
30
|
const cfg = { query: "bla", limit: 5, proximity: "17.7,-45.2" };
|
|
31
31
|
|
|
32
32
|
return geocoder.forwardGeocodingBAN(cfg).then(res => {
|
|
33
|
-
expect(global.fetch.mock.calls).toEqual([["https://
|
|
33
|
+
expect(global.fetch.mock.calls).toEqual([["https://data.geopf.fr/geocodage/search/?q=bla&limit=5&lat=17.7&lon=-45.2"]]);
|
|
34
34
|
expect(res).toMatchSnapshot();
|
|
35
35
|
});
|
|
36
36
|
});
|
|
@@ -8,18 +8,18 @@ jest.mock("../../src/utils/map", () => ({
|
|
|
8
8
|
|
|
9
9
|
describe("getGrade", () => {
|
|
10
10
|
it("works with null-like", () => {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
11
|
+
expect(utils.getGrade(utils.QUALITYSCORE_RES_FLAT_VALUES, null)).toBeNull();
|
|
12
|
+
expect(utils.getGrade(utils.QUALITYSCORE_RES_FLAT_VALUES, undefined)).toBeNull();
|
|
13
|
+
expect(utils.getGrade(utils.QUALITYSCORE_RES_FLAT_VALUES, "")).toBeNull();
|
|
14
|
+
});
|
|
15
15
|
|
|
16
16
|
it("works with grade values", () => {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
17
|
+
expect(utils.getGrade(utils.QUALITYSCORE_RES_FLAT_VALUES, 0)).toBe(1);
|
|
18
|
+
expect(utils.getGrade(utils.QUALITYSCORE_RES_FLAT_VALUES, 5)).toBe(1);
|
|
19
|
+
expect(utils.getGrade(utils.QUALITYSCORE_RES_FLAT_VALUES, 12)).toBe(2);
|
|
20
|
+
expect(utils.getGrade(utils.QUALITYSCORE_RES_FLAT_VALUES, 25)).toBe(3);
|
|
21
|
+
expect(utils.getGrade(utils.QUALITYSCORE_RES_FLAT_VALUES, 40)).toBe(4);
|
|
22
|
+
});
|
|
23
23
|
});
|
|
24
24
|
|
|
25
25
|
describe("getDistance", () => {
|
|
@@ -32,25 +32,25 @@ describe("getDistance", () => {
|
|
|
32
32
|
});
|
|
33
33
|
|
|
34
34
|
describe("svgToPSVLink", () => {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
35
|
+
it("works", () => {
|
|
36
|
+
const base64Svg = "data:image/svg+xml;base64,PHN2ZyB4bWxucz0naHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnPjxjaXJjbGUgY3g9JzUnIGN5PSc1JyByPSc1JyBmaWxsPScjMDAwJy8+PC9zdmc+";
|
|
37
|
+
const fillColor = "red";
|
|
38
|
+
const result = utils.svgToPSVLink(base64Svg, fillColor);
|
|
39
|
+
|
|
40
|
+
expect(result).toBeInstanceOf(HTMLButtonElement);
|
|
41
|
+
expect(result.classList.contains("pnx-psv-tour-arrows")).toBe(true);
|
|
42
|
+
expect(result.style.color).toBe(fillColor);
|
|
43
|
+
expect(result.querySelector("svg")).not.toBeNull();
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
it("works with invalid input", () => {
|
|
47
|
+
const invalidBase64Svg = "http://test.net/invalid_string";
|
|
48
|
+
const result = utils.svgToPSVLink(invalidBase64Svg, "blue");
|
|
49
|
+
|
|
50
|
+
expect(result).toBeInstanceOf(HTMLImageElement);
|
|
51
|
+
expect(result.src).toBe(invalidBase64Svg);
|
|
52
|
+
expect(result.alt).toBe("");
|
|
53
|
+
});
|
|
54
54
|
});
|
|
55
55
|
|
|
56
56
|
describe("getAzimuth", () => {
|
|
@@ -197,92 +197,119 @@ describe("xyzToPosition", () => {
|
|
|
197
197
|
});
|
|
198
198
|
});
|
|
199
199
|
|
|
200
|
+
describe("degToDms", () => {
|
|
201
|
+
it("converts positive decimal degrees to DMS correctly", () => {
|
|
202
|
+
const result = utils.degToDms(45.7896541);
|
|
203
|
+
expect(result).toEqual({ d: 45, m: 47, s: 22.755 });
|
|
204
|
+
});
|
|
205
|
+
|
|
206
|
+
it("converts negative decimal degrees to DMS correctly 1", () => {
|
|
207
|
+
const result = utils.degToDms(-12.751234);
|
|
208
|
+
expect(result).toEqual({ d: -12, m: 45, s: 4.442 });
|
|
209
|
+
});
|
|
210
|
+
|
|
211
|
+
it("converts negative decimal degrees to DMS correctly 2", () => {
|
|
212
|
+
const result = utils.degToDms(-21.007598);
|
|
213
|
+
expect(result).toEqual({ d: -21, m: 0, s: 27.353 });
|
|
214
|
+
});
|
|
215
|
+
|
|
216
|
+
it("converts zero degrees to DMS correctly", () => {
|
|
217
|
+
const result = utils.degToDms(0);
|
|
218
|
+
expect(result).toEqual({ d: 0, m: 0, s: 0 });
|
|
219
|
+
});
|
|
220
|
+
|
|
221
|
+
it("handles integer degrees correctly", () => {
|
|
222
|
+
const result = utils.degToDms(90);
|
|
223
|
+
expect(result).toEqual({ d: 90, m: 0, s: 0 });
|
|
224
|
+
});
|
|
225
|
+
});
|
|
226
|
+
|
|
200
227
|
describe("josmBboxParameters", () => {
|
|
201
228
|
it("works with null-like", () => {
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
229
|
+
expect(utils.josmBboxParameters(null)).toBeNull();
|
|
230
|
+
expect(utils.josmBboxParameters(undefined)).toBeNull();
|
|
231
|
+
});
|
|
232
|
+
|
|
233
|
+
it("works without azimuth", () => {
|
|
234
|
+
const meta = { gps: [2.3522, 48.8566] };
|
|
235
|
+
const result = utils.josmBboxParameters(meta);
|
|
236
|
+
expect(result).toBe("left=2.3522&right=2.3522&top=48.8566&bottom=48.8566&changeset_source=Panoramax");
|
|
237
|
+
});
|
|
238
|
+
|
|
239
|
+
it("works with azimuth = 0", () => {
|
|
240
|
+
const meta = { gps: [2.3522, 48.8566], properties: { "view:azimuth": 0 } };
|
|
241
|
+
const result = utils.josmBboxParameters(meta);
|
|
242
|
+
expect(result).toBe("left=2.3522&right=2.3524&top=48.8568&bottom=48.8566&changeset_source=Panoramax");
|
|
243
|
+
});
|
|
244
|
+
|
|
245
|
+
it("works with azimuth = 180", () => {
|
|
246
|
+
const meta = { gps: [2.3522, 48.8566], properties: { "view:azimuth": 180 } };
|
|
247
|
+
const result = utils.josmBboxParameters(meta);
|
|
248
|
+
expect(result).toBe("left=2.352&right=2.3524&top=48.8566&bottom=48.8564&changeset_source=Panoramax");
|
|
249
|
+
});
|
|
250
|
+
|
|
251
|
+
it("works with azimuth = 90", () => {
|
|
252
|
+
const meta = { gps: [2.3522, 48.8566], properties: { "view:azimuth": 90 } };
|
|
253
|
+
const result = utils.josmBboxParameters(meta);
|
|
254
|
+
expect(result).toBe("left=2.3522&right=2.3524&top=48.8568&bottom=48.8564&changeset_source=Panoramax");
|
|
255
|
+
});
|
|
256
|
+
|
|
257
|
+
it("works with azimuth = 270", () => {
|
|
258
|
+
const meta = { gps: [2.3522, 48.8566], properties: { "view:azimuth": 270 } };
|
|
259
|
+
const result = utils.josmBboxParameters(meta);
|
|
260
|
+
expect(result).toBe("left=2.352&right=2.3522&top=48.8568&bottom=48.8564&changeset_source=Panoramax");
|
|
261
|
+
});
|
|
235
262
|
});
|
|
236
263
|
|
|
237
264
|
describe("getCookie", () => {
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
265
|
+
it("should return the value of the specified cookie", () => {
|
|
266
|
+
jest.spyOn(document, "cookie", "get").mockReturnValueOnce("session=abc123");
|
|
267
|
+
expect(utils.getCookie("session")).toBe("abc123");
|
|
268
|
+
});
|
|
269
|
+
|
|
270
|
+
it("should return null if the cookie is not found", () => {
|
|
271
|
+
jest.spyOn(document, "cookie", "get").mockReturnValueOnce("session=abc123");
|
|
272
|
+
expect(utils.getCookie("user_id")).toBeUndefined();
|
|
273
|
+
});
|
|
274
|
+
|
|
275
|
+
it("should return the correct value when multiple cookies are set", () => {
|
|
276
|
+
jest.spyOn(document, "cookie", "get").mockReturnValueOnce("session=abc123; user_id=789; user_name=John");
|
|
277
|
+
expect(utils.getCookie("user_id")).toBe("789");
|
|
278
|
+
});
|
|
279
|
+
|
|
280
|
+
it("should return null if cookie with the specified name has no value", () => {
|
|
281
|
+
jest.spyOn(document, "cookie", "get").mockReturnValueOnce("session=; user_id=789");
|
|
282
|
+
expect(utils.getCookie("session")).toBe("");
|
|
283
|
+
});
|
|
284
|
+
|
|
285
|
+
it("should return the correct value when the cookie contains =", () => {
|
|
286
|
+
jest.spyOn(document, "cookie", "get").mockReturnValueOnce("custom_cookie=abc=123");
|
|
287
|
+
expect(utils.getCookie("custom_cookie")).toBe("abc=123");
|
|
288
|
+
});
|
|
262
289
|
});
|
|
263
290
|
|
|
264
291
|
describe("getUserAccount", () => {
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
292
|
+
it("should return an object with user id and name when all cookies are present", () => {
|
|
293
|
+
jest.spyOn(document, "cookie", "get").mockReturnValue("session=abc123; user_id=789; user_name=John");
|
|
294
|
+
expect(utils.getUserAccount()).toEqual({ id: "789", name: "John" });
|
|
295
|
+
});
|
|
296
|
+
|
|
297
|
+
it("should return null if session cookie is missing", () => {
|
|
298
|
+
jest.spyOn(document, "cookie", "get").mockReturnValue("user_id=789; user_name=John");
|
|
299
|
+
expect(utils.getUserAccount()).toBeNull();
|
|
300
|
+
});
|
|
301
|
+
|
|
302
|
+
it("should return null if user_id cookie is missing", () => {
|
|
303
|
+
jest.spyOn(document, "cookie", "get").mockReturnValue("session=abc123; user_name=John");
|
|
304
|
+
expect(utils.getUserAccount()).toBeNull();
|
|
305
|
+
});
|
|
306
|
+
|
|
307
|
+
it("should return null if user_name cookie is missing", () => {
|
|
308
|
+
jest.spyOn(document, "cookie", "get").mockReturnValue("session=abc123; user_id=789");
|
|
309
|
+
expect(utils.getUserAccount()).toBeNull();
|
|
310
|
+
});
|
|
311
|
+
|
|
312
|
+
it("should return null if all cookies are missing", () => {
|
|
313
|
+
expect(utils.getUserAccount()).toBeNull();
|
|
314
|
+
});
|
|
288
315
|
});
|