fix: student res code + json returns bij post, delete
This commit is contained in:
		
							parent
							
								
									064810b4b8
								
							
						
					
					
						commit
						c0995d3933
					
				
					 4 changed files with 56 additions and 53 deletions
				
			
		|  | @ -30,7 +30,7 @@ export async function getStudentHandler(req: Request, res: Response): Promise<vo | ||||||
| 
 | 
 | ||||||
|     const student = await getStudent(username); |     const student = await getStudent(username); | ||||||
| 
 | 
 | ||||||
|     res.status(201).json({ student }); |     res.json({ student }); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| export async function createStudentHandler(req: Request, res: Response) { | export async function createStudentHandler(req: Request, res: Response) { | ||||||
|  | @ -41,16 +41,16 @@ export async function createStudentHandler(req: Request, res: Response) { | ||||||
| 
 | 
 | ||||||
|     const userData = req.body as StudentDTO; |     const userData = req.body as StudentDTO; | ||||||
| 
 | 
 | ||||||
|     await createStudent(userData); |     const student = await createStudent(userData); | ||||||
|     res.sendStatus(201); |     res.json({ student }); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| export async function deleteStudentHandler(req: Request, res: Response) { | export async function deleteStudentHandler(req: Request, res: Response) { | ||||||
|     const username = req.params.username; |     const username = req.params.username; | ||||||
|     requireFields({ username }); |     requireFields({ username }); | ||||||
| 
 | 
 | ||||||
|     await deleteStudent(username); |     const student = await deleteStudent(username); | ||||||
|     res.sendStatus(200); |     res.json({ student }); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| export async function getStudentClassesHandler(req: Request, res: Response): Promise<void> { | export async function getStudentClassesHandler(req: Request, res: Response): Promise<void> { | ||||||
|  | @ -60,9 +60,7 @@ export async function getStudentClassesHandler(req: Request, res: Response): Pro | ||||||
| 
 | 
 | ||||||
|     const classes = await getStudentClasses(username, full); |     const classes = await getStudentClasses(username, full); | ||||||
| 
 | 
 | ||||||
|     res.json({ |     res.json({ classes }); | ||||||
|         classes, |  | ||||||
|     }); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // TODO
 | // TODO
 | ||||||
|  | @ -76,9 +74,7 @@ export async function getStudentAssignmentsHandler(req: Request, res: Response): | ||||||
| 
 | 
 | ||||||
|     const assignments = getStudentAssignments(username, full); |     const assignments = getStudentAssignments(username, full); | ||||||
| 
 | 
 | ||||||
|     res.json({ |     res.json({ assignments }); | ||||||
|         assignments, |  | ||||||
|     }); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| export async function getStudentGroupsHandler(req: Request, res: Response): Promise<void> { | export async function getStudentGroupsHandler(req: Request, res: Response): Promise<void> { | ||||||
|  | @ -88,9 +84,7 @@ export async function getStudentGroupsHandler(req: Request, res: Response): Prom | ||||||
| 
 | 
 | ||||||
|     const groups = await getStudentGroups(username, full); |     const groups = await getStudentGroups(username, full); | ||||||
| 
 | 
 | ||||||
|     res.json({ |     res.json({ groups }); | ||||||
|         groups, |  | ||||||
|     }); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| export async function getStudentSubmissionsHandler(req: Request, res: Response): Promise<void> { | export async function getStudentSubmissionsHandler(req: Request, res: Response): Promise<void> { | ||||||
|  | @ -100,9 +94,7 @@ export async function getStudentSubmissionsHandler(req: Request, res: Response): | ||||||
| 
 | 
 | ||||||
|     const submissions = await getStudentSubmissions(username, full); |     const submissions = await getStudentSubmissions(username, full); | ||||||
| 
 | 
 | ||||||
|     res.json({ |     res.json({ submissions }); | ||||||
|         submissions, |  | ||||||
|     }); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| export async function getStudentQuestionsHandler(req: Request, res: Response): Promise<void> { | export async function getStudentQuestionsHandler(req: Request, res: Response): Promise<void> { | ||||||
|  | @ -112,9 +104,7 @@ export async function getStudentQuestionsHandler(req: Request, res: Response): P | ||||||
| 
 | 
 | ||||||
|     const questions = await getStudentQuestions(username, full); |     const questions = await getStudentQuestions(username, full); | ||||||
| 
 | 
 | ||||||
|     res.json({ |     res.json({ questions }); | ||||||
|         questions, |  | ||||||
|     }); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| export async function createStudentRequestHandler(req: Request, res: Response): Promise<void> { | export async function createStudentRequestHandler(req: Request, res: Response): Promise<void> { | ||||||
|  | @ -122,8 +112,8 @@ export async function createStudentRequestHandler(req: Request, res: Response): | ||||||
|     const classId = req.body.classId; |     const classId = req.body.classId; | ||||||
|     requireFields({ username, classId }); |     requireFields({ username, classId }); | ||||||
| 
 | 
 | ||||||
|     await createClassJoinRequest(username, classId); |     const request = await createClassJoinRequest(username, classId); | ||||||
|     res.sendStatus(201); |     res.json({ request }); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| export async function getStudentRequestHandler(req: Request, res: Response): Promise<void> { | export async function getStudentRequestHandler(req: Request, res: Response): Promise<void> { | ||||||
|  | @ -131,7 +121,7 @@ export async function getStudentRequestHandler(req: Request, res: Response): Pro | ||||||
|     requireFields({ username }); |     requireFields({ username }); | ||||||
| 
 | 
 | ||||||
|     const requests = await getJoinRequestsByStudent(username); |     const requests = await getJoinRequestsByStudent(username); | ||||||
|     res.status(201).json({ requests }); |     res.json({ requests }); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| export async function deleteClassJoinRequestHandler(req: Request, res: Response) { | 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; |     const classId = req.params.classId; | ||||||
|     requireFields({ username, classId }); |     requireFields({ username, classId }); | ||||||
| 
 | 
 | ||||||
|     await deleteClassJoinRequest(username, classId); |     const request = await deleteClassJoinRequest(username, classId); | ||||||
|     res.sendStatus(204); |     res.json({ request }); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -45,19 +45,21 @@ export async function getStudent(username: string): Promise<StudentDTO> { | ||||||
|     return mapToStudentDTO(user); |     return mapToStudentDTO(user); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| export async function createStudent(userData: StudentDTO): Promise<void> { | export async function createStudent(userData: StudentDTO): Promise<StudentDTO> { | ||||||
|     const studentRepository = getStudentRepository(); |     const studentRepository = getStudentRepository(); | ||||||
| 
 | 
 | ||||||
|     const newStudent = mapToStudent(userData); |     const newStudent = mapToStudent(userData); | ||||||
|     await studentRepository.save(newStudent, { preventOverwrite: true }); |     await studentRepository.save(newStudent, { preventOverwrite: true }); | ||||||
|  |     return userData; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| export async function deleteStudent(username: string): Promise<void> { | export async function deleteStudent(username: string): Promise<StudentDTO> { | ||||||
|     const studentRepository = getStudentRepository(); |     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); |     await studentRepository.deleteByUsername(username); | ||||||
|  |     return mapToStudentDTO(student); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| export async function getStudentClasses(username: string, full: boolean): Promise<ClassDTO[] | string[]> { | export async function getStudentClasses(username: string, full: boolean): Promise<ClassDTO[] | string[]> { | ||||||
|  | @ -131,6 +133,7 @@ export async function createClassJoinRequest(studentUsername: string, classId: s | ||||||
| 
 | 
 | ||||||
|     const request = mapToStudentRequest(student, cls); |     const request = mapToStudentRequest(student, cls); | ||||||
|     await requestRepo.save(request, { preventOverwrite: true }); |     await requestRepo.save(request, { preventOverwrite: true }); | ||||||
|  |     return mapToStudentRequestDTO(request); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| export async function getJoinRequestsByStudent(studentUsername: string) { | export async function getJoinRequestsByStudent(studentUsername: string) { | ||||||
|  | @ -155,4 +158,5 @@ export async function deleteClassJoinRequest(studentUsername: string, classId: s | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     await requestRepo.deleteBy(student, cls); |     await requestRepo.deleteBy(student, cls); | ||||||
|  |     return mapToStudentRequestDTO(request); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -26,8 +26,6 @@ describe('Student controllers', () => { | ||||||
|     let res: Partial<Response>; |     let res: Partial<Response>; | ||||||
| 
 | 
 | ||||||
|     let jsonMock: Mock; |     let jsonMock: Mock; | ||||||
|     let statusMock: Mock; |  | ||||||
|     let sendStatusMock: Mock; |  | ||||||
| 
 | 
 | ||||||
|     beforeAll(async () => { |     beforeAll(async () => { | ||||||
|         await setupTestApp(); |         await setupTestApp(); | ||||||
|  | @ -35,12 +33,8 @@ describe('Student controllers', () => { | ||||||
| 
 | 
 | ||||||
|     beforeEach(() => { |     beforeEach(() => { | ||||||
|         jsonMock = vi.fn(); |         jsonMock = vi.fn(); | ||||||
|         statusMock = vi.fn().mockReturnThis(); |  | ||||||
|         sendStatusMock = vi.fn().mockReturnThis(); |  | ||||||
|         res = { |         res = { | ||||||
|             json: jsonMock, |             json: jsonMock, | ||||||
|             status: statusMock, |  | ||||||
|             sendStatus: sendStatusMock, |  | ||||||
|         }; |         }; | ||||||
|     }); |     }); | ||||||
| 
 | 
 | ||||||
|  | @ -55,33 +49,39 @@ describe('Student controllers', () => { | ||||||
|     it('Student not found', async () => { |     it('Student not found', async () => { | ||||||
|         req = { params: { username: 'doesnotexist' } }; |         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 () => { |     it('No username', async () => { | ||||||
|         req = { params: {} }; |         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 () => { |     it('Create and delete student', async () => { | ||||||
|  |         const student = { | ||||||
|  |             id: 'coolstudent', | ||||||
|  |             username: 'coolstudent', | ||||||
|  |             firstName: 'New', | ||||||
|  |             lastName: 'Student', | ||||||
|  |         } as StudentDTO; | ||||||
|         req = { |         req = { | ||||||
|             body: { |             body: student | ||||||
|                 username: 'coolstudent', |  | ||||||
|                 firstName: 'New', |  | ||||||
|                 lastName: 'Student', |  | ||||||
|             }, |  | ||||||
|         }; |         }; | ||||||
| 
 | 
 | ||||||
|         await createStudentHandler(req as Request, res as Response); |         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' } }; |         req = { params: { username: 'coolstudent' } }; | ||||||
| 
 | 
 | ||||||
|         await deleteStudentHandler(req as Request, res as Response); |         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 () => { |     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 () => { |     it('Create student no body', async () => { | ||||||
|         req = { body: {} }; |         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 () => { |     it('Student list', async () => { | ||||||
|  | @ -176,7 +178,6 @@ describe('Student controllers', () => { | ||||||
| 
 | 
 | ||||||
|         await getStudentRequestHandler(req as Request, res as Response); |         await getStudentRequestHandler(req as Request, res as Response); | ||||||
| 
 | 
 | ||||||
|         expect(statusMock).toHaveBeenCalledWith(201); |  | ||||||
|         expect(jsonMock).toHaveBeenCalledWith( |         expect(jsonMock).toHaveBeenCalledWith( | ||||||
|             expect.objectContaining({ |             expect.objectContaining({ | ||||||
|                 requests: expect.anything(), |                 requests: expect.anything(), | ||||||
|  | @ -196,7 +197,7 @@ describe('Student controllers', () => { | ||||||
| 
 | 
 | ||||||
|         await createStudentRequestHandler(req as Request, res as Response); |         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 () => { |     it('Create join request duplicate', async () => { | ||||||
|  | @ -205,7 +206,8 @@ describe('Student controllers', () => { | ||||||
|             body: { classId: 'id02' }, |             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 () => { |     it('Delete join request', async () => { | ||||||
|  | @ -215,8 +217,9 @@ describe('Student controllers', () => { | ||||||
| 
 | 
 | ||||||
|         await deleteClassJoinRequestHandler(req as Request, res as Response); |         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); | ||||||
|     }); |     }); | ||||||
| }); | }); | ||||||
|  |  | ||||||
|  | @ -28,7 +28,7 @@ export class BaseController { | ||||||
|         return res.json(); |         return res.json(); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     protected async post(path: string, body: unknown): Promise<void> { |     protected async post<T>(path: string, body: unknown): Promise<T> { | ||||||
|         const res = await fetch(`${this.baseUrl}${path}`, { |         const res = await fetch(`${this.baseUrl}${path}`, { | ||||||
|             method: "POST", |             method: "POST", | ||||||
|             headers: { "Content-Type": "application/json" }, |             headers: { "Content-Type": "application/json" }, | ||||||
|  | @ -39,9 +39,11 @@ export class BaseController { | ||||||
|             const errorData = await res.json().catch(() => ({})); |             const errorData = await res.json().catch(() => ({})); | ||||||
|             throw new Error(errorData?.error || `Error ${res.status}: ${res.statusText}`); |             throw new Error(errorData?.error || `Error ${res.status}: ${res.statusText}`); | ||||||
|         } |         } | ||||||
|  | 
 | ||||||
|  |         return res.json(); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     protected async delete(path: string): Promise<void> { |     protected async delete<T>(path: string): Promise<T> { | ||||||
|         const res = await fetch(`${this.baseUrl}${path}`, { |         const res = await fetch(`${this.baseUrl}${path}`, { | ||||||
|             method: "DELETE", |             method: "DELETE", | ||||||
|         }); |         }); | ||||||
|  | @ -50,9 +52,11 @@ export class BaseController { | ||||||
|             const errorData = await res.json().catch(() => ({})); |             const errorData = await res.json().catch(() => ({})); | ||||||
|             throw new Error(errorData?.error || `Error ${res.status}: ${res.statusText}`); |             throw new Error(errorData?.error || `Error ${res.status}: ${res.statusText}`); | ||||||
|         } |         } | ||||||
|  | 
 | ||||||
|  |         return res.json(); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     protected async put(path: string, body: unknown): Promise<void> { |     protected async put<T>(path: string, body: unknown): Promise<T> { | ||||||
|         const res = await fetch(`${this.baseUrl}${path}`, { |         const res = await fetch(`${this.baseUrl}${path}`, { | ||||||
|             method: "PUT", |             method: "PUT", | ||||||
|             headers: { "Content-Type": "application/json" }, |             headers: { "Content-Type": "application/json" }, | ||||||
|  | @ -63,5 +67,7 @@ export class BaseController { | ||||||
|             const errorData = await res.json().catch(() => ({})); |             const errorData = await res.json().catch(() => ({})); | ||||||
|             throw new Error(errorData?.error || `Error ${res.status}: ${res.statusText}`); |             throw new Error(errorData?.error || `Error ${res.status}: ${res.statusText}`); | ||||||
|         } |         } | ||||||
|  | 
 | ||||||
|  |         return res.json(); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
		Reference in a new issue
	
	 Gabriellvl
						Gabriellvl