From 067ee45a1bbec78dd30e8431a01d941511cce30c Mon Sep 17 00:00:00 2001 From: shishirbychapur Date: Sat, 21 Sep 2024 23:27:24 +0800 Subject: [PATCH 1/4] feat: add delete api route for soft deleting user --- .../__tests__/routes/user.routes.test.ts | 28 ++++++++++++++----- .../src/controllers/user.controller.ts | 20 ++++++++++++- .../src/models/user.repository.ts | 4 +-- .../user-service/src/routes/user.routes.ts | 3 +- 4 files changed, 44 insertions(+), 11 deletions(-) diff --git a/backend/user-service/__tests__/routes/user.routes.test.ts b/backend/user-service/__tests__/routes/user.routes.test.ts index 9f801e6b93..36c5463b57 100644 --- a/backend/user-service/__tests__/routes/user.routes.test.ts +++ b/backend/user-service/__tests__/routes/user.routes.test.ts @@ -1,15 +1,15 @@ import { MongoDBContainer, StartedMongoDBContainer } from '@testcontainers/mongodb' -import { generateKeyPairSync } from 'crypto' import express, { Express } from 'express' -import mongoose from 'mongoose' -import request from 'supertest' +import { Proficiency } from '../../src/types/Proficiency' +import { Role } from '../../src/types/Role' import config from '../../src/common/config.util' -import logger from '../../src/common/logger.util' import connectToDatabase from '../../src/common/mongodb.util' +import { generateKeyPairSync } from 'crypto' +import logger from '../../src/common/logger.util' +import mongoose from 'mongoose' +import request from 'supertest' import userRouter from '../../src/routes/user.routes' -import { Proficiency } from '../../src/types/Proficiency' -import { Role } from '../../src/types/Role' jest.mock('../../src/common/config.util', () => ({ NODE_ENV: 'test', @@ -98,7 +98,7 @@ describe('User Routes', () => { }) }) - describe('PUT /users', () => { + describe('PUT /users/:id', () => { it('should return 200 for successful update', async () => { const user1 = await request(app).post('/users').send(CREATE_USER_DTO1) const response = await request(app).put(`/users/${user1.body.id}`).send({ @@ -132,4 +132,18 @@ describe('User Routes', () => { expect(response.status).toBe(409) }) }) + + describe('DELETE /users/:id', () => { + it('should return 200 for successful deletion', async () => { + const user1 = await request(app).post('/users').send(CREATE_USER_DTO1) + const response = await request(app).delete(`/users/${user1.body.id}`).send() + expect(response.status).toBe(200) + expect(response.body.deletedAt).toBeDefined() + }) + it('should return 500 for requests with invalid ids', async () => { + const response = await request(app).delete('/users/111').send() + expect(response.status).toBe(500) + expect(response.body).toHaveLength(1) + }) + }) }) diff --git a/backend/user-service/src/controllers/user.controller.ts b/backend/user-service/src/controllers/user.controller.ts index 040e6d5a20..e61a15b5ee 100644 --- a/backend/user-service/src/controllers/user.controller.ts +++ b/backend/user-service/src/controllers/user.controller.ts @@ -1,4 +1,10 @@ -import { createUser, findOneUserByEmail, findOneUserByUsername, updateUser } from '../models/user.repository' +import { + createUser, + findOneUserByEmail, + findOneUserByUsername, + softDeleteUser, + updateUser, +} from '../models/user.repository' import { CreateUserDto } from '../types/CreateUserDto' import { Response } from 'express' @@ -61,3 +67,15 @@ export async function handleUpdateProfile(request: TypedRequest, response.status(500).json(['INVALID_USER_ID']).send() } } + +export async function handleDeleteUser(request: TypedRequest, response: Response): Promise { + const id = request.params.id + + try { + const user = await softDeleteUser(id) + response.status(200).json(user).send() + } catch (e) { + logger.error(e) + response.status(500).json(['INVALID_USER_ID']).send() + } +} diff --git a/backend/user-service/src/models/user.repository.ts b/backend/user-service/src/models/user.repository.ts index 6a4e031d82..b4f63b5d89 100644 --- a/backend/user-service/src/models/user.repository.ts +++ b/backend/user-service/src/models/user.repository.ts @@ -32,6 +32,6 @@ export async function updateUser(id: string, dto: UserDto | UserProfileDto): Pro return userModel.findByIdAndUpdate(id, dto, { new: true }) } -export async function deleteUser(id: string): Promise { - await userModel.findByIdAndDelete(id) +export async function softDeleteUser(id: string): Promise { + return userModel.findByIdAndUpdate(id, { deletedAt: new Date() }) } diff --git a/backend/user-service/src/routes/user.routes.ts b/backend/user-service/src/routes/user.routes.ts index a8fb4ba39c..29664096e6 100644 --- a/backend/user-service/src/routes/user.routes.ts +++ b/backend/user-service/src/routes/user.routes.ts @@ -1,4 +1,4 @@ -import { handleCreateUser, handleUpdateProfile } from '../controllers/user.controller' +import { handleCreateUser, handleDeleteUser, handleUpdateProfile } from '../controllers/user.controller' import { Router } from 'express' @@ -6,5 +6,6 @@ const router = Router() router.post('/', handleCreateUser) router.put('/:id', handleUpdateProfile) +router.delete('/:id', handleDeleteUser) export default router From 04b916ba4afe8dab787403710810307b527ffdbe Mon Sep 17 00:00:00 2001 From: shishirbychapur Date: Sat, 21 Sep 2024 23:38:55 +0800 Subject: [PATCH 2/4] feat: add codeowners file to automate review process --- CODEOWNERS | 1 + 1 file changed, 1 insertion(+) create mode 100644 CODEOWNERS diff --git a/CODEOWNERS b/CODEOWNERS new file mode 100644 index 0000000000..675bf95ed4 --- /dev/null +++ b/CODEOWNERS @@ -0,0 +1 @@ +* @shishirbychapur @glemenneo @Daviancold @lynnlow175 yunruu \ No newline at end of file From b05325184453e50d2c8b49d67c8e7d48c6f84d02 Mon Sep 17 00:00:00 2001 From: shishirbychapur Date: Sat, 21 Sep 2024 23:40:00 +0800 Subject: [PATCH 3/4] fix: resolve bug in codeowners file --- CODEOWNERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CODEOWNERS b/CODEOWNERS index 675bf95ed4..c0a5c78b6e 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -1 +1 @@ -* @shishirbychapur @glemenneo @Daviancold @lynnlow175 yunruu \ No newline at end of file +* @shishirbychapur @glemenneo @Daviancold @lynnlow175 @yunruu \ No newline at end of file From 6719bbe5bf4ac022c7fe3771ee38c60f9528a4eb Mon Sep 17 00:00:00 2001 From: shishirbychapur Date: Sat, 21 Sep 2024 23:50:36 +0800 Subject: [PATCH 4/4] fix: change logic to hard delete --- backend/user-service/__tests__/routes/user.routes.test.ts | 4 +++- backend/user-service/src/controllers/user.controller.ts | 4 ++-- backend/user-service/src/models/user.repository.ts | 4 ++-- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/backend/user-service/__tests__/routes/user.routes.test.ts b/backend/user-service/__tests__/routes/user.routes.test.ts index 36c5463b57..0421657909 100644 --- a/backend/user-service/__tests__/routes/user.routes.test.ts +++ b/backend/user-service/__tests__/routes/user.routes.test.ts @@ -138,7 +138,9 @@ describe('User Routes', () => { const user1 = await request(app).post('/users').send(CREATE_USER_DTO1) const response = await request(app).delete(`/users/${user1.body.id}`).send() expect(response.status).toBe(200) - expect(response.body.deletedAt).toBeDefined() + expect(response.body.username).toEqual('test1') + const confirmation = await request(app).delete('/users/${user1.body.id}').send() + expect(confirmation.status).toBe(500) }) it('should return 500 for requests with invalid ids', async () => { const response = await request(app).delete('/users/111').send() diff --git a/backend/user-service/src/controllers/user.controller.ts b/backend/user-service/src/controllers/user.controller.ts index e61a15b5ee..8e1b35e2c8 100644 --- a/backend/user-service/src/controllers/user.controller.ts +++ b/backend/user-service/src/controllers/user.controller.ts @@ -1,8 +1,8 @@ import { createUser, + deleteUser, findOneUserByEmail, findOneUserByUsername, - softDeleteUser, updateUser, } from '../models/user.repository' @@ -72,7 +72,7 @@ export async function handleDeleteUser(request: TypedRequest, response: Re const id = request.params.id try { - const user = await softDeleteUser(id) + const user = await deleteUser(id) response.status(200).json(user).send() } catch (e) { logger.error(e) diff --git a/backend/user-service/src/models/user.repository.ts b/backend/user-service/src/models/user.repository.ts index b4f63b5d89..6a24ce5ad9 100644 --- a/backend/user-service/src/models/user.repository.ts +++ b/backend/user-service/src/models/user.repository.ts @@ -32,6 +32,6 @@ export async function updateUser(id: string, dto: UserDto | UserProfileDto): Pro return userModel.findByIdAndUpdate(id, dto, { new: true }) } -export async function softDeleteUser(id: string): Promise { - return userModel.findByIdAndUpdate(id, { deletedAt: new Date() }) +export async function deleteUser(id: string): Promise { + return userModel.findByIdAndDelete(id) }