- Extract evaluateCondition + rule types into src/lib/rules.ts for testability - 48 unit tests for evaluateCondition (all fields/operators) and formatCategory - 21 integration tests for getTransactions filters and getParticipantBalances - Vitest configs for unit (vitest.config.ts) and integration (vitest.integration.config.ts) - setup-test-db.sh creates personal_test DB from production schema via pg_dump - Use vi.doMock + dynamic import pattern to isolate test DB from Prisma singleton
77 lines
2.4 KiB
TypeScript
77 lines
2.4 KiB
TypeScript
import { describe, it, expect, beforeEach, afterAll } from "vitest";
|
|
import { createPool, resetDB } from "./helpers";
|
|
|
|
const pool = createPool();
|
|
|
|
beforeEach(async () => {
|
|
await resetDB(pool);
|
|
});
|
|
|
|
afterAll(async () => {
|
|
await pool.end();
|
|
});
|
|
|
|
// This tests the name-substitution logic applied in /api/participants GET.
|
|
// The rule: the participant matching the current user's ID gets name "Me";
|
|
// everyone else keeps their real name.
|
|
function substituteMe(
|
|
participants: { id: number; name: string }[],
|
|
currentUserId: number
|
|
) {
|
|
return participants.map((p) =>
|
|
p.id === currentUserId ? { ...p, name: "Me" } : p
|
|
);
|
|
}
|
|
|
|
describe("participant Me substitution", () => {
|
|
it("replaces the current user's name with Me", async () => {
|
|
const r = await pool.query(
|
|
`INSERT INTO participants (name) VALUES ('Siddharth') RETURNING id`
|
|
);
|
|
const userId = r.rows[0].id;
|
|
const participants = [
|
|
{ id: userId, name: "Siddharth" },
|
|
{ id: userId + 1, name: "Sonu" },
|
|
];
|
|
|
|
const result = substituteMe(participants, userId);
|
|
expect(result.find((p) => p.id === userId)?.name).toBe("Me");
|
|
expect(result.find((p) => p.id === userId + 1)?.name).toBe("Sonu");
|
|
});
|
|
|
|
it("leaves all names unchanged when currentUserId does not match", () => {
|
|
const participants = [
|
|
{ id: 1, name: "Siddharth" },
|
|
{ id: 2, name: "Sonu" },
|
|
];
|
|
const result = substituteMe(participants, 999);
|
|
expect(result).toEqual(participants);
|
|
});
|
|
|
|
it("Sonu sees Me for herself and Siddharth for the primary user", async () => {
|
|
const r1 = await pool.query(
|
|
`INSERT INTO participants (name) VALUES ('Siddharth') RETURNING id`
|
|
);
|
|
const r2 = await pool.query(
|
|
`INSERT INTO participants (name, email) VALUES ('Sonu', 'sonu@example.com') RETURNING id`
|
|
);
|
|
const siddharthId = r1.rows[0].id;
|
|
const sonuId = r2.rows[0].id;
|
|
|
|
const rawParticipants = [
|
|
{ id: siddharthId, name: "Siddharth" },
|
|
{ id: sonuId, name: "Sonu" },
|
|
];
|
|
|
|
// Siddharth's view
|
|
const siddharthView = substituteMe(rawParticipants, siddharthId);
|
|
expect(siddharthView.find((p) => p.id === siddharthId)?.name).toBe("Me");
|
|
expect(siddharthView.find((p) => p.id === sonuId)?.name).toBe("Sonu");
|
|
|
|
// Sonu's view
|
|
const sonuView = substituteMe(rawParticipants, sonuId);
|
|
expect(sonuView.find((p) => p.id === siddharthId)?.name).toBe("Siddharth");
|
|
expect(sonuView.find((p) => p.id === sonuId)?.name).toBe("Me");
|
|
});
|
|
});
|