Browse Source

Update test format (#821)

* Lint tests, format JSON

* Update test formatting

---------

Co-authored-by: philon- <[email protected]>
pull/822/head
Jeremy Gallant 9 months ago
committed by GitHub
parent
commit
90cf136b8c
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 32
      packages/transport-http/src/transport.test.ts
  2. 20
      packages/transport-node-serial/src/transport.test.ts
  3. 35
      packages/transport-node/src/transport.test.ts
  4. 3
      packages/web/src/components/Dialog/DeleteMessagesDialog/DeleteMessagesDialog.test.tsx
  5. 77
      packages/web/src/components/Dialog/RebootDialog.test.tsx
  6. 10
      packages/web/src/components/Dialog/RefreshKeysDialog/RefreshKeysDialog.test.tsx
  7. 2
      packages/web/src/components/Dialog/UnsafeRolesDialog/useUnsafeRolesDialog.test.tsx
  8. 3
      packages/web/src/components/PageComponents/Messages/TraceRoute.test.tsx
  9. 13
      packages/web/src/components/UI/Checkbox/Checkbox.test.tsx
  10. 2
      packages/web/src/core/hooks/useFavoriteNode.test.ts
  11. 4
      packages/web/src/core/hooks/useIgnoreNode.test.ts
  12. 2
      packages/web/src/core/hooks/useToast.test.tsx
  13. 6
      packages/web/src/core/stores/utils/indexDB.test.ts

32
packages/transport-http/src/transport.test.ts

@ -1,13 +1,23 @@
import { describe, vi, expect, it, beforeEach, afterEach, type MockInstance } from "vitest"; import {
afterEach,
beforeEach,
describe,
expect,
it,
type MockInstance,
vi,
} from "vitest";
import { runTransportContract } from "../../../tests/utils/transportContract"; import { runTransportContract } from "../../../tests/utils/transportContract";
import { TransportHTTP } from "./transport"; import { TransportHTTP } from "./transport";
let abortTimeoutSpy: MockInstance | undefined; let abortTimeoutSpy: MockInstance | undefined;
beforeEach(() => { beforeEach(() => {
abortTimeoutSpy = vi.spyOn( abortTimeoutSpy = vi
.spyOn(
globalThis.AbortSignal as unknown as { timeout(ms: number): AbortSignal }, globalThis.AbortSignal as unknown as { timeout(ms: number): AbortSignal },
"timeout", "timeout",
).mockImplementation((ms: number) => { )
.mockImplementation((ms: number) => {
const ctrl = new AbortController(); const ctrl = new AbortController();
const abort = () => const abort = () =>
ctrl.abort(new DOMException("Timeout reached", "TimeoutError")); ctrl.abort(new DOMException("Timeout reached", "TimeoutError"));
@ -118,20 +128,28 @@ describe("TransportHTTP (contract)", () => {
vi.unstubAllGlobals(); vi.unstubAllGlobals();
}, },
create: async () => { create: async () => {
(globalThis as unknown as { __http: ReturnType<typeof stubFetch> }).__http = stubFetch(); (
globalThis as unknown as { __http: ReturnType<typeof stubFetch> }
).__http = stubFetch();
const transport = await TransportHTTP.create("127.0.0.1:80", false); const transport = await TransportHTTP.create("127.0.0.1:80", false);
await tickNextTimer(); await tickNextTimer();
return transport; return transport;
}, },
pushIncoming: async (bytes) => { pushIncoming: async (bytes) => {
(globalThis as unknown as { __http: ReturnType<typeof stubFetch> }).__http.pushIncoming(bytes); (
globalThis as unknown as { __http: ReturnType<typeof stubFetch> }
).__http.pushIncoming(bytes);
await tickNextTimer(); await tickNextTimer();
}, },
assertLastWritten: (bytes) => { assertLastWritten: (bytes) => {
(globalThis as unknown as { __http: ReturnType<typeof stubFetch> }).__http.assertLastWritten(bytes); (
globalThis as unknown as { __http: ReturnType<typeof stubFetch> }
).__http.assertLastWritten(bytes);
}, },
triggerDisconnect: async () => { triggerDisconnect: async () => {
(globalThis as unknown as { __http: ReturnType<typeof stubFetch> }).__http.forceReadErrorOnce(); (
globalThis as unknown as { __http: ReturnType<typeof stubFetch> }
).__http.forceReadErrorOnce();
await tickNextTimer(); await tickNextTimer();
}, },
}); });

20
packages/transport-node-serial/src/transport.test.ts

@ -1,7 +1,7 @@
import { describe, vi, expect, beforeEach, afterEach, it } from "vitest";
import { Duplex } from "node:stream"; import { Duplex } from "node:stream";
import type { SerialPort } from "serialport";
import { Types, Utils } from "@meshtastic/core"; import { Types, Utils } from "@meshtastic/core";
import type { SerialPort } from "serialport";
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
import { runTransportContract } from "../../../tests/utils/transportContract"; import { runTransportContract } from "../../../tests/utils/transportContract";
import { TransportNodeSerial } from "./transport"; import { TransportNodeSerial } from "./transport";
@ -112,21 +112,21 @@ describe("TransportNodeSerial (contract)", () => {
return transport; return transport;
}, },
pushIncoming: async (bytes) => { pushIncoming: async (bytes) => {
(globalThis as unknown as { __fakePort: FakeSerialPort }).__fakePort.pushIncoming( (
bytes, globalThis as unknown as { __fakePort: FakeSerialPort }
); ).__fakePort.pushIncoming(bytes);
await Promise.resolve(); await Promise.resolve();
}, },
assertLastWritten: (bytes) => { assertLastWritten: (bytes) => {
const port = const port = (globalThis as unknown as { __fakePort: FakeSerialPort })
(globalThis as unknown as { __fakePort: FakeSerialPort }).__fakePort; .__fakePort;
expect(port.lastWritten).toBeDefined(); expect(port.lastWritten).toBeDefined();
expect(port.lastWritten).toEqual(bytes); expect(port.lastWritten).toEqual(bytes);
}, },
triggerDisconnect: async () => { triggerDisconnect: async () => {
(globalThis as unknown as { __fakePort: FakeSerialPort }).__fakePort.emitErrorOnce( (
"test-disconnect", globalThis as unknown as { __fakePort: FakeSerialPort }
); ).__fakePort.emitErrorOnce("test-disconnect");
await Promise.resolve(); await Promise.resolve();
}, },
}); });

35
packages/transport-node/src/transport.test.ts

@ -1,9 +1,9 @@
import { describe, vi, expect, beforeEach, afterEach, it } from "vitest";
import { Duplex } from "node:stream";
import type { Socket } from "node:net"; import type { Socket } from "node:net";
import { Duplex } from "node:stream";
import { Types, Utils } from "@meshtastic/core";
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
import { runTransportContract } from "../../../tests/utils/transportContract"; import { runTransportContract } from "../../../tests/utils/transportContract";
import { TransportNode } from "./transport"; import { TransportNode } from "./transport";
import { Utils, Types } from "@meshtastic/core";
function isStatusEvent( function isStatusEvent(
out: Types.DeviceOutput | undefined, out: Types.DeviceOutput | undefined,
@ -71,15 +71,13 @@ function stubCoreTransforms() {
toDevice as unknown as typeof Utils.toDeviceStream, toDevice as unknown as typeof Utils.toDeviceStream,
); );
vi vi.spyOn(Utils, "fromDeviceStream").mockImplementation(
.spyOn(Utils, "fromDeviceStream") () =>
.mockImplementation( fromDeviceFactory() as unknown as TransformStream<
() => Uint8Array,
fromDeviceFactory() as unknown as TransformStream< Types.DeviceOutput
Uint8Array, >,
Types.DeviceOutput );
>,
);
return { return {
restore: () => vi.restoreAllMocks(), restore: () => vi.restoreAllMocks(),
@ -112,9 +110,9 @@ describe("TransportNode (contract)", () => {
return transport; return transport;
}, },
pushIncoming: async (bytes) => { pushIncoming: async (bytes) => {
(globalThis as unknown as { __nodeSock: FakeSocket }).__nodeSock.pushIncoming( (
bytes, globalThis as unknown as { __nodeSock: FakeSocket }
); ).__nodeSock.pushIncoming(bytes);
await Promise.resolve(); await Promise.resolve();
}, },
assertLastWritten: (bytes) => { assertLastWritten: (bytes) => {
@ -124,9 +122,9 @@ describe("TransportNode (contract)", () => {
expect(sock.lastWritten).toEqual(bytes); expect(sock.lastWritten).toEqual(bytes);
}, },
triggerDisconnect: async () => { triggerDisconnect: async () => {
(globalThis as unknown as { __nodeSock: FakeSocket }).__nodeSock.emitErrorOnce( (
"test-disconnect", globalThis as unknown as { __nodeSock: FakeSocket }
); ).__nodeSock.emitErrorOnce("test-disconnect");
await Promise.resolve(); await Promise.resolve();
}, },
}); });
@ -182,5 +180,4 @@ describe("TransportNode (extras)", () => {
reader.releaseLock(); reader.releaseLock();
await transport.disconnect(); await transport.disconnect();
}); });
}); });

3
packages/web/src/components/Dialog/DeleteMessagesDialog/DeleteMessagesDialog.test.tsx

@ -1,8 +1,7 @@
import { DeleteMessagesDialog } from "@components/Dialog/DeleteMessagesDialog/DeleteMessagesDialog.tsx"; import { DeleteMessagesDialog } from "@components/Dialog/DeleteMessagesDialog/DeleteMessagesDialog.tsx";
import { useMessageStore } from "@core/stores";
import { fireEvent, render, screen } from "@testing-library/react"; import { fireEvent, render, screen } from "@testing-library/react";
import { beforeEach, describe, expect, it, vi } from "vitest"; import { beforeEach, describe, expect, it, vi } from "vitest";
// Ensure the path is correct for import
import { useMessageStore } from "@core/stores";
vi.mock("@core/stores", () => ({ vi.mock("@core/stores", () => ({
useMessageStore: vi.fn(() => ({ useMessageStore: vi.fn(() => ({

77
packages/web/src/components/Dialog/RebootDialog.test.tsx

@ -1,4 +1,4 @@
import { fireEvent, render, screen, act } from "@testing-library/react"; import { act, fireEvent, render, screen } from "@testing-library/react";
import type { import type {
ButtonHTMLAttributes, ButtonHTMLAttributes,
ClassAttributes, ClassAttributes,
@ -11,10 +11,12 @@ import { RebootDialog } from "./RebootDialog.tsx";
const rebootMock = vi.fn(); const rebootMock = vi.fn();
const rebootOtaMock = vi.fn(); const rebootOtaMock = vi.fn();
let mockConnection: { let mockConnection:
rebootOta: (delay: number) => void, | {
reboot: (delay: number) => void rebootOta: (delay: number) => void;
} | undefined = { reboot: (delay: number) => void;
}
| undefined = {
reboot: rebootMock, reboot: rebootMock,
rebootOta: rebootOtaMock, rebootOta: rebootOtaMock,
}; };
@ -82,42 +84,44 @@ describe("RebootDialog", () => {
expect( expect(
screen.getByRole("heading", { name: /reboot device/i, level: 1 }), screen.getByRole("heading", { name: /reboot device/i, level: 1 }),
).toBeInTheDocument(); ).toBeInTheDocument();
expect(screen.getByRole("button", { name: /reboot now/i })).toBeInTheDocument(); expect(
screen.getByRole("button", { name: /reboot now/i }),
).toBeInTheDocument();
}); });
it("calls correct reboot function based on OTA checkbox state", () => { it("calls correct reboot function based on OTA checkbox state", () => {
render(<RebootDialog open onOpenChange={() => {}} />); render(<RebootDialog open onOpenChange={() => {}} />);
// Schedule non-OTA reboot // Schedule non-OTA reboot
act(() => { act(() => {
fireEvent.click(screen.getByTestId("scheduleRebootBtn")); fireEvent.click(screen.getByTestId("scheduleRebootBtn"));
}); });
expect(rebootMock).toHaveBeenCalledWith(5); expect(rebootMock).toHaveBeenCalledWith(5);
expect(rebootOtaMock).not.toHaveBeenCalled(); expect(rebootOtaMock).not.toHaveBeenCalled();
rebootMock.mockClear(); rebootMock.mockClear();
rebootOtaMock.mockClear(); rebootOtaMock.mockClear();
// Cancel scheduled // Cancel scheduled
act(() => { act(() => {
fireEvent.click(screen.getByTestId("cancelRebootBtn")); fireEvent.click(screen.getByTestId("cancelRebootBtn"));
}); });
expect(rebootMock).toHaveBeenCalledWith(-1); expect(rebootMock).toHaveBeenCalledWith(-1);
expect(rebootOtaMock).not.toHaveBeenCalled(); expect(rebootOtaMock).not.toHaveBeenCalled();
rebootMock.mockClear(); rebootMock.mockClear();
rebootOtaMock.mockClear(); rebootOtaMock.mockClear();
// Schedule OTA reboot // Schedule OTA reboot
act(() => { act(() => {
fireEvent.click(screen.getByText(/reboot into ota mode/i)); fireEvent.click(screen.getByText(/reboot into ota mode/i));
});
act(() => {
fireEvent.click(screen.getByTestId("scheduleRebootBtn"));
});
expect(rebootOtaMock).toHaveBeenCalledWith(5);
expect(rebootMock).not.toHaveBeenCalled();
}); });
act(() => {
fireEvent.click(screen.getByTestId("scheduleRebootBtn"));
});
expect(rebootOtaMock).toHaveBeenCalledWith(5);
expect(rebootMock).not.toHaveBeenCalled();
});
it("schedules a reboot with delay and calls rebootOta", async () => { it("schedules a reboot with delay and calls rebootOta", async () => {
const onOpenChangeMock = vi.fn(); const onOpenChangeMock = vi.fn();
@ -132,7 +136,7 @@ describe("RebootDialog", () => {
act(() => { act(() => {
fireEvent.click(screen.getByTestId("scheduleRebootBtn")); fireEvent.click(screen.getByTestId("scheduleRebootBtn"));
}); });
expect(rebootMock).toHaveBeenCalledWith(3); expect(rebootMock).toHaveBeenCalledWith(3);
expect(screen.getByText(/reboot has been scheduled/i)).toBeInTheDocument(); expect(screen.getByText(/reboot has been scheduled/i)).toBeInTheDocument();
@ -142,7 +146,6 @@ describe("RebootDialog", () => {
}); });
expect(onOpenChangeMock).toHaveBeenCalledWith(false); expect(onOpenChangeMock).toHaveBeenCalledWith(false);
}); });
it("triggers an instant reboot", async () => { it("triggers an instant reboot", async () => {
@ -196,6 +199,8 @@ describe("RebootDialog", () => {
fireEvent.click(screen.getByRole("button", { name: /cancel/i })); fireEvent.click(screen.getByRole("button", { name: /cancel/i }));
}); });
expect(rebootMock).toHaveBeenCalledWith(-1); expect(rebootMock).toHaveBeenCalledWith(-1);
expect(screen.queryByText(/reboot has been scheduled/i)).not.toBeInTheDocument(); expect(
screen.queryByText(/reboot has been scheduled/i),
).not.toBeInTheDocument();
}); });
}); });

10
packages/web/src/components/Dialog/RefreshKeysDialog/RefreshKeysDialog.test.tsx

@ -1,11 +1,17 @@
import { CurrentDeviceContext, useDeviceStore, useMessageStore } from "@core/stores"; import {
CurrentDeviceContext,
useDeviceStore,
useMessageStore,
} from "@core/stores";
import { render } from "@testing-library/react"; import { render } from "@testing-library/react";
import { afterEach, beforeEach, expect, test, vi } from "vitest"; import { afterEach, beforeEach, expect, test, vi } from "vitest";
import { RefreshKeysDialog } from "./RefreshKeysDialog.tsx"; import { RefreshKeysDialog } from "./RefreshKeysDialog.tsx";
import { useRefreshKeysDialog } from "./useRefreshKeysDialog.ts"; import { useRefreshKeysDialog } from "./useRefreshKeysDialog.ts";
vi.mock("@core/stores", async () => { vi.mock("@core/stores", async () => {
const actual = (await vi.importActual("@core/stores")) as typeof import("@core/stores"); const actual = (await vi.importActual(
"@core/stores",
)) as typeof import("@core/stores");
return { return {
...actual, ...actual,
useMessageStore: vi.fn(), useMessageStore: vi.fn(),

2
packages/web/src/components/Dialog/UnsafeRolesDialog/useUnsafeRolesDialog.test.tsx

@ -38,7 +38,7 @@ const mockDevice = {
vi.mock("@core/stores", () => ({ vi.mock("@core/stores", () => ({
CurrentDeviceContext: { CurrentDeviceContext: {
_currentValue: { deviceId: 123 }, _currentValue: { deviceId: 123 },
}, },
useDevice: () => ({ useDevice: () => ({
setDialogOpen: mockDevice.setDialogOpen, setDialogOpen: mockDevice.setDialogOpen,

3
packages/web/src/components/PageComponents/Messages/TraceRoute.test.tsx

@ -1,6 +1,6 @@
import { TraceRoute } from "@components/PageComponents/Messages/TraceRoute.tsx"; import { TraceRoute } from "@components/PageComponents/Messages/TraceRoute.tsx";
import { mockNodeDBStore } from "@core/stores/nodeDBStore/nodeDBStore.mock.ts";
import { useNodeDB } from "@core/stores"; import { useNodeDB } from "@core/stores";
import { mockNodeDBStore } from "@core/stores/nodeDBStore/nodeDBStore.mock.ts";
import { Protobuf } from "@meshtastic/core"; import { Protobuf } from "@meshtastic/core";
import { render, screen } from "@testing-library/react"; import { render, screen } from "@testing-library/react";
import { beforeEach, describe, expect, it, vi } from "vitest"; import { beforeEach, describe, expect, it, vi } from "vitest";
@ -64,7 +64,6 @@ describe("TraceRoute", () => {
]); ]);
beforeEach(() => { beforeEach(() => {
vi.resetAllMocks(); vi.resetAllMocks();
vi.mocked(useNodeDB).mockReturnValue({ vi.mocked(useNodeDB).mockReturnValue({
...mockNodeDBStore, ...mockNodeDBStore,

13
packages/web/src/components/UI/Checkbox/Checkbox.test.tsx

@ -58,7 +58,9 @@ describe("Checkbox", () => {
it("controlled: reflects external prop changes after onChange", () => { it("controlled: reflects external prop changes after onChange", () => {
const onChange = vi.fn(); const onChange = vi.fn();
const { rerender } = render(<Checkbox checked={false} onChange={onChange} />); const { rerender } = render(
<Checkbox checked={false} onChange={onChange} />,
);
const checkbox = screen.getByRole("checkbox"); const checkbox = screen.getByRole("checkbox");
const presentation = screen.getByRole("presentation"); const presentation = screen.getByRole("presentation");
@ -79,7 +81,9 @@ describe("Checkbox", () => {
it("renders children inside the label", () => { it("renders children inside the label", () => {
render(<Checkbox>Test Label</Checkbox>); render(<Checkbox>Test Label</Checkbox>);
expect(screen.getByTestId("label-component")).toHaveTextContent("Test Label"); expect(screen.getByTestId("label-component")).toHaveTextContent(
"Test Label",
);
}); });
it("applies custom className to wrapper label", () => { it("applies custom className to wrapper label", () => {
@ -112,7 +116,10 @@ describe("Checkbox", () => {
it("passes through additional props to the input", () => { it("passes through additional props to the input", () => {
render(<Checkbox data-testid="extra-prop" />); render(<Checkbox data-testid="extra-prop" />);
expect(screen.getByRole("checkbox")).toHaveAttribute("data-testid", "extra-prop"); expect(screen.getByRole("checkbox")).toHaveAttribute(
"data-testid",
"extra-prop",
);
}); });
it("uncontrolled: toggles checked state when clicking the visual box", () => { it("uncontrolled: toggles checked state when clicking the visual box", () => {

2
packages/web/src/core/hooks/useFavoriteNode.test.ts

@ -18,7 +18,7 @@ const mockSendAdminMessage = vi.fn();
vi.mock("@core/stores", () => ({ vi.mock("@core/stores", () => ({
CurrentDeviceContext: { CurrentDeviceContext: {
_currentValue: { deviceId: 1234 }, _currentValue: { deviceId: 1234 },
}, },
useNodeDB: () => ({ useNodeDB: () => ({
updateFavorite: mockUpdateFavorite, updateFavorite: mockUpdateFavorite,

4
packages/web/src/core/hooks/useIgnoreNode.test.ts

@ -17,8 +17,8 @@ const mockToast = vi.fn();
const mockSendAdminMessage = vi.fn(); const mockSendAdminMessage = vi.fn();
vi.mock("@core/stores", () => ({ vi.mock("@core/stores", () => ({
CurrentDeviceContext: { CurrentDeviceContext: {
_currentValue: { deviceId: 1234 }, _currentValue: { deviceId: 1234 },
}, },
useNodeDB: () => ({ useNodeDB: () => ({
updateIgnore: mockUpdateIgnore, updateIgnore: mockUpdateIgnore,

2
packages/web/src/core/hooks/useToast.test.tsx

@ -28,7 +28,7 @@ describe("useToast", () => {
vi.runAllTimers(); vi.runAllTimers();
}); });
const toast = result.current.toasts[0]; const toast = result.current.toasts[0]!;
expect(result.current.toasts.length).toBe(1); expect(result.current.toasts.length).toBe(1);
expect(toast.title).toBe("Backup Reminder"); expect(toast.title).toBe("Backup Reminder");
expect(toast.description).toBe("Don't forget to backup!"); expect(toast.description).toBe("Don't forget to backup!");

6
packages/web/src/core/stores/utils/indexDB.test.ts

@ -1,5 +1,5 @@
import { beforeEach, describe, expect, it, vi } from "vitest";
import * as idb from "idb-keyval"; import * as idb from "idb-keyval";
import { beforeEach, describe, expect, it, vi } from "vitest";
import { createStorage } from "./indexDB"; import { createStorage } from "./indexDB";
type PersistStorage<T> = ReturnType<typeof createStorage<T>>; type PersistStorage<T> = ReturnType<typeof createStorage<T>>;
@ -109,7 +109,7 @@ describe("indexDB.ts persistence (steps 1–5)", () => {
const out = await roundTrip({ state: { m }, version: 0 }); const out = await roundTrip({ state: { m }, version: 0 });
const m2 = out!.state.m as Map<number, { key: Uint8Array }>; const m2 = out!.state.m as Map<number, { key: Uint8Array }>;
expect(m2 instanceof Map).toBe(true); expect(m2 instanceof Map).toBe(true);
const got = m2.get(42)!; const got = m2.get(42)!;
expect(got.key instanceof Uint8Array).toBe(true); expect(got.key instanceof Uint8Array).toBe(true);
expect(Array.from(got.key)).toEqual([7, 8]); expect(Array.from(got.key)).toEqual([7, 8]);
@ -155,4 +155,4 @@ describe("indexDB.ts persistence (steps 1–5)", () => {
expect(m2 instanceof Map).toBe(true); expect(m2 instanceof Map).toBe(true);
expect(m2.get(1)).toBe("x"); expect(m2.get(1)).toBe("x");
}); });
}); });

Loading…
Cancel
Save