|
@@ -0,0 +1,194 @@
|
|
|
+import waitForExpect from "wait-for-expect";
|
|
|
+import {
|
|
|
+ useFirstSubmitter,
|
|
|
+ useIsFaded,
|
|
|
+ useIsFinished,
|
|
|
+ usePano,
|
|
|
+ useSavePanoSettings,
|
|
|
+} from "../components/screens/GamePanel/hooks";
|
|
|
+
|
|
|
+jest.mock("react");
|
|
|
+jest.mock("../domain/gameStore");
|
|
|
+jest.mock("../domain/apiMethods");
|
|
|
+jest.mock("../domain/localStorageMethods");
|
|
|
+
|
|
|
+import { useEffect, useRef, useState } from "react";
|
|
|
+import { dispatch, useCurrentRound, useGameId } from "../domain/gameStore";
|
|
|
+import { getFirstSubmitter } from "../domain/apiMethods";
|
|
|
+import {
|
|
|
+ savePanoPositionToLocalStorage,
|
|
|
+ savePanoPovToLocalStorage,
|
|
|
+} from "../domain/localStorageMethods";
|
|
|
+
|
|
|
+describe("GamePanel hooks", () => {
|
|
|
+ describe("useIsFinished", () => {
|
|
|
+ beforeEach(() => {
|
|
|
+ useEffect.mockImplementation(fn => {
|
|
|
+ fn();
|
|
|
+ });
|
|
|
+ });
|
|
|
+ it("returns false if the current round is non-null", () => {
|
|
|
+ useCurrentRound.mockReturnValue("1");
|
|
|
+ expect(useIsFinished()).toBe(false);
|
|
|
+ expect(dispatch.goToSummary).not.toHaveBeenCalled();
|
|
|
+ });
|
|
|
+ it("returns true and goes to summary if the current round is null", () => {
|
|
|
+ useCurrentRound.mockReturnValue(null);
|
|
|
+ expect(useIsFinished()).toBe(true);
|
|
|
+ expect(dispatch.goToSummary).toHaveBeenCalled();
|
|
|
+ });
|
|
|
+ });
|
|
|
+
|
|
|
+ describe("usePano", () => {
|
|
|
+ beforeEach(() => {
|
|
|
+ useEffect.mockImplementation(fn => {
|
|
|
+ fn();
|
|
|
+ });
|
|
|
+ });
|
|
|
+ it("creates a new pano", () => {
|
|
|
+ useRef.mockImplementation(current => ({ current }));
|
|
|
+ const { current } = usePano(
|
|
|
+ { current: "pano-div-ref" },
|
|
|
+ { lat: 1, lng: 2 },
|
|
|
+ { heading: 3, pitch: 4 }
|
|
|
+ );
|
|
|
+ expect(current).toMatchSnapshot();
|
|
|
+ });
|
|
|
+ it("does not create a new pano when one exists and just moves old one", () => {
|
|
|
+ const setPosition = jest.fn();
|
|
|
+ const setPov = jest.fn();
|
|
|
+ useRef.mockImplementation(() => ({ current: { setPosition, setPov } }));
|
|
|
+ const { current } = usePano(
|
|
|
+ { current: "pano-div-ref" },
|
|
|
+ { lat: 1, lng: 2 },
|
|
|
+ { heading: 3, pitch: 4 }
|
|
|
+ );
|
|
|
+ expect(current).toMatchSnapshot();
|
|
|
+ expect(setPosition).toMatchSnapshot();
|
|
|
+ expect(setPov).toMatchSnapshot();
|
|
|
+ });
|
|
|
+ });
|
|
|
+
|
|
|
+ describe("useSavePanoSettings", () => {
|
|
|
+ beforeEach(() => {
|
|
|
+ useEffect.mockImplementation(fn => {
|
|
|
+ const cleanup = fn();
|
|
|
+ if (cleanup) {
|
|
|
+ cleanup();
|
|
|
+ }
|
|
|
+ });
|
|
|
+ });
|
|
|
+ it("attaches listeners to the given panoRef", () => {
|
|
|
+ const listeners = {};
|
|
|
+ useSavePanoSettings({
|
|
|
+ current: {
|
|
|
+ getPosition: () => ({ lat: () => 1, lng: () => 2 }),
|
|
|
+ getPov: () => ({ heading: 3, pitch: 4 }),
|
|
|
+ addListener: (event, fn) => {
|
|
|
+ listeners[event] = fn;
|
|
|
+ },
|
|
|
+ },
|
|
|
+ });
|
|
|
+ expect(savePanoPositionToLocalStorage).not.toHaveBeenCalled();
|
|
|
+ expect(savePanoPovToLocalStorage).not.toHaveBeenCalled();
|
|
|
+ listeners["position_changed"]();
|
|
|
+ expect(savePanoPositionToLocalStorage).toHaveBeenCalledWith(1, 2);
|
|
|
+ listeners["pov_changed"]();
|
|
|
+ expect(savePanoPovToLocalStorage).toHaveBeenCalledWith(3, 4);
|
|
|
+ });
|
|
|
+ it("does nothing when panoRef.current is null", () => {
|
|
|
+ useSavePanoSettings({ current: null });
|
|
|
+ expect(savePanoPositionToLocalStorage).not.toHaveBeenCalled();
|
|
|
+ expect(savePanoPovToLocalStorage).not.toHaveBeenCalled();
|
|
|
+ });
|
|
|
+ });
|
|
|
+
|
|
|
+ describe("useIsFaded", () => {
|
|
|
+ beforeEach(() => {
|
|
|
+ useEffect.mockImplementation(fn => {
|
|
|
+ const cleanup = fn();
|
|
|
+ if (cleanup) {
|
|
|
+ cleanup();
|
|
|
+ }
|
|
|
+ });
|
|
|
+ });
|
|
|
+ it("does nothing when first is null", () => {
|
|
|
+ useState.mockReturnValue([]);
|
|
|
+ useIsFaded(null);
|
|
|
+ expect(setTimeout).not.toHaveBeenCalled();
|
|
|
+ });
|
|
|
+ it("sets faded 2 seconds after first is non-null", () => {
|
|
|
+ const setFaded = jest.fn();
|
|
|
+ useState.mockReturnValue([false, setFaded]);
|
|
|
+ setTimeout.mockImplementation(fn => {
|
|
|
+ fn();
|
|
|
+ });
|
|
|
+ useIsFaded("first-submitter");
|
|
|
+ expect(setFaded).toHaveBeenCalledWith(true);
|
|
|
+ expect(setTimeout).toHaveBeenCalledWith(expect.any(Function), 2000);
|
|
|
+ expect(clearTimeout).toHaveBeenCalled();
|
|
|
+ });
|
|
|
+ });
|
|
|
+
|
|
|
+ describe("useFirstSubmitter", () => {
|
|
|
+ beforeEach(() => {
|
|
|
+ useGameId.mockReturnValue("test-game-id");
|
|
|
+ useCurrentRound.mockReturnValue("1");
|
|
|
+ useEffect.mockImplementation(fn => {
|
|
|
+ const cleanup = fn();
|
|
|
+ if (cleanup) {
|
|
|
+ cleanup();
|
|
|
+ }
|
|
|
+ });
|
|
|
+ });
|
|
|
+ it("queries to find first submitter if not found yet", async () => {
|
|
|
+ const setFirst = jest.fn();
|
|
|
+ useState.mockReturnValue([null, setFirst]);
|
|
|
+ getFirstSubmitter.mockReturnValue("first");
|
|
|
+ dispatch.updateRoundSeconds.mockImplementation(fn => fn(100));
|
|
|
+ useFirstSubmitter("rate", 10);
|
|
|
+ await waitForExpect(() => {
|
|
|
+ expect(setFirst).toHaveBeenCalledWith("first");
|
|
|
+ });
|
|
|
+ expect(dispatch.updateRoundSeconds).toHaveReturnedWith(10);
|
|
|
+ // TODO don't understand why these are losing their call record
|
|
|
+ // expect(setInterval).toHaveBeenCalledWith(expect.any(Function), "rate");
|
|
|
+ // expect(clearInterval).toHaveBeenCalled();
|
|
|
+ });
|
|
|
+ it("uses min of cutoff arg and current round seconds", async () => {
|
|
|
+ const setFirst = jest.fn();
|
|
|
+ useState.mockReturnValue([null, setFirst]);
|
|
|
+ getFirstSubmitter.mockReturnValue("first");
|
|
|
+ dispatch.updateRoundSeconds.mockImplementation(fn => fn(15));
|
|
|
+ useFirstSubmitter("rate", 200);
|
|
|
+ await waitForExpect(() => {
|
|
|
+ expect(setFirst).toHaveBeenCalledWith("first");
|
|
|
+ });
|
|
|
+ expect(dispatch.updateRoundSeconds).toHaveReturnedWith(15);
|
|
|
+ // TODO don't understand why these are losing their call record
|
|
|
+ // expect(setInterval).toHaveBeenCalledWith(expect.anything(), "rate");
|
|
|
+ // expect(clearInterval).toHaveBeenCalled();
|
|
|
+ });
|
|
|
+ it("does nothing after query if it returns null", async () => {
|
|
|
+ const setFirst = jest.fn();
|
|
|
+ useState.mockReturnValue([null, setFirst]);
|
|
|
+ getFirstSubmitter.mockReturnValue(null);
|
|
|
+ dispatch.updateRoundSeconds.mockImplementation(fn => fn(100));
|
|
|
+ useFirstSubmitter("rate", 10);
|
|
|
+ expect(setFirst).not.toHaveBeenCalled();
|
|
|
+ expect(dispatch.updateRoundSeconds).not.toHaveBeenCalled();
|
|
|
+ // TODO don't understand why these are losing their call record
|
|
|
+ // expect(setInterval).toHaveBeenCalledWith(expect.any(Function), "rate");
|
|
|
+ // expect(clearInterval).toHaveBeenCalled();
|
|
|
+ });
|
|
|
+ it("does nothing if there's already a first submitter found", () => {
|
|
|
+ const setFirst = jest.fn();
|
|
|
+ useState.mockReturnValue(["first", setFirst]);
|
|
|
+ const first = useFirstSubmitter("rate", 10);
|
|
|
+ expect(first).toBe("first");
|
|
|
+ expect(setFirst).not.toHaveBeenCalled();
|
|
|
+ expect(setInterval).not.toHaveBeenCalled();
|
|
|
+ expect(clearInterval).not.toHaveBeenCalled();
|
|
|
+ });
|
|
|
+ });
|
|
|
+});
|