UNPKG

@panoramax/web-viewer

Version:

Panoramax web viewer for geolocated pictures

371 lines (334 loc) 11.9 kB
import Photo from "../../../src/components/ui/Photo"; import fs from "fs"; import path from "path"; const createParent = () => ({ addEventListener: jest.fn(), dispatchEvent: jest.fn(), isWidthSmall: jest.fn(), select: jest.fn(), _t: { pnx: {} }, api: { _getFetchOptions: jest.fn(), _getPSVWithCredentials: () => false, getPictureMetadataUrl: (picId, seqId) => `https://geovisio.fr/api/collections/${seqId}/items/${picId}`, cleanResourceURL: u => u, }, }); describe("constructor", () => { it("works", () => { const p = createParent(); const c = document.createElement("div"); const ph = new Photo(p, c); expect(c.className).toBe("pnx-psv"); }); }); describe("_getNodeFromAPI", () => { beforeEach(() => { jest.clearAllMocks(); }); it("works", async () => { const p = createParent(); const c = document.createElement("div"); const ph = new Photo(p, c); global.fetch = jest.fn(() => Promise.resolve({ ok: true, json: () => Promise.resolve(JSON.parse(fs.readFileSync(path.join(__dirname, "..", "..", "data", "Viewer_pictures_1.json")))), }) ); global.Date = jest.fn(() => ({ toLocaleDateString: () => "June 3 2022" })); const res = await ph._getNodeFromAPI("id"); expect(res).toMatchSnapshot(); }); it("works with nav filter", async () => { const p = createParent(); const c = document.createElement("div"); const ph = new Photo(p, c); p._picturesNavFilter = () => false; global.fetch = jest.fn(() => Promise.resolve({ ok: true, json: () => Promise.resolve(JSON.parse(fs.readFileSync(path.join(__dirname, "..", "..", "data", "Viewer_pictures_1.json")))), }) ); global.Date = jest.fn(() => ({ toLocaleDateString: () => "June 3 2022" })); const res = await ph._getNodeFromAPI("id"); expect(res).toMatchSnapshot(); }); }); describe("getPictureMetadata", () => { it("works when pic is selected", () => { const p = createParent(); const c = document.createElement("div"); const ph = new Photo(p, c); ph._myVTour.state.currentNode = { id: "1234", bla: "bla" }; expect(ph.getPictureMetadata()).toStrictEqual({ id: "1234", bla: "bla" }); }); it("nulls when no pic is selected", () => { const p = createParent(); const c = document.createElement("div"); const ph = new Photo(p, c); expect(ph.getPictureMetadata()).toBeNull(); }); }); describe("_onSelect", () => { it("works", () => { const p = createParent(); const c = document.createElement("div"); const ph = new Photo(p, c); ph._myVTour = { setCurrentNode: jest.fn(() => Promise.resolve()), getCurrentNode: jest.fn() }; ph._onSelect({ detail: { picId: "id" } }); expect(ph._myVTour.setCurrentNode.mock.calls).toEqual([["id"]]); }); it("works on pic ID already used", () => { const p = createParent(); const c = document.createElement("div"); const ph = new Photo(p, c); ph._myVTour = { setCurrentNode: jest.fn(() => Promise.resolve()), getCurrentNode: () => "id" }; ph._onSelect({ detail: { picId: "id" } }); expect(ph._myVTour.setCurrentNode.mock.calls).toEqual([["id"]]); }); }); describe("goToNextPicture", () => { it("fails if no current picture", () => { const p = createParent(); const c = document.createElement("div"); const ph = new Photo(p, c); ph._myVTour = { state: { currentNode: undefined } }; expect(() => ph.goToNextPicture()).toThrow(new Error("No picture currently selected")); }); it("works if next pic exists", () => { const p = createParent(); const c = document.createElement("div"); const ph = new Photo(p, c); ph._myVTour = { state: { currentNode: { id: "bla", sequence: { id: "seq", nextPic: "idnext" } } } }; ph.goToNextPicture(); expect(p.select.mock.calls).toEqual([["seq", "idnext"]]); }); it("fails if no next picture", () => { const p = createParent(); const c = document.createElement("div"); const ph = new Photo(p, c); ph._myVTour = { state: { currentNode: { id: "bla", sequence: {} } } }; expect(() => ph.goToNextPicture()).toThrow(new Error("No next picture available")); }); }); describe("goToPrevPicture", () => { it("fails if no current picture", () => { const p = createParent(); const c = document.createElement("div"); const ph = new Photo(p, c); ph._myVTour = { state: { currentNode: undefined } }; expect(() => ph.goToPrevPicture()).toThrow(new Error("No picture currently selected")); }); it("works if next pic exists", () => { const p = createParent(); const c = document.createElement("div"); const ph = new Photo(p, c); ph._myVTour = { state: { currentNode: { id: "bla", sequence: { id: "seq", prevPic: "idprev" } } } }; ph.goToPrevPicture(); expect(p.select.mock.calls).toEqual([["seq", "idprev"]]); }); it("fails if no next picture", () => { const p = createParent(); const c = document.createElement("div"); const ph = new Photo(p, c); ph._myVTour = { state: { currentNode: { id: "bla", sequence: {} } } }; expect(() => ph.goToPrevPicture()).toThrow(new Error("No previous picture available")); }); }); describe("goToPosition", () => { it("works", async () => { const p = createParent(); const c = document.createElement("div"); const ph = new Photo(p, c); p.api = { getPicturesAroundCoordinates: () => Promise.resolve(JSON.parse(fs.readFileSync(path.join(__dirname, "..", "..", "data", "Viewer_pictures_1.json")))), _getFetchOptions: jest.fn() }; const res = await ph.goToPosition(48.7, -1.8); expect(res).toEqual("0005086d-65eb-4a90-9764-86b3661aaa77"); expect(p.select.mock.calls).toEqual([["bb129602-5ac1-4512-bf67-9ec1fa23033f", "0005086d-65eb-4a90-9764-86b3661aaa77"]]); }); it("handles empty result from API", () => { const p = createParent(); const c = document.createElement("div"); const ph = new Photo(p, c); p.api = { getPicturesAroundCoordinates: () => Promise.resolve({ "features": [] }), _getFetchOptions: jest.fn() }; return expect(ph.goToPosition()).rejects.toStrictEqual(new Error("No picture found nearby given coordinates")); }); }); describe("getXY", () => { it("works", () => { const p = createParent(); const c = document.createElement("div"); const ph = new Photo(p, c); ph.getPosition = () => ({ yaw: 0.7853981634, pitch: -1.2217304764 }); expect(ph.getXY()).toEqual({ x: 45.0000000001462, y: -70.00000000022743 }); }); }); describe("getXYZ", () => { it("works", () => { const p = createParent(); const c = document.createElement("div"); const ph = new Photo(p, c); ph.getPosition = () => ({ yaw: 0.7853981634, pitch: -1.2217304764 }); ph.getZoomLevel = () => 15; expect(ph.getXYZ()).toEqual({ x: 45.0000000001462, y: -70.00000000022743, z: 15 }); }); }); describe("clearPictureMetadataCache", () => { it("works when no pic is selected", async () => { const p = createParent(); const c = document.createElement("div"); const ph = new Photo(p, c); await ph.clearPictureMetadataCache(); expect(ph._myVTour.state.currentNode).toBeNull(); expect(ph._myVTour.state.datasource.nodes).toStrictEqual({}); }); it("works when a pic is selected", async () => { const p = createParent(); const c = document.createElement("div"); const ph = new Photo(p, c); ph._myVTour.state.currentNode = { id: "pic", sequence: { id: "seq" } }; await ph.clearPictureMetadataCache(); expect(p.select.mock.calls).toMatchSnapshot(); }); }); describe("setXYZ", () => { it("works", () => { const p = createParent(); const c = document.createElement("div"); const ph = new Photo(p, c); ph.rotate = jest.fn(); ph.zoom = jest.fn(); ph.setXYZ(45, -45, 3); expect(ph.zoom.mock.calls).toEqual([[3]]); expect(ph.rotate.mock.calls).toEqual([[{ yaw: 0.7853981633974483, pitch: -0.7853981633974483 }]]); }); }); describe("setHigherContrast", () => { it("works on enable", () => { const p = createParent(); const c = document.createElement("div"); const ph = new Photo(p, c); ph.needsUpdate = jest.fn(); ph.setHigherContrast(true); expect(ph.renderer.renderer.toneMapping).toBe(3); expect(ph.renderer.renderer.toneMappingExposure).toBe(2); expect(ph.needsUpdate.mock.calls.length).toBe(1); }); it("works on disable", () => { const p = createParent(); const c = document.createElement("div"); const ph = new Photo(p, c); ph.needsUpdate = jest.fn(); ph.setHigherContrast(false); expect(ph.renderer.renderer.toneMapping).toBe(0); expect(ph.renderer.renderer.toneMappingExposure).toBe(1); expect(ph.needsUpdate.mock.calls.length).toBe(1); }); }); describe("getTransitionDuration", () => { it("works", () => { const p = createParent(); const c = document.createElement("div"); const ph = new Photo(p, c, { transitionDuration: 42 }); expect(ph.getTransitionDuration()).toBe(42); }); }); describe("setTransitionDuration", () => { it("works", () => { const p = createParent(); const c = document.createElement("div"); const ph = new Photo(p, c); ph.setTransitionDuration(1024); expect(ph.getTransitionDuration()).toBe(1024); expect(p.dispatchEvent.mock.calls).toMatchSnapshot(); }); it("fails when value is invalid", () => { const p = createParent(); const c = document.createElement("div"); const ph = new Photo(p, c); expect(() => ph.setTransitionDuration(-1)).toThrowError("Invalid transition duration (should be between 100 and 3000)"); expect(() => ph.setTransitionDuration(3001)).toThrowError("Invalid transition duration (should be between 100 and 3000)"); }); }); describe("playSequence", () => { it("sends event", () => { const p = createParent(); const c = document.createElement("div"); const ph = new Photo(p, c); return new Promise(resolve => { ph.addEventListener("sequence-playing", resolve); ph.playSequence(); }); }); }); describe("stopSequence", () => { it("sends event", async () => { const p = createParent(); const c = document.createElement("div"); const ph = new Photo(p, c); return new Promise(resolve => { ph.addEventListener("sequence-stopped", resolve); ph.stopSequence(); }); }); }); describe("isSequencePlaying", () => { it("is true when sequence is playing", () => { const p = createParent(); const c = document.createElement("div"); const ph = new Photo(p, c); ph.goToNextPicture = jest.fn(); ph.playSequence(); expect(ph.isSequencePlaying()).toBe(true); }); it("is false when sequence never played", () => { const p = createParent(); const c = document.createElement("div"); const ph = new Photo(p, c); expect(ph.isSequencePlaying()).toBe(false); }); it("is false when sequence stopped", () => { const p = createParent(); const c = document.createElement("div"); const ph = new Photo(p, c); ph.playSequence(); ph.stopSequence(); expect(ph.isSequencePlaying()).toBe(false); }); }); describe("getPicturesNavigation", () => { it("works", () => { const p = createParent(); const c = document.createElement("div"); const ph = new Photo(p, c, {picturesNavigation: "pic"}); expect(ph.getPicturesNavigation()).toBe("pic"); ph._picturesNavigation = "seq"; expect(ph.getPicturesNavigation()).toBe("seq"); }); }); describe("setPicturesNavigation", () => { it("works", () => { const p = createParent(); const c = document.createElement("div"); const ph = new Photo(p, c); const eventWatcher = jest.fn(); ph.addEventListener("pictures-navigation-changed", eventWatcher); expect(ph.getPicturesNavigation()).toBe("any"); ph.setPicturesNavigation("pic"); expect(ph.getPicturesNavigation()).toBe("pic"); ph.setPicturesNavigation("seq"); expect(ph.getPicturesNavigation()).toBe("seq"); ph.setPicturesNavigation("any"); expect(ph.getPicturesNavigation()).toBe("any"); ph.setPicturesNavigation("none"); expect(ph.getPicturesNavigation()).toBe("pic"); expect(eventWatcher.mock.calls).toMatchSnapshot(); }); });