feat: status teacher invite
This commit is contained in:
		
							parent
							
								
									783c91b2e3
								
							
						
					
					
						commit
						f3d2b3313c
					
				
					 16 changed files with 184 additions and 79 deletions
				
			
		|  | @ -1,11 +1,17 @@ | ||||||
| import { Request, Response } from 'express'; | import {Request, Response} from 'express'; | ||||||
| import { requireFields } from './error-helper'; | import {requireFields} from './error-helper'; | ||||||
| import { createInvitation, deleteInvitationFor, getAllInvitations } from '../services/teacher-invitations'; | import { | ||||||
| import { TeacherInvitationData } from '@dwengo-1/common/interfaces/teacher-invitation'; |     createInvitation, | ||||||
|  |     deleteInvitation, | ||||||
|  |     getAllInvitations, | ||||||
|  |     getInvitation, | ||||||
|  |     updateInvitation | ||||||
|  | } from '../services/teacher-invitations'; | ||||||
|  | import {TeacherInvitationData} from '@dwengo-1/common/interfaces/teacher-invitation'; | ||||||
| 
 | 
 | ||||||
| export async function getAllInvitationsHandler(req: Request, res: Response): Promise<void> { | export async function getAllInvitationsHandler(req: Request, res: Response): Promise<void> { | ||||||
|     const username = req.params.username; |     const username = req.params.username; | ||||||
|     const by = req.query.by === 'true'; |     const by = req.query.sent === 'true'; | ||||||
|     requireFields({ username }); |     requireFields({ username }); | ||||||
| 
 | 
 | ||||||
|     const invitations = await getAllInvitations(username, by); |     const invitations = await getAllInvitations(username, by); | ||||||
|  | @ -13,6 +19,17 @@ export async function getAllInvitationsHandler(req: Request, res: Response): Pro | ||||||
|     res.json({ invitations }); |     res.json({ invitations }); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | export async function getInvitationHandler(req: Request, res: Response): Promise<void> { | ||||||
|  |     const sender = req.params.sender; | ||||||
|  |     const receiver = req.params.receiver; | ||||||
|  |     const classId = req.params.classId; | ||||||
|  |     requireFields({ sender, receiver, classId }); | ||||||
|  | 
 | ||||||
|  |     const invitation = await getInvitation(sender, receiver, classId); | ||||||
|  | 
 | ||||||
|  |     res.json({ invitation }); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| export async function createInvitationHandler(req: Request, res: Response): Promise<void> { | export async function createInvitationHandler(req: Request, res: Response): Promise<void> { | ||||||
|     const sender = req.body.sender; |     const sender = req.body.sender; | ||||||
|     const receiver = req.body.receiver; |     const receiver = req.body.receiver; | ||||||
|  | @ -25,14 +42,29 @@ export async function createInvitationHandler(req: Request, res: Response): Prom | ||||||
|     res.json({ invitation }); |     res.json({ invitation }); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| export async function deleteInvitationForHandler(req: Request, res: Response): Promise<void> { | export async function updateInvitationHandler(req: Request, res: Response): Promise<void> { | ||||||
|     const sender = req.params.sender; |     const sender = req.body.sender; | ||||||
|     const receiver = req.params.receiver; |     const receiver = req.body.receiver; | ||||||
|     const classId = req.params.classId; |     const classId = req.body.class; | ||||||
|     const accepted = req.body.accepted !== 'false'; |     req.body.accepted = req.body.accepted !== 'false'; | ||||||
|     requireFields({ sender, receiver, classId }); |     requireFields({ sender, receiver, classId }); | ||||||
| 
 | 
 | ||||||
|     const invitation = await deleteInvitationFor(sender, receiver, classId, accepted); |     const data = req.body as TeacherInvitationData; | ||||||
|  |     const invitation = await updateInvitation(data); | ||||||
|  | 
 | ||||||
|  |     res.json({ invitation }); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | export async function deleteInvitationHandler(req: Request, res: Response): Promise<void> { | ||||||
|  |     const sender = req.params.sender; | ||||||
|  |     const receiver = req.params.receiver; | ||||||
|  |     const classId = req.params.classId; | ||||||
|  |     requireFields({ sender, receiver, classId }); | ||||||
|  | 
 | ||||||
|  |     const data: TeacherInvitationData = { | ||||||
|  |         sender, receiver, class: classId | ||||||
|  |     }; | ||||||
|  |     const invitation = await deleteInvitation(data); | ||||||
| 
 | 
 | ||||||
|     res.json({ invitation }); |     res.json({ invitation }); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -2,14 +2,14 @@ import { DwengoEntityRepository } from '../dwengo-entity-repository.js'; | ||||||
| import { Class } from '../../entities/classes/class.entity.js'; | import { Class } from '../../entities/classes/class.entity.js'; | ||||||
| import { ClassJoinRequest } from '../../entities/classes/class-join-request.entity.js'; | import { ClassJoinRequest } from '../../entities/classes/class-join-request.entity.js'; | ||||||
| import { Student } from '../../entities/users/student.entity.js'; | import { Student } from '../../entities/users/student.entity.js'; | ||||||
| import { ClassJoinRequestStatus } from '@dwengo-1/common/util/class-join-request'; | import { ClassStatus } from '@dwengo-1/common/util/class-join-request'; | ||||||
| 
 | 
 | ||||||
| export class ClassJoinRequestRepository extends DwengoEntityRepository<ClassJoinRequest> { | export class ClassJoinRequestRepository extends DwengoEntityRepository<ClassJoinRequest> { | ||||||
|     public async findAllRequestsBy(requester: Student): Promise<ClassJoinRequest[]> { |     public async findAllRequestsBy(requester: Student): Promise<ClassJoinRequest[]> { | ||||||
|         return this.findAll({ where: { requester: requester } }); |         return this.findAll({ where: { requester: requester } }); | ||||||
|     } |     } | ||||||
|     public async findAllOpenRequestsTo(clazz: Class): Promise<ClassJoinRequest[]> { |     public async findAllOpenRequestsTo(clazz: Class): Promise<ClassJoinRequest[]> { | ||||||
|         return this.findAll({ where: { class: clazz, status: ClassJoinRequestStatus.Open } }); // TODO check if works like this
 |         return this.findAll({ where: { class: clazz, status: ClassStatus.Open } }); // TODO check if works like this
 | ||||||
|     } |     } | ||||||
|     public async findByStudentAndClass(requester: Student, clazz: Class): Promise<ClassJoinRequest | null> { |     public async findByStudentAndClass(requester: Student, clazz: Class): Promise<ClassJoinRequest | null> { | ||||||
|         return this.findOne({ requester, class: clazz }); |         return this.findOne({ requester, class: clazz }); | ||||||
|  |  | ||||||
|  | @ -1,7 +1,8 @@ | ||||||
| import { DwengoEntityRepository } from '../dwengo-entity-repository.js'; | import {DwengoEntityRepository} from '../dwengo-entity-repository.js'; | ||||||
| import { Class } from '../../entities/classes/class.entity.js'; | import {Class} from '../../entities/classes/class.entity.js'; | ||||||
| import { TeacherInvitation } from '../../entities/classes/teacher-invitation.entity.js'; | import {TeacherInvitation} from '../../entities/classes/teacher-invitation.entity.js'; | ||||||
| import { Teacher } from '../../entities/users/teacher.entity.js'; | import {Teacher} from '../../entities/users/teacher.entity.js'; | ||||||
|  | import {ClassStatus} from "@dwengo-1/common/util/class-join-request"; | ||||||
| 
 | 
 | ||||||
| export class TeacherInvitationRepository extends DwengoEntityRepository<TeacherInvitation> { | export class TeacherInvitationRepository extends DwengoEntityRepository<TeacherInvitation> { | ||||||
|     public async findAllInvitationsForClass(clazz: Class): Promise<TeacherInvitation[]> { |     public async findAllInvitationsForClass(clazz: Class): Promise<TeacherInvitation[]> { | ||||||
|  | @ -11,7 +12,7 @@ export class TeacherInvitationRepository extends DwengoEntityRepository<TeacherI | ||||||
|         return this.findAll({ where: { sender: sender } }); |         return this.findAll({ where: { sender: sender } }); | ||||||
|     } |     } | ||||||
|     public async findAllInvitationsFor(receiver: Teacher): Promise<TeacherInvitation[]> { |     public async findAllInvitationsFor(receiver: Teacher): Promise<TeacherInvitation[]> { | ||||||
|         return this.findAll({ where: { receiver: receiver } }); |         return this.findAll({ where: { receiver: receiver, status: ClassStatus.Open } }); | ||||||
|     } |     } | ||||||
|     public async deleteBy(clazz: Class, sender: Teacher, receiver: Teacher): Promise<void> { |     public async deleteBy(clazz: Class, sender: Teacher, receiver: Teacher): Promise<void> { | ||||||
|         return this.deleteWhere({ |         return this.deleteWhere({ | ||||||
|  |  | ||||||
|  | @ -2,7 +2,7 @@ import { Entity, Enum, ManyToOne } from '@mikro-orm/core'; | ||||||
| import { Student } from '../users/student.entity.js'; | import { Student } from '../users/student.entity.js'; | ||||||
| import { Class } from './class.entity.js'; | import { Class } from './class.entity.js'; | ||||||
| import { ClassJoinRequestRepository } from '../../data/classes/class-join-request-repository.js'; | import { ClassJoinRequestRepository } from '../../data/classes/class-join-request-repository.js'; | ||||||
| import { ClassJoinRequestStatus } from '@dwengo-1/common/util/class-join-request'; | import { ClassStatus } from '@dwengo-1/common/util/class-join-request'; | ||||||
| 
 | 
 | ||||||
| @Entity({ | @Entity({ | ||||||
|     repository: () => ClassJoinRequestRepository, |     repository: () => ClassJoinRequestRepository, | ||||||
|  | @ -20,6 +20,6 @@ export class ClassJoinRequest { | ||||||
|     }) |     }) | ||||||
|     class!: Class; |     class!: Class; | ||||||
| 
 | 
 | ||||||
|     @Enum(() => ClassJoinRequestStatus) |     @Enum(() => ClassStatus) | ||||||
|     status!: ClassJoinRequestStatus; |     status!: ClassStatus; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -1,7 +1,8 @@ | ||||||
| import { Entity, ManyToOne } from '@mikro-orm/core'; | import {Entity, Enum, ManyToOne} from '@mikro-orm/core'; | ||||||
| import { Teacher } from '../users/teacher.entity.js'; | import { Teacher } from '../users/teacher.entity.js'; | ||||||
| import { Class } from './class.entity.js'; | import { Class } from './class.entity.js'; | ||||||
| import { TeacherInvitationRepository } from '../../data/classes/teacher-invitation-repository.js'; | import { TeacherInvitationRepository } from '../../data/classes/teacher-invitation-repository.js'; | ||||||
|  | import {ClassStatus} from "@dwengo-1/common/util/class-join-request"; | ||||||
| 
 | 
 | ||||||
| /** | /** | ||||||
|  * Invitation of a teacher into a class (in order to teach it). |  * Invitation of a teacher into a class (in order to teach it). | ||||||
|  | @ -25,4 +26,7 @@ export class TeacherInvitation { | ||||||
|         primary: true, |         primary: true, | ||||||
|     }) |     }) | ||||||
|     class!: Class; |     class!: Class; | ||||||
|  | 
 | ||||||
|  |     @Enum(() => ClassStatus) | ||||||
|  |     status!: ClassStatus; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -4,7 +4,7 @@ import { getClassJoinRequestRepository } from '../data/repositories.js'; | ||||||
| import { Student } from '../entities/users/student.entity.js'; | import { Student } from '../entities/users/student.entity.js'; | ||||||
| import { Class } from '../entities/classes/class.entity.js'; | import { Class } from '../entities/classes/class.entity.js'; | ||||||
| import { ClassJoinRequestDTO } from '@dwengo-1/common/interfaces/class-join-request'; | import { ClassJoinRequestDTO } from '@dwengo-1/common/interfaces/class-join-request'; | ||||||
| import { ClassJoinRequestStatus } from '@dwengo-1/common/util/class-join-request'; | import { ClassStatus } from '@dwengo-1/common/util/class-join-request'; | ||||||
| 
 | 
 | ||||||
| export function mapToStudentRequestDTO(request: ClassJoinRequest): ClassJoinRequestDTO { | export function mapToStudentRequestDTO(request: ClassJoinRequest): ClassJoinRequestDTO { | ||||||
|     return { |     return { | ||||||
|  | @ -18,6 +18,6 @@ export function mapToStudentRequest(student: Student, cls: Class): ClassJoinRequ | ||||||
|     return getClassJoinRequestRepository().create({ |     return getClassJoinRequestRepository().create({ | ||||||
|         requester: student, |         requester: student, | ||||||
|         class: cls, |         class: cls, | ||||||
|         status: ClassJoinRequestStatus.Open, |         status: ClassStatus.Open, | ||||||
|     }); |     }); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -1,15 +1,17 @@ | ||||||
| import { TeacherInvitation } from '../entities/classes/teacher-invitation.entity.js'; | import {TeacherInvitation} from '../entities/classes/teacher-invitation.entity.js'; | ||||||
| import { mapToUserDTO } from './user.js'; | import {mapToUserDTO} from './user.js'; | ||||||
| import { TeacherInvitationDTO } from '@dwengo-1/common/interfaces/teacher-invitation'; | import {TeacherInvitationDTO} from '@dwengo-1/common/interfaces/teacher-invitation'; | ||||||
| import { getTeacherInvitationRepository } from '../data/repositories'; | import {getTeacherInvitationRepository} from '../data/repositories'; | ||||||
| import { Teacher } from '../entities/users/teacher.entity'; | import {Teacher} from '../entities/users/teacher.entity'; | ||||||
| import { Class } from '../entities/classes/class.entity'; | import {Class} from '../entities/classes/class.entity'; | ||||||
|  | import {ClassStatus} from "@dwengo-1/common/util/class-join-request"; | ||||||
| 
 | 
 | ||||||
| export function mapToTeacherInvitationDTO(invitation: TeacherInvitation): TeacherInvitationDTO { | export function mapToTeacherInvitationDTO(invitation: TeacherInvitation): TeacherInvitationDTO { | ||||||
|     return { |     return { | ||||||
|         sender: mapToUserDTO(invitation.sender), |         sender: mapToUserDTO(invitation.sender), | ||||||
|         receiver: mapToUserDTO(invitation.receiver), |         receiver: mapToUserDTO(invitation.receiver), | ||||||
|         classId: invitation.class.classId!, |         classId: invitation.class.classId!, | ||||||
|  |         status: invitation.status | ||||||
|     }; |     }; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -18,6 +20,7 @@ export function mapToTeacherInvitationDTOIds(invitation: TeacherInvitation): Tea | ||||||
|         sender: invitation.sender.username, |         sender: invitation.sender.username, | ||||||
|         receiver: invitation.receiver.username, |         receiver: invitation.receiver.username, | ||||||
|         classId: invitation.class.classId!, |         classId: invitation.class.classId!, | ||||||
|  |         status: invitation.status | ||||||
|     }; |     }; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -26,5 +29,6 @@ export function mapToInvitation(sender: Teacher, receiver: Teacher, cls: Class): | ||||||
|         sender, |         sender, | ||||||
|         receiver, |         receiver, | ||||||
|         class: cls, |         class: cls, | ||||||
|  |         status: ClassStatus.Open, | ||||||
|     }); |     }); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -1,12 +1,21 @@ | ||||||
| import express from 'express'; | import express from 'express'; | ||||||
| import { createInvitationHandler, deleteInvitationForHandler, getAllInvitationsHandler } from '../controllers/teacher-invitations'; | import { | ||||||
|  |     createInvitationHandler, | ||||||
|  |     deleteInvitationHandler, | ||||||
|  |     getAllInvitationsHandler, getInvitationHandler, | ||||||
|  |     updateInvitationHandler | ||||||
|  | } from '../controllers/teacher-invitations'; | ||||||
| 
 | 
 | ||||||
| const router = express.Router({ mergeParams: true }); | const router = express.Router({ mergeParams: true }); | ||||||
| 
 | 
 | ||||||
| router.get('/:username', getAllInvitationsHandler); | router.get('/:username', getAllInvitationsHandler); | ||||||
| 
 | 
 | ||||||
|  | router.get('/:sender/:receiver/:classId', getInvitationHandler); | ||||||
|  | 
 | ||||||
| router.post('/', createInvitationHandler); | router.post('/', createInvitationHandler); | ||||||
| 
 | 
 | ||||||
| router.delete('/:sender/:receiver/:classId', deleteInvitationForHandler); | router.put('/', updateInvitationHandler); | ||||||
|  | 
 | ||||||
|  | router.delete('/:sender/:receiver/:classId', deleteInvitationHandler); | ||||||
| 
 | 
 | ||||||
| export default router; | export default router; | ||||||
|  |  | ||||||
|  | @ -1,20 +1,19 @@ | ||||||
| import { fetchTeacher } from './teachers'; | import {fetchTeacher} from './teachers'; | ||||||
| import { getTeacherInvitationRepository } from '../data/repositories'; | import {getTeacherInvitationRepository} from '../data/repositories'; | ||||||
| import { mapToInvitation, mapToTeacherInvitationDTO } from '../interfaces/teacher-invitation'; | import {mapToInvitation, mapToTeacherInvitationDTO} from '../interfaces/teacher-invitation'; | ||||||
| import { addClassTeacher, fetchClass } from './classes'; | import {addClassTeacher, fetchClass} from './classes'; | ||||||
| import { TeacherInvitationData, TeacherInvitationDTO } from '@dwengo-1/common/interfaces/teacher-invitation'; | import {TeacherInvitationData, TeacherInvitationDTO} from '@dwengo-1/common/interfaces/teacher-invitation'; | ||||||
| import { ConflictException } from '../exceptions/conflict-exception'; | import {ConflictException} from '../exceptions/conflict-exception'; | ||||||
| import { Teacher } from '../entities/users/teacher.entity'; | import {NotFoundException} from '../exceptions/not-found-exception'; | ||||||
| import { Class } from '../entities/classes/class.entity'; | import {TeacherInvitation} from '../entities/classes/teacher-invitation.entity'; | ||||||
| import { NotFoundException } from '../exceptions/not-found-exception'; | import {ClassStatus} from "@dwengo-1/common/util/class-join-request"; | ||||||
| import { TeacherInvitation } from '../entities/classes/teacher-invitation.entity'; |  | ||||||
| 
 | 
 | ||||||
| export async function getAllInvitations(username: string, by: boolean): Promise<TeacherInvitationDTO[]> { | export async function getAllInvitations(username: string, sent: boolean): Promise<TeacherInvitationDTO[]> { | ||||||
|     const teacher = await fetchTeacher(username); |     const teacher = await fetchTeacher(username); | ||||||
|     const teacherInvitationRepository = getTeacherInvitationRepository(); |     const teacherInvitationRepository = getTeacherInvitationRepository(); | ||||||
| 
 | 
 | ||||||
|     let invitations; |     let invitations; | ||||||
|     if (by) { |     if (sent) { | ||||||
|         invitations = await teacherInvitationRepository.findAllInvitationsBy(teacher); |         invitations = await teacherInvitationRepository.findAllInvitationsBy(teacher); | ||||||
|     } else { |     } else { | ||||||
|         invitations = await teacherInvitationRepository.findAllInvitationsFor(teacher); |         invitations = await teacherInvitationRepository.findAllInvitationsFor(teacher); | ||||||
|  | @ -39,7 +38,11 @@ export async function createInvitation(data: TeacherInvitationData): Promise<Tea | ||||||
|     return mapToTeacherInvitationDTO(newInvitation); |     return mapToTeacherInvitationDTO(newInvitation); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| async function fetchInvitation(sender: Teacher, receiver: Teacher, cls: Class): Promise<TeacherInvitation> { | async function fetchInvitation(usernameSender: string, usernameReceiver: string, classId: string): Promise<TeacherInvitation> { | ||||||
|  |     const sender = await fetchTeacher(usernameSender); | ||||||
|  |     const receiver = await fetchTeacher(usernameReceiver); | ||||||
|  |     const cls = await fetchClass(classId); | ||||||
|  | 
 | ||||||
|     const teacherInvitationRepository = getTeacherInvitationRepository(); |     const teacherInvitationRepository = getTeacherInvitationRepository(); | ||||||
|     const invite = await teacherInvitationRepository.findBy(cls, sender, receiver); |     const invite = await teacherInvitationRepository.findBy(cls, sender, receiver); | ||||||
| 
 | 
 | ||||||
|  | @ -50,24 +53,35 @@ async function fetchInvitation(sender: Teacher, receiver: Teacher, cls: Class): | ||||||
|     return invite; |     return invite; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| export async function deleteInvitationFor( | export async function getInvitation(sender: string, receiver: string, classId: string): Promise<TeacherInvitationDTO> { | ||||||
|     usernameSender: string, |     const invitation = await fetchInvitation(sender, receiver, classId); | ||||||
|     usernameReceiver: string, |     return mapToTeacherInvitationDTO(invitation); | ||||||
|     classId: string, | } | ||||||
|     accepted: boolean |  | ||||||
| ): Promise<TeacherInvitationDTO> { |  | ||||||
|     const teacherInvitationRepository = getTeacherInvitationRepository(); |  | ||||||
|     const sender = await fetchTeacher(usernameSender); |  | ||||||
|     const receiver = await fetchTeacher(usernameReceiver); |  | ||||||
| 
 | 
 | ||||||
|     const cls = await fetchClass(classId); | export async function updateInvitation(data: TeacherInvitationData): Promise<TeacherInvitationDTO> { | ||||||
|  |     const invitation = await fetchInvitation(data.sender, data.receiver, data.class); | ||||||
|  |     invitation.status = ClassStatus.Declined; | ||||||
| 
 | 
 | ||||||
|     const invitation = await fetchInvitation(sender, receiver, cls); |     if (data.accepted) { | ||||||
|     await teacherInvitationRepository.deleteBy(cls, sender, receiver); |         invitation.status = ClassStatus.Accepted; | ||||||
| 
 |         await addClassTeacher(data.class, data.receiver); | ||||||
|     if (accepted) { |  | ||||||
|         await addClassTeacher(classId, usernameReceiver); |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     const teacherInvitationRepository = getTeacherInvitationRepository(); | ||||||
|  |     await teacherInvitationRepository.save(invitation); | ||||||
|  | 
 | ||||||
|  |     return mapToTeacherInvitationDTO(invitation); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | export async function deleteInvitation(data: TeacherInvitationData): Promise<TeacherInvitationDTO> { | ||||||
|  |     const invitation = await fetchInvitation(data.sender, data.receiver, data.class); | ||||||
|  | 
 | ||||||
|  |     const sender = await fetchTeacher(data.sender); | ||||||
|  |     const receiver = await fetchTeacher(data.receiver); | ||||||
|  |     const cls = await fetchClass(data.class); | ||||||
|  | 
 | ||||||
|  |     const teacherInvitationRepository = getTeacherInvitationRepository(); | ||||||
|  |     await teacherInvitationRepository.deleteBy(cls, sender, receiver); | ||||||
|  | 
 | ||||||
|     return mapToTeacherInvitationDTO(invitation); |     return mapToTeacherInvitationDTO(invitation); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -28,7 +28,7 @@ import { ClassDTO } from '@dwengo-1/common/interfaces/class'; | ||||||
| import { StudentDTO } from '@dwengo-1/common/interfaces/student'; | import { StudentDTO } from '@dwengo-1/common/interfaces/student'; | ||||||
| import { QuestionDTO, QuestionId } from '@dwengo-1/common/interfaces/question'; | import { QuestionDTO, QuestionId } from '@dwengo-1/common/interfaces/question'; | ||||||
| import { ClassJoinRequestDTO } from '@dwengo-1/common/interfaces/class-join-request'; | import { ClassJoinRequestDTO } from '@dwengo-1/common/interfaces/class-join-request'; | ||||||
| import { ClassJoinRequestStatus } from '@dwengo-1/common/util/class-join-request'; | import { ClassStatus } from '@dwengo-1/common/util/class-join-request'; | ||||||
| import { ConflictException } from '../exceptions/conflict-exception.js'; | import { ConflictException } from '../exceptions/conflict-exception.js'; | ||||||
| 
 | 
 | ||||||
| export async function getAllTeachers(full: boolean): Promise<TeacherDTO[] | string[]> { | export async function getAllTeachers(full: boolean): Promise<TeacherDTO[] | string[]> { | ||||||
|  | @ -160,10 +160,10 @@ export async function updateClassJoinRequestStatus(studentUsername: string, clas | ||||||
|         throw new NotFoundException('Join request not found'); |         throw new NotFoundException('Join request not found'); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     request.status = ClassJoinRequestStatus.Declined; |     request.status = ClassStatus.Declined; | ||||||
| 
 | 
 | ||||||
|     if (accepted) { |     if (accepted) { | ||||||
|         request.status = ClassJoinRequestStatus.Accepted; |         request.status = ClassStatus.Accepted; | ||||||
|         await addClassStudent(classId, studentUsername); |         await addClassStudent(classId, studentUsername); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -1,9 +1,15 @@ | ||||||
| import { beforeAll, beforeEach, describe, expect, it, Mock, vi } from 'vitest'; | import { beforeAll, beforeEach, describe, expect, it, Mock, vi } from 'vitest'; | ||||||
| import { Request, Response } from 'express'; | import { Request, Response } from 'express'; | ||||||
| import { setupTestApp } from '../setup-tests.js'; | import { setupTestApp } from '../setup-tests.js'; | ||||||
| import { createInvitationHandler, deleteInvitationForHandler, getAllInvitationsHandler } from '../../src/controllers/teacher-invitations'; | import { | ||||||
|  |     createInvitationHandler, | ||||||
|  |     deleteInvitationHandler, | ||||||
|  |     getAllInvitationsHandler, | ||||||
|  |     getInvitationHandler | ||||||
|  | } from '../../src/controllers/teacher-invitations'; | ||||||
| import { TeacherInvitationData } from '@dwengo-1/common/interfaces/teacher-invitation'; | import { TeacherInvitationData } from '@dwengo-1/common/interfaces/teacher-invitation'; | ||||||
| import { getClassHandler } from '../../src/controllers/classes'; | import { getClassHandler } from '../../src/controllers/classes'; | ||||||
|  | import {BadRequestException} from "../../src/exceptions/bad-request-exception"; | ||||||
| 
 | 
 | ||||||
| describe('Teacher controllers', () => { | describe('Teacher controllers', () => { | ||||||
|     let req: Partial<Request>; |     let req: Partial<Request>; | ||||||
|  | @ -23,13 +29,14 @@ describe('Teacher controllers', () => { | ||||||
|     }); |     }); | ||||||
| 
 | 
 | ||||||
|     it('Get teacher invitations by', async () => { |     it('Get teacher invitations by', async () => { | ||||||
|         req = { params: { username: 'LimpBizkit' }, query: { by: 'true' } }; |         req = { params: { username: 'LimpBizkit' }, query: { sent: 'true' } }; | ||||||
| 
 | 
 | ||||||
|         await getAllInvitationsHandler(req as Request, res as Response); |         await getAllInvitationsHandler(req as Request, res as Response); | ||||||
| 
 | 
 | ||||||
|         expect(jsonMock).toHaveBeenCalledWith(expect.objectContaining({ invitations: expect.anything() })); |         expect(jsonMock).toHaveBeenCalledWith(expect.objectContaining({ invitations: expect.anything() })); | ||||||
| 
 | 
 | ||||||
|         const result = jsonMock.mock.lastCall?.[0]; |         const result = jsonMock.mock.lastCall?.[0]; | ||||||
|  |         console.log(result.invitations); | ||||||
|         expect(result.invitations).to.have.length.greaterThan(0); |         expect(result.invitations).to.have.length.greaterThan(0); | ||||||
|     }); |     }); | ||||||
| 
 | 
 | ||||||
|  | @ -63,9 +70,33 @@ describe('Teacher controllers', () => { | ||||||
|             body: { accepted: 'false' }, |             body: { accepted: 'false' }, | ||||||
|         }; |         }; | ||||||
| 
 | 
 | ||||||
|         await deleteInvitationForHandler(req as Request, res as Response); |         await deleteInvitationHandler(req as Request, res as Response); | ||||||
|     }); |     }); | ||||||
| 
 | 
 | ||||||
|  |     it('Get invitation', async () => { | ||||||
|  |         req = { | ||||||
|  |             params: { | ||||||
|  |                 sender: 'LimpBizkit', | ||||||
|  |                 receiver: 'FooFighters', | ||||||
|  |                 classId: '34d484a1-295f-4e9f-bfdc-3e7a23d86a89', | ||||||
|  |             }, | ||||||
|  |         }; | ||||||
|  |         await getInvitationHandler(req as Request, res as Response); | ||||||
|  | 
 | ||||||
|  |         expect(jsonMock).toHaveBeenCalledWith(expect.objectContaining({ invitation: expect.anything() })); | ||||||
|  |     }); | ||||||
|  | 
 | ||||||
|  |     it('Get invitation error', async () => { | ||||||
|  |         req = { | ||||||
|  |             params: { no: 'no params' }, | ||||||
|  |         }; | ||||||
|  | 
 | ||||||
|  |         await expect( async () => getInvitationHandler(req as Request, res as Response)) | ||||||
|  |             .rejects.toThrowError(BadRequestException); | ||||||
|  |     }); | ||||||
|  | 
 | ||||||
|  |     /* | ||||||
|  | 
 | ||||||
|     it('Create and accept invitation', async () => { |     it('Create and accept invitation', async () => { | ||||||
|         const body = { |         const body = { | ||||||
|             sender: 'LimpBizkit', |             sender: 'LimpBizkit', | ||||||
|  | @ -85,7 +116,7 @@ describe('Teacher controllers', () => { | ||||||
|             body: { accepted: 'true' }, |             body: { accepted: 'true' }, | ||||||
|         }; |         }; | ||||||
| 
 | 
 | ||||||
|         await deleteInvitationForHandler(req as Request, res as Response); |         await deleteInvitationHandler(req as Request, res as Response); | ||||||
| 
 | 
 | ||||||
|         req = { |         req = { | ||||||
|             params: { |             params: { | ||||||
|  | @ -98,4 +129,6 @@ describe('Teacher controllers', () => { | ||||||
|         const result = jsonMock.mock.lastCall?.[0]; |         const result = jsonMock.mock.lastCall?.[0]; | ||||||
|         expect(result.class.teachers).toContain('testleerkracht1'); |         expect(result.class.teachers).toContain('testleerkracht1'); | ||||||
|     }); |     }); | ||||||
|  | 
 | ||||||
|  |      */ | ||||||
| }); | }); | ||||||
|  |  | ||||||
|  | @ -2,31 +2,31 @@ import { EntityManager } from '@mikro-orm/core'; | ||||||
| import { ClassJoinRequest } from '../../../src/entities/classes/class-join-request.entity'; | import { ClassJoinRequest } from '../../../src/entities/classes/class-join-request.entity'; | ||||||
| import { Student } from '../../../src/entities/users/student.entity'; | import { Student } from '../../../src/entities/users/student.entity'; | ||||||
| import { Class } from '../../../src/entities/classes/class.entity'; | import { Class } from '../../../src/entities/classes/class.entity'; | ||||||
| import { ClassJoinRequestStatus } from '@dwengo-1/common/util/class-join-request'; | import { ClassStatus } from '@dwengo-1/common/util/class-join-request'; | ||||||
| 
 | 
 | ||||||
| export function makeTestClassJoinRequests(em: EntityManager, students: Student[], classes: Class[]): ClassJoinRequest[] { | export function makeTestClassJoinRequests(em: EntityManager, students: Student[], classes: Class[]): ClassJoinRequest[] { | ||||||
|     const classJoinRequest01 = em.create(ClassJoinRequest, { |     const classJoinRequest01 = em.create(ClassJoinRequest, { | ||||||
|         requester: students[4], |         requester: students[4], | ||||||
|         class: classes[1], |         class: classes[1], | ||||||
|         status: ClassJoinRequestStatus.Open, |         status: ClassStatus.Open, | ||||||
|     }); |     }); | ||||||
| 
 | 
 | ||||||
|     const classJoinRequest02 = em.create(ClassJoinRequest, { |     const classJoinRequest02 = em.create(ClassJoinRequest, { | ||||||
|         requester: students[2], |         requester: students[2], | ||||||
|         class: classes[1], |         class: classes[1], | ||||||
|         status: ClassJoinRequestStatus.Open, |         status: ClassStatus.Open, | ||||||
|     }); |     }); | ||||||
| 
 | 
 | ||||||
|     const classJoinRequest03 = em.create(ClassJoinRequest, { |     const classJoinRequest03 = em.create(ClassJoinRequest, { | ||||||
|         requester: students[4], |         requester: students[4], | ||||||
|         class: classes[2], |         class: classes[2], | ||||||
|         status: ClassJoinRequestStatus.Open, |         status: ClassStatus.Open, | ||||||
|     }); |     }); | ||||||
| 
 | 
 | ||||||
|     const classJoinRequest04 = em.create(ClassJoinRequest, { |     const classJoinRequest04 = em.create(ClassJoinRequest, { | ||||||
|         requester: students[3], |         requester: students[3], | ||||||
|         class: classes[2], |         class: classes[2], | ||||||
|         status: ClassJoinRequestStatus.Open, |         status: ClassStatus.Open, | ||||||
|     }); |     }); | ||||||
| 
 | 
 | ||||||
|     return [classJoinRequest01, classJoinRequest02, classJoinRequest03, classJoinRequest04]; |     return [classJoinRequest01, classJoinRequest02, classJoinRequest03, classJoinRequest04]; | ||||||
|  |  | ||||||
|  | @ -1,31 +1,36 @@ | ||||||
| import { EntityManager } from '@mikro-orm/core'; | import {EntityManager} from '@mikro-orm/core'; | ||||||
| import { TeacherInvitation } from '../../../src/entities/classes/teacher-invitation.entity'; | import {TeacherInvitation} from '../../../src/entities/classes/teacher-invitation.entity'; | ||||||
| import { Teacher } from '../../../src/entities/users/teacher.entity'; | import {Teacher} from '../../../src/entities/users/teacher.entity'; | ||||||
| import { Class } from '../../../src/entities/classes/class.entity'; | import {Class} from '../../../src/entities/classes/class.entity'; | ||||||
|  | import {ClassStatus} from "@dwengo-1/common/util/class-join-request"; | ||||||
| 
 | 
 | ||||||
| export function makeTestTeacherInvitations(em: EntityManager, teachers: Teacher[], classes: Class[]): TeacherInvitation[] { | export function makeTestTeacherInvitations(em: EntityManager, teachers: Teacher[], classes: Class[]): TeacherInvitation[] { | ||||||
|     const teacherInvitation01 = em.create(TeacherInvitation, { |     const teacherInvitation01 = em.create(TeacherInvitation, { | ||||||
|         sender: teachers[1], |         sender: teachers[1], | ||||||
|         receiver: teachers[0], |         receiver: teachers[0], | ||||||
|         class: classes[1], |         class: classes[1], | ||||||
|  |         status: ClassStatus.Open | ||||||
|     }); |     }); | ||||||
| 
 | 
 | ||||||
|     const teacherInvitation02 = em.create(TeacherInvitation, { |     const teacherInvitation02 = em.create(TeacherInvitation, { | ||||||
|         sender: teachers[1], |         sender: teachers[1], | ||||||
|         receiver: teachers[2], |         receiver: teachers[2], | ||||||
|         class: classes[1], |         class: classes[1], | ||||||
|  |         status: ClassStatus.Open | ||||||
|     }); |     }); | ||||||
| 
 | 
 | ||||||
|     const teacherInvitation03 = em.create(TeacherInvitation, { |     const teacherInvitation03 = em.create(TeacherInvitation, { | ||||||
|         sender: teachers[2], |         sender: teachers[2], | ||||||
|         receiver: teachers[0], |         receiver: teachers[0], | ||||||
|         class: classes[2], |         class: classes[2], | ||||||
|  |         status: ClassStatus.Open | ||||||
|     }); |     }); | ||||||
| 
 | 
 | ||||||
|     const teacherInvitation04 = em.create(TeacherInvitation, { |     const teacherInvitation04 = em.create(TeacherInvitation, { | ||||||
|         sender: teachers[0], |         sender: teachers[0], | ||||||
|         receiver: teachers[1], |         receiver: teachers[1], | ||||||
|         class: classes[0], |         class: classes[0], | ||||||
|  |         status: ClassStatus.Open | ||||||
|     }); |     }); | ||||||
| 
 | 
 | ||||||
|     return [teacherInvitation01, teacherInvitation02, teacherInvitation03, teacherInvitation04]; |     return [teacherInvitation01, teacherInvitation02, teacherInvitation03, teacherInvitation04]; | ||||||
|  |  | ||||||
|  | @ -1,8 +1,8 @@ | ||||||
| import { StudentDTO } from './student'; | import { StudentDTO } from './student'; | ||||||
| import { ClassJoinRequestStatus } from '../util/class-join-request'; | import { ClassStatus } from '../util/class-join-request'; | ||||||
| 
 | 
 | ||||||
| export interface ClassJoinRequestDTO { | export interface ClassJoinRequestDTO { | ||||||
|     requester: StudentDTO; |     requester: StudentDTO; | ||||||
|     class: string; |     class: string; | ||||||
|     status: ClassJoinRequestStatus; |     status: ClassStatus; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -1,13 +1,16 @@ | ||||||
| import { UserDTO } from './user'; | import { UserDTO } from './user'; | ||||||
|  | import {ClassStatus} from "../util/class-join-request"; | ||||||
| 
 | 
 | ||||||
| export interface TeacherInvitationDTO { | export interface TeacherInvitationDTO { | ||||||
|     sender: string | UserDTO; |     sender: string | UserDTO; | ||||||
|     receiver: string | UserDTO; |     receiver: string | UserDTO; | ||||||
|     classId: string; |     classId: string; | ||||||
|  |     status: ClassStatus; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| export interface TeacherInvitationData { | export interface TeacherInvitationData { | ||||||
|     sender: string; |     sender: string; | ||||||
|     receiver: string; |     receiver: string; | ||||||
|     class: string; |     class: string; | ||||||
|  |     accepted?: boolean; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -1,4 +1,4 @@ | ||||||
| export enum ClassJoinRequestStatus { | export enum ClassStatus { | ||||||
|     Open = 'open', |     Open = 'open', | ||||||
|     Accepted = 'accepted', |     Accepted = 'accepted', | ||||||
|     Declined = 'declined', |     Declined = 'declined', | ||||||
|  |  | ||||||
		Reference in a new issue
	
	 Gabriellvl
						Gabriellvl