Skip to content

Commit

Permalink
🧪 add test for app
Browse files Browse the repository at this point in the history
  • Loading branch information
kawamataryo committed Mar 4, 2024
1 parent f8a869c commit fee9e35
Show file tree
Hide file tree
Showing 2 changed files with 126 additions and 45 deletions.
78 changes: 78 additions & 0 deletions src/app.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import {
InteractionResponseType,
InteractionType,
} from "discord-api-types/v10";
import { testClient } from "hono/testing";
import { describe, expect, it, vi } from "vitest";
import app, { interactionRoot } from "./app";
import { handleApplicationCommands } from "./interactions/handleApplicationCommands";
import { handleModalSubmits } from "./interactions/handleModalSubmit";
import { verifyDiscordInteraction } from "./middleware/verifyDiscordInteraction";

vi.mock("./middleware/verifyDiscordInteraction", () => {
return {
verifyDiscordInteraction: vi.fn(async (c, next) => await next()),
};
});
vi.mock("./interactions/handleApplicationCommands", () => ({
handleApplicationCommands: vi.fn(async () => ({ res: "ok" })),
}));
vi.mock("./interactions/handleModalSubmit", () => ({
handleModalSubmits: vi.fn(async () => ({ res: "ok" })),
}));

const mockEnv = {
DB: {},
DISCORD_TOKEN: "test-token",
MOKUMOKU_CHANNEL_ID: "test-channel-id",
};

describe("intensions", () => {
it.each([
{
type: InteractionType.ApplicationCommand,
handler: handleApplicationCommands,
},
{
type: InteractionType.ModalSubmit,
handler: handleModalSubmits,
},
])(
"should call correct handler based on interaction type",
async ({ type, handler }) => {
const res = await testClient<typeof interactionRoot>(
app,
mockEnv,
).interaction.$post({
json: {
type,
data: {},
},
});

expect(verifyDiscordInteraction).toHaveBeenCalled();
expect(handler).toHaveBeenCalled();
expect(await res.json()).toEqual({ res: "ok" });
},
);

it("should return error response if un handle interaction type is received", async () => {
const res = await testClient<typeof interactionRoot>(
app,
mockEnv,
).interaction.$post({
json: {
type: "UNHANDLED_TYPE",
data: {},
},
});

expect(await res.json()).toEqual({
type: InteractionResponseType.ChannelMessageWithSource,
data: {
content: "🚨 エラーが発生しました",
embeds: expect.any(Array),
},
});
});
});
93 changes: 48 additions & 45 deletions src/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,54 +18,57 @@ import { Bindings, Clients, Repositories } from "./types";

const app = new Hono<{ Bindings: Bindings }>();

app.post("/interaction", verifyDiscordInteraction, async (c) => {
const body = await c.req.json();
export const interactionRoot = app.post(
"/interaction",
verifyDiscordInteraction,
async (c) => {
const body = await c.req.json();

const repositories: Repositories = {
usersRepository: new UsersRepository(c.env.DB),
checkinsRepository: new CheckinsRepository(c.env.DB),
eventsRepository: new EventsRepository(c.env.DB),
eventsToCheckinsRepository: new EventsToCheckinsRepository(c.env.DB),
};
const repositories: Repositories = {
usersRepository: new UsersRepository(c.env.DB),
checkinsRepository: new CheckinsRepository(c.env.DB),
eventsRepository: new EventsRepository(c.env.DB),
eventsToCheckinsRepository: new EventsToCheckinsRepository(c.env.DB),
};

const clients: Clients = {
discordClient: new DiscordClient(c.env.DISCORD_TOKEN),
connpassClient: new ConnpassClient(),
};
const clients: Clients = {
discordClient: new DiscordClient(c.env.DISCORD_TOKEN),
connpassClient: new ConnpassClient(),
};

try {
switch (body.type) {
case InteractionType.APPLICATION_COMMAND:
return c.json(
await handleApplicationCommands({
repositories,
clients,
intentObj: body,
commands: [
checkinCommand,
mokumokuStartCommand,
generateEventDescription,
],
}),
);
case InteractionType.MODAL_SUBMIT:
return c.json(
await handleModalSubmits({
repositories,
clients,
modalSubmitObj: body,
modals: [checkinModal],
}),
);
default:
throw new Error("Invalid interaction");
try {
switch (body.type) {
case InteractionType.APPLICATION_COMMAND:
return c.json(
await handleApplicationCommands({
repositories,
clients,
intentObj: body,
commands: [
checkinCommand,
mokumokuStartCommand,
generateEventDescription,
],
}),
);
case InteractionType.MODAL_SUBMIT:
return c.json(
await handleModalSubmits({
repositories,
clients,
modalSubmitObj: body,
modals: [checkinModal],
}),
);
default:
throw new Error("Invalid interaction");
}
} catch (e) {
return c.json(
errorResponse(e instanceof Error ? e.message : "Unknown error"),
);
}
} catch (e) {
console.error(e);
return c.json(
errorResponse(e instanceof Error ? e.message : "Unknown error"),
);
}
});
},
);

export default app;

0 comments on commit fee9e35

Please sign in to comment.