Skip to content

Commit

Permalink
Tests for get shared deck
Browse files Browse the repository at this point in the history
  • Loading branch information
kubk committed Jan 5, 2024
1 parent 342fd3a commit d2bed4c
Show file tree
Hide file tree
Showing 4 changed files with 167 additions and 5 deletions.
10 changes: 7 additions & 3 deletions functions/db/deck-access/get-deck-access-by-share-id-db.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,25 @@ const resultSchema = z.object({
used_by: z.number().nullable(),
});

type GetDeckAccessByShareIdDbResultType = z.infer<typeof resultSchema>;

export const getDeckAccessByShareIdDb = async (
envSafe: EnvSafe,
shareId: string,
) => {
): Promise<GetDeckAccessByShareIdDbResultType | null> => {
const db = getDatabase(envSafe);

const oneTimeShareLinkResult = await db
.from("deck_access")
.select("deck_id, author_id, used_by")
.eq("share_id", shareId)
.single();
.maybeSingle();

if (oneTimeShareLinkResult.error) {
throw new DatabaseException(oneTimeShareLinkResult.error);
}

return resultSchema.parse(oneTimeShareLinkResult.data);
return oneTimeShareLinkResult.data
? resultSchema.parse(oneTimeShareLinkResult.data)
: null;
};
10 changes: 8 additions & 2 deletions functions/db/deck/get-deck-with-cards-by-id-db.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
import { DatabaseException } from "../database-exception.ts";
import { deckWithCardsSchema } from "./decks-with-cards-schema.ts";
import {
DeckWithCardsDbType,
deckWithCardsSchema,
} from "./decks-with-cards-schema.ts";
import { EnvSafe } from "../../env/env-schema.ts";
import { getDatabase } from "../get-database.ts";

export const getDeckWithCardsById = async (env: EnvSafe, deckId: number) => {
export const getDeckWithCardsById = async (
env: EnvSafe,
deckId: number,
): Promise<DeckWithCardsDbType> => {
const db = getDatabase(env);

const stableShareLinkResult = await db
Expand Down
139 changes: 139 additions & 0 deletions functions/get-shared-deck.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
import { afterEach, describe, expect, test, vi } from "vitest";
import { onRequest as getSharedDeckRequest } from "./get-shared-deck.ts";
import { DeckWithCardsDbType } from "./db/deck/decks-with-cards-schema.ts";
import { createMockRequest } from "./lib/cloudflare/create-mock-request.ts";

vi.mock("./services/get-user.ts", () => ({
getUser: async () => ({ id: 1 }),
}));

const getDeckAccessByShareIdMock = vi.hoisted(() => vi.fn());
vi.mock("./db/deck-access/get-deck-access-by-share-id-db.ts", () => ({
getDeckAccessByShareIdDb: async () => getDeckAccessByShareIdMock(),
}));

const createJsonResponseMock = vi.hoisted(() => vi.fn());
vi.mock("./lib/json-response/create-json-response.ts", () => ({
createJsonResponse: async () => createJsonResponseMock(),
}));

const getDeckWithCardsByIdMock = vi.hoisted(() => vi.fn());
vi.mock("./db/deck/get-deck-with-cards-by-id-db.ts", () => ({
getDeckWithCardsById: async () => getDeckWithCardsByIdMock(),
}));

const getDeckWithCardsByShareIdDbMock = vi.hoisted(() => vi.fn());
vi.mock("./db/deck/get-deck-with-cards-by-share-id-db.ts", () => ({
getDeckWithCardsByShareIdDb: async () => getDeckWithCardsByShareIdDbMock(),
}));

const createBadRequestResponseMock = vi.hoisted(() => vi.fn());
vi.mock("./lib/json-response/create-bad-request-response.ts", () => ({
createBadRequestResponse: async () => createBadRequestResponseMock(),
}));

const startUsingDeckAccessDbMock = vi.hoisted(() => vi.fn());
vi.mock("./db/deck-access/start-using-deck-access-db.ts", () => ({
startUsingDeckAccessDb: async () => startUsingDeckAccessDbMock(),
}));

const mockDeckOfUser1: DeckWithCardsDbType = {
id: 1,
name: "name",
description: "description",
share_id: "share_id",
author_id: 1,
created_at: new Date().toISOString(),
deck_category: null,
deck_card: [],
is_public: false,
speak_field: null,
available_in: null,
category_id: null,
speak_locale: null,
};

const mockDeckOfUser2: DeckWithCardsDbType = {
id: 2,
name: "name",
description: "description",
share_id: "share_id",
author_id: 2,
created_at: new Date().toISOString(),
deck_category: null,
deck_card: [],
is_public: false,
speak_field: null,
available_in: null,
category_id: null,
speak_locale: null,
};

describe("get shared deck", () => {
afterEach(() => {
vi.clearAllMocks();
});

test("deck author equals deck", async () => {
getDeckAccessByShareIdMock.mockReturnValue({
author_id: 1,
used_by: null,
deck_id: 1,
});
getDeckWithCardsByIdMock.mockReturnValue(mockDeckOfUser1);

await getSharedDeckRequest(
createMockRequest(`https://example.com?share_id=SHARE_ID1`),
);

expect(getDeckWithCardsByIdMock).toBeCalled();
expect(getDeckWithCardsByShareIdDbMock).not.toBeCalled();
expect(createBadRequestResponseMock).not.toBeCalled();
expect(startUsingDeckAccessDbMock).not.toBeCalled();
});

test("no one time access found", async () => {
getDeckAccessByShareIdMock.mockReturnValue(null);
getDeckWithCardsByShareIdDbMock.mockReturnValue(mockDeckOfUser1);

await getSharedDeckRequest(
createMockRequest(`https://example.com?share_id=SHARE_ID1`),
);

expect(getDeckWithCardsByIdMock).not.toBeCalled();
expect(getDeckWithCardsByShareIdDbMock).toBeCalled();
expect(createBadRequestResponseMock).not.toBeCalled();
expect(startUsingDeckAccessDbMock).not.toBeCalled();
});

test("one time access found, but already used by another user", async () => {
getDeckAccessByShareIdMock.mockReturnValue({
author_id: 2,
used_by: 2,
deck_id: 2,
});
getDeckWithCardsByIdMock.mockReturnValue(mockDeckOfUser2);

await getSharedDeckRequest(
createMockRequest(`https://example.com?share_id=SHARE_ID1`),
);

expect(createBadRequestResponseMock).toBeCalled();
});

test("one time access found and it is not used", async () => {
getDeckAccessByShareIdMock.mockReturnValue({
author_id: 2,
used_by: null,
deck_id: 2,
});
getDeckWithCardsByIdMock.mockReturnValue(mockDeckOfUser2);

await getSharedDeckRequest(
createMockRequest(`https://example.com?share_id=SHARE_ID1`),
);

expect(getDeckWithCardsByIdMock).toBeCalled();
expect(startUsingDeckAccessDbMock).toBeCalled();
});
});
13 changes: 13 additions & 0 deletions functions/lib/cloudflare/create-mock-request.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
export const createMockRequest = (url: string) => {
const mockEnv = {
BOT_TOKEN: "BOT_TOKEN",
SUPABASE_KEY: "SUPABASE_KEY",
SUPABASE_URL: "SUPABASE_URL",
VITE_BOT_APP_URL: "VITE_BOT_APP_URL",
};

return {
request: { url: url },
env: mockEnv,
} as any;
};

0 comments on commit d2bed4c

Please sign in to comment.