Skip to content

Commit

Permalink
test: tests for paginate helper
Browse files Browse the repository at this point in the history
  • Loading branch information
carlos3g committed Aug 27, 2024
1 parent 8f2fa19 commit c38a7c2
Show file tree
Hide file tree
Showing 5 changed files with 109 additions and 11 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@
"pug": "^3.0.3",
"reflect-metadata": "^0.2.0",
"rxjs": "^7.8.1",
"type-fest": "^4.25.0",
"uuid": "^9.0.1"
},
"devDependencies": {
Expand Down Expand Up @@ -95,7 +96,6 @@
"ts-loader": "^9.4.3",
"ts-node": "^10.9.1",
"tsconfig-paths": "^4.2.0",
"type-fest": "^4.25.0",
"typescript": "^5.1.3"
},
"prisma": {
Expand Down
6 changes: 3 additions & 3 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

98 changes: 97 additions & 1 deletion src/lib/prisma/helpers/pagination.spec.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
import { calcSkip, getMeta } from '@app/lib/prisma/helpers/pagination';
import { calcSkip, getMeta, paginate } from '@app/lib/prisma/helpers/pagination';
import type { ModelDelegates } from '@app/lib/prisma/types';
import type { ValueOf } from 'type-fest';

const makeModelMock = () => ({
count: jest.fn(),
findMany: jest.fn(),
});

describe('calcSkip', () => {
it('should return 0 when page is 1', () => {
Expand Down Expand Up @@ -82,3 +89,92 @@ describe('getMeta', () => {
});
});
});

describe('paginate', () => {
let model: {
count: jest.Mock;
findMany: jest.Mock;
};

beforeEach(() => {
model = makeModelMock();
});

it('should calculate skip correctly', () => {
expect(calcSkip(1, 20)).toBe(0);
expect(calcSkip(2, 20)).toBe(20);
expect(calcSkip(3, 20)).toBe(40);
});

it('should calculate metadata correctly', () => {
const meta = getMeta(100, 2, 20);
expect(meta).toEqual({
total: 100,
lastPage: 5,
currentPage: 2,
perPage: 20,
prev: 1,
next: 3,
});
});

it('should paginate results correctly', async () => {
model.count.mockResolvedValue(100);
model.findMany.mockResolvedValue(['item1', 'item2']);

const result = await paginate(model as unknown as ValueOf<ModelDelegates>, {}, { page: 2, perPage: 20 });

expect(model.count).toHaveBeenCalledWith({ where: undefined });
expect(model.findMany).toHaveBeenCalledWith({
take: 20,
skip: 20,
});
expect(result).toEqual({
data: ['item1', 'item2'],
meta: {
total: 100,
lastPage: 5,
currentPage: 2,
perPage: 20,
prev: 1,
next: 3,
},
});
});

it('should handle default values for page and perPage', async () => {
model.count.mockResolvedValue(50);
model.findMany.mockResolvedValue(['item1', 'item2', 'item3', 'item4']);

const result = await paginate(model as unknown as ValueOf<ModelDelegates>, {}, {});

expect(result.meta.currentPage).toBe(1);
expect(result.meta.perPage).toBe(20);
});

it('should handle pagination when there is only one page', async () => {
model.count.mockResolvedValue(10);
model.findMany.mockResolvedValue(['item1', 'item2']);

const result = await paginate(model as unknown as ValueOf<ModelDelegates>, {}, { page: 1, perPage: 10 });

expect(result.meta).toEqual({
total: 10,
lastPage: 1,
currentPage: 1,
perPage: 10,
prev: null,
next: null,
});
});

it('should return empty data if no items found', async () => {
model.count.mockResolvedValue(0);
model.findMany.mockResolvedValue([]);

const result = await paginate(model as unknown as ValueOf<ModelDelegates>, {}, { page: 1, perPage: 10 });

expect(result.data).toEqual([]);
expect(result.meta.total).toBe(0);
});
});
8 changes: 2 additions & 6 deletions src/lib/prisma/helpers/pagination.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/* eslint-disable @typescript-eslint/ban-ts-comment */
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
import type { Prisma, PrismaClient } from '@prisma/client';
import type { ModelDelegates } from '@app/lib/prisma/types';
import type { Prisma } from '@prisma/client';

export interface PaginatedResult<T> {
data: T[];
Expand All @@ -14,11 +15,6 @@ export interface PaginatedResult<T> {
};
}

// see: https://github.com/prisma/prisma/issues/6980
type ModelDelegates = {
[K in Prisma.ModelName]: PrismaClient[Uncapitalize<K>];
};

export type PaginateOptions = { page?: number; perPage?: number };
export type PaginateFunction = <T, K extends Prisma.ModelName>(
model: ModelDelegates[K],
Expand Down
6 changes: 6 additions & 0 deletions src/lib/prisma/types/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import type { Prisma, PrismaClient } from '@prisma/client';

// see: https://github.com/prisma/prisma/issues/6980
export type ModelDelegates = {
[K in Prisma.ModelName]: PrismaClient[Uncapitalize<K>];
};

0 comments on commit c38a7c2

Please sign in to comment.