73 lines
2.3 KiB
TypeScript
73 lines
2.3 KiB
TypeScript
// @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<typeof vi.fn>;
|
|
const findMany = db.log.findMany as unknown as ReturnType<typeof vi.fn>;
|
|
|
|
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<string, Date> = {
|
|
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);
|
|
});
|
|
});
|