From 8f3fc6688c65c0b803c318d2dc143e8d387d4014 Mon Sep 17 00:00:00 2001 From: Florian Sylvain Date: Fri, 3 Feb 2023 09:42:00 +0100 Subject: [PATCH] Added pagination on Snippets GET route --- src/__tests__/app.test.ts | 11 +++++++++ src/routers/snippet.ts | 48 ++++++++++++++++++++++++++++++--------- 2 files changed, 48 insertions(+), 11 deletions(-) diff --git a/src/__tests__/app.test.ts b/src/__tests__/app.test.ts index 03f9278..e332408 100644 --- a/src/__tests__/app.test.ts +++ b/src/__tests__/app.test.ts @@ -220,6 +220,17 @@ describe('GET /v1/snippet/', () => { expect(res.body.snippets[0].title).toEqual('Vue3 CompAPI TS script-template-style') expect(res.body.snippets[0].category_id).toEqual(category_id) }) + + it('returns status code 200 and no snippets', async () => { + const res = await request(app) + .get('/v1/snippet?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/snippet?start=10&per_page=5') + expect(res.body.links.prev).toEqual('/v1/snippet?start=0&per_page=5') + }) }) describe('PUT /v1/snippet/:id', () => { diff --git a/src/routers/snippet.ts b/src/routers/snippet.ts index 4a18e87..b8765a0 100644 --- a/src/routers/snippet.ts +++ b/src/routers/snippet.ts @@ -3,6 +3,11 @@ import express, { RequestHandler } from "express" import { z } from "zod" import { userIdMiddleware } from "./user.js" +interface Pagination { + skip: number, + take: number +} + const snippetRouter = express.Router() const prisma = new PrismaClient() @@ -25,6 +30,11 @@ 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 })) @@ -32,27 +42,43 @@ function shortenSnippetsTagDepth(snippets: Snippet[]) { }) } -// TODO Ajouter paramètres sur la requête pour rechercher des snippets -// TODO Ajouter pagination +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 }, + include: { + Snippet_tag: { + select: { tag: { select: { id: true, name: true } } }, + } + }, + ...pagination + }) +} + const snippetGet: RequestHandler = async (req, res) => { let snippets: Snippet[] | null = null + const pagination = queryPaginationParser.parse(req.query) try { - snippets = await prisma.snippet.findMany({ - where: { user_id: req.body.userId }, - include: { - Snippet_tag: { - select: { tag: { select: { id: true, name: true } } }, - } - } - }) + snippets = await findSnippets(req.body.userId, pagination) shortenSnippetsTagDepth(snippets) } catch (error: any) { res.status(400).json({ message: (error.issues ?? error) }) return; } - res.json({ snippets }) + res.json({ + snippets, + pagination, + links: getPaginationLinks(pagination), + total: snippets.length + }) } const snippetGetUnique: RequestHandler = async (req, res) => {