@panoramax/web-viewer 3.0.2-develop-a8ea8e60

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.
Files changed (125) hide show
  1. package/.dockerignore +6 -0
  2. package/.gitlab-ci.yml +71 -0
  3. package/CHANGELOG.md +428 -0
  4. package/CODE_OF_CONDUCT.md +134 -0
  5. package/Dockerfile +14 -0
  6. package/LICENSE +21 -0
  7. package/README.md +39 -0
  8. package/build/editor.html +1 -0
  9. package/build/index.css +36 -0
  10. package/build/index.css.map +1 -0
  11. package/build/index.html +1 -0
  12. package/build/index.js +25 -0
  13. package/build/index.js.map +1 -0
  14. package/build/map.html +1 -0
  15. package/build/viewer.html +1 -0
  16. package/config/env.js +104 -0
  17. package/config/getHttpsConfig.js +66 -0
  18. package/config/getPackageJson.js +25 -0
  19. package/config/jest/babelTransform.js +29 -0
  20. package/config/jest/cssTransform.js +14 -0
  21. package/config/jest/fileTransform.js +40 -0
  22. package/config/modules.js +134 -0
  23. package/config/paths.js +72 -0
  24. package/config/pnpTs.js +35 -0
  25. package/config/webpack/persistentCache/createEnvironmentHash.js +9 -0
  26. package/config/webpack.config.js +885 -0
  27. package/config/webpackDevServer.config.js +127 -0
  28. package/docs/01_Start.md +149 -0
  29. package/docs/02_Usage.md +828 -0
  30. package/docs/03_URL_settings.md +140 -0
  31. package/docs/04_Advanced_examples.md +214 -0
  32. package/docs/05_Compatibility.md +85 -0
  33. package/docs/09_Develop.md +62 -0
  34. package/docs/90_Releases.md +27 -0
  35. package/docs/images/class_diagram.drawio +129 -0
  36. package/docs/images/class_diagram.jpg +0 -0
  37. package/docs/images/screenshot.jpg +0 -0
  38. package/mkdocs.yml +45 -0
  39. package/package.json +254 -0
  40. package/public/editor.html +54 -0
  41. package/public/favicon.ico +0 -0
  42. package/public/index.html +59 -0
  43. package/public/map.html +53 -0
  44. package/public/viewer.html +67 -0
  45. package/scripts/build.js +217 -0
  46. package/scripts/start.js +176 -0
  47. package/scripts/test.js +52 -0
  48. package/src/Editor.css +37 -0
  49. package/src/Editor.js +359 -0
  50. package/src/StandaloneMap.js +114 -0
  51. package/src/Viewer.css +203 -0
  52. package/src/Viewer.js +1186 -0
  53. package/src/components/CoreView.css +64 -0
  54. package/src/components/CoreView.js +159 -0
  55. package/src/components/Loader.css +56 -0
  56. package/src/components/Loader.js +111 -0
  57. package/src/components/Map.css +65 -0
  58. package/src/components/Map.js +841 -0
  59. package/src/components/Photo.css +36 -0
  60. package/src/components/Photo.js +687 -0
  61. package/src/img/arrow_360.svg +14 -0
  62. package/src/img/arrow_flat.svg +11 -0
  63. package/src/img/arrow_triangle.svg +10 -0
  64. package/src/img/arrow_turn.svg +9 -0
  65. package/src/img/bg_aerial.jpg +0 -0
  66. package/src/img/bg_streets.jpg +0 -0
  67. package/src/img/loader_base.jpg +0 -0
  68. package/src/img/loader_hd.jpg +0 -0
  69. package/src/img/logo_dead.svg +91 -0
  70. package/src/img/marker.svg +17 -0
  71. package/src/img/marker_blue.svg +20 -0
  72. package/src/img/switch_big.svg +44 -0
  73. package/src/img/switch_mini.svg +48 -0
  74. package/src/index.js +10 -0
  75. package/src/translations/de.json +163 -0
  76. package/src/translations/en.json +164 -0
  77. package/src/translations/eo.json +6 -0
  78. package/src/translations/es.json +164 -0
  79. package/src/translations/fi.json +1 -0
  80. package/src/translations/fr.json +164 -0
  81. package/src/translations/hu.json +133 -0
  82. package/src/translations/nl.json +1 -0
  83. package/src/translations/zh_Hant.json +136 -0
  84. package/src/utils/API.js +709 -0
  85. package/src/utils/Exif.js +198 -0
  86. package/src/utils/I18n.js +75 -0
  87. package/src/utils/Map.js +382 -0
  88. package/src/utils/PhotoAdapter.js +45 -0
  89. package/src/utils/Utils.js +568 -0
  90. package/src/utils/Widgets.js +477 -0
  91. package/src/viewer/URLHash.js +334 -0
  92. package/src/viewer/Widgets.css +711 -0
  93. package/src/viewer/Widgets.js +1196 -0
  94. package/tests/Editor.test.js +125 -0
  95. package/tests/StandaloneMap.test.js +44 -0
  96. package/tests/Viewer.test.js +363 -0
  97. package/tests/__snapshots__/Editor.test.js.snap +300 -0
  98. package/tests/__snapshots__/StandaloneMap.test.js.snap +30 -0
  99. package/tests/__snapshots__/Viewer.test.js.snap +195 -0
  100. package/tests/components/CoreView.test.js +91 -0
  101. package/tests/components/Loader.test.js +38 -0
  102. package/tests/components/Map.test.js +230 -0
  103. package/tests/components/Photo.test.js +335 -0
  104. package/tests/components/__snapshots__/Loader.test.js.snap +15 -0
  105. package/tests/components/__snapshots__/Map.test.js.snap +767 -0
  106. package/tests/components/__snapshots__/Photo.test.js.snap +205 -0
  107. package/tests/data/Map_geocoder_ban.json +36 -0
  108. package/tests/data/Map_geocoder_nominatim.json +56 -0
  109. package/tests/data/Viewer_pictures_1.json +148 -0
  110. package/tests/setupTests.js +5 -0
  111. package/tests/utils/API.test.js +906 -0
  112. package/tests/utils/Exif.test.js +124 -0
  113. package/tests/utils/I18n.test.js +28 -0
  114. package/tests/utils/Map.test.js +105 -0
  115. package/tests/utils/Utils.test.js +300 -0
  116. package/tests/utils/Widgets.test.js +107 -0
  117. package/tests/utils/__snapshots__/API.test.js.snap +132 -0
  118. package/tests/utils/__snapshots__/Exif.test.js.snap +43 -0
  119. package/tests/utils/__snapshots__/Map.test.js.snap +48 -0
  120. package/tests/utils/__snapshots__/Utils.test.js.snap +41 -0
  121. package/tests/utils/__snapshots__/Widgets.test.js.snap +44 -0
  122. package/tests/viewer/URLHash.test.js +537 -0
  123. package/tests/viewer/Widgets.test.js +127 -0
  124. package/tests/viewer/__snapshots__/URLHash.test.js.snap +98 -0
  125. package/tests/viewer/__snapshots__/Widgets.test.js.snap +393 -0
