Skip to content

Commit

Permalink
feat(@kampus/gql-utils): add createPrismaCountLoader (#583)
Browse files Browse the repository at this point in the history
# Description

Create createPrismaCountLoader to use for post and comment upvote counts
  • Loading branch information
rasitds authored Aug 1, 2023
1 parent d538b53 commit 5a2dada
Show file tree
Hide file tree
Showing 5 changed files with 66 additions and 4 deletions.
12 changes: 11 additions & 1 deletion packages/gql-utils/prisma/__mocks__/prisma.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { beforeEach } from "vitest";
import { mockDeep, mockReset } from "vitest-mock-extended";

import { type PrismaClient, type User } from "@kampus/prisma";
import { type PrismaClient, type Upvote, type User } from "@kampus/prisma";

beforeEach(() => {
mockReset(mockedPrisma);
Expand All @@ -23,3 +23,13 @@ export const mockUser = (overrides: Partial<User>): User => ({
email: "[email protected]",
...overrides,
});

export const mockUpvote = (overrides: Partial<Upvote>): Upvote => ({
id: "1",
postID: "1",
userID: "1",
createdAt: mockDate(),
updatedAt: mockDate(),
deletedAt: null,
...overrides,
});
7 changes: 4 additions & 3 deletions packages/gql-utils/prisma/create-connection-loader.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,14 @@ describe(createPrismaConnectionLoader, () => {
});
});

it("returns null when there is an identifier but no parentID in key", async () => {
it("returns null when there is an identifier but no parentID in key", () => {
// need to find a better example because "name" doesn't make sense with "parentID"
// "name" needs to be replaced with an "id" column to represent real usecases.
const allUsers = createPrismaConnectionLoader(mockedPrisma.user, "name");

const users = await allUsers.load(new ConnectionKey());
expect(users).toEqual(null);
void expect(async () => {
await allUsers.load(new ConnectionKey());
}).rejects.toThrowError(/name/);
});

it("works", async () => {
Expand Down
29 changes: 29 additions & 0 deletions packages/gql-utils/prisma/create-count-loader.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { beforeEach, describe, expect, it } from "vitest";

import { mockedPrisma } from "./__mocks__/prisma";
import { ConnectionKey } from "./connection-key";
import { createPrismaCountLoader } from "./create-count-loader";

describe(createPrismaCountLoader, () => {
beforeEach(() => {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
mockedPrisma.upvote.count.mockImplementation((args: any): any => {
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
return Promise.resolve(args?.where?.postID === "1" ? 1 : 0);
});
});

it("works", async () => {
const byID = createPrismaCountLoader(mockedPrisma.upvote, "postID");

const result = await byID.load(new ConnectionKey("1"));
expect(result).toBe(1);
});

it("returns zero when trying to load a model that doesn't exist", async () => {
const byID = createPrismaCountLoader(mockedPrisma.upvote, "postID");

const result = await byID.load(new ConnectionKey("2"));
expect(result).toBe(0);
});
});
21 changes: 21 additions & 0 deletions packages/gql-utils/prisma/create-count-loader.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import DataLoader from "dataloader";

import { type ConnectionKey } from "./connection-key";
import { type PrismaModel } from "./types";

export function createPrismaCountLoader<TPrisma extends { id: string }>(
table: PrismaModel<TPrisma>,
identifier: string
) {
return new DataLoader(async (keys: readonly ConnectionKey[]) => {
const counts = await Promise.all(
keys.map((key) => {
const where = { [identifier]: key.parentID, deletedAt: null };

return table.count({ where });
})
);

return counts;
});
}
1 change: 1 addition & 0 deletions packages/gql-utils/prisma/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ export * from "./types";
export * from "./connection-key";

export * from "./create-loader";
export * from "./create-count-loader";
export * from "./create-connection-loader";

0 comments on commit 5a2dada

Please sign in to comment.