/* eslint-disable max-lines-per-function -- Test suites naturally have many cases */ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; vi.mock("../../src/db/client.js", () => ({ prisma: { player: { updateMany: vi.fn() }, }, })); vi.mock("../../src/services/logger.js", () => ({ logger: { error: vi.fn().mockResolvedValue(undefined), log: vi.fn().mockResolvedValue(undefined), }, })); import { prisma } from "../../src/db/client.js"; const discordGuildId = "1354624415861833870"; describe("gateway service", () => { beforeEach(() => { vi.resetAllMocks(); }); afterEach(() => { vi.clearAllMocks(); }); describe("handleGuildMemberAdd", () => { it("sets inGuild to true for the matching guild", async () => { vi.mocked(prisma.player.updateMany).mockResolvedValueOnce({ count: 1 }); const { handleGuildMemberAdd } = await import("../../src/services/gateway.js"); await handleGuildMemberAdd("user123", discordGuildId); expect(prisma.player.updateMany).toHaveBeenCalledWith({ data: { inGuild: true }, where: { discordId: "user123" }, }); }); it("no-ops when guild id does not match the configured guild", async () => { const { handleGuildMemberAdd } = await import("../../src/services/gateway.js"); await handleGuildMemberAdd("user123", "other_guild"); expect(prisma.player.updateMany).not.toHaveBeenCalled(); }); it("logs error when prisma throws an Error", async () => { const dbError = new Error("DB failure"); vi.mocked(prisma.player.updateMany).mockRejectedValueOnce(dbError); const { handleGuildMemberAdd } = await import("../../src/services/gateway.js"); const { logger } = await import("../../src/services/logger.js"); await handleGuildMemberAdd("user123", discordGuildId); expect(logger.error).toHaveBeenCalledWith("gateway_member_add", dbError); }); it("logs error when prisma throws a non-Error", async () => { vi.mocked(prisma.player.updateMany).mockRejectedValueOnce("raw error"); const { handleGuildMemberAdd } = await import("../../src/services/gateway.js"); const { logger } = await import("../../src/services/logger.js"); await handleGuildMemberAdd("user123", discordGuildId); expect(logger.error).toHaveBeenCalledWith( "gateway_member_add", new Error("raw error"), ); }); }); describe("handleGuildMemberRemove", () => { it("sets inGuild to false for the matching guild", async () => { vi.mocked(prisma.player.updateMany).mockResolvedValueOnce({ count: 1 }); const { handleGuildMemberRemove } = await import("../../src/services/gateway.js"); await handleGuildMemberRemove("user123", discordGuildId); expect(prisma.player.updateMany).toHaveBeenCalledWith({ data: { inGuild: false }, where: { discordId: "user123" }, }); }); it("no-ops when guild id does not match the configured guild", async () => { const { handleGuildMemberRemove } = await import("../../src/services/gateway.js"); await handleGuildMemberRemove("user123", "other_guild"); expect(prisma.player.updateMany).not.toHaveBeenCalled(); }); it("logs error when prisma throws an Error", async () => { const dbError = new Error("DB failure"); vi.mocked(prisma.player.updateMany).mockRejectedValueOnce(dbError); const { handleGuildMemberRemove } = await import("../../src/services/gateway.js"); const { logger } = await import("../../src/services/logger.js"); await handleGuildMemberRemove("user123", discordGuildId); expect(logger.error).toHaveBeenCalledWith("gateway_member_remove", dbError); }); it("logs error when prisma throws a non-Error", async () => { vi.mocked(prisma.player.updateMany).mockRejectedValueOnce("raw error"); const { handleGuildMemberRemove } = await import("../../src/services/gateway.js"); const { logger } = await import("../../src/services/logger.js"); await handleGuildMemberRemove("user123", discordGuildId); expect(logger.error).toHaveBeenCalledWith( "gateway_member_remove", new Error("raw error"), ); }); }); });