@@ -0,0 +1,125 @@
1
+ import Editor from "../src/Editor";
2
+
3
+ jest.mock("maplibre-gl", () => ({
4
+ addProtocol: jest.fn(),
5
+ }));
6
+
7
+ jest.mock("@photo-sphere-viewer/core", () => ({
8
+ SYSTEM: {},
9
+ }));
10
+
11
+ jest.mock("../src/components/Photo", () => class {
12
+ constructor() {
13
+ this._myVTour = { datasource: {} };
14
+ this._api = {
15
+ onceReady: () => Promise.resolves(),
16
+ };
17
+ }
18
+ });
19
+
20
+ jest.mock("../src/components/Map", () => class {});
21
+
22
+ const API_URL = "http://localhost:5000/api/search";
23
+
24
+ describe("constructor", () => {
25
+ it("works", () => {
26
+ const d = document.createElement("div");
27
+ const ed = new Editor(d, API_URL, { testing: true, selectedSequence: "bla" });
28
+ expect(ed).toBeDefined();
29
+ });
30
+
31
+ it("fails if no sequence is selected", () => {
32
+ global.console = { error: jest.fn() };
33
+ const d = document.createElement("div");
34
+ expect(() => new Editor(d, API_URL, { testing: true })).toThrow("No sequence is selected");
35
+ });
36
+ });
37
+
38
+ describe("_createMapStyle", () => {
39
+ it("works", () => {
40
+ const d = document.createElement("div");
41
+ const ed = new Editor(d, API_URL, { testing: true, selectedSequence: "bla" });
42
+ expect(ed._createMapStyle()).toMatchSnapshot();
43
+ });
44
+ });
45
+
46
+ describe("_bindPicturesEvents", () => {
47
+ it("works", () => {
48
+ const d = document.createElement("div");
49
+ const ed = new Editor(d, API_URL, { testing: true, selectedSequence: "bla" });
50
+ ed.map = { on: jest.fn(), _onPictureClick: jest.fn() };
51
+ ed._bindPicturesEvents();
52
+ expect(ed.map.on.mock.calls).toMatchSnapshot();
53
+ });
54
+ });
55
+
56
+ describe("_getNode", () => {
57
+ it("works", () => {
58
+ const d = document.createElement("div");
59
+ const ed = new Editor(d, API_URL, { testing: true, selectedSequence: "bla" });
60
+ ed._sequenceData = [
61
+ {
62
+ assets: { pic: { roles: ["visual"], type: "image/jpeg", href: "1.jpg" } },
63
+ links: [],
64
+ properties: { id: "1" },
65
+ geometry: { coordinates: [0,0] }
66
+ },
67
+ {
68
+ assets: { pic: { roles: ["visual"], type: "image/jpeg", href: "2.jpg" } },
69
+ links: [],
70
+ properties: { id: "2" },
71
+ geometry: { coordinates: [0.1,0.1] }
72
+ },
73
+ ];
74
+ expect(ed._getNode("2")).toMatchSnapshot();
75
+ });
76
+ });
77
+
78
+ describe("_addMapBackgroundWidget", () => {
79
+ it("works", () => {
80
+ const d = document.createElement("div");
81
+ const ed = new Editor(d, API_URL, { testing: true, selectedSequence: "bla" });
82
+ ed.map = { getBackground: jest.fn() };
83
+ ed._addMapBackgroundWidget();
84
+ expect(ed.mapContainer).toMatchSnapshot();
85
+ });
86
+ });
87
+
88
+ describe("previewSequenceHeadingChange", () => {
89
+ it("works when setting preview", () => {
90
+ const d = document.createElement("div");
91
+ const ed = new Editor(d, API_URL, { testing: true, selectedSequence: "bla" });
92
+ ed.psv = { getPictureRelativeHeading: () => 12 };
93
+ ed.map = {
94
+ getLayer: () => undefined,
95
+ addLayer: jest.fn(),
96
+ setLayoutProperty: jest.fn(),
97
+ setFilter: jest.fn(),
98
+ _picMarker: { setRotation: jest.fn() },
99
+ _picMarkerPreview: { remove: jest.fn() },
100
+ };
101
+ ed.previewSequenceHeadingChange(10);
102
+ expect(ed.map.addLayer.mock.calls).toMatchSnapshot();
103
+ expect(ed.map.setLayoutProperty.mock.calls).toMatchSnapshot();
104
+ expect(ed.map.setFilter.mock.calls).toMatchSnapshot();
105
+ });
106
+
107
+ it("works when unsetting", () => {
108
+ const d = document.createElement("div");
109
+ const ed = new Editor(d, API_URL, { testing: true, selectedSequence: "bla" });
110
+ ed.psv = { getPictureRelativeHeading: () => 12 };
111
+ ed.map = {
112
+ getLayer: () => true,
113
+ addLayer: jest.fn(),
114
+ setLayoutProperty: jest.fn(),
115
+ setFilter: jest.fn(),
116
+ _picMarker: { setRotation: jest.fn() },
117
+ _picMarkerPreview: { remove: jest.fn() },
118
+ };
119
+ ed.previewSequenceHeadingChange(10);
120
+ ed.previewSequenceHeadingChange();
121
+ expect(ed.map.addLayer.mock.calls).toMatchSnapshot();
122
+ expect(ed.map.setLayoutProperty.mock.calls).toMatchSnapshot();
123
+ expect(ed.map.setFilter.mock.calls).toMatchSnapshot();
124
+ });
125
+ });
@@ -0,0 +1,44 @@
1
+ import StandaloneMap from "../src/StandaloneMap";
2
+
3
+ jest.mock("maplibre-gl", () => ({
4
+ addProtocol: jest.fn(),
5
+ }));
6
+
7
+ jest.mock("../src/components/Map", () => class {});
8
+
9
+ const API_URL = "http://localhost:5000/api/search";
10
+
11
+ describe("constructor", () => {
12
+ it("works", () => {
13
+ const d = document.createElement("div");
14
+ const ed = new StandaloneMap(d, API_URL, { testing: true });
15
+ expect(ed).toBeDefined();
16
+ });
17
+ });
18
+
19
+ describe("destroy", () => {
20
+ it("works", () => {
21
+ const d = document.createElement("div");
22
+ const ed = new StandaloneMap(d, API_URL, { testing: true });
23
+ const mapDestroy = jest.fn();
24
+ ed.map = { destroy: mapDestroy };
25
+ ed.destroy();
26
+ expect(mapDestroy.mock.calls).toMatchSnapshot();
27
+ expect(ed.container.innerHTML).toBe("");
28
+ });
29
+ });
30
+
31
+ describe("_onSelect", () => {
32
+ it("works", () => {
33
+ const d = document.createElement("div");
34
+ const ed = new StandaloneMap(d, API_URL, { testing: true });
35
+ ed.map = {
36
+ queryRenderedFeatures: jest.fn(() => ({ features: [ {id: "bla"} ] })),
37
+ _userLayers: new Set(["geovisio", "toto"]),
38
+ _attachPreviewToPictures: jest.fn(),
39
+ };
40
+ ed._onSelect({ detail: { picId: "bla", seqId: "blo" } });
41
+ expect(ed.map.queryRenderedFeatures.mock.calls).toMatchSnapshot();
42
+ expect(ed.map._attachPreviewToPictures.mock.calls).toMatchSnapshot();
43
+ });
44
+ });
@@ -0,0 +1,363 @@
1
+ import Viewer from "../src/Viewer";
2
+
3
+ jest.mock("@photo-sphere-viewer/core", () => ({
4
+ Viewer: class {},
5
+ SYSTEM: {},
6
+ DEFAULTS: {},
7
+ }));
8
+
9
+ jest.mock("@photo-sphere-viewer/equirectangular-tiles-adapter", () => ({
10
+ EquirectangularTilesAdapter: jest.fn(),
11
+ }));
12
+
13
+ jest.mock("@photo-sphere-viewer/virtual-tour-plugin", () => ({
14
+ VirtualTourPlugin: jest.fn(),
15
+ }));
16
+
17
+ jest.mock("maplibre-gl", () => ({
18
+ addProtocol: jest.fn(),
19
+ Map: class {},
20
+ }));
21
+
22
+ const API_URL = "http://localhost:5000/api/search";
23
+
24
+
25
+ describe("constructor", () => {
26
+ it("works", () => {
27
+ const d = document.createElement("div");
28
+ const v = new Viewer(d, API_URL, { testing: true });
29
+ expect(v).toBeDefined();
30
+ });
31
+ });
32
+
33
+ describe("destroy", () => {
34
+ it("works", () => {
35
+ const d = document.createElement("div");
36
+ d.id = "geovisio";
37
+ document.body.appendChild(d);
38
+ const v = new Viewer(d, API_URL, { testing: true });
39
+ v._initContainerStructure("geovisio");
40
+ v._hash = { destroy: jest.fn() };
41
+ v._widgets = { destroy: jest.fn() };
42
+ v.map = { destroy: jest.fn() };
43
+ v.psv = { destroy: jest.fn() };
44
+
45
+ v.destroy();
46
+
47
+ expect(v._api).toBeUndefined();
48
+ expect(v._hash).toBeUndefined();
49
+ expect(v.map).toBeUndefined();
50
+ expect(v.psv).toBeUndefined();
51
+ expect(d.innerHTML).toBe("");
52
+ });
53
+ });
54
+
55
+ describe("_initContainerStructure", () => {
56
+ beforeEach(() => {
57
+ document.body.innerHTML = "";
58
+ });
59
+
60
+ it("works with string", () => {
61
+ const d = document.createElement("div");
62
+ d.id = "geovisio";
63
+ document.body.appendChild(d);
64
+ const v = new Viewer("geovisio", API_URL, { testing: true });
65
+ v._initContainerStructure();
66
+ expect([...d.children].find(n => n.className.includes("gvs-main"))).toBeDefined();
67
+ expect([...d.children].find(n => n.className.includes("gvs-mini"))).toBeDefined();
68
+ expect(d.className).toBe("gvs gvs-viewer");
69
+ });
70
+
71
+ it("works with Element", () => {
72
+ const d = document.createElement("div");
73
+ const v = new Viewer(d, API_URL, { testing: true });
74
+ v._initContainerStructure();
75
+ expect([...d.children].find(n => n.className.includes("gvs-main"))).toBeDefined();
76
+ expect([...d.children].find(n => n.className.includes("gvs-mini"))).toBeDefined();
77
+ expect(d.className).toBe("gvs gvs-viewer");
78
+ });
79
+ });
80
+
81
+ describe("setPopup", () => {
82
+ it("opens", () => {
83
+ const d = document.createElement("div");
84
+ const v = new Viewer(d, API_URL, { testing: true });
85
+ v._initContainerStructure();
86
+ v.psv = {
87
+ startKeyboardControl: jest.fn(),
88
+ stopKeyboardControl: jest.fn(),
89
+ };
90
+ v.setPopup(true, "BLABLABLA");
91
+ expect(v.popupContainer.innerHTML).toMatchSnapshot();
92
+ expect(v.popupContainer.classList.contains("gvs-hidden")).toBeFalsy();
93
+ });
94
+
95
+ it("closes", () => {
96
+ const d = document.createElement("div");
97
+ const v = new Viewer(d, API_URL, { map: false, testing: true });
98
+ v._initContainerStructure();
99
+ v.psv = {
100
+ autoSize: jest.fn(),
101
+ startKeyboardControl: jest.fn(),
102
+ stopKeyboardControl: jest.fn(),
103
+ adapter: { __refresh: jest.fn() },
104
+ needsUpdate: jest.fn(),
105
+ _myVTour: { getCurrentNode: jest.fn() },
106
+ };
107
+ v.setPopup(true, "BLABLABLA");
108
+ v.setPopup(false);
109
+ expect(v.popupContainer.classList.contains("gvs-hidden")).toBeTruthy();
110
+ });
111
+
112
+ it("reopens", () => {
113
+ const d = document.createElement("div");
114
+ const v = new Viewer(d, API_URL, { testing: true });
115
+ v._initContainerStructure();
116
+ v.psv = {
117
+ autoSize: jest.fn(),
118
+ startKeyboardControl: jest.fn(),
119
+ stopKeyboardControl: jest.fn(),
120
+ adapter: { __refresh: jest.fn() },
121
+ needsUpdate: jest.fn(),
122
+ _myVTour: { getCurrentNode: jest.fn() },
123
+ };
124
+ v.setPopup(true, "BLABLABLA");
125
+ v.setPopup(false);
126
+ v.setPopup(true);
127
+ expect(v.popupContainer.innerHTML).toMatchSnapshot();
128
+ expect(v.popupContainer.classList.contains("gvs-hidden")).toBeFalsy();
129
+ });
130
+ });
131
+
132
+ describe("playSequence", () => {
133
+ it("sends event", () => {
134
+ const d = document.createElement("div");
135
+ const v = new Viewer(d, API_URL, { testing: true });
136
+ return expect(new Promise(resolve => {
137
+ v.addEventListener("sequence-playing", resolve);
138
+ v.playSequence();
139
+ })).resolves.toBeDefined();
140
+ });
141
+ });
142
+
143
+ describe("stopSequence", () => {
144
+ it("sends event", async () => {
145
+ const d = document.createElement("div");
146
+ const v = new Viewer(d, API_URL, { testing: true });
147
+ v.psv = {
148
+ adapter: { __refresh: jest.fn() },
149
+ needsUpdate: jest.fn(),
150
+ _myVTour: { getCurrentNode: jest.fn() },
151
+ }
152
+ return expect(new Promise(resolve => {
153
+ v.addEventListener("sequence-stopped", resolve);
154
+ v.stopSequence();
155
+ })).resolves.toBeDefined();
156
+ });
157
+ });
158
+
159
+ describe("isSequencePlaying", () => {
160
+ it("is true when sequence is playing", () => {
161
+ const d = document.createElement("div");
162
+ const v = new Viewer(d, API_URL, { testing: true });
163
+ v.psv = { addEventListener: jest.fn() };
164
+ v.psv.goToNextPicture = jest.fn();
165
+ v.playSequence();
166
+ expect(v.isSequencePlaying()).toBe(true);
167
+ });
168
+
169
+ it("is false when sequence never played", () => {
170
+ const d = document.createElement("div");
171
+ const v = new Viewer(d, API_URL, { testing: true });
172
+ v.psv = { addEventListener: jest.fn() };
173
+ expect(v.isSequencePlaying()).toBe(false);
174
+ });
175
+
176
+ it("is false when sequence stopped", () => {
177
+ const d = document.createElement("div");
178
+ const v = new Viewer(d, API_URL, { testing: true });
179
+ v.psv = {
180
+ addEventListener: jest.fn(),
181
+ adapter: { __refresh: jest.fn() },
182
+ needsUpdate: jest.fn(),
183
+ _myVTour: { getCurrentNode: jest.fn() },
184
+ };
185
+ v.playSequence();
186
+ v.stopSequence();
187
+ expect(v.isSequencePlaying()).toBe(false);
188
+ });
189
+ });
190
+
191
+ describe("isMapWide", () => {
192
+ it("works with map small", () => {
193
+ const d = document.createElement("div");
194
+ const v = new Viewer(d, API_URL, { testing: true });
195
+ v._initContainerStructure(d);
196
+ v.map = {};
197
+ expect(v.isMapWide()).toBe(false);
198
+ });
199
+
200
+ it("works with map wide", () => {
201
+ const d = document.createElement("div");
202
+ const v = new Viewer(d, API_URL, { testing: true });
203
+ v._initContainerStructure(d);
204
+ v.map = {
205
+ keyboard: { enable: jest.fn() },
206
+ resize: jest.fn(),
207
+ getCanvas: () => ({ focus: jest.fn() })
208
+ };
209
+ v.psv = {
210
+ autoSize: jest.fn(),
211
+ stopKeyboardControl: jest.fn(),
212
+ adapter: { __refresh: jest.fn() },
213
+ needsUpdate: jest.fn(),
214
+ _myVTour: { getCurrentNode: jest.fn() },
215
+ };
216
+ v.setFocus("map");
217
+ expect(v.isMapWide()).toBe(true);
218
+ });
219
+
220
+ it("fails if no map set", () => {
221
+ const d = document.createElement("div");
222
+ const v = new Viewer(d, API_URL, { testing: true });
223
+ v._initContainerStructure(d);
224
+ expect(() => v.isMapWide()).toThrow(new Error("Map is not enabled"));
225
+ });
226
+ });
227
+
228
+ describe("setFocus", () => {
229
+ it("changes focus from map to pic", () => {
230
+ const d = document.createElement("div");
231
+ const v = new Viewer(d, API_URL, { testing: true });
232
+ v._initContainerStructure(d);
233
+ v.dispatchEvent = jest.fn();
234
+ v.map = {
235
+ keyboard: { enable: jest.fn(), disable: jest.fn() },
236
+ resize: jest.fn(),
237
+ getCanvas: () => ({ focus: jest.fn() })
238
+ };
239
+ v.psv = {
240
+ autoSize: jest.fn(),
241
+ startKeyboardControl: jest.fn(),
242
+ stopKeyboardControl: jest.fn(),
243
+ adapter: { __refresh: jest.fn() },
244
+ needsUpdate: jest.fn(),
245
+ _myVTour: { getCurrentNode: jest.fn() },
246
+ };
247
+ v.setFocus("map");
248
+ expect(v.isMapWide()).toBe(true);
249
+ });
250
+
251
+ it("changes focus from pic to map", () => {
252
+ const d = document.createElement("div");
253
+ const v = new Viewer(d, API_URL, { testing: true });
254
+ v._initContainerStructure(d);
255
+ v.dispatchEvent = jest.fn();
256
+ v.map = {
257
+ keyboard: { enable: jest.fn(), disable: jest.fn() },
258
+ resize: jest.fn(),
259
+ getCanvas: () => ({ focus: jest.fn() })
260
+ };
261
+ v.psv = {
262
+ autoSize: jest.fn(),
263
+ startKeyboardControl: jest.fn(),
264
+ stopKeyboardControl: jest.fn(),
265
+ adapter: { __refresh: jest.fn() },
266
+ needsUpdate: jest.fn(),
267
+ _myVTour: { getCurrentNode: jest.fn() },
268
+ };
269
+ v.setFocus("pic");
270
+ expect(v.isMapWide()).toBe(false);
271
+ });
272
+
273
+ it("skips event", async () => {
274
+ const d = document.createElement("div");
275
+ const v = new Viewer(d, API_URL, { testing: true });
276
+ v._initContainerStructure(d);
277
+ v.dispatchEvent = jest.fn();
278
+ v.map = {
279
+ keyboard: { enable: jest.fn(), disable: jest.fn() },
280
+ resize: jest.fn(),
281
+ getCanvas: () => ({ focus: jest.fn() })
282
+ };
283
+ v.psv = {
284
+ autoSize: jest.fn(),
285
+ startKeyboardControl: jest.fn(),
286
+ stopKeyboardControl: jest.fn(),
287
+ adapter: { __refresh: jest.fn() },
288
+ needsUpdate: jest.fn(),
289
+ _myVTour: { getCurrentNode: jest.fn() },
290
+ };
291
+ v.setFocus("map", true);
292
+ expect(v.dispatchEvent.mock.calls).toEqual([]);
293
+ });
294
+
295
+ it("fails if param is invalid", () => {
296
+ const d = document.createElement("div");
297
+ const v = new Viewer(d, API_URL, { testing: true });
298
+ expect(() => v.setFocus()).toThrow(new Error("Invalid focus value (should be pic or map)"));
299
+ });
300
+
301
+ it("fails if no map set", () => {
302
+ const d = document.createElement("div");
303
+ const v = new Viewer(d, API_URL, { map: false, testing: true });
304
+ expect(() => v.setFocus("map")).toThrow(new Error("Map is not enabled"));
305
+ });
306
+ });
307
+
308
+ describe("getPicturesNavigation", () => {
309
+ it("works", () => {
310
+ const d = document.createElement("div");
311
+ const v = new Viewer(d, API_URL, { picturesNavigation: "pic", testing: true });
312
+ expect(v.getPicturesNavigation()).toBe("pic");
313
+ v._picNav = "seq";
314
+ expect(v.getPicturesNavigation()).toBe("seq");
315
+ });
316
+ });
317
+
318
+ describe("setPicturesNavigation", () => {
319
+ it("works", () => {
320
+ const d = document.createElement("div");
321
+ const v = new Viewer(d, API_URL, { testing: true });
322
+ const eventWatcher = jest.fn();
323
+ v.addEventListener("pictures-navigation-changed", eventWatcher);
324
+ expect(v.getPicturesNavigation()).toBe("any");
325
+ v.setPicturesNavigation("pic");
326
+ expect(v.getPicturesNavigation()).toBe("pic");
327
+ v.setPicturesNavigation("seq");
328
+ expect(v.getPicturesNavigation()).toBe("seq");
329
+ v.setPicturesNavigation("any");
330
+ expect(v.getPicturesNavigation()).toBe("any");
331
+ expect(eventWatcher.mock.calls).toMatchSnapshot();
332
+ });
333
+ });
334
+
335
+ describe("setFilters", () => {
336
+ it("works", () => {
337
+ const d = document.createElement("div");
338
+ const v = new Viewer(d, API_URL, { testing: true });
339
+ v.map = {
340
+ _userLayers: new Set(["geovisio"]),
341
+ getZoom: jest.fn(),
342
+ reloadLayersStyles: jest.fn(),
343
+ filterUserLayersContent: jest.fn(),
344
+ getVisibleUsers: () => ["geovisio"],
345
+ };
346
+ v.dispatchEvent = jest.fn();
347
+ Date.prototype.getDate = () => 8;
348
+ Date.prototype.setDate = jest.fn();
349
+ Date.prototype.toISOString = () => "2023-08-09T00:00:00Z";
350
+ v.setFilters({
351
+ "minDate": "2023-01-01",
352
+ "maxDate": "2023-08-08",
353
+ "camera": "sony",
354
+ "type": "equirectangular",
355
+ "theme": "age",
356
+ });
357
+ v.setFilters({});
358
+ expect(v._mapTheme).toBe("age");
359
+ expect(v.dispatchEvent.mock.calls).toMatchSnapshot();
360
+ expect(v.map.reloadLayersStyles.mock.calls).toMatchSnapshot();
361
+ expect(v.map.filterUserLayersContent.mock.calls).toMatchSnapshot();
362
+ });
363
+ });