ledgerone_backend/test/auto-sync.service.spec.ts

71 lines
2.1 KiB
TypeScript

import { AutoSyncService } from "../src/transactions/auto-sync.service";
const createService = () => {
const prisma = {
account: {
findMany: jest.fn(),
},
};
const plaid = {
syncTransactionsForUser: jest.fn(),
};
return { service: new AutoSyncService(prisma as any, plaid as any), prisma, plaid };
};
describe("AutoSyncService", () => {
const originalEnv = process.env;
beforeEach(() => {
process.env = {
...originalEnv,
AUTO_SYNC_INTERVAL_MINUTES: "15",
AUTO_SYNC_STALE_MINUTES: "15",
AUTO_SYNC_LOOKBACK_DAYS: "7",
AUTO_SYNC_MAX_USERS_PER_RUN: "25",
};
});
afterEach(() => {
process.env = originalEnv;
jest.restoreAllMocks();
});
it("syncs only stale Plaid users selected by the query", async () => {
const { service, prisma, plaid } = createService();
prisma.account.findMany.mockResolvedValue([{ userId: "user_1" }, { userId: "user_2" }]);
plaid.syncTransactionsForUser.mockResolvedValue({ created: 3 });
const result = await service.runOnce();
expect(prisma.account.findMany).toHaveBeenCalledWith(expect.objectContaining({
where: expect.objectContaining({
isActive: true,
plaidAccessToken: { not: null },
plaidAccountId: { not: null },
syncStatus: { not: "syncing" },
}),
distinct: ["userId"],
take: 25,
}));
expect(plaid.syncTransactionsForUser).toHaveBeenCalledTimes(2);
expect(result).toEqual({ usersScanned: 2, usersSynced: 2, created: 6, failed: 0 });
});
it("skips overlapping runs", async () => {
const { service, prisma, plaid } = createService();
prisma.account.findMany.mockResolvedValue([{ userId: "user_1" }]);
let release!: () => void;
plaid.syncTransactionsForUser.mockReturnValue(new Promise((resolve) => {
release = () => resolve({ created: 1 });
}));
const firstRun = service.runOnce();
const secondRun = await service.runOnce();
release();
await firstRun;
expect(secondRun).toEqual({ skipped: true, reason: "already_running" });
expect(plaid.syncTransactionsForUser).toHaveBeenCalledTimes(1);
});
});