From c0995d3933fc84341cb9fc6a341226164e6a7045 Mon Sep 17 00:00:00 2001 From: Gabriellvl Date: Tue, 1 Apr 2025 11:48:14 +0200 Subject: [PATCH] fix: student res code + json returns bij post, delete --- backend/src/controllers/students.ts | 40 +++++++----------- backend/src/services/students.ts | 10 +++-- backend/tests/controllers/students.test.ts | 47 +++++++++++---------- frontend/src/controllers/base-controller.ts | 12 ++++-- 4 files changed, 56 insertions(+), 53 deletions(-) diff --git a/backend/src/controllers/students.ts b/backend/src/controllers/students.ts index aa3fd9ba..a6807827 100644 --- a/backend/src/controllers/students.ts +++ b/backend/src/controllers/students.ts @@ -30,7 +30,7 @@ export async function getStudentHandler(req: Request, res: Response): Promise { @@ -60,9 +60,7 @@ export async function getStudentClassesHandler(req: Request, res: Response): Pro const classes = await getStudentClasses(username, full); - res.json({ - classes, - }); + res.json({ classes }); } // TODO @@ -76,9 +74,7 @@ export async function getStudentAssignmentsHandler(req: Request, res: Response): const assignments = getStudentAssignments(username, full); - res.json({ - assignments, - }); + res.json({ assignments }); } export async function getStudentGroupsHandler(req: Request, res: Response): Promise { @@ -88,9 +84,7 @@ export async function getStudentGroupsHandler(req: Request, res: Response): Prom const groups = await getStudentGroups(username, full); - res.json({ - groups, - }); + res.json({ groups }); } export async function getStudentSubmissionsHandler(req: Request, res: Response): Promise { @@ -100,9 +94,7 @@ export async function getStudentSubmissionsHandler(req: Request, res: Response): const submissions = await getStudentSubmissions(username, full); - res.json({ - submissions, - }); + res.json({ submissions }); } export async function getStudentQuestionsHandler(req: Request, res: Response): Promise { @@ -112,9 +104,7 @@ export async function getStudentQuestionsHandler(req: Request, res: Response): P const questions = await getStudentQuestions(username, full); - res.json({ - questions, - }); + res.json({ questions }); } export async function createStudentRequestHandler(req: Request, res: Response): Promise { @@ -122,8 +112,8 @@ export async function createStudentRequestHandler(req: Request, res: Response): const classId = req.body.classId; requireFields({ username, classId }); - await createClassJoinRequest(username, classId); - res.sendStatus(201); + const request = await createClassJoinRequest(username, classId); + res.json({ request }); } export async function getStudentRequestHandler(req: Request, res: Response): Promise { @@ -131,7 +121,7 @@ export async function getStudentRequestHandler(req: Request, res: Response): Pro requireFields({ username }); const requests = await getJoinRequestsByStudent(username); - res.status(201).json({ requests }); + res.json({ requests }); } export async function deleteClassJoinRequestHandler(req: Request, res: Response) { @@ -139,6 +129,6 @@ export async function deleteClassJoinRequestHandler(req: Request, res: Response) const classId = req.params.classId; requireFields({ username, classId }); - await deleteClassJoinRequest(username, classId); - res.sendStatus(204); + const request = await deleteClassJoinRequest(username, classId); + res.json({ request }); } diff --git a/backend/src/services/students.ts b/backend/src/services/students.ts index e043ceee..8f3cd30d 100644 --- a/backend/src/services/students.ts +++ b/backend/src/services/students.ts @@ -45,19 +45,21 @@ export async function getStudent(username: string): Promise { return mapToStudentDTO(user); } -export async function createStudent(userData: StudentDTO): Promise { +export async function createStudent(userData: StudentDTO): Promise { const studentRepository = getStudentRepository(); const newStudent = mapToStudent(userData); await studentRepository.save(newStudent, { preventOverwrite: true }); + return userData; } -export async function deleteStudent(username: string): Promise { +export async function deleteStudent(username: string): Promise { const studentRepository = getStudentRepository(); - await fetchStudent(username); // Throws error if it does not exist + const student = await fetchStudent(username); // Throws error if it does not exist await studentRepository.deleteByUsername(username); + return mapToStudentDTO(student); } export async function getStudentClasses(username: string, full: boolean): Promise { @@ -131,6 +133,7 @@ export async function createClassJoinRequest(studentUsername: string, classId: s const request = mapToStudentRequest(student, cls); await requestRepo.save(request, { preventOverwrite: true }); + return mapToStudentRequestDTO(request); } export async function getJoinRequestsByStudent(studentUsername: string) { @@ -155,4 +158,5 @@ export async function deleteClassJoinRequest(studentUsername: string, classId: s } await requestRepo.deleteBy(student, cls); + return mapToStudentRequestDTO(request); } diff --git a/backend/tests/controllers/students.test.ts b/backend/tests/controllers/students.test.ts index fae8a479..8c1d020a 100644 --- a/backend/tests/controllers/students.test.ts +++ b/backend/tests/controllers/students.test.ts @@ -26,8 +26,6 @@ describe('Student controllers', () => { let res: Partial; let jsonMock: Mock; - let statusMock: Mock; - let sendStatusMock: Mock; beforeAll(async () => { await setupTestApp(); @@ -35,12 +33,8 @@ describe('Student controllers', () => { beforeEach(() => { jsonMock = vi.fn(); - statusMock = vi.fn().mockReturnThis(); - sendStatusMock = vi.fn().mockReturnThis(); res = { json: jsonMock, - status: statusMock, - sendStatus: sendStatusMock, }; }); @@ -55,33 +49,39 @@ describe('Student controllers', () => { it('Student not found', async () => { req = { params: { username: 'doesnotexist' } }; - await expect(() => getStudentHandler(req as Request, res as Response)).rejects.toThrow(NotFoundException); + await expect(() => getStudentHandler(req as Request, res as Response)) + .rejects.toThrow(NotFoundException); }); it('No username', async () => { req = { params: {} }; - await expect(() => getStudentHandler(req as Request, res as Response)).rejects.toThrowError(BadRequestException); + await expect(() => getStudentHandler(req as Request, res as Response)) + .rejects.toThrowError(BadRequestException); }); it('Create and delete student', async () => { + const student = { + id: 'coolstudent', + username: 'coolstudent', + firstName: 'New', + lastName: 'Student', + } as StudentDTO; req = { - body: { - username: 'coolstudent', - firstName: 'New', - lastName: 'Student', - }, + body: student }; await createStudentHandler(req as Request, res as Response); - expect(sendStatusMock).toHaveBeenCalledWith(201); + expect(jsonMock).toHaveBeenCalledWith(expect.objectContaining({ student: expect.objectContaining(student) })); + + console.log(jsonMock) req = { params: { username: 'coolstudent' } }; await deleteStudentHandler(req as Request, res as Response); - expect(sendStatusMock).toHaveBeenCalledWith(200); + expect(jsonMock).toHaveBeenCalledWith(expect.objectContaining({ student: expect.objectContaining(student) })); }); it('Create duplicate student', async () => { @@ -93,13 +93,15 @@ describe('Student controllers', () => { }, }; - await expect(() => createStudentHandler(req as Request, res as Response)).rejects.toThrowError(EntityAlreadyExistsException); + await expect(() => createStudentHandler(req as Request, res as Response)) + .rejects.toThrowError(EntityAlreadyExistsException); }); it('Create student no body', async () => { req = { body: {} }; - await expect(() => createStudentHandler(req as Request, res as Response)).rejects.toThrowError(BadRequestException); + await expect(() => createStudentHandler(req as Request, res as Response)) + .rejects.toThrowError(BadRequestException); }); it('Student list', async () => { @@ -176,7 +178,6 @@ describe('Student controllers', () => { await getStudentRequestHandler(req as Request, res as Response); - expect(statusMock).toHaveBeenCalledWith(201); expect(jsonMock).toHaveBeenCalledWith( expect.objectContaining({ requests: expect.anything(), @@ -196,7 +197,7 @@ describe('Student controllers', () => { await createStudentRequestHandler(req as Request, res as Response); - expect(sendStatusMock).toHaveBeenCalledWith(201); + expect(jsonMock).toHaveBeenCalledWith(expect.objectContaining({ request: expect.anything() })); }); it('Create join request duplicate', async () => { @@ -205,7 +206,8 @@ describe('Student controllers', () => { body: { classId: 'id02' }, }; - await expect(() => createStudentRequestHandler(req as Request, res as Response)).rejects.toThrow(ConflictException); + await expect(() => createStudentRequestHandler(req as Request, res as Response)) + .rejects.toThrow(ConflictException); }); it('Delete join request', async () => { @@ -215,8 +217,9 @@ describe('Student controllers', () => { await deleteClassJoinRequestHandler(req as Request, res as Response); - expect(sendStatusMock).toHaveBeenCalledWith(204); + expect(jsonMock).toHaveBeenCalledWith(expect.objectContaining({ request: expect.anything() })); - await expect(() => deleteClassJoinRequestHandler(req as Request, res as Response)).rejects.toThrow(NotFoundException); + await expect(() => deleteClassJoinRequestHandler(req as Request, res as Response)) + .rejects.toThrow(NotFoundException); }); }); diff --git a/frontend/src/controllers/base-controller.ts b/frontend/src/controllers/base-controller.ts index 7a72f542..c6024e52 100644 --- a/frontend/src/controllers/base-controller.ts +++ b/frontend/src/controllers/base-controller.ts @@ -28,7 +28,7 @@ export class BaseController { return res.json(); } - protected async post(path: string, body: unknown): Promise { + protected async post(path: string, body: unknown): Promise { const res = await fetch(`${this.baseUrl}${path}`, { method: "POST", headers: { "Content-Type": "application/json" }, @@ -39,9 +39,11 @@ export class BaseController { const errorData = await res.json().catch(() => ({})); throw new Error(errorData?.error || `Error ${res.status}: ${res.statusText}`); } + + return res.json(); } - protected async delete(path: string): Promise { + protected async delete(path: string): Promise { const res = await fetch(`${this.baseUrl}${path}`, { method: "DELETE", }); @@ -50,9 +52,11 @@ export class BaseController { const errorData = await res.json().catch(() => ({})); throw new Error(errorData?.error || `Error ${res.status}: ${res.statusText}`); } + + return res.json(); } - protected async put(path: string, body: unknown): Promise { + protected async put(path: string, body: unknown): Promise { const res = await fetch(`${this.baseUrl}${path}`, { method: "PUT", headers: { "Content-Type": "application/json" }, @@ -63,5 +67,7 @@ export class BaseController { const errorData = await res.json().catch(() => ({})); throw new Error(errorData?.error || `Error ${res.status}: ${res.statusText}`); } + + return res.json(); } }