diff --git a/src/__tests__/app.test.ts b/src/__tests__/app.test.ts index e332408..f82131f 100644 --- a/src/__tests__/app.test.ts +++ b/src/__tests__/app.test.ts @@ -139,6 +139,17 @@ describe('GET /v1/category/', () => { expect(res.status).toEqual(200) expect(res.body.categories[0].name).toEqual('VueJS Composition API') }) + + it('returns status code 200 and no categories', async () => { + const res = await request(app) + .get('/v1/category?skip=5&take=5') + .set('Content-Type', 'application/json') + .set('Cookie', jwtCookie as string) + + expect(res.status).toEqual(200) + expect(res.body.links.next).toEqual('/v1/category?start=10&per_page=5') + expect(res.body.links.prev).toEqual('/v1/category?start=0&per_page=5') + }) }) describe('GET /v1/category/:id', () => { diff --git a/src/routers/category.ts b/src/routers/category.ts index 9d7e2c1..18756e8 100644 --- a/src/routers/category.ts +++ b/src/routers/category.ts @@ -1,6 +1,7 @@ import { Category, Prisma, PrismaClient } from "@prisma/client" import express, { RequestHandler } from "express" import { z } from "zod" +import { getPaginationLinks, Pagination, queryPaginationParser } from "../utils/pagination.js" import { userIdMiddleware } from "./user.js" const categoryRouter = express.Router() @@ -18,20 +19,30 @@ const paramsIdParser = z.object({ id: z.coerce.number(), }).required() -// TODO Ajouter pagination et queries de recherche +async function findCategories(userId: number, pagination: Pagination): Promise { + return await prisma.category.findMany({ + where: { user_id: userId }, + ...pagination + }) +} + const categoryGet: RequestHandler = async (req, res) => { let categories: Category[] | null = null + const pagination = queryPaginationParser.parse(req.query) try { - categories = await prisma.category.findMany({ - where: { user_id: req.body.userId } - }) + categories = await findCategories(req.body.userId, pagination) } catch (error: any) { res.status(400).json({ message: (error.issues ?? error) }) return; } - res.json({ categories }) + res.json({ + categories, + pagination, + links: getPaginationLinks(pagination, 'category'), + total: categories.length + }) } const categoryGetUnique: RequestHandler = async (req, res) => { diff --git a/src/routers/snippet.ts b/src/routers/snippet.ts index b8765a0..288d5b6 100644 --- a/src/routers/snippet.ts +++ b/src/routers/snippet.ts @@ -1,13 +1,9 @@ import { Prisma, PrismaClient, Snippet } from "@prisma/client" import express, { RequestHandler } from "express" import { z } from "zod" +import { Pagination, getPaginationLinks, queryPaginationParser } from "../utils/pagination.js" import { userIdMiddleware } from "./user.js" -interface Pagination { - skip: number, - take: number -} - const snippetRouter = express.Router() const prisma = new PrismaClient() @@ -30,11 +26,6 @@ const paramsIdParser = z.object({ id: z.coerce.number(), }).required() -const queryPaginationParser = z.object({ - skip: z.coerce.number().optional().default(0), - take: z.coerce.number().optional().default(10) -}) - function shortenSnippetsTagDepth(snippets: Snippet[]) { snippets.forEach((snippet: any) => { snippet.tags = snippet.Snippet_tag.map((x: any) => ({ ...x.tag })) @@ -42,13 +33,6 @@ function shortenSnippetsTagDepth(snippets: Snippet[]) { }) } -function getPaginationLinks(query: Pagination): object { - return { - next: `/v1/snippet?start=${query.skip + query.take}&per_page=${query.take}`, - prev: `/v1/snippet?start=${Math.max(0, query.skip - query.take)}&per_page=${query.take}` - } -} - async function findSnippets(userId: number, pagination: Pagination): Promise { return await prisma.snippet.findMany({ where: { user_id: userId }, @@ -76,7 +60,7 @@ const snippetGet: RequestHandler = async (req, res) => { res.json({ snippets, pagination, - links: getPaginationLinks(pagination), + links: getPaginationLinks(pagination, 'snippet'), total: snippets.length }) } diff --git a/src/utils/pagination.ts b/src/utils/pagination.ts new file mode 100644 index 0000000..bac87ee --- /dev/null +++ b/src/utils/pagination.ts @@ -0,0 +1,18 @@ +import { z } from "zod" + +export interface Pagination { + skip: number, + take: number +} + +export const queryPaginationParser = z.object({ + skip: z.coerce.number().optional().default(0), + take: z.coerce.number().optional().default(10) +}) + +export function getPaginationLinks(query: Pagination, routeName: string): object { + return { + next: `/v1/${routeName}?start=${query.skip + query.take}&per_page=${query.take}`, + prev: `/v1/${routeName}?start=${Math.max(0, query.skip - query.take)}&per_page=${query.take}` + } +}