|
@@ -0,0 +1,100 @@
|
|
|
+import {
|
|
|
+ useMapResizeKeybindings,
|
|
|
+ useRoundTimer,
|
|
|
+} from "../components/screens/GamePanel/GuessPane/hooks";
|
|
|
+
|
|
|
+jest.mock("react");
|
|
|
+jest.mock("../domain/gameStore");
|
|
|
+
|
|
|
+import { useEffect, useState } from "react";
|
|
|
+import { dispatch, useRoundSeconds } from "../domain/gameStore";
|
|
|
+
|
|
|
+describe("GuessPane hooks", () => {
|
|
|
+ describe("useMapResizeKeybindings", () => {
|
|
|
+ document.addEventListener = jest.fn();
|
|
|
+ document.removeEventListener = jest.fn();
|
|
|
+
|
|
|
+ it("attaches key listener on mount and removes them on unmount", () => {
|
|
|
+ let listener;
|
|
|
+ document.addEventListener.mockImplementation((_, fn) => {
|
|
|
+ listener = fn;
|
|
|
+ });
|
|
|
+ let cleanup;
|
|
|
+ useEffect.mockImplementation(fn => {
|
|
|
+ cleanup = fn();
|
|
|
+ });
|
|
|
+ const toggleMapSize = jest.fn();
|
|
|
+ useMapResizeKeybindings(toggleMapSize);
|
|
|
+ expect(document.addEventListener).toHaveBeenCalledWith(
|
|
|
+ "keydown",
|
|
|
+ listener,
|
|
|
+ false
|
|
|
+ );
|
|
|
+ listener({ code: "Escape" });
|
|
|
+ expect(toggleMapSize).toHaveBeenCalled();
|
|
|
+ cleanup();
|
|
|
+ expect(document.removeEventListener).toHaveBeenCalledWith(
|
|
|
+ "keydown",
|
|
|
+ listener,
|
|
|
+ false
|
|
|
+ );
|
|
|
+ });
|
|
|
+ it("attaches key listener that only listens on escape", () => {
|
|
|
+ let listener;
|
|
|
+ document.addEventListener.mockImplementation((_, fn) => {
|
|
|
+ listener = fn;
|
|
|
+ });
|
|
|
+ let cleanup;
|
|
|
+ useEffect.mockImplementation(fn => {
|
|
|
+ cleanup = fn();
|
|
|
+ });
|
|
|
+ const toggleMapSize = jest.fn();
|
|
|
+ useMapResizeKeybindings(toggleMapSize);
|
|
|
+ expect(document.addEventListener).toHaveBeenCalledWith(
|
|
|
+ "keydown",
|
|
|
+ listener,
|
|
|
+ false
|
|
|
+ );
|
|
|
+ listener({ code: "Enter" });
|
|
|
+ expect(toggleMapSize).not.toHaveBeenCalled();
|
|
|
+ });
|
|
|
+ });
|
|
|
+ describe("useRoundTimer", () => {
|
|
|
+ beforeEach(() => {
|
|
|
+ useEffect.mockImplementation(f => {
|
|
|
+ const cleanup = f();
|
|
|
+ if (cleanup) {
|
|
|
+ cleanup();
|
|
|
+ }
|
|
|
+ });
|
|
|
+ setTimeout.mockImplementation(f => f());
|
|
|
+ dispatch.updateRoundSeconds.mockImplementation(f => f(100));
|
|
|
+ });
|
|
|
+ it("sets up a timer and counts down", () => {
|
|
|
+ useRoundSeconds.mockReturnValue(100);
|
|
|
+ useState.mockReturnValue([false, () => {}]);
|
|
|
+ const onTimeout = jest.fn();
|
|
|
+ expect(useRoundTimer(onTimeout)).toBe(100);
|
|
|
+ expect(setTimeout).toHaveBeenCalledWith(expect.any(Function), 1000);
|
|
|
+ expect(dispatch.updateRoundSeconds).toHaveReturnedWith(99);
|
|
|
+ expect(clearTimeout).toHaveBeenCalled();
|
|
|
+ expect(onTimeout).not.toHaveBeenCalled();
|
|
|
+ });
|
|
|
+ it("calls onTimeout when round ends", () => {
|
|
|
+ useRoundSeconds.mockReturnValue(0);
|
|
|
+ useState.mockReturnValue([false, () => {}]);
|
|
|
+ const onTimeout = jest.fn();
|
|
|
+ expect(useRoundTimer(onTimeout)).toBe(0);
|
|
|
+ expect(setTimeout).not.toHaveBeenCalled();
|
|
|
+ expect(dispatch.updateRoundSeconds).not.toHaveBeenCalled();
|
|
|
+ expect(onTimeout).toHaveBeenCalled();
|
|
|
+ });
|
|
|
+ it("only calls onTimeout once", () => {
|
|
|
+ useRoundSeconds.mockReturnValue(0);
|
|
|
+ useState.mockReturnValue([true, () => {}]);
|
|
|
+ const onTimeout = jest.fn();
|
|
|
+ expect(useRoundTimer(onTimeout)).toBe(0);
|
|
|
+ expect(onTimeout).not.toHaveBeenCalled();
|
|
|
+ });
|
|
|
+ });
|
|
|
+});
|