ledgerone_backend/test/view.service.spec.ts

100 lines
3.4 KiB
TypeScript

/// <reference types="jest" />
import { Prisma } from "@prisma/client";
import { ViewService } from "../src/view/view.service";
import { createPrismaMock } from "./utils/mock-prisma";
describe("ViewService", () => {
const userId = "user_1";
let prisma: ReturnType<typeof createPrismaMock>;
let service: ViewService;
beforeEach(() => {
prisma = createPrismaMock();
service = new ViewService(
prisma as never,
{ create: jest.fn((userId, type, id) => `${type}_${id}_view`) } as never,
);
});
it("returns account presentation data without stable database or provider ids", async () => {
prisma.account.findMany.mockResolvedValue([
{
id: "acct_1",
institutionName: "Bank",
accountType: "checking",
mask: "1234",
currentBalance: new Prisma.Decimal(100),
availableBalance: new Prisma.Decimal(90),
isoCurrencyCode: "USD",
syncStatus: "synced",
lastSyncError: null,
syncConsecutiveFailures: 0,
plaidWebhookCode: null,
plaidWebhookAt: null,
tellerAccountId: null,
ownershipType: "mine",
lastBalanceSync: new Date("2026-07-16T00:00:00.000Z"),
lastTransactionSync: null,
lastSyncAttemptAt: null,
},
]);
prisma.account.count.mockResolvedValue(1);
const result = await service.accounts(userId, 1, 100);
expect(prisma.account.findMany).toHaveBeenCalledWith(expect.objectContaining({ take: 25 }));
expect(result.accounts[0]).toEqual(expect.objectContaining({
viewRef: expect.any(String),
institutionName: "Bank",
currentBalance: "100.00",
}));
expect(result.accounts[0].viewRef).not.toBe("acct_1");
expect(result.accounts[0]).not.toHaveProperty("id");
expect(result.accounts[0]).not.toHaveProperty("plaidAccountId");
expect(result.accounts[0]).not.toHaveProperty("tellerAccountId");
expect(result.limit).toBe(25);
});
it("returns transaction presentation data without raw payloads or action-capable ids", async () => {
prisma.transactionRaw.findMany.mockResolvedValue([
{
id: "tx_1",
date: new Date("2026-07-15T00:00:00.000Z"),
amount: new Prisma.Decimal(42.5),
description: "Coffee",
source: "plaid",
derived: {
userCategory: "Food",
userNotes: "",
attribution: "mine",
splitMode: "none",
splitMinePercent: 50,
splitYoursPercent: 50,
isHidden: false,
},
account: { institutionName: "Bank", accountType: "checking", mask: "1234" },
},
]);
prisma.transactionRaw.count.mockResolvedValue(1);
const result = await service.transactions(userId, { limit: 100 });
expect(prisma.transactionRaw.findMany).toHaveBeenCalledWith(expect.objectContaining({
take: 25,
select: expect.not.objectContaining({ rawPayload: true, bankTransactionId: true, accountId: true }),
}));
expect(result.transactions[0]).toEqual(expect.objectContaining({
viewRef: expect.any(String),
description: "Coffee",
amount: "42.50",
accountLabel: "Bank (checking) ••1234",
}));
expect(result.transactions[0]).not.toHaveProperty("id");
expect(result.transactions[0]).not.toHaveProperty("rawPayload");
expect(result.transactions[0]).not.toHaveProperty("bankTransactionId");
expect(result.transactions[0]).not.toHaveProperty("accountId");
expect(result.limit).toBe(25);
});
});