ledgerone_backend/test/credit-score.service.spec.ts

72 lines
2.4 KiB
TypeScript

/// <reference types="jest" />
import { CreditScoreService } from "../src/credit-score/credit-score.service";
import { createPrismaMock } from "./utils/mock-prisma";
describe("CreditScoreService", () => {
const userId = "user_1";
let prisma: ReturnType<typeof createPrismaMock>;
let notifications: { notifyUser: jest.Mock };
let service: CreditScoreService;
beforeEach(() => {
prisma = createPrismaMock();
notifications = { notifyUser: jest.fn().mockResolvedValue({}) };
service = new CreditScoreService(prisma as never, notifications as never);
prisma.auditLog.create.mockResolvedValue({});
});
it("creates a score entry and sends an alert for a large drop", async () => {
prisma.creditScoreEntry.findFirst.mockResolvedValue({
id: "old_1",
userId,
score: 760,
bureau: "experian",
scoreDate: new Date("2026-06-01T00:00:00.000Z"),
});
prisma.creditScoreEntry.create.mockResolvedValue({
id: "score_1",
userId,
score: 730,
bureau: "experian",
source: "manual",
model: "fico_8",
scoreDate: new Date("2026-07-01T00:00:00.000Z"),
factors: {},
metadata: {},
});
const result = await service.createEntry(userId, {
score: 730,
bureau: "experian",
model: "fico_8",
scoreDate: "2026-07-01",
});
expect(result.change).toBe(-30);
expect(prisma.auditLog.create).toHaveBeenCalledWith(expect.objectContaining({
data: expect.objectContaining({ action: "credit_score.entry_create" }),
}));
expect(notifications.notifyUser).toHaveBeenCalledWith(userId, expect.objectContaining({
type: "credit_score.change",
severity: "warning",
}));
});
it("summarizes latest score, bureau snapshots, and trend", async () => {
prisma.creditScoreEntry.findMany.mockResolvedValue([
{ id: "s2", score: 720, bureau: "equifax", scoreDate: new Date("2026-07-05T00:00:00.000Z") },
{ id: "s1", score: 700, bureau: "equifax", scoreDate: new Date("2026-06-05T00:00:00.000Z") },
{ id: "s3", score: 740, bureau: "experian", scoreDate: new Date("2026-07-01T00:00:00.000Z") },
]);
const summary = await service.summary(userId);
expect(summary.latest.id).toBe("s2");
expect(summary.change).toBe(20);
expect(summary.averageScore).toBe(720);
expect(summary.latestByBureau).toHaveLength(2);
expect(summary.trend).toHaveLength(3);
});
});