From f8f15915f0d6fc2206f932bde6d81e2236496053 Mon Sep 17 00:00:00 2001 From: kawamataryo Date: Tue, 5 Mar 2024 10:26:29 +0900 Subject: [PATCH] =?UTF-8?q?=F0=9F=A7=AA=20add=20test=20for=20middleware?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../verifyDiscordInteraction.test.ts | 81 +++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 src/middleware/verifyDiscordInteraction.test.ts diff --git a/src/middleware/verifyDiscordInteraction.test.ts b/src/middleware/verifyDiscordInteraction.test.ts new file mode 100644 index 0000000..0220fcc --- /dev/null +++ b/src/middleware/verifyDiscordInteraction.test.ts @@ -0,0 +1,81 @@ +import { InteractionResponseType, verifyKey } from "discord-interactions"; +import { + Mock, + VitestUtils, + beforeEach, + describe, + expect, + it, + vi, +} from "vitest"; +import { verifyDiscordInteraction } from "./verifyDiscordInteraction"; + +vi.mock("hono/adapter", () => ({ + env: () => ({ DISCORD_PUBLIC_KEY: "test-key" }), +})); +vi.mock("discord-interactions", async (importOriginal) => { + const mod = await importOriginal(); + return { + ...mod, + verifyKey: vi.fn().mockReturnValue(true), + }; +}); + +describe("verifyDiscordInteraction", () => { + // biome-ignore lint/suspicious/noExplicitAny: + let ctx: any; + // biome-ignore lint/suspicious/noExplicitAny: + let next: any; + + beforeEach(() => { + vi.clearAllMocks(); + ctx = { + req: { + header: vi.fn().mockReturnValue("ok"), + raw: { + clone: () => ({ text: () => JSON.stringify({ type: "no-pong" }) }), + }, + }, + json: vi.fn(), + // biome-ignore lint/suspicious/noExplicitAny: + } as any; + next = vi.fn(); + }); + + it("returns 401 if signature or timestamp is missing", async () => { + ctx.req.header.mockReturnValueOnce(null); + await verifyDiscordInteraction(ctx, next); + expect(ctx.json).toHaveBeenCalledWith( + { message: "invalid request signature" }, + 401, + ); + }); + + it("returns 401 if request is not valid", async () => { + (verifyKey as Mock).mockReturnValueOnce(false); + await verifyDiscordInteraction(ctx, next); + expect(ctx.json).toHaveBeenCalledWith( + { message: "invalid request signature" }, + 401, + ); + }); + + it("returns PONG if interaction type is PONG", async () => { + ctx.req.raw.clone = () => ({ + text: () => JSON.stringify({ type: InteractionResponseType.PONG }), + }); + await verifyDiscordInteraction(ctx, next); + (verifyKey as Mock).mockReturnValueOnce(true); + expect(ctx.json).toHaveBeenCalledWith({ + type: InteractionResponseType.PONG, + }); + }); + + it("calls next middleware if request is valid and interaction type is not PONG", async () => { + ctx.req.raw.clone = () => ({ + text: () => JSON.stringify({ type: "no-pong" }), + }); + await verifyDiscordInteraction(ctx, next); + expect(next).toHaveBeenCalled(); + }); +});