From a1504eed2ac3477c30429174051214ea418042d9 Mon Sep 17 00:00:00 2001 From: Sem Bauke Date: Tue, 25 Apr 2023 18:01:32 +0200 Subject: [PATCH] feat: update my theme endpoint (#50183) Co-authored-by: Shaun Hamilton Co-authored-by: Oliver Eyton-Williams Co-authored-by: Muhammed Mustafa Co-authored-by: Tom --- api/src/app.ts | 2 + api/src/routes/settings.test.ts | 145 ++++++++++++++++++++------------ api/src/routes/settings.ts | 39 +++++++++ 3 files changed, 132 insertions(+), 54 deletions(-) diff --git a/api/src/app.ts b/api/src/app.ts index 09da59b1a9a..21de2743ace 100644 --- a/api/src/app.ts +++ b/api/src/app.ts @@ -49,6 +49,8 @@ export type FastifyInstanceWithTypeProvider = FastifyInstance< export const build = async ( options: FastifyHttpOptions = {} ): Promise => { + // TODO: Old API returns 403s for failed validation. We now return 400 (default) from AJV. + // Watch when implementing in client const fastify = Fastify(options).withTypeProvider(); void fastify.register(security); diff --git a/api/src/routes/settings.test.ts b/api/src/routes/settings.test.ts index e4c909edea5..5f908ebfeb2 100644 --- a/api/src/routes/settings.test.ts +++ b/api/src/routes/settings.test.ts @@ -37,12 +37,6 @@ describe('settingRoutes', () => { await fastify?.close(); }); - test('PUT /update-my-profileui returns 401 status code for un-authenticated users', async () => { - const response = await request(fastify?.server).put('/update-my-profileui'); - - expect(response?.statusCode).toEqual(401); - }); - describe('Authenticated user', () => { let cookies: string[]; @@ -55,63 +49,106 @@ describe('settingRoutes', () => { cookies = res.get('Set-Cookie'); }); - test('PUT /update-my-profileui returns 200 status code with "success" message', async () => { - const response = await request(fastify?.server) - .put('/update-my-profileui') - .set('Cookie', cookies) - .send({ profileUI }); + describe('/update-my-profileui', () => { + test('PUT returns 200 status code with "success" message', async () => { + const response = await request(fastify?.server) + .put('/update-my-profileui') + .set('Cookie', cookies) + .send({ profileUI }); - const user = await fastify?.prisma.user.findFirst({ - where: { email: 'foo@bar.com' } - }); - - expect(response?.statusCode).toEqual(200); - expect(response?.body).toEqual({ - message: 'flash.updated-preferences', - type: 'success' - }); - expect(user?.profileUI).toEqual(profileUI); - }); - - test('PUT /update-my-profileui ignores invalid keys', async () => { - const response = await request(fastify?.server) - .put('/update-my-profileui') - .set('Cookie', cookies) - .send({ - profileUI: { - ...profileUI, - invalidKey: 'invalidValue' - } + const user = await fastify?.prisma.user.findFirst({ + where: { email: 'foo@bar.com' } }); - const user = await fastify?.prisma.user.findFirst({ - where: { email: 'foo@bar.com' } + expect(response?.statusCode).toEqual(200); + expect(response?.body).toEqual({ + message: 'flash.updated-preferences', + type: 'success' + }); + expect(user?.profileUI).toEqual(profileUI); }); - expect(response?.statusCode).toEqual(200); - expect(user?.profileUI).toEqual(profileUI); - }); + test('PUT ignores invalid keys', async () => { + const response = await request(fastify?.server) + .put('/update-my-profileui') + .set('Cookie', cookies) + .send({ + profileUI: { + ...profileUI, + invalidKey: 'invalidValue' + } + }); - test('PUT /update-my-profileui returns 400 status code with missing keys', async () => { - const response = await request(fastify?.server) - .put('/update-my-profileui') - .set('Cookie', cookies) - .send({ - profileUI: { - isLocked: true, - showName: true, - showPoints: false, - showPortfolio: true, - showTimeLine: false - } + const user = await fastify?.prisma.user.findFirst({ + where: { email: 'foo@bar.com' } }); - expect(response?.statusCode).toEqual(400); - expect(response?.body).toEqual({ - error: 'Bad Request', - message: `body/profileUI must have required property 'showAbout'`, - statusCode: 400 + expect(response?.statusCode).toEqual(200); + expect(user?.profileUI).toEqual(profileUI); + }); + + test('PUT returns 400 status code with missing keys', async () => { + const response = await request(fastify?.server) + .put('/update-my-profileui') + .set('Cookie', cookies) + .send({ + profileUI: { + isLocked: true, + showName: true, + showPoints: false, + showPortfolio: true, + showTimeLine: false + } + }); + + expect(response?.statusCode).toEqual(400); + expect(response?.body).toEqual({ + error: 'Bad Request', + message: `body/profileUI must have required property 'showAbout'`, + statusCode: 400 + }); + }); + }); + + describe('/update-my-theme', () => { + test('PUT returns 200 status code with "success" message', async () => { + const response = await request(fastify?.server) + .put('/update-my-theme') + .set('Cookie', cookies) + .send({ theme: 'night' }); + + expect(response?.statusCode).toEqual(200); + + expect(response?.body).toEqual({ + message: 'flash.updated-themes', + type: 'success' + }); + }); + + test('PUT returns 400 status code with invalid theme', async () => { + const response = await request(fastify?.server) + .put('/update-my-theme') + .set('Cookie', cookies) + .send({ theme: 'invalid' }); + + expect(response?.statusCode).toEqual(400); }); }); }); + + describe('Unauthenticated User', () => { + test('PUT /update-my-profileui returns 401 status code for un-authenticated users', async () => { + const response = await request(fastify?.server).put( + '/update-my-profileui' + ); + + expect(response?.statusCode).toEqual(401); + }); + + test('PUT /update-my-theme returns 401 status code for un-authenticated users', async () => { + const response = await request(fastify?.server).put('/update-my-theme'); + + expect(response?.statusCode).toEqual(401); + }); + }); }); diff --git a/api/src/routes/settings.ts b/api/src/routes/settings.ts index cff143fb593..9e6930e0f40 100644 --- a/api/src/routes/settings.ts +++ b/api/src/routes/settings.ts @@ -73,5 +73,44 @@ export const settingRoutes: FastifyPluginCallbackTypebox = ( } ); + fastify.put( + '/update-my-theme', + { + schema: { + body: Type.Object({ + theme: Type.Union([Type.Literal('default'), Type.Literal('night')]) + }), + response: { + 200: Type.Object({ + message: Type.Literal('flash.updated-themes'), + type: Type.Literal('success') + }), + 500: Type.Object({ + message: Type.Literal('flash.wrong-updating'), + type: Type.Literal('danger') + }) + } + } + }, + async (req, reply) => { + try { + await fastify.prisma.user.update({ + where: { id: req.session.user.id }, + data: { + theme: req.body.theme + } + }); + + return { + message: 'flash.updated-themes', + type: 'success' + } as const; + } catch (err) { + fastify.log.error(err); + void reply.code(500); + return { message: 'flash.wrong-updating', type: 'danger' } as const; + } + } + ); done(); };