From e967256654d564cea0edadcf16e261e691d1b225 Mon Sep 17 00:00:00 2001 From: Florian Sylvain Date: Sun, 29 Jan 2023 22:45:14 +0100 Subject: [PATCH] Improved tets and added PUT route for user acc --- .../migration.sql | 8 +++ prisma/schema.prisma | 2 +- src/__tests__/app.test.ts | 50 +++++++++++++------ src/routers/user.ts | 34 +++++++------ 4 files changed, 63 insertions(+), 31 deletions(-) create mode 100644 prisma/migrations/20230129213325_user_email_unique/migration.sql diff --git a/prisma/migrations/20230129213325_user_email_unique/migration.sql b/prisma/migrations/20230129213325_user_email_unique/migration.sql new file mode 100644 index 0000000..81eb2fd --- /dev/null +++ b/prisma/migrations/20230129213325_user_email_unique/migration.sql @@ -0,0 +1,8 @@ +/* + Warnings: + + - A unique constraint covering the columns `[email]` on the table `User` will be added. If there are existing duplicate values, this will fail. + +*/ +-- CreateIndex +CREATE UNIQUE INDEX `User_email_key` ON `User`(`email`); diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 2efd6ce..fc5eb95 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -9,7 +9,7 @@ datasource db { model User { id Int @id @default(autoincrement()) - email String + email String @unique password String name String picture_path String diff --git a/src/__tests__/app.test.ts b/src/__tests__/app.test.ts index 75c1169..5aa7fa5 100644 --- a/src/__tests__/app.test.ts +++ b/src/__tests__/app.test.ts @@ -1,10 +1,22 @@ import { initServer } from '../app.js' import request from 'supertest' -import { User } from '.prisma/client' +import { PrismaClient } from '@prisma/client' +const prisma = new PrismaClient() const app = initServer() let jwtCookie: string | undefined +const testUserCredentials = { + email: "a@a.com", + password: "aaaaaaaaaa" +} + +afterAll(async () => { + await prisma.user.delete({ + where: { email: "a@a.com" } + }) +}) + describe('GET /v1', () => { it('returns status code 200 and api version message', async () => { const res = await request(app) @@ -15,50 +27,60 @@ describe('GET /v1', () => { }) }) +describe('POST /v1/session/register', () => { + it('returns status code 200 and a success message', async () => { + const res = await request(app) + .post('/v1/session/register') + .set('Content-Type', 'application/json') + .send(JSON.stringify(testUserCredentials)) + + expect(res.statusCode).toEqual(200) + expect(res.body).toHaveProperty('message') + }) +}) + describe('POST /v1/session/login', () => { it('returns status code 200 and set httpOnly jwt token cookie', async () => { const res = await request(app) .post('/v1/session/login') .set('Content-Type', 'application/json') - .send(JSON.stringify({ - email: "a@a.com", - password: "aaaaaaaaaa" - })) + .send(JSON.stringify(testUserCredentials)) const jwtRegEx = /^jwt=.*Path=\/.*HttpOnly.*Secure.*SameSite=Strict.*$/ jwtCookie = res.get('Set-Cookie') ?.filter(cookie => cookie.match(jwtRegEx))[0] - // jwtToken = jwtCookie.match('(^|;)\\s*jwt\\s*=\\s*([^;]+)')?.pop() || '' - expect(res.statusCode).toEqual(200) expect(jwtCookie).not.toBe(undefined) }) }) - describe('PUT /v1/user', () => { - it('returns status code 200', async () => { + it('returns status code 200 and success message', async () => { const res = await request(app) .put('/v1/user') .set('Content-Type', 'application/json') .set('Cookie', jwtCookie as string) .send(JSON.stringify({ - name: 'didier' + id: 1234, + name: 'didier', + pouet: 'alo' })) expect(res.statusCode).toEqual(200) + expect(res.body).toHaveProperty('message') }) - it('returns status code 400 and an error message', async () => { + it('returns status code 400 and error message', async () => { const res = await request(app) .put('/v1/user') .set('Content-Type', 'application/json') - .set('Cookie', 'jwt=23897yr0287yf.12423fv.23f4325') + .set('Cookie', jwtCookie as string) .send(JSON.stringify({ - name: 'didier' + picture_path: 424242 })) expect(res.statusCode).toEqual(400) + expect(res.body).toHaveProperty('message') }) -}) \ No newline at end of file +}) diff --git a/src/routers/user.ts b/src/routers/user.ts index f571cd4..b80fb5c 100644 --- a/src/routers/user.ts +++ b/src/routers/user.ts @@ -1,10 +1,16 @@ -import { PrismaClient, User } from '@prisma/client' +import { PrismaClient } from '@prisma/client' import express, { RequestHandler } from 'express' import jwt from 'jsonwebtoken' +import { z } from 'zod' const userRouter = express.Router() const prisma = new PrismaClient() +const editableUserData = z.object({ + name: z.string().optional(), + picture_path: z.string().optional() +}) + function parseJwtUserId(jwtoken: string): number | undefined { const payload = jwt.decode(jwtoken) if (payload == undefined) { @@ -15,28 +21,24 @@ function parseJwtUserId(jwtoken: string): number | undefined { return payload.userId } -async function updateUser(userId: number): Promise { - return await prisma.user.update({ - where: { id: userId }, - data: { - } - }) -} - const userRouterPut: RequestHandler = async (req, res) => { const userId = parseJwtUserId(req.cookies.jwt) if (userId === undefined) { - res.status(400).json({ - message: 'Incorrect JWT payload.' - }) + res.status(400).json({ message: 'Incorrect JWT payload.' }) return; } - await updateUser(userId) + try { + await prisma.user.update({ + where: { id: userId }, + data: editableUserData.parse(req.body) + }) + } catch (error: any) { + res.status(400).json({ message: (error.issues ?? error) }) + return; + } - res.json({ - message: 'User successfully updated.' - }) + res.json({ message: 'User successfully updated.' }) } userRouter.put("/", userRouterPut)