// @vitest-environment node import { beforeEach, describe, expect, it, vi } from "vitest"; vi.mock("../db.server", () => { return { db: { log: { groupBy: vi.fn(), findMany: vi.fn(), }, }, }; }); import { db } from "../db.server"; import { getLastUserLogsByUserIds } from "./logs.db.server"; const groupBy = db.log.groupBy as unknown as ReturnType; const findMany = db.log.findMany as unknown as ReturnType; describe("getLastUserLogsByUserIds", () => { beforeEach(() => { groupBy.mockReset(); findMany.mockReset(); }); it("issues no queries when given an empty user id list", async () => { const result = await getLastUserLogsByUserIds([]); expect(result.size).toBe(0); expect(groupBy).not.toHaveBeenCalled(); expect(findMany).not.toHaveBeenCalled(); }); it("uses a single groupBy and a single findMany regardless of user count (no N+1)", async () => { const userIds = ["u1", "u2", "u3", "u4", "u5"]; const newest: Record = { u1: new Date("2026-05-01T10:00:00.000Z"), u2: new Date("2026-05-02T10:00:00.000Z"), u3: new Date("2026-05-03T10:00:00.000Z"), }; groupBy.mockResolvedValueOnce( Object.entries(newest).map(([userId, createdAt]) => ({ userId, _max: { createdAt } })) ); findMany.mockResolvedValueOnce( Object.entries(newest).map(([userId, createdAt]) => ({ id: `log-${userId}`, userId, createdAt })) ); const result = await getLastUserLogsByUserIds(userIds); expect(groupBy).toHaveBeenCalledTimes(1); expect(findMany).toHaveBeenCalledTimes(1); expect(groupBy).toHaveBeenCalledWith({ by: ["userId"], where: { userId: { in: userIds } }, _max: { createdAt: true }, }); expect(result.get("u1")).toMatchObject({ id: "log-u1", userId: "u1" }); expect(result.get("u3")).toMatchObject({ id: "log-u3" }); expect(result.size).toBe(3); }); it("skips the findMany when no users have logs", async () => { groupBy.mockResolvedValueOnce([{ userId: "u1", _max: { createdAt: null } }]); const result = await getLastUserLogsByUserIds(["u1"]); expect(groupBy).toHaveBeenCalledTimes(1); expect(findMany).not.toHaveBeenCalled(); expect(result.size).toBe(0); }); });