17 changed files with 471 additions and 368 deletions
@ -1,102 +1,97 @@ |
|||||
import { render, screen, fireEvent } from "@testing-library/react"; |
import { render, screen } from "@testing-library/react"; |
||||
import { beforeEach, describe, expect, it, vi, Mock } from "vitest"; |
import { DeviceContext, useDeviceStore } from "@core/stores/deviceStore.ts"; |
||||
import { RefreshKeysDialog } from "./RefreshKeysDialog.tsx"; |
import { RefreshKeysDialog } from "./RefreshKeysDialog.tsx"; |
||||
|
import { useMessageStore } from "@core/stores/messageStore.ts"; |
||||
import { useRefreshKeysDialog } from "./useRefreshKeysDialog.ts"; |
import { useRefreshKeysDialog } from "./useRefreshKeysDialog.ts"; |
||||
import { useMessageStore } from "@core/stores/messageStore.ts"; // Import for mocking
|
import { expect, test, vi, beforeEach, afterEach } from 'vitest'; |
||||
import { useDevice } from "@core/stores/deviceStore.ts"; // Import for mocking
|
|
||||
import { Protobuf } from "@meshtastic/core"; |
import { Protobuf } from "@meshtastic/core"; |
||||
|
|
||||
|
vi.mock("@core/stores/messageStore"); |
||||
vi.mock("@core/stores/messageStore.ts", () => ({ |
vi.mock("./useRefreshKeysDialog"); |
||||
useMessageStore: vi.fn(), |
|
||||
})); |
const mockUseMessageStore = vi.mocked(useMessageStore); |
||||
|
const mockUseRefreshKeysDialog = vi.mocked(useRefreshKeysDialog); |
||||
const mockNodeWithError: Partial<Protobuf.Mesh.NodeInfo> = { |
|
||||
user: { longName: "Test Node Long", shortName: "TNL", id: 456 }, |
const getInitialState = () => useDeviceStore.getInitialState?.() ?? { devices: new Map(), remoteDevices: new Map() }; |
||||
}; |
|
||||
const mockNodes = new Map([[456, mockNodeWithError]]); |
beforeEach(() => { |
||||
const mockNodeErrors = new Map([[123, { node: 456 }]]); |
useDeviceStore.setState(getInitialState(), true); |
||||
|
vi.clearAllMocks(); |
||||
vi.mock("@core/stores/deviceStore.ts", () => ({ |
}); |
||||
useDevice: vi.fn(), |
|
||||
})); |
afterEach(() => { |
||||
|
vi.restoreAllMocks(); |
||||
const mockHandleCloseDialog = vi.fn(); |
}); |
||||
const mockHandleNodeRemove = vi.fn(); |
|
||||
vi.mock("./useRefreshKeysDialog.ts", () => ({ |
test("renders dialog when there is a node error for the active chat", () => { |
||||
useRefreshKeysDialog: vi.fn(() => ({ |
const deviceId = 1; |
||||
handleCloseDialog: mockHandleCloseDialog, |
const nodeWithErrorNum = 12345; |
||||
handleNodeRemove: mockHandleNodeRemove, |
const activeChatNum = nodeWithErrorNum; |
||||
})), |
|
||||
})); |
const deviceStore = useDeviceStore.getState().addDevice(deviceId); |
||||
|
|
||||
describe("RefreshKeysDialog Component", () => { |
deviceStore.addNodeInfo({ |
||||
let onOpenChangeMock: Mock; |
num: nodeWithErrorNum, |
||||
|
user: { |
||||
beforeEach(() => { |
id: nodeWithErrorNum.toString(), |
||||
vi.clearAllMocks(); |
publicKey: new Uint8Array(0), |
||||
onOpenChangeMock = vi.fn(); |
hwModel: Protobuf.Mesh.HardwareModel.HELTEC_V3, |
||||
|
longName: "Problem Node Long", |
||||
vi.mocked(useMessageStore).mockReturnValue({ activeChat: 123 }); |
shortName: "ProbNode", |
||||
vi.mocked(useDevice).mockReturnValue({ |
isLicensed: false, |
||||
nodeErrors: mockNodeErrors, |
macaddr: new Uint8Array(0) |
||||
nodes: mockNodes, |
}, |
||||
}); |
lastHeard: Date.now() / 1000, |
||||
vi.mocked(useRefreshKeysDialog).mockReturnValue({ |
snr: 10 |
||||
handleCloseDialog: mockHandleCloseDialog, |
} as Protobuf.Mesh.NodeInfo); |
||||
handleNodeRemove: mockHandleNodeRemove, |
|
||||
}); |
deviceStore.setNodeError(activeChatNum, "PKI_MISMATCH"); |
||||
|
|
||||
|
const updatedDeviceState = useDeviceStore.getState().getDevice(deviceId); |
||||
|
if (!updatedDeviceState) { |
||||
|
throw new Error("Failed to get updated device state from store for provider"); |
||||
|
} |
||||
|
|
||||
|
mockUseMessageStore.mockReturnValue({ activeChat: activeChatNum }); |
||||
|
const mockHandleClose = vi.fn(); |
||||
|
const mockHandleRemove = vi.fn(); |
||||
|
mockUseRefreshKeysDialog.mockReturnValue({ |
||||
|
handleCloseDialog: mockHandleClose, |
||||
|
handleNodeRemove: mockHandleRemove, |
||||
}); |
}); |
||||
|
|
||||
it("should render the dialog with dynamic content when open and data is available", () => { |
render( |
||||
render(<RefreshKeysDialog open onOpenChange={onOpenChangeMock} />); |
<DeviceContext.Provider value={updatedDeviceState}> |
||||
|
<RefreshKeysDialog open onOpenChange={vi.fn()} /> |
||||
expect(screen.getByText(`Keys Mismatch - ${mockNodeWithError?.user?.longName}`)).toBeInTheDocument(); |
</DeviceContext.Provider> |
||||
expect(screen.getByText(new RegExp(`${mockNodeWithError?.user?.longName}.*${mockNodeWithError?.user?.shortName}`))).toBeInTheDocument(); |
); |
||||
expect(screen.getByRole('button', { name: /request new keys/i })).toBeInTheDocument(); |
|
||||
expect(screen.getByRole('button', { name: /dismiss/i })).toBeInTheDocument(); |
|
||||
expect(screen.getByRole('button', { name: /Close/i })).toBeInTheDocument(); |
|
||||
}); |
|
||||
|
|
||||
it("should call handleNodeRemove when 'Request New Keys' button is clicked", () => { |
expect(screen.getByText(/Keys Mismatch - Problem Node Long/)).toBeInTheDocument(); |
||||
render(<RefreshKeysDialog open onOpenChange={onOpenChangeMock} />); |
expect(screen.getByText(/Your node is unable to send a direct message to node: Problem Node Long \(ProbNode\)/)).toBeInTheDocument(); |
||||
fireEvent.click(screen.getByRole('button', { name: /request new keys/i })); |
expect(screen.getByRole("button", { name: "Request New Keys" })).toBeInTheDocument(); |
||||
expect(mockHandleNodeRemove).toHaveBeenCalledTimes(1); |
expect(screen.getByRole("button", { name: "Dismiss" })).toBeInTheDocument(); |
||||
}); |
}); |
||||
|
|
||||
it("should call handleCloseDialog when 'Dismiss' button is clicked", () => { |
test("does not render dialog if no error exists for active chat", () => { |
||||
render(<RefreshKeysDialog open onOpenChange={onOpenChangeMock} />); |
const deviceId = 1; |
||||
fireEvent.click(screen.getByRole('button', { name: /dismiss/i })); |
const activeChatNum = 54321; |
||||
expect(mockHandleCloseDialog).toHaveBeenCalledTimes(1); |
|
||||
}); |
|
||||
|
|
||||
it("should call handleCloseDialog when the explicit DialogClose button is clicked", () => { |
useDeviceStore.getState().addDevice(deviceId); |
||||
render(<RefreshKeysDialog open onOpenChange={onOpenChangeMock} />); |
|
||||
fireEvent.click(screen.getByRole('button', { name: /close/i })); // Use the aria-label
|
|
||||
expect(mockHandleCloseDialog).toHaveBeenCalledTimes(1); |
|
||||
}); |
|
||||
|
|
||||
|
const currentDeviceState = useDeviceStore.getState().getDevice(deviceId); |
||||
|
if (!currentDeviceState) throw new Error("Device not found"); |
||||
|
|
||||
it("should not render the dialog when open is false", () => { |
mockUseMessageStore.mockReturnValue({ activeChat: activeChatNum }); |
||||
render(<RefreshKeysDialog open={false} onOpenChange={onOpenChangeMock} />); |
mockUseRefreshKeysDialog.mockReturnValue({ |
||||
expect(screen.queryByRole("dialog")).not.toBeInTheDocument(); |
handleCloseDialog: vi.fn(), |
||||
|
handleNodeRemove: vi.fn(), |
||||
}); |
}); |
||||
|
|
||||
it("should render null if nodeErrorNum is not found for activeChat", () => { |
const { container } = render( |
||||
vi.mocked(useDevice).mockReturnValue({ |
<DeviceContext.Provider value={currentDeviceState}> |
||||
nodeErrors: new Map(), |
<RefreshKeysDialog open onOpenChange={vi.fn()} /> |
||||
nodes: mockNodes, |
</DeviceContext.Provider> |
||||
}); |
); |
||||
const { container } = render(<RefreshKeysDialog open onOpenChange={onOpenChangeMock} />); |
|
||||
expect(container.firstChild).toBeNull(); |
|
||||
}); |
|
||||
|
|
||||
it("should render null if nodeWithError is not found for nodeErrorNum.node", () => { |
expect(container.firstChild).toBeNull(); |
||||
vi.mocked(useDevice).mockReturnValue({ |
}); |
||||
nodeErrors: mockNodeErrors, |
|
||||
nodes: new Map(), |
|
||||
}); |
|
||||
const { container } = render(<RefreshKeysDialog open onOpenChange={onOpenChangeMock} />); |
|
||||
expect(container.firstChild).toBeNull(); |
|
||||
}); |
|
||||
}); |
|
||||
|
|||||
Loading…
Reference in new issue