mirror of
https://github.com/ramvignesh-b/pi-ku.git
synced 2026-05-04 08:56:52 +00:00
test: enhance tests to be specific
This commit is contained in:
@@ -1,13 +1,5 @@
|
||||
import { HttpResponse, http } from "msw";
|
||||
import {
|
||||
afterAll,
|
||||
beforeAll,
|
||||
beforeEach,
|
||||
describe,
|
||||
expect,
|
||||
it,
|
||||
vi,
|
||||
} from "vitest";
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import { mockUser } from "../../test/fixtures/user.fixture";
|
||||
import { server } from "../../test/mocks/server";
|
||||
import { useAuthStore } from "../store/useAuthStore";
|
||||
@@ -21,13 +13,10 @@ beforeEach(() => {
|
||||
user: null,
|
||||
isInitializing: false,
|
||||
});
|
||||
});
|
||||
|
||||
beforeAll(() => {
|
||||
vi.stubEnv("VITE_API_URL", VITE_API_URL);
|
||||
});
|
||||
|
||||
afterAll(() => {
|
||||
afterEach(() => {
|
||||
vi.unstubAllEnvs();
|
||||
});
|
||||
|
||||
|
||||
@@ -6,7 +6,6 @@ import { mockUser } from "../../test/fixtures/user.fixture";
|
||||
import { server } from "../../test/mocks/server";
|
||||
import { useAuthStore } from "../store/useAuthStore";
|
||||
import { useKeyStore } from "../store/useKeyStore";
|
||||
import { CryptoUtils } from "../utils/crypto";
|
||||
import {
|
||||
clearMasterKey,
|
||||
loadMasterKey,
|
||||
@@ -14,7 +13,6 @@ import {
|
||||
} from "../utils/keystore";
|
||||
import { useAuth } from "./useAuth";
|
||||
|
||||
vi.mock("../utils/crypto");
|
||||
vi.mock("../utils/keystore");
|
||||
|
||||
const VITE_API_URL = "http://piku-server";
|
||||
@@ -22,12 +20,6 @@ const VITE_API_URL = "http://piku-server";
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks();
|
||||
|
||||
// hack to set up mock implementations using fixtures
|
||||
vi.mocked(CryptoUtils.deriveKeyBundle).mockResolvedValue({
|
||||
masterKey: mockMasterKey,
|
||||
authHash: "mock-auth-hash",
|
||||
});
|
||||
|
||||
vi.mocked(loadMasterKey).mockResolvedValue(mockMasterKey);
|
||||
vi.mocked(saveMasterKey).mockResolvedValue("masterKey");
|
||||
vi.mocked(clearMasterKey).mockResolvedValue(undefined);
|
||||
|
||||
@@ -0,0 +1,113 @@
|
||||
import { renderHook, waitFor } from "@testing-library/react";
|
||||
import { HttpResponse, http } from "msw";
|
||||
import { beforeEach, describe, expect, it } from "vitest";
|
||||
import { server } from "../../test/mocks/server";
|
||||
import { endpoints } from "../config/endpoints";
|
||||
import { useKeyStore } from "../store/useKeyStore";
|
||||
import { CryptoUtils } from "../utils/crypto";
|
||||
import { useLetters } from "./useLetters";
|
||||
|
||||
describe("useLetters hook", () => {
|
||||
let masterKey: CryptoKey;
|
||||
let utils: CryptoUtils;
|
||||
|
||||
beforeEach(async () => {
|
||||
utils = new CryptoUtils();
|
||||
await utils.initialize();
|
||||
const bundle = await CryptoUtils.deriveKeyBundle("password", "salt");
|
||||
masterKey = bundle.masterKey;
|
||||
|
||||
useKeyStore.setState({ masterKey: null });
|
||||
});
|
||||
|
||||
it("should indicate authentication is required when masterKey is missing", () => {
|
||||
const { result } = renderHook(() => useLetters());
|
||||
|
||||
expect(result.current.isAuthRequired).toBe(true);
|
||||
});
|
||||
|
||||
it("should fetch, decrypt, and categorize letters when masterKey is present", async () => {
|
||||
useKeyStore.setState({ masterKey });
|
||||
|
||||
const draftPayload = { objects: [] };
|
||||
const encryptedDraft = await utils.encryptMetadata(
|
||||
{ recipient: "Draft Recipient" },
|
||||
masterKey,
|
||||
);
|
||||
|
||||
const lettersResponse = [
|
||||
{
|
||||
public_id: "letter-1",
|
||||
type: "KEPT",
|
||||
status: "DRAFT",
|
||||
updated_at: new Date().toISOString(),
|
||||
encrypted_metadata: encryptedDraft.encrypted_content,
|
||||
encrypted_content: JSON.stringify(draftPayload),
|
||||
encrypted_dek: encryptedDraft.encrypted_dek,
|
||||
},
|
||||
];
|
||||
|
||||
server.use(
|
||||
http.get(`${import.meta.env.VITE_API_URL}${endpoints.LETTERS}`, () => {
|
||||
return HttpResponse.json(lettersResponse);
|
||||
}),
|
||||
);
|
||||
|
||||
const { result } = renderHook(() => useLetters());
|
||||
|
||||
// Initially loading
|
||||
expect(result.current.loading).toBe(true);
|
||||
|
||||
await waitFor(() => expect(result.current.loading).toBe(false));
|
||||
|
||||
expect(result.current.drafts).toHaveLength(1);
|
||||
expect(result.current.drafts[0].metadata.recipient).toBe("Draft Recipient");
|
||||
expect(result.current.kept).toHaveLength(0);
|
||||
});
|
||||
|
||||
it("should sort letters by updated_at in descending order", async () => {
|
||||
useKeyStore.setState({ masterKey });
|
||||
|
||||
const metadata = await utils.encryptMetadata(
|
||||
{ recipient: "test" },
|
||||
masterKey,
|
||||
);
|
||||
|
||||
const now = new Date();
|
||||
const older = new Date(now.getTime() - 10000);
|
||||
|
||||
const lettersResponse = [
|
||||
{
|
||||
public_id: "older",
|
||||
type: "KEPT",
|
||||
status: "SEALED",
|
||||
updated_at: older.toISOString(),
|
||||
encrypted_metadata: metadata.encrypted_content,
|
||||
encrypted_content: "{}",
|
||||
encrypted_dek: metadata.encrypted_dek,
|
||||
},
|
||||
{
|
||||
public_id: "newer",
|
||||
type: "KEPT",
|
||||
status: "SEALED",
|
||||
updated_at: now.toISOString(),
|
||||
encrypted_metadata: metadata.encrypted_content,
|
||||
encrypted_content: "{}",
|
||||
encrypted_dek: metadata.encrypted_dek,
|
||||
},
|
||||
];
|
||||
|
||||
server.use(
|
||||
http.get(`${import.meta.env.VITE_API_URL}${endpoints.LETTERS}`, () => {
|
||||
return HttpResponse.json(lettersResponse);
|
||||
}),
|
||||
);
|
||||
|
||||
const { result } = renderHook(() => useLetters());
|
||||
|
||||
await waitFor(() => expect(result.current.loading).toBe(false));
|
||||
|
||||
expect(result.current.kept[0].public_id).toBe("newer");
|
||||
expect(result.current.kept[1].public_id).toBe("older");
|
||||
});
|
||||
});
|
||||
@@ -1,10 +1,13 @@
|
||||
import { render, screen } from "@testing-library/react";
|
||||
import { MemoryRouter } from "react-router-dom";
|
||||
import { beforeEach, describe, expect, it } from "vitest";
|
||||
import { beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import { mockUser } from "../../test/fixtures/user.fixture";
|
||||
import { useLetters } from "../hooks/useLetters";
|
||||
import { useAuthStore } from "../store/useAuthStore";
|
||||
import Drawer from "./Drawer";
|
||||
|
||||
vi.mock("../hooks/useLetters");
|
||||
|
||||
describe("Drawer Page", () => {
|
||||
beforeEach(() => {
|
||||
// Setup authenticated state for the test
|
||||
@@ -13,6 +16,15 @@ describe("Drawer Page", () => {
|
||||
accessToken: "fake-token",
|
||||
isInitializing: false,
|
||||
});
|
||||
|
||||
vi.mocked(useLetters).mockReturnValue({
|
||||
drafts: [],
|
||||
kept: [],
|
||||
sent: [],
|
||||
vault: [],
|
||||
loading: false,
|
||||
isAuthRequired: false,
|
||||
});
|
||||
});
|
||||
|
||||
it("renders the cabinet sections and empty state message", () => {
|
||||
@@ -27,4 +39,43 @@ describe("Drawer Page", () => {
|
||||
expect(screen.getByText(/Vault/i)).toBeInTheDocument();
|
||||
expect(screen.getByText(/This drawer remains silent/i)).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("renders the loading state", () => {
|
||||
vi.mocked(useLetters).mockReturnValue({
|
||||
drafts: [],
|
||||
kept: [],
|
||||
sent: [],
|
||||
vault: [],
|
||||
loading: true,
|
||||
isAuthRequired: false,
|
||||
});
|
||||
|
||||
render(
|
||||
<MemoryRouter>
|
||||
<Drawer />
|
||||
</MemoryRouter>,
|
||||
);
|
||||
|
||||
expect(screen.getByText(/Opening your cabinet/i)).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("renders the authentication required modal when api requires auth", () => {
|
||||
vi.mocked(useLetters).mockReturnValue({
|
||||
drafts: [],
|
||||
kept: [],
|
||||
sent: [],
|
||||
vault: [],
|
||||
loading: false,
|
||||
isAuthRequired: true,
|
||||
});
|
||||
|
||||
render(
|
||||
<MemoryRouter>
|
||||
<Drawer />
|
||||
</MemoryRouter>,
|
||||
);
|
||||
|
||||
expect(screen.getByText(/Authentication Required/i)).toBeInTheDocument();
|
||||
expect(screen.getByPlaceholderText(/password/i)).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -169,7 +169,7 @@ describe("encryptImage / decryptImage", () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe("Sharing Key Decryption (TDD)", () => {
|
||||
describe("Sharing Key Decryption", () => {
|
||||
let masterKey: CryptoKey;
|
||||
beforeEach(async () => {
|
||||
const bundle = await CryptoUtils.deriveKeyBundle("password", "salt");
|
||||
|
||||
Reference in New Issue
Block a user