Merge pull request #97 from SELab-2/test/testen-voor-datalaag-#87
test: Datalaag testen
This commit is contained in:
		
						commit
						17786e604f
					
				
					 43 changed files with 2456 additions and 3082 deletions
				
			
		|  | @ -60,6 +60,14 @@ De tech-stack bestaat uit: | |||
| Voor meer informatie over de keuze van deze tech-stack, | ||||
| zie [designkeuzes](https://github.com/SELab-2/Dwengo-1/wiki/Developer:-Design-keuzes). | ||||
| 
 | ||||
| ## Testen | ||||
| 
 | ||||
| Voer volgende commando's uit om de <frontend/backend> te testen: | ||||
| 
 | ||||
| ``` | ||||
| npm run test:unit | ||||
| ``` | ||||
| 
 | ||||
| ## Bijdragen aan Dwengo-1 | ||||
| 
 | ||||
| Zie [CONTRIBUTING.md](./CONTRIBUTING.md) voor meer informatie over hoe je kan bijdragen aan Dwengo-1. | ||||
|  |  | |||
|  | @ -21,6 +21,14 @@ npm run build | |||
| npm run start | ||||
| ``` | ||||
| 
 | ||||
| ### Tests | ||||
| 
 | ||||
| Voer volgend commando uit om de unit tests uit te voeren: | ||||
| 
 | ||||
| ``` | ||||
| npm run test:unit | ||||
| ``` | ||||
| 
 | ||||
| ## Keycloak configuratie | ||||
| 
 | ||||
| Tijdens development is het voldoende om gebruik te maken van de keycloak configuratie die automatisch ingeladen wordt. | ||||
|  |  | |||
|  | @ -14,12 +14,11 @@ | |||
|         "test:unit": "vitest" | ||||
|     }, | ||||
|     "dependencies": { | ||||
|         "@mikro-orm/core": "6.4.6", | ||||
|         "@mikro-orm/postgresql": "6.4.6", | ||||
|         "@mikro-orm/reflection": "6.4.6", | ||||
|         "@mikro-orm/sqlite": "6.4.6", | ||||
|         "@types/cors": "^2.8.17", | ||||
|         "@types/js-yaml": "^4.0.9", | ||||
|         "@mikro-orm/core": "6.4.9", | ||||
|         "@mikro-orm/knex": "6.4.9", | ||||
|         "@mikro-orm/postgresql": "6.4.9", | ||||
|         "@mikro-orm/reflection": "6.4.9", | ||||
|         "@mikro-orm/sqlite": "6.4.9", | ||||
|         "axios": "^1.8.2", | ||||
|         "cors": "^2.8.5", | ||||
|         "cross": "^1.0.0", | ||||
|  | @ -40,8 +39,10 @@ | |||
|         "winston-loki": "^6.1.3" | ||||
|     }, | ||||
|     "devDependencies": { | ||||
|         "@mikro-orm/cli": "6.4.6", | ||||
|         "@mikro-orm/cli": "6.4.9", | ||||
|         "@types/cors": "^2.8.17", | ||||
|         "@types/express": "^5.0.0", | ||||
|         "@types/js-yaml": "^4.0.9", | ||||
|         "@types/node": "^22.13.4", | ||||
|         "@types/response-time": "^2.3.8", | ||||
|         "globals": "^15.15.0", | ||||
|  |  | |||
|  | @ -5,10 +5,12 @@ import { Teacher } from '../../entities/users/teacher.entity.js'; | |||
| 
 | ||||
| export class AnswerRepository extends DwengoEntityRepository<Answer> { | ||||
|     public createAnswer(answer: { toQuestion: Question; author: Teacher; content: string }): Promise<Answer> { | ||||
|         const answerEntity = new Answer(); | ||||
|         answerEntity.toQuestion = answer.toQuestion; | ||||
|         answerEntity.author = answer.author; | ||||
|         answerEntity.content = answer.content; | ||||
|         const answerEntity = this.create({ | ||||
|             toQuestion: answer.toQuestion, | ||||
|             author: answer.author, | ||||
|             content: answer.content, | ||||
|             timestamp: new Date(), | ||||
|         }); | ||||
|         return this.insert(answerEntity); | ||||
|     } | ||||
|     public findAllAnswersToQuestion(question: Question): Promise<Answer[]> { | ||||
|  |  | |||
|  | @ -5,7 +5,14 @@ import { Student } from '../../entities/users/student.entity.js'; | |||
| 
 | ||||
| export class QuestionRepository extends DwengoEntityRepository<Question> { | ||||
|     public createQuestion(question: { loId: LearningObjectIdentifier; author: Student; content: string }): Promise<Question> { | ||||
|         const questionEntity = new Question(); | ||||
|         const questionEntity = this.create({ | ||||
|             learningObjectHruid: question.loId.hruid, | ||||
|             learningObjectLanguage: question.loId.language, | ||||
|             learningObjectVersion: question.loId.version, | ||||
|             author: question.author, | ||||
|             content: question.content, | ||||
|             timestamp: new Date(), | ||||
|         }); | ||||
|         questionEntity.learningObjectHruid = question.loId.hruid; | ||||
|         questionEntity.learningObjectLanguage = question.loId.language; | ||||
|         questionEntity.learningObjectVersion = question.loId.version; | ||||
|  |  | |||
|  | @ -61,7 +61,7 @@ export const getTeacherRepository = repositoryGetter<Teacher, TeacherRepository> | |||
| /* Classes */ | ||||
| export const getClassRepository = repositoryGetter<Class, ClassRepository>(Class); | ||||
| export const getClassJoinRequestRepository = repositoryGetter<ClassJoinRequest, ClassJoinRequestRepository>(ClassJoinRequest); | ||||
| export const getTeacherInvitationRepository = repositoryGetter<TeacherInvitation, TeacherInvitationRepository>(TeacherInvitationRepository); | ||||
| export const getTeacherInvitationRepository = repositoryGetter<TeacherInvitation, TeacherInvitationRepository>(TeacherInvitation); | ||||
| 
 | ||||
| /* Assignments */ | ||||
| export const getAssignmentRepository = repositoryGetter<Assignment, AssignmentRepository>(Assignment); | ||||
|  |  | |||
|  | @ -7,6 +7,9 @@ import { TeacherInvitationRepository } from '../../data/classes/teacher-invitati | |||
|  * Invitation of a teacher into a class (in order to teach it). | ||||
|  */ | ||||
| @Entity({ repository: () => TeacherInvitationRepository }) | ||||
| @Entity({ | ||||
|     repository: () => TeacherInvitationRepository, | ||||
| }) | ||||
| export class TeacherInvitation { | ||||
|     @ManyToOne({ | ||||
|         entity: () => Teacher, | ||||
|  |  | |||
|  | @ -17,8 +17,8 @@ export class Answer { | |||
|     }) | ||||
|     toQuestion!: Question; | ||||
| 
 | ||||
|     @PrimaryKey({ type: 'integer' }) | ||||
|     sequenceNumber!: number; | ||||
|     @PrimaryKey({ type: 'integer', autoincrement: true }) | ||||
|     sequenceNumber?: number; | ||||
| 
 | ||||
|     @Property({ type: 'datetime' }) | ||||
|     timestamp: Date = new Date(); | ||||
|  |  | |||
|  | @ -17,8 +17,8 @@ export class Question { | |||
|     @PrimaryKey({ type: 'number' }) | ||||
|     learningObjectVersion: number = 1; | ||||
| 
 | ||||
|     @PrimaryKey({ type: 'integer' }) | ||||
|     sequenceNumber!: number; | ||||
|     @PrimaryKey({ type: 'integer', autoincrement: true }) | ||||
|     sequenceNumber?: number; | ||||
| 
 | ||||
|     @ManyToOne({ | ||||
|         entity: () => Student, | ||||
|  |  | |||
|  | @ -7,4 +7,12 @@ import { TeacherRepository } from '../../data/users/teacher-repository.js'; | |||
| export class Teacher extends User { | ||||
|     @ManyToMany(() => Class) | ||||
|     classes!: Collection<Class>; | ||||
| 
 | ||||
|     constructor( | ||||
|         public username: string, | ||||
|         public firstName: string, | ||||
|         public lastName: string | ||||
|     ) { | ||||
|         super(); | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -24,6 +24,7 @@ import { LearningPath } from './entities/content/learning-path.entity.js'; | |||
| 
 | ||||
| import { Answer } from './entities/questions/answer.entity.js'; | ||||
| import { Question } from './entities/questions/question.entity.js'; | ||||
| import { SqliteAutoincrementSubscriber } from './sqlite-autoincrement-workaround.js'; | ||||
| 
 | ||||
| const entities = [ | ||||
|     User, | ||||
|  | @ -47,6 +48,7 @@ function config(testingMode: boolean = false): Options { | |||
|         return { | ||||
|             driver: SqliteDriver, | ||||
|             dbName: getEnvVar(EnvVars.DbName), | ||||
|             subscribers: [new SqliteAutoincrementSubscriber()], | ||||
|             entities: entities, | ||||
|             // EntitiesTs: entitiesTs,
 | ||||
| 
 | ||||
|  |  | |||
							
								
								
									
										41
									
								
								backend/src/sqlite-autoincrement-workaround.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								backend/src/sqlite-autoincrement-workaround.ts
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,41 @@ | |||
| import { EntityProperty, EventArgs, EventSubscriber } from '@mikro-orm/core'; | ||||
| 
 | ||||
| /** | ||||
|  * The tests are ran on an in-memory SQLite database. However, SQLite does not allow fields which are part of composite | ||||
|  * primary keys to be autoincremented (while PostgreSQL, which we use in production, does). This Subscriber works around | ||||
|  * the issue by remembering the highest values for every autoincremented part of a primary key and assigning them when | ||||
|  * creating a new entity. | ||||
|  * | ||||
|  * However, it is important to note the following limitations: | ||||
|  * - this class can only be used for in-memory SQLite databases since the information on what the highest sequence | ||||
|  *   number for each of the properties is, is only saved transiently. | ||||
|  * - automatically setting the generated "autoincremented" value for properties only works when the entity is created | ||||
|  *   via an entityManager.create(...) or repo.create(...) method. Otherwise, onInit will not be called and therefore, | ||||
|  *   the sequence number will not be filled in. | ||||
|  */ | ||||
| export class SqliteAutoincrementSubscriber implements EventSubscriber { | ||||
|     private sequenceNumbersForEntityType: Map<string, number> = new Map(); | ||||
| 
 | ||||
|     /** | ||||
|      * When an entity with an autoincremented property which is part of the composite private key is created, | ||||
|      * automatically fill this property so we won't face not-null-constraint exceptions when persisting it. | ||||
|      */ | ||||
|     onInit<T extends object>(args: EventArgs<T>): void { | ||||
|         if (!args.meta.compositePK) { | ||||
|             return; // If there is not a composite primary key, autoincrement works fine with SQLite anyway.
 | ||||
|         } | ||||
| 
 | ||||
|         for (const prop of Object.values(args.meta.properties)) { | ||||
|             const property = prop as EntityProperty<T>; | ||||
|             if (property.primary && property.autoincrement && !(args.entity as Record<string, any>)[property.name]) { | ||||
|                 // Obtain and increment sequence number of this entity.
 | ||||
|                 const propertyKey = args.meta.class.name + '.' + property.name; | ||||
|                 const nextSeqNumber = this.sequenceNumbersForEntityType.get(propertyKey) || 0; | ||||
|                 this.sequenceNumbersForEntityType.set(propertyKey, nextSeqNumber + 1); | ||||
| 
 | ||||
|                 // Set the property accordingly.
 | ||||
|                 (args.entity as Record<string, any>)[property.name] = nextSeqNumber + 1; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
							
								
								
									
										42
									
								
								backend/tests/data/assignments/assignments.test.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								backend/tests/data/assignments/assignments.test.ts
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,42 @@ | |||
| import { beforeAll, describe, expect, it } from 'vitest'; | ||||
| import { setupTestApp } from '../../setup-tests'; | ||||
| import { AssignmentRepository } from '../../../src/data/assignments/assignment-repository'; | ||||
| import { getAssignmentRepository, getClassRepository } from '../../../src/data/repositories'; | ||||
| import { ClassRepository } from '../../../src/data/classes/class-repository'; | ||||
| 
 | ||||
| describe('AssignmentRepository', () => { | ||||
|     let assignmentRepository: AssignmentRepository; | ||||
|     let classRepository: ClassRepository; | ||||
| 
 | ||||
|     beforeAll(async () => { | ||||
|         await setupTestApp(); | ||||
|         assignmentRepository = getAssignmentRepository(); | ||||
|         classRepository = getClassRepository(); | ||||
|     }); | ||||
| 
 | ||||
|     it('should return the requested assignment', async () => { | ||||
|         const class_ = await classRepository.findById('id02'); | ||||
|         const assignment = await assignmentRepository.findByClassAndId(class_!, 2); | ||||
| 
 | ||||
|         expect(assignment).toBeTruthy(); | ||||
|         expect(assignment!.title).toBe('tool'); | ||||
|     }); | ||||
| 
 | ||||
|     it('should return all assignments for a class', async () => { | ||||
|         const class_ = await classRepository.findById('id02'); | ||||
|         const assignments = await assignmentRepository.findAllAssignmentsInClass(class_!); | ||||
| 
 | ||||
|         expect(assignments).toBeTruthy(); | ||||
|         expect(assignments).toHaveLength(1); | ||||
|         expect(assignments[0].title).toBe('tool'); | ||||
|     }); | ||||
| 
 | ||||
|     it('should not find removed assignment', async () => { | ||||
|         const class_ = await classRepository.findById('id01'); | ||||
|         await assignmentRepository.deleteByClassAndId(class_!, 3); | ||||
| 
 | ||||
|         const assignment = await assignmentRepository.findByClassAndId(class_!, 3); | ||||
| 
 | ||||
|         expect(assignment).toBeNull(); | ||||
|     }); | ||||
| }); | ||||
							
								
								
									
										49
									
								
								backend/tests/data/assignments/groups.test.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								backend/tests/data/assignments/groups.test.ts
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,49 @@ | |||
| import { beforeAll, describe, expect, it } from 'vitest'; | ||||
| import { setupTestApp } from '../../setup-tests'; | ||||
| import { GroupRepository } from '../../../src/data/assignments/group-repository'; | ||||
| import { getAssignmentRepository, getClassRepository, getGroupRepository } from '../../../src/data/repositories'; | ||||
| import { AssignmentRepository } from '../../../src/data/assignments/assignment-repository'; | ||||
| import { ClassRepository } from '../../../src/data/classes/class-repository'; | ||||
| 
 | ||||
| describe('GroupRepository', () => { | ||||
|     let groupRepository: GroupRepository; | ||||
|     let assignmentRepository: AssignmentRepository; | ||||
|     let classRepository: ClassRepository; | ||||
| 
 | ||||
|     beforeAll(async () => { | ||||
|         await setupTestApp(); | ||||
|         groupRepository = getGroupRepository(); | ||||
|         assignmentRepository = getAssignmentRepository(); | ||||
|         classRepository = getClassRepository(); | ||||
|     }); | ||||
| 
 | ||||
|     it('should return the requested group', async () => { | ||||
|         const class_ = await classRepository.findById('id01'); | ||||
|         const assignment = await assignmentRepository.findByClassAndId(class_!, 1); | ||||
| 
 | ||||
|         const group = await groupRepository.findByAssignmentAndGroupNumber(assignment!, 1); | ||||
| 
 | ||||
|         expect(group).toBeTruthy(); | ||||
|     }); | ||||
| 
 | ||||
|     it('should return all groups for assignment', async () => { | ||||
|         const class_ = await classRepository.findById('id01'); | ||||
|         const assignment = await assignmentRepository.findByClassAndId(class_!, 1); | ||||
| 
 | ||||
|         const groups = await groupRepository.findAllGroupsForAssignment(assignment!); | ||||
| 
 | ||||
|         expect(groups).toBeTruthy(); | ||||
|         expect(groups).toHaveLength(3); | ||||
|     }); | ||||
| 
 | ||||
|     it('should not find removed group', async () => { | ||||
|         const class_ = await classRepository.findById('id02'); | ||||
|         const assignment = await assignmentRepository.findByClassAndId(class_!, 2); | ||||
| 
 | ||||
|         await groupRepository.deleteByAssignmentAndGroupNumber(assignment!, 1); | ||||
| 
 | ||||
|         const group = await groupRepository.findByAssignmentAndGroupNumber(assignment!, 1); | ||||
| 
 | ||||
|         expect(group).toBeNull(); | ||||
|     }); | ||||
| }); | ||||
							
								
								
									
										70
									
								
								backend/tests/data/assignments/submissions.test.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										70
									
								
								backend/tests/data/assignments/submissions.test.ts
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,70 @@ | |||
| import { beforeAll, describe, expect, it } from 'vitest'; | ||||
| import { setupTestApp } from '../../setup-tests'; | ||||
| import { SubmissionRepository } from '../../../src/data/assignments/submission-repository'; | ||||
| import { | ||||
|     getAssignmentRepository, | ||||
|     getClassRepository, | ||||
|     getGroupRepository, | ||||
|     getStudentRepository, | ||||
|     getSubmissionRepository, | ||||
| } from '../../../src/data/repositories'; | ||||
| import { LearningObjectIdentifier } from '../../../src/entities/content/learning-object-identifier'; | ||||
| import { Language } from '../../../src/entities/content/language'; | ||||
| import { StudentRepository } from '../../../src/data/users/student-repository'; | ||||
| import { GroupRepository } from '../../../src/data/assignments/group-repository'; | ||||
| import { AssignmentRepository } from '../../../src/data/assignments/assignment-repository'; | ||||
| import { ClassRepository } from '../../../src/data/classes/class-repository'; | ||||
| 
 | ||||
| describe('SubmissionRepository', () => { | ||||
|     let submissionRepository: SubmissionRepository; | ||||
|     let studentRepository: StudentRepository; | ||||
|     let groupRepository: GroupRepository; | ||||
|     let assignmentRepository: AssignmentRepository; | ||||
|     let classRepository: ClassRepository; | ||||
| 
 | ||||
|     beforeAll(async () => { | ||||
|         await setupTestApp(); | ||||
|         submissionRepository = getSubmissionRepository(); | ||||
|         studentRepository = getStudentRepository(); | ||||
|         groupRepository = getGroupRepository(); | ||||
|         assignmentRepository = getAssignmentRepository(); | ||||
|         classRepository = getClassRepository(); | ||||
|     }); | ||||
| 
 | ||||
|     it('should find the requested submission', async () => { | ||||
|         const id = new LearningObjectIdentifier('id03', Language.English, '1'); | ||||
|         const submission = await submissionRepository.findSubmissionByLearningObjectAndSubmissionNumber(id, 1); | ||||
| 
 | ||||
|         expect(submission).toBeTruthy(); | ||||
|         expect(submission?.content).toBe('sub1'); | ||||
|     }); | ||||
| 
 | ||||
|     it('should find the most recent submission for a student', async () => { | ||||
|         const id = new LearningObjectIdentifier('id02', Language.English, '1'); | ||||
|         const student = await studentRepository.findByUsername('Noordkaap'); | ||||
|         const submission = await submissionRepository.findMostRecentSubmissionForStudent(id, student!); | ||||
| 
 | ||||
|         expect(submission).toBeTruthy(); | ||||
|         expect(submission?.submissionTime.getDate()).toBe(25); | ||||
|     }); | ||||
| 
 | ||||
|     it('should find the most recent submission for a group', async () => { | ||||
|         const id = new LearningObjectIdentifier('id03', Language.English, '1'); | ||||
|         const class_ = await classRepository.findById('id01'); | ||||
|         const assignment = await assignmentRepository.findByClassAndId(class_!, 1); | ||||
|         const group = await groupRepository.findByAssignmentAndGroupNumber(assignment!, 1); | ||||
|         const submission = await submissionRepository.findMostRecentSubmissionForGroup(id, group!); | ||||
| 
 | ||||
|         expect(submission).toBeTruthy(); | ||||
|         expect(submission?.submissionTime.getDate()).toBe(25); | ||||
|     }); | ||||
| 
 | ||||
|     it('should not find a deleted submission', async () => { | ||||
|         const id = new LearningObjectIdentifier('id01', Language.English, '1'); | ||||
|         await submissionRepository.deleteSubmissionByLearningObjectAndSubmissionNumber(id, 1); | ||||
| 
 | ||||
|         const submission = await submissionRepository.findSubmissionByLearningObjectAndSubmissionNumber(id, 1); | ||||
| 
 | ||||
|         expect(submission).toBeNull(); | ||||
|     }); | ||||
| }); | ||||
							
								
								
									
										47
									
								
								backend/tests/data/classes/class-join-request.test.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								backend/tests/data/classes/class-join-request.test.ts
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,47 @@ | |||
| import { beforeAll, describe, expect, it } from 'vitest'; | ||||
| import { setupTestApp } from '../../setup-tests'; | ||||
| import { ClassJoinRequestRepository } from '../../../src/data/classes/class-join-request-repository'; | ||||
| import { getClassJoinRequestRepository, getClassRepository, getStudentRepository } from '../../../src/data/repositories'; | ||||
| import { StudentRepository } from '../../../src/data/users/student-repository'; | ||||
| import { Class } from '../../../src/entities/classes/class.entity'; | ||||
| import { ClassRepository } from '../../../src/data/classes/class-repository'; | ||||
| import { Student } from '../../../src/entities/users/student.entity'; | ||||
| 
 | ||||
| describe('ClassJoinRequestRepository', () => { | ||||
|     let classJoinRequestRepository: ClassJoinRequestRepository; | ||||
|     let studentRepository: StudentRepository; | ||||
|     let cassRepository: ClassRepository; | ||||
| 
 | ||||
|     beforeAll(async () => { | ||||
|         await setupTestApp(); | ||||
|         classJoinRequestRepository = getClassJoinRequestRepository(); | ||||
|         studentRepository = getStudentRepository(); | ||||
|         cassRepository = getClassRepository(); | ||||
|     }); | ||||
| 
 | ||||
|     it('should list all requests from student to join classes', async () => { | ||||
|         const student = await studentRepository.findByUsername('PinkFloyd'); | ||||
|         const requests = await classJoinRequestRepository.findAllRequestsBy(student!); | ||||
| 
 | ||||
|         expect(requests).toBeTruthy(); | ||||
|         expect(requests).toHaveLength(2); | ||||
|     }); | ||||
| 
 | ||||
|     it('should list all requests to a single class', async () => { | ||||
|         const class_ = await cassRepository.findById('id02'); | ||||
|         const requests = await classJoinRequestRepository.findAllOpenRequestsTo(class_!); | ||||
| 
 | ||||
|         expect(requests).toBeTruthy(); | ||||
|         expect(requests).toHaveLength(2); | ||||
|     }); | ||||
| 
 | ||||
|     it('should not find a removed request', async () => { | ||||
|         const student = await studentRepository.findByUsername('SmashingPumpkins'); | ||||
|         const class_ = await cassRepository.findById('id03'); | ||||
|         await classJoinRequestRepository.deleteBy(student!, class_!); | ||||
| 
 | ||||
|         const request = await classJoinRequestRepository.findAllRequestsBy(student!); | ||||
| 
 | ||||
|         expect(request).toHaveLength(0); | ||||
|     }); | ||||
| }); | ||||
							
								
								
									
										34
									
								
								backend/tests/data/classes/classes.test.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								backend/tests/data/classes/classes.test.ts
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,34 @@ | |||
| import { beforeAll, describe, expect, it } from 'vitest'; | ||||
| import { ClassRepository } from '../../../src/data/classes/class-repository'; | ||||
| import { setupTestApp } from '../../setup-tests'; | ||||
| import { getClassRepository } from '../../../src/data/repositories'; | ||||
| 
 | ||||
| describe('ClassRepository', () => { | ||||
|     let classRepository: ClassRepository; | ||||
| 
 | ||||
|     beforeAll(async () => { | ||||
|         await setupTestApp(); | ||||
|         classRepository = getClassRepository(); | ||||
|     }); | ||||
| 
 | ||||
|     it('should return nothing because id does not exist', async () => { | ||||
|         const classVar = await classRepository.findById('test_id'); | ||||
| 
 | ||||
|         expect(classVar).toBeNull(); | ||||
|     }); | ||||
| 
 | ||||
|     it('should return requested class', async () => { | ||||
|         const classVar = await classRepository.findById('id01'); | ||||
| 
 | ||||
|         expect(classVar).toBeTruthy(); | ||||
|         expect(classVar?.displayName).toBe('class01'); | ||||
|     }); | ||||
| 
 | ||||
|     it('class should be gone after deletion', async () => { | ||||
|         await classRepository.deleteById('id04'); | ||||
| 
 | ||||
|         const classVar = await classRepository.findById('id04'); | ||||
| 
 | ||||
|         expect(classVar).toBeNull(); | ||||
|     }); | ||||
| }); | ||||
							
								
								
									
										54
									
								
								backend/tests/data/classes/teacher-invitation.test.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								backend/tests/data/classes/teacher-invitation.test.ts
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,54 @@ | |||
| import { beforeAll, describe, expect, it } from 'vitest'; | ||||
| import { setupTestApp } from '../../setup-tests'; | ||||
| import { getClassRepository, getTeacherInvitationRepository, getTeacherRepository } from '../../../src/data/repositories'; | ||||
| import { TeacherInvitationRepository } from '../../../src/data/classes/teacher-invitation-repository'; | ||||
| import { TeacherRepository } from '../../../src/data/users/teacher-repository'; | ||||
| import { ClassRepository } from '../../../src/data/classes/class-repository'; | ||||
| 
 | ||||
| describe('ClassRepository', () => { | ||||
|     let teacherInvitationRepository: TeacherInvitationRepository; | ||||
|     let teacherRepository: TeacherRepository; | ||||
|     let classRepository: ClassRepository; | ||||
| 
 | ||||
|     beforeAll(async () => { | ||||
|         await setupTestApp(); | ||||
|         teacherInvitationRepository = getTeacherInvitationRepository(); | ||||
|         teacherRepository = getTeacherRepository(); | ||||
|         classRepository = getClassRepository(); | ||||
|     }); | ||||
| 
 | ||||
|     it('should return all invitations from a teacher', async () => { | ||||
|         const teacher = await teacherRepository.findByUsername('LimpBizkit'); | ||||
|         const invitations = await teacherInvitationRepository.findAllInvitationsBy(teacher!); | ||||
| 
 | ||||
|         expect(invitations).toBeTruthy(); | ||||
|         expect(invitations).toHaveLength(2); | ||||
|     }); | ||||
| 
 | ||||
|     it('should return all invitations for a teacher', async () => { | ||||
|         const teacher = await teacherRepository.findByUsername('FooFighters'); | ||||
|         const invitations = await teacherInvitationRepository.findAllInvitationsFor(teacher!); | ||||
| 
 | ||||
|         expect(invitations).toBeTruthy(); | ||||
|         expect(invitations).toHaveLength(2); | ||||
|     }); | ||||
| 
 | ||||
|     it('should return all invitations for a class', async () => { | ||||
|         const class_ = await classRepository.findById('id02'); | ||||
|         const invitations = await teacherInvitationRepository.findAllInvitationsForClass(class_!); | ||||
| 
 | ||||
|         expect(invitations).toBeTruthy(); | ||||
|         expect(invitations).toHaveLength(2); | ||||
|     }); | ||||
| 
 | ||||
|     it('should not find a removed invitation', async () => { | ||||
|         const class_ = await classRepository.findById('id01'); | ||||
|         const sender = await teacherRepository.findByUsername('FooFighters'); | ||||
|         const receiver = await teacherRepository.findByUsername('LimpBizkit'); | ||||
|         await teacherInvitationRepository.deleteBy(class_!, sender!, receiver!); | ||||
| 
 | ||||
|         const invitation = await teacherInvitationRepository.findAllInvitationsBy(sender!); | ||||
| 
 | ||||
|         expect(invitation).toHaveLength(0); | ||||
|     }); | ||||
| }); | ||||
							
								
								
									
										31
									
								
								backend/tests/data/content/attachments.test.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								backend/tests/data/content/attachments.test.ts
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,31 @@ | |||
| import { beforeAll, describe, expect, it } from 'vitest'; | ||||
| import { setupTestApp } from '../../setup-tests.js'; | ||||
| import { getAttachmentRepository, getLearningObjectRepository } from '../../../src/data/repositories.js'; | ||||
| import { AttachmentRepository } from '../../../src/data/content/attachment-repository.js'; | ||||
| import { LearningObjectRepository } from '../../../src/data/content/learning-object-repository.js'; | ||||
| import { LearningObjectIdentifier } from '../../../src/entities/content/learning-object-identifier.js'; | ||||
| import { Language } from '../../../src/entities/content/language.js'; | ||||
| 
 | ||||
| describe('AttachmentRepository', () => { | ||||
|     let attachmentRepository: AttachmentRepository; | ||||
|     let learningObjectRepository: LearningObjectRepository; | ||||
| 
 | ||||
|     beforeAll(async () => { | ||||
|         await setupTestApp(); | ||||
|         attachmentRepository = getAttachmentRepository(); | ||||
|         learningObjectRepository = getLearningObjectRepository(); | ||||
|     }); | ||||
| 
 | ||||
|     it('should return the requested attachment', async () => { | ||||
|         const id = new LearningObjectIdentifier('id02', Language.English, '1'); | ||||
|         const learningObject = await learningObjectRepository.findByIdentifier(id); | ||||
| 
 | ||||
|         const attachment = await attachmentRepository.findByMostRecentVersionOfLearningObjectAndName( | ||||
|             learningObject!, | ||||
|             Language.English, | ||||
|             'attachment01' | ||||
|         ); | ||||
| 
 | ||||
|         expect(attachment).toBeTruthy(); | ||||
|     }); | ||||
| }); | ||||
							
								
								
									
										32
									
								
								backend/tests/data/content/learning-objects.test.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								backend/tests/data/content/learning-objects.test.ts
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,32 @@ | |||
| import { beforeAll, describe, expect, it } from 'vitest'; | ||||
| import { LearningObjectRepository } from '../../../src/data/content/learning-object-repository'; | ||||
| import { getLearningObjectRepository } from '../../../src/data/repositories'; | ||||
| import { setupTestApp } from '../../setup-tests'; | ||||
| import { LearningObjectIdentifier } from '../../../src/entities/content/learning-object-identifier'; | ||||
| import { Language } from '../../../src/entities/content/language'; | ||||
| 
 | ||||
| describe('LearningObjectRepository', () => { | ||||
|     let learningObjectRepository: LearningObjectRepository; | ||||
| 
 | ||||
|     beforeAll(async () => { | ||||
|         await setupTestApp(); | ||||
|         learningObjectRepository = getLearningObjectRepository(); | ||||
|     }); | ||||
| 
 | ||||
|     const id01 = new LearningObjectIdentifier('id01', Language.English, '1'); | ||||
|     const id02 = new LearningObjectIdentifier('test_id', Language.English, '1'); | ||||
| 
 | ||||
|     it('should return the learning object that matches identifier 1', async () => { | ||||
|         const learningObject = await learningObjectRepository.findByIdentifier(id01); | ||||
| 
 | ||||
|         expect(learningObject).toBeTruthy(); | ||||
|         expect(learningObject?.title).toBe('Undertow'); | ||||
|         expect(learningObject?.description).toBe('debute'); | ||||
|     }); | ||||
| 
 | ||||
|     it('should return nothing because the identifier does not exist in the database', async () => { | ||||
|         const learningObject = await learningObjectRepository.findByIdentifier(id02); | ||||
| 
 | ||||
|         expect(learningObject).toBeNull(); | ||||
|     }); | ||||
| }); | ||||
							
								
								
									
										28
									
								
								backend/tests/data/content/learning-paths.test.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								backend/tests/data/content/learning-paths.test.ts
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,28 @@ | |||
| import { beforeAll, describe, expect, it } from 'vitest'; | ||||
| import { getLearningPathRepository } from '../../../src/data/repositories'; | ||||
| import { LearningPathRepository } from '../../../src/data/content/learning-path-repository'; | ||||
| import { setupTestApp } from '../../setup-tests'; | ||||
| import { Language } from '../../../src/entities/content/language'; | ||||
| 
 | ||||
| describe('LearningPathRepository', () => { | ||||
|     let learningPathRepository: LearningPathRepository; | ||||
| 
 | ||||
|     beforeAll(async () => { | ||||
|         await setupTestApp(); | ||||
|         learningPathRepository = getLearningPathRepository(); | ||||
|     }); | ||||
| 
 | ||||
|     it('should return nothing because no match for hruid and language', async () => { | ||||
|         const learningPath = await learningPathRepository.findByHruidAndLanguage('test_id', Language.Dutch); | ||||
| 
 | ||||
|         expect(learningPath).toBeNull(); | ||||
|     }); | ||||
| 
 | ||||
|     it('should return requested learning path', async () => { | ||||
|         const learningPath = await learningPathRepository.findByHruidAndLanguage('id01', Language.English); | ||||
| 
 | ||||
|         expect(learningPath).toBeTruthy(); | ||||
|         expect(learningPath?.title).toBe('repertoire Tool'); | ||||
|         expect(learningPath?.description).toBe('all about Tool'); | ||||
|     }); | ||||
| }); | ||||
							
								
								
									
										66
									
								
								backend/tests/data/questions/answers.test.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										66
									
								
								backend/tests/data/questions/answers.test.ts
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,66 @@ | |||
| import { beforeAll, describe, expect, it } from 'vitest'; | ||||
| import { setupTestApp } from '../../setup-tests'; | ||||
| import { AnswerRepository } from '../../../src/data/questions/answer-repository'; | ||||
| import { getAnswerRepository, getQuestionRepository, getTeacherRepository } from '../../../src/data/repositories'; | ||||
| import { QuestionRepository } from '../../../src/data/questions/question-repository'; | ||||
| import { LearningObjectIdentifier } from '../../../src/entities/content/learning-object-identifier'; | ||||
| import { Language } from '../../../src/entities/content/language'; | ||||
| import { TeacherRepository } from '../../../src/data/users/teacher-repository'; | ||||
| 
 | ||||
| describe('AnswerRepository', () => { | ||||
|     let answerRepository: AnswerRepository; | ||||
|     let questionRepository: QuestionRepository; | ||||
|     let teacherRepository: TeacherRepository; | ||||
| 
 | ||||
|     beforeAll(async () => { | ||||
|         await setupTestApp(); | ||||
|         answerRepository = getAnswerRepository(); | ||||
|         questionRepository = getQuestionRepository(); | ||||
|         teacherRepository = getTeacherRepository(); | ||||
|     }); | ||||
| 
 | ||||
|     it('should find all answers to a question', async () => { | ||||
|         const id = new LearningObjectIdentifier('id05', Language.English, '1'); | ||||
|         const questions = await questionRepository.findAllQuestionsAboutLearningObject(id); | ||||
| 
 | ||||
|         const question = questions.filter((it) => it.sequenceNumber == 2)[0]; | ||||
| 
 | ||||
|         const answers = await answerRepository.findAllAnswersToQuestion(question); | ||||
| 
 | ||||
|         expect(answers).toBeTruthy(); | ||||
|         expect(answers).toHaveLength(2); | ||||
|         expect(answers[0].content).toBeOneOf(['answer', 'answer2']); | ||||
|         expect(answers[1].content).toBeOneOf(['answer', 'answer2']); | ||||
|     }); | ||||
| 
 | ||||
|     it('should create an answer to a question', async () => { | ||||
|         const teacher = await teacherRepository.findByUsername('FooFighters'); | ||||
|         const id = new LearningObjectIdentifier('id05', Language.English, '1'); | ||||
|         const questions = await questionRepository.findAllQuestionsAboutLearningObject(id); | ||||
| 
 | ||||
|         const question = questions[0]; | ||||
| 
 | ||||
|         await answerRepository.createAnswer({ | ||||
|             toQuestion: question, | ||||
|             author: teacher!, | ||||
|             content: 'created answer', | ||||
|         }); | ||||
| 
 | ||||
|         const answers = await answerRepository.findAllAnswersToQuestion(question); | ||||
| 
 | ||||
|         expect(answers).toBeTruthy(); | ||||
|         expect(answers).toHaveLength(1); | ||||
|         expect(answers[0].content).toBe('created answer'); | ||||
|     }); | ||||
| 
 | ||||
|     it('should not find a removed answer', async () => { | ||||
|         const id = new LearningObjectIdentifier('id04', Language.English, '1'); | ||||
|         const questions = await questionRepository.findAllQuestionsAboutLearningObject(id); | ||||
| 
 | ||||
|         await answerRepository.removeAnswerByQuestionAndSequenceNumber(questions[0], 1); | ||||
| 
 | ||||
|         const emptyList = await answerRepository.findAllAnswersToQuestion(questions[0]); | ||||
| 
 | ||||
|         expect(emptyList).toHaveLength(0); | ||||
|     }); | ||||
| }); | ||||
							
								
								
									
										52
									
								
								backend/tests/data/questions/questions.test.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								backend/tests/data/questions/questions.test.ts
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,52 @@ | |||
| import { beforeAll, describe, expect, it } from 'vitest'; | ||||
| import { setupTestApp } from '../../setup-tests'; | ||||
| import { QuestionRepository } from '../../../src/data/questions/question-repository'; | ||||
| import { getLearningObjectRepository, getQuestionRepository, getStudentRepository } from '../../../src/data/repositories'; | ||||
| import { StudentRepository } from '../../../src/data/users/student-repository'; | ||||
| import { LearningObjectRepository } from '../../../src/data/content/learning-object-repository'; | ||||
| import { LearningObjectIdentifier } from '../../../src/entities/content/learning-object-identifier'; | ||||
| import { Language } from '../../../src/entities/content/language'; | ||||
| 
 | ||||
| describe('QuestionRepository', () => { | ||||
|     let questionRepository: QuestionRepository; | ||||
|     let studentRepository: StudentRepository; | ||||
|     let learningObjectRepository: LearningObjectRepository; | ||||
| 
 | ||||
|     beforeAll(async () => { | ||||
|         await setupTestApp(); | ||||
|         questionRepository = getQuestionRepository(); | ||||
|         studentRepository = getStudentRepository(); | ||||
|         learningObjectRepository = getLearningObjectRepository(); | ||||
|     }); | ||||
| 
 | ||||
|     it('should return all questions part of the given learning object', async () => { | ||||
|         const id = new LearningObjectIdentifier('id05', Language.English, '1'); | ||||
|         const questions = await questionRepository.findAllQuestionsAboutLearningObject(id); | ||||
| 
 | ||||
|         expect(questions).toBeTruthy(); | ||||
|         expect(questions).toHaveLength(2); | ||||
|     }); | ||||
| 
 | ||||
|     it('should create new question', async () => { | ||||
|         const id = new LearningObjectIdentifier('id03', Language.English, '1'); | ||||
|         const student = await studentRepository.findByUsername('Noordkaap'); | ||||
|         await questionRepository.createQuestion({ | ||||
|             loId: id, | ||||
|             author: student!, | ||||
|             content: 'question?', | ||||
|         }); | ||||
|         const question = await questionRepository.findAllQuestionsAboutLearningObject(id); | ||||
| 
 | ||||
|         expect(question).toBeTruthy(); | ||||
|         expect(question).toHaveLength(1); | ||||
|     }); | ||||
| 
 | ||||
|     it('should not find removed question', async () => { | ||||
|         const id = new LearningObjectIdentifier('id04', Language.English, '1'); | ||||
|         await questionRepository.removeQuestionByLearningObjectAndSequenceNumber(id, 1); | ||||
| 
 | ||||
|         const question = await questionRepository.findAllQuestionsAboutLearningObject(id); | ||||
| 
 | ||||
|         expect(question).toHaveLength(0); | ||||
|     }); | ||||
| }); | ||||
|  | @ -1,8 +1,8 @@ | |||
| import { setupTestApp } from '../setup-tests.js'; | ||||
| import { Student } from '../../src/entities/users/student.entity.js'; | ||||
| import { setupTestApp } from '../../setup-tests.js'; | ||||
| import { Student } from '../../../src/entities/users/student.entity.js'; | ||||
| import { describe, it, expect, beforeAll } from 'vitest'; | ||||
| import { StudentRepository } from '../../src/data/users/student-repository.js'; | ||||
| import { getStudentRepository } from '../../src/data/repositories.js'; | ||||
| import { StudentRepository } from '../../../src/data/users/student-repository.js'; | ||||
| import { getStudentRepository } from '../../../src/data/repositories.js'; | ||||
| 
 | ||||
| const username = 'teststudent'; | ||||
| const firstName = 'John'; | ||||
|  | @ -15,6 +15,20 @@ describe('StudentRepository', () => { | |||
|         studentRepository = getStudentRepository(); | ||||
|     }); | ||||
| 
 | ||||
|     it('should not return a student because username does not exist', async () => { | ||||
|         const student = await studentRepository.findByUsername('test'); | ||||
| 
 | ||||
|         expect(student).toBeNull(); | ||||
|     }); | ||||
| 
 | ||||
|     it('should return student from the datbase', async () => { | ||||
|         const student = await studentRepository.findByUsername('Noordkaap'); | ||||
| 
 | ||||
|         expect(student).toBeTruthy(); | ||||
|         expect(student?.firstName).toBe('Stijn'); | ||||
|         expect(student?.lastName).toBe('Meuris'); | ||||
|     }); | ||||
| 
 | ||||
|     it('should return the queried student after he was added', async () => { | ||||
|         await studentRepository.insert(new Student(username, firstName, lastName)); | ||||
| 
 | ||||
							
								
								
									
										47
									
								
								backend/tests/data/users/teachers.test.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								backend/tests/data/users/teachers.test.ts
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,47 @@ | |||
| import { describe, it, expect, beforeAll } from 'vitest'; | ||||
| import { TeacherRepository } from '../../../src/data/users/teacher-repository'; | ||||
| import { setupTestApp } from '../../setup-tests'; | ||||
| import { getTeacherRepository } from '../../../src/data/repositories'; | ||||
| import { Teacher } from '../../../src/entities/users/teacher.entity'; | ||||
| 
 | ||||
| const username = 'testteacher'; | ||||
| const firstName = 'John'; | ||||
| const lastName = 'Doe'; | ||||
| describe('TeacherRepository', () => { | ||||
|     let teacherRepository: TeacherRepository; | ||||
| 
 | ||||
|     beforeAll(async () => { | ||||
|         await setupTestApp(); | ||||
|         teacherRepository = getTeacherRepository(); | ||||
|     }); | ||||
| 
 | ||||
|     it('should not return a teacher because username does not exist', async () => { | ||||
|         const teacher = await teacherRepository.findByUsername('test'); | ||||
| 
 | ||||
|         expect(teacher).toBeNull(); | ||||
|     }); | ||||
| 
 | ||||
|     it('should return teacher from the datbase', async () => { | ||||
|         const teacher = await teacherRepository.findByUsername('FooFighters'); | ||||
| 
 | ||||
|         expect(teacher).toBeTruthy(); | ||||
|         expect(teacher?.firstName).toBe('Dave'); | ||||
|         expect(teacher?.lastName).toBe('Grohl'); | ||||
|     }); | ||||
| 
 | ||||
|     it('should return the queried teacher after he was added', async () => { | ||||
|         await teacherRepository.insert(new Teacher(username, firstName, lastName)); | ||||
| 
 | ||||
|         const retrievedTeacher = await teacherRepository.findByUsername(username); | ||||
|         expect(retrievedTeacher).toBeTruthy(); | ||||
|         expect(retrievedTeacher?.firstName).toBe(firstName); | ||||
|         expect(retrievedTeacher?.lastName).toBe(lastName); | ||||
|     }); | ||||
| 
 | ||||
|     it('should no longer return the queried teacher after he was removed again', async () => { | ||||
|         await teacherRepository.deleteByUsername('ZesdeMetaal'); | ||||
| 
 | ||||
|         const retrievedTeacher = await teacherRepository.findByUsername('ZesdeMetaal'); | ||||
|         expect(retrievedTeacher).toBeNull(); | ||||
|     }); | ||||
| }); | ||||
|  | @ -1,7 +1,59 @@ | |||
| import { initORM } from '../src/orm.js'; | ||||
| import { forkEntityManager, initORM } from '../src/orm.js'; | ||||
| import dotenv from 'dotenv'; | ||||
| import { makeTestStudents } from './test_assets/users/students.testdata.js'; | ||||
| import { makeTestTeachers } from './test_assets/users/teachers.testdata.js'; | ||||
| import { makeTestLearningObjects } from './test_assets/content/learning-objects.testdata.js'; | ||||
| import { makeTestLearningPaths } from './test_assets/content/learning-paths.testdata.js'; | ||||
| import { makeTestClasses } from './test_assets/classes/classes.testdata.js'; | ||||
| import { makeTestAssignemnts } from './test_assets/assignments/assignments.testdata.js'; | ||||
| import { makeTestGroups } from './test_assets/assignments/groups.testdata.js'; | ||||
| import { makeTestTeacherInvitations } from './test_assets/classes/teacher-invitations.testdata.js'; | ||||
| import { makeTestClassJoinRequests } from './test_assets/classes/class-join-requests.testdata.js'; | ||||
| import { makeTestAttachments } from './test_assets/content/attachments.testdata.js'; | ||||
| import { makeTestQuestions } from './test_assets/questions/questions.testdata.js'; | ||||
| import { makeTestAnswers } from './test_assets/questions/answers.testdata.js'; | ||||
| import { makeTestSubmissions } from './test_assets/assignments/submission.testdata.js'; | ||||
| 
 | ||||
| export async function setupTestApp() { | ||||
|     dotenv.config({ path: '.env.test' }); | ||||
|     await initORM(true); | ||||
| 
 | ||||
|     const em = forkEntityManager(); | ||||
| 
 | ||||
|     const students = makeTestStudents(em); | ||||
|     const teachers = makeTestTeachers(em); | ||||
|     const learningObjects = makeTestLearningObjects(em); | ||||
|     const learningPaths = makeTestLearningPaths(em); | ||||
|     const classes = makeTestClasses(em, students, teachers); | ||||
|     const assignments = makeTestAssignemnts(em, classes); | ||||
|     const groups = makeTestGroups(em, students, assignments); | ||||
| 
 | ||||
|     assignments[0].groups = groups.slice(0, 3); | ||||
|     assignments[1].groups = groups.slice(3, 4); | ||||
| 
 | ||||
|     const teacherInvitations = makeTestTeacherInvitations(em, teachers, classes); | ||||
|     const classJoinRequests = makeTestClassJoinRequests(em, students, classes); | ||||
|     const attachments = makeTestAttachments(em, learningObjects); | ||||
| 
 | ||||
|     learningObjects[1].attachments = attachments; | ||||
| 
 | ||||
|     const questions = makeTestQuestions(em, students); | ||||
|     const answers = makeTestAnswers(em, teachers, questions); | ||||
|     const submissions = makeTestSubmissions(em, students, groups); | ||||
| 
 | ||||
|     await em.persistAndFlush([ | ||||
|         ...students, | ||||
|         ...teachers, | ||||
|         ...learningObjects, | ||||
|         ...learningPaths, | ||||
|         ...classes, | ||||
|         ...assignments, | ||||
|         ...groups, | ||||
|         ...teacherInvitations, | ||||
|         ...classJoinRequests, | ||||
|         ...attachments, | ||||
|         ...questions, | ||||
|         ...answers, | ||||
|         ...submissions, | ||||
|     ]); | ||||
| } | ||||
|  |  | |||
|  | @ -0,0 +1,38 @@ | |||
| import { Connection, EntityManager, IDatabaseDriver } from '@mikro-orm/core'; | ||||
| import { Assignment } from '../../../src/entities/assignments/assignment.entity'; | ||||
| import { Class } from '../../../src/entities/classes/class.entity'; | ||||
| import { Language } from '../../../src/entities/content/language'; | ||||
| 
 | ||||
| export function makeTestAssignemnts(em: EntityManager<IDatabaseDriver<Connection>>, classes: Array<Class>): Array<Assignment> { | ||||
|     const assignment01 = em.create(Assignment, { | ||||
|         within: classes[0], | ||||
|         id: 1, | ||||
|         title: 'dire straits', | ||||
|         description: 'reading', | ||||
|         learningPathHruid: 'id02', | ||||
|         learningPathLanguage: Language.English, | ||||
|         groups: [], | ||||
|     }); | ||||
| 
 | ||||
|     const assignment02 = em.create(Assignment, { | ||||
|         within: classes[1], | ||||
|         id: 2, | ||||
|         title: 'tool', | ||||
|         description: 'reading', | ||||
|         learningPathHruid: 'id01', | ||||
|         learningPathLanguage: Language.English, | ||||
|         groups: [], | ||||
|     }); | ||||
| 
 | ||||
|     const assignment03 = em.create(Assignment, { | ||||
|         within: classes[0], | ||||
|         id: 3, | ||||
|         title: 'delete', | ||||
|         description: 'will be deleted', | ||||
|         learningPathHruid: 'id02', | ||||
|         learningPathLanguage: Language.English, | ||||
|         groups: [], | ||||
|     }); | ||||
| 
 | ||||
|     return [assignment01, assignment02, assignment03]; | ||||
| } | ||||
							
								
								
									
										36
									
								
								backend/tests/test_assets/assignments/groups.testdata.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								backend/tests/test_assets/assignments/groups.testdata.ts
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,36 @@ | |||
| import { Connection, EntityManager, IDatabaseDriver } from '@mikro-orm/core'; | ||||
| import { Group } from '../../../src/entities/assignments/group.entity'; | ||||
| import { Assignment } from '../../../src/entities/assignments/assignment.entity'; | ||||
| import { Student } from '../../../src/entities/users/student.entity'; | ||||
| 
 | ||||
| export function makeTestGroups( | ||||
|     em: EntityManager<IDatabaseDriver<Connection>>, | ||||
|     students: Array<Student>, | ||||
|     assignments: Array<Assignment> | ||||
| ): Array<Group> { | ||||
|     const group01 = em.create(Group, { | ||||
|         assignment: assignments[0], | ||||
|         groupNumber: 1, | ||||
|         members: students.slice(0, 2), | ||||
|     }); | ||||
| 
 | ||||
|     const group02 = em.create(Group, { | ||||
|         assignment: assignments[0], | ||||
|         groupNumber: 2, | ||||
|         members: students.slice(2, 4), | ||||
|     }); | ||||
| 
 | ||||
|     const group03 = em.create(Group, { | ||||
|         assignment: assignments[0], | ||||
|         groupNumber: 3, | ||||
|         members: students.slice(4, 6), | ||||
|     }); | ||||
| 
 | ||||
|     const group04 = em.create(Group, { | ||||
|         assignment: assignments[1], | ||||
|         groupNumber: 4, | ||||
|         members: students.slice(3, 4), | ||||
|     }); | ||||
| 
 | ||||
|     return [group01, group02, group03, group04]; | ||||
| } | ||||
							
								
								
									
										65
									
								
								backend/tests/test_assets/assignments/submission.testdata.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										65
									
								
								backend/tests/test_assets/assignments/submission.testdata.ts
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,65 @@ | |||
| import { Connection, EntityManager, IDatabaseDriver } from '@mikro-orm/core'; | ||||
| import { Submission } from '../../../src/entities/assignments/submission.entity'; | ||||
| import { Language } from '../../../src/entities/content/language'; | ||||
| import { Student } from '../../../src/entities/users/student.entity'; | ||||
| import { Group } from '../../../src/entities/assignments/group.entity'; | ||||
| 
 | ||||
| export function makeTestSubmissions( | ||||
|     em: EntityManager<IDatabaseDriver<Connection>>, | ||||
|     students: Array<Student>, | ||||
|     groups: Array<Group> | ||||
| ): Array<Submission> { | ||||
|     const submission01 = em.create(Submission, { | ||||
|         learningObjectHruid: 'id03', | ||||
|         learningObjectLanguage: Language.English, | ||||
|         learningObjectVersion: '1', | ||||
|         submissionNumber: 1, | ||||
|         submitter: students[0], | ||||
|         submissionTime: new Date(2025, 2, 20), | ||||
|         onBehalfOf: groups[0], | ||||
|         content: 'sub1', | ||||
|     }); | ||||
| 
 | ||||
|     const submission02 = em.create(Submission, { | ||||
|         learningObjectHruid: 'id03', | ||||
|         learningObjectLanguage: Language.English, | ||||
|         learningObjectVersion: '1', | ||||
|         submissionNumber: 2, | ||||
|         submitter: students[0], | ||||
|         submissionTime: new Date(2025, 2, 25), | ||||
|         onBehalfOf: groups[0], | ||||
|         content: '', | ||||
|     }); | ||||
| 
 | ||||
|     const submission03 = em.create(Submission, { | ||||
|         learningObjectHruid: 'id02', | ||||
|         learningObjectLanguage: Language.English, | ||||
|         learningObjectVersion: '1', | ||||
|         submissionNumber: 1, | ||||
|         submitter: students[0], | ||||
|         submissionTime: new Date(2025, 2, 20), | ||||
|         content: '', | ||||
|     }); | ||||
| 
 | ||||
|     const submission04 = em.create(Submission, { | ||||
|         learningObjectHruid: 'id02', | ||||
|         learningObjectLanguage: Language.English, | ||||
|         learningObjectVersion: '1', | ||||
|         submissionNumber: 2, | ||||
|         submitter: students[0], | ||||
|         submissionTime: new Date(2025, 2, 25), | ||||
|         content: '', | ||||
|     }); | ||||
| 
 | ||||
|     const submission05 = em.create(Submission, { | ||||
|         learningObjectHruid: 'id01', | ||||
|         learningObjectLanguage: Language.English, | ||||
|         learningObjectVersion: '1', | ||||
|         submissionNumber: 1, | ||||
|         submitter: students[1], | ||||
|         submissionTime: new Date(2025, 2, 20), | ||||
|         content: '', | ||||
|     }); | ||||
| 
 | ||||
|     return [submission01, submission02, submission03, submission04, submission05]; | ||||
| } | ||||
|  | @ -0,0 +1,36 @@ | |||
| import { Connection, EntityManager, IDatabaseDriver } from '@mikro-orm/core'; | ||||
| import { ClassJoinRequest, ClassJoinRequestStatus } from '../../../src/entities/classes/class-join-request.entity'; | ||||
| import { Student } from '../../../src/entities/users/student.entity'; | ||||
| import { Class } from '../../../src/entities/classes/class.entity'; | ||||
| 
 | ||||
| export function makeTestClassJoinRequests( | ||||
|     em: EntityManager<IDatabaseDriver<Connection>>, | ||||
|     students: Array<Student>, | ||||
|     classes: Array<Class> | ||||
| ): Array<ClassJoinRequest> { | ||||
|     const classJoinRequest01 = em.create(ClassJoinRequest, { | ||||
|         requester: students[4], | ||||
|         class: classes[1], | ||||
|         status: ClassJoinRequestStatus.Open, | ||||
|     }); | ||||
| 
 | ||||
|     const classJoinRequest02 = em.create(ClassJoinRequest, { | ||||
|         requester: students[2], | ||||
|         class: classes[1], | ||||
|         status: ClassJoinRequestStatus.Open, | ||||
|     }); | ||||
| 
 | ||||
|     const classJoinRequest03 = em.create(ClassJoinRequest, { | ||||
|         requester: students[4], | ||||
|         class: classes[2], | ||||
|         status: ClassJoinRequestStatus.Open, | ||||
|     }); | ||||
| 
 | ||||
|     const classJoinRequest04 = em.create(ClassJoinRequest, { | ||||
|         requester: students[3], | ||||
|         class: classes[2], | ||||
|         status: ClassJoinRequestStatus.Open, | ||||
|     }); | ||||
| 
 | ||||
|     return [classJoinRequest01, classJoinRequest02, classJoinRequest03, classJoinRequest04]; | ||||
| } | ||||
							
								
								
									
										48
									
								
								backend/tests/test_assets/classes/classes.testdata.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								backend/tests/test_assets/classes/classes.testdata.ts
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,48 @@ | |||
| import { Connection, EntityManager, IDatabaseDriver } from '@mikro-orm/core'; | ||||
| import { Class } from '../../../src/entities/classes/class.entity'; | ||||
| import { Student } from '../../../src/entities/users/student.entity'; | ||||
| import { Teacher } from '../../../src/entities/users/teacher.entity'; | ||||
| 
 | ||||
| export function makeTestClasses(em: EntityManager<IDatabaseDriver<Connection>>, students: Array<Student>, teachers: Array<Teacher>): Array<Class> { | ||||
|     const studentsClass01 = students.slice(0, 7); | ||||
|     const teacherClass01: Array<Teacher> = teachers.slice(0, 1); | ||||
| 
 | ||||
|     const class01 = em.create(Class, { | ||||
|         classId: 'id01', | ||||
|         displayName: 'class01', | ||||
|         teachers: teacherClass01, | ||||
|         students: studentsClass01, | ||||
|     }); | ||||
| 
 | ||||
|     const studentsClass02: Array<Student> = students.slice(0, 2).concat(students.slice(3, 4)); | ||||
|     const teacherClass02: Array<Teacher> = teachers.slice(1, 2); | ||||
| 
 | ||||
|     const class02 = em.create(Class, { | ||||
|         classId: 'id02', | ||||
|         displayName: 'class02', | ||||
|         teachers: teacherClass02, | ||||
|         students: studentsClass02, | ||||
|     }); | ||||
| 
 | ||||
|     const studentsClass03: Array<Student> = students.slice(1, 4); | ||||
|     const teacherClass03: Array<Teacher> = teachers.slice(2, 3); | ||||
| 
 | ||||
|     const class03 = em.create(Class, { | ||||
|         classId: 'id03', | ||||
|         displayName: 'class03', | ||||
|         teachers: teacherClass03, | ||||
|         students: studentsClass03, | ||||
|     }); | ||||
| 
 | ||||
|     const studentsClass04: Array<Student> = students.slice(0, 2); | ||||
|     const teacherClass04: Array<Teacher> = teachers.slice(2, 3); | ||||
| 
 | ||||
|     const class04 = em.create(Class, { | ||||
|         classId: 'id04', | ||||
|         displayName: 'class04', | ||||
|         teachers: teacherClass04, | ||||
|         students: studentsClass04, | ||||
|     }); | ||||
| 
 | ||||
|     return [class01, class02, class03, class04]; | ||||
| } | ||||
|  | @ -0,0 +1,36 @@ | |||
| import { Connection, EntityManager, IDatabaseDriver } from '@mikro-orm/core'; | ||||
| import { TeacherInvitation } from '../../../src/entities/classes/teacher-invitation.entity'; | ||||
| import { Teacher } from '../../../src/entities/users/teacher.entity'; | ||||
| import { Class } from '../../../src/entities/classes/class.entity'; | ||||
| 
 | ||||
| export function makeTestTeacherInvitations( | ||||
|     em: EntityManager<IDatabaseDriver<Connection>>, | ||||
|     teachers: Array<Teacher>, | ||||
|     classes: Array<Class> | ||||
| ): Array<TeacherInvitation> { | ||||
|     const teacherInvitation01 = em.create(TeacherInvitation, { | ||||
|         sender: teachers[1], | ||||
|         receiver: teachers[0], | ||||
|         class: classes[1], | ||||
|     }); | ||||
| 
 | ||||
|     const teacherInvitation02 = em.create(TeacherInvitation, { | ||||
|         sender: teachers[1], | ||||
|         receiver: teachers[2], | ||||
|         class: classes[1], | ||||
|     }); | ||||
| 
 | ||||
|     const teacherInvitation03 = em.create(TeacherInvitation, { | ||||
|         sender: teachers[2], | ||||
|         receiver: teachers[0], | ||||
|         class: classes[2], | ||||
|     }); | ||||
| 
 | ||||
|     const teacherInvitation04 = em.create(TeacherInvitation, { | ||||
|         sender: teachers[0], | ||||
|         receiver: teachers[1], | ||||
|         class: classes[0], | ||||
|     }); | ||||
| 
 | ||||
|     return [teacherInvitation01, teacherInvitation02, teacherInvitation03, teacherInvitation04]; | ||||
| } | ||||
							
								
								
									
										14
									
								
								backend/tests/test_assets/content/attachments.testdata.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								backend/tests/test_assets/content/attachments.testdata.ts
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,14 @@ | |||
| import { Connection, EntityManager, IDatabaseDriver } from '@mikro-orm/core'; | ||||
| import { Attachment } from '../../../src/entities/content/attachment.entity'; | ||||
| import { LearningObject } from '../../../src/entities/content/learning-object.entity'; | ||||
| 
 | ||||
| export function makeTestAttachments(em: EntityManager<IDatabaseDriver<Connection>>, learningObjects: Array<LearningObject>): Array<Attachment> { | ||||
|     const attachment01 = em.create(Attachment, { | ||||
|         learningObject: learningObjects[1], | ||||
|         name: 'attachment01', | ||||
|         mimeType: '', | ||||
|         content: Buffer.from(''), | ||||
|     }); | ||||
| 
 | ||||
|     return [attachment01]; | ||||
| } | ||||
							
								
								
									
										134
									
								
								backend/tests/test_assets/content/learning-objects.testdata.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										134
									
								
								backend/tests/test_assets/content/learning-objects.testdata.ts
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,134 @@ | |||
| import { Connection, EntityManager, IDatabaseDriver } from '@mikro-orm/core'; | ||||
| import { LearningObject, ReturnValue } from '../../../src/entities/content/learning-object.entity'; | ||||
| import { Language } from '../../../src/entities/content/language'; | ||||
| import { DwengoContentType } from '../../../src/services/learning-objects/processing/content-type'; | ||||
| 
 | ||||
| export function makeTestLearningObjects(em: EntityManager<IDatabaseDriver<Connection>>): Array<LearningObject> { | ||||
|     const returnValue: ReturnValue = new ReturnValue(); | ||||
|     returnValue.callbackSchema = ''; | ||||
|     returnValue.callbackUrl = ''; | ||||
| 
 | ||||
|     const learningObject01 = em.create(LearningObject, { | ||||
|         hruid: 'id01', | ||||
|         language: Language.English, | ||||
|         version: 1, | ||||
|         admins: [], | ||||
|         title: 'Undertow', | ||||
|         description: 'debute', | ||||
|         contentType: DwengoContentType.TEXT_MARKDOWN, | ||||
|         keywords: [], | ||||
|         teacherExclusive: false, | ||||
|         skosConcepts: [], | ||||
|         educationalGoals: [], | ||||
|         copyright: '', | ||||
|         license: '', | ||||
|         estimatedTime: 45, | ||||
|         returnValue: returnValue, | ||||
|         available: true, | ||||
|         contentLocation: '', | ||||
|         attachments: [], | ||||
|         content: Buffer.from("there's a shadow just behind me, shrouding every step i take, making every promise empty pointing every finger at me"), | ||||
|     }); | ||||
| 
 | ||||
|     const learningObject02 = em.create(LearningObject, { | ||||
|         hruid: 'id02', | ||||
|         language: Language.English, | ||||
|         version: 1, | ||||
|         admins: [], | ||||
|         title: 'Aenema', | ||||
|         description: 'second album', | ||||
|         contentType: DwengoContentType.TEXT_MARKDOWN, | ||||
|         keywords: [], | ||||
|         teacherExclusive: false, | ||||
|         skosConcepts: [], | ||||
|         educationalGoals: [], | ||||
|         copyright: '', | ||||
|         license: '', | ||||
|         estimatedTime: 80, | ||||
|         returnValue: returnValue, | ||||
|         available: true, | ||||
|         contentLocation: '', | ||||
|         attachments: [], | ||||
|         content: Buffer.from( | ||||
|             "I've been crawling on my belly clearing out what could've been I've been wallowing in my own confused and insecure delusions" | ||||
|         ), | ||||
|     }); | ||||
| 
 | ||||
|     const learningObject03 = em.create(LearningObject, { | ||||
|         hruid: 'id03', | ||||
|         language: Language.English, | ||||
|         version: 1, | ||||
|         admins: [], | ||||
|         title: 'love over gold', | ||||
|         description: 'third album', | ||||
|         contentType: DwengoContentType.TEXT_MARKDOWN, | ||||
|         keywords: [], | ||||
|         teacherExclusive: false, | ||||
|         skosConcepts: [], | ||||
|         educationalGoals: [], | ||||
|         copyright: '', | ||||
|         license: '', | ||||
|         estimatedTime: 55, | ||||
|         returnValue: returnValue, | ||||
|         available: true, | ||||
|         contentLocation: '', | ||||
|         attachments: [], | ||||
|         content: Buffer.from( | ||||
|             'he wrote me a prescription, he said you are depressed, \ | ||||
|                     but I am glad you came to see me to get this off your chest, \ | ||||
|                     come back and see me later next patient please \ | ||||
|                     send in another victim of industrial disease' | ||||
|         ), | ||||
|     }); | ||||
| 
 | ||||
|     const learningObject04 = em.create(LearningObject, { | ||||
|         hruid: 'id04', | ||||
|         language: Language.English, | ||||
|         version: 1, | ||||
|         admins: [], | ||||
|         title: 'making movies', | ||||
|         description: 'fifth album', | ||||
|         contentType: DwengoContentType.TEXT_MARKDOWN, | ||||
|         keywords: [], | ||||
|         teacherExclusive: false, | ||||
|         skosConcepts: [], | ||||
|         educationalGoals: [], | ||||
|         copyright: '', | ||||
|         license: '', | ||||
|         estimatedTime: 55, | ||||
|         returnValue: returnValue, | ||||
|         available: true, | ||||
|         contentLocation: '', | ||||
|         attachments: [], | ||||
|         content: Buffer.from( | ||||
|             'I put my hand upon the lever \ | ||||
|                     Said let it rock and let it roll \ | ||||
|                     I had the one-arm bandit fever \ | ||||
|                     There was an arrow through my heart and my soul' | ||||
|         ), | ||||
|     }); | ||||
| 
 | ||||
|     const learningObject05 = em.create(LearningObject, { | ||||
|         hruid: 'id05', | ||||
|         language: Language.English, | ||||
|         version: 1, | ||||
|         admins: [], | ||||
|         title: 'on every street', | ||||
|         description: 'sixth album', | ||||
|         contentType: DwengoContentType.TEXT_MARKDOWN, | ||||
|         keywords: [], | ||||
|         teacherExclusive: false, | ||||
|         skosConcepts: [], | ||||
|         educationalGoals: [], | ||||
|         copyright: '', | ||||
|         license: '', | ||||
|         estimatedTime: 55, | ||||
|         returnValue: returnValue, | ||||
|         available: true, | ||||
|         contentLocation: '', | ||||
|         attachments: [], | ||||
|         content: Buffer.from('calling Elvis, is anybody home, calling elvis, I am here all alone'), | ||||
|     }); | ||||
| 
 | ||||
|     return [learningObject01, learningObject02, learningObject03, learningObject04, learningObject05]; | ||||
| } | ||||
							
								
								
									
										100
									
								
								backend/tests/test_assets/content/learning-paths.testdata.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										100
									
								
								backend/tests/test_assets/content/learning-paths.testdata.ts
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,100 @@ | |||
| import { Connection, EntityManager, IDatabaseDriver } from '@mikro-orm/core'; | ||||
| import { LearningPath } from '../../../src/entities/content/learning-path.entity'; | ||||
| import { Language } from '../../../src/entities/content/language'; | ||||
| import { LearningPathTransition } from '../../../src/entities/content/learning-path-transition.entity'; | ||||
| import { LearningPathNode } from '../../../src/entities/content/learning-path-node.entity'; | ||||
| 
 | ||||
| export function makeTestLearningPaths(em: EntityManager<IDatabaseDriver<Connection>>): Array<LearningPath> { | ||||
|     const learningPathNode01: LearningPathNode = new LearningPathNode(); | ||||
|     const learningPathNode02: LearningPathNode = new LearningPathNode(); | ||||
|     const learningPathNode03: LearningPathNode = new LearningPathNode(); | ||||
|     const learningPathNode04: LearningPathNode = new LearningPathNode(); | ||||
|     const learningPathNode05: LearningPathNode = new LearningPathNode(); | ||||
| 
 | ||||
|     const transitions01: LearningPathTransition = new LearningPathTransition(); | ||||
|     const transitions02: LearningPathTransition = new LearningPathTransition(); | ||||
|     const transitions03: LearningPathTransition = new LearningPathTransition(); | ||||
|     const transitions04: LearningPathTransition = new LearningPathTransition(); | ||||
|     const transitions05: LearningPathTransition = new LearningPathTransition(); | ||||
| 
 | ||||
|     transitions01.condition = 'true'; | ||||
|     transitions01.next = learningPathNode02; | ||||
| 
 | ||||
|     transitions02.condition = 'true'; | ||||
|     transitions02.next = learningPathNode02; | ||||
| 
 | ||||
|     transitions03.condition = 'true'; | ||||
|     transitions03.next = learningPathNode04; | ||||
| 
 | ||||
|     transitions04.condition = 'true'; | ||||
|     transitions04.next = learningPathNode05; | ||||
| 
 | ||||
|     transitions05.condition = 'true'; | ||||
|     transitions05.next = learningPathNode05; | ||||
| 
 | ||||
|     learningPathNode01.instruction = ''; | ||||
|     learningPathNode01.language = Language.English; | ||||
|     learningPathNode01.learningObjectHruid = 'id01'; | ||||
|     learningPathNode01.startNode = true; | ||||
|     learningPathNode01.transitions = [transitions01]; | ||||
|     learningPathNode01.version = 1; | ||||
| 
 | ||||
|     learningPathNode02.instruction = ''; | ||||
|     learningPathNode02.language = Language.English; | ||||
|     learningPathNode02.learningObjectHruid = 'id02'; | ||||
|     learningPathNode02.startNode = false; | ||||
|     learningPathNode02.transitions = [transitions02]; | ||||
|     learningPathNode02.version = 1; | ||||
| 
 | ||||
|     learningPathNode03.instruction = ''; | ||||
|     learningPathNode03.language = Language.English; | ||||
|     learningPathNode03.learningObjectHruid = 'id03'; | ||||
|     learningPathNode03.startNode = true; | ||||
|     learningPathNode03.transitions = [transitions03]; | ||||
|     learningPathNode03.version = 1; | ||||
| 
 | ||||
|     learningPathNode04.instruction = ''; | ||||
|     learningPathNode04.language = Language.English; | ||||
|     learningPathNode04.learningObjectHruid = 'id04'; | ||||
|     learningPathNode04.startNode = false; | ||||
|     learningPathNode04.transitions = [transitions04]; | ||||
|     learningPathNode04.version = 1; | ||||
| 
 | ||||
|     learningPathNode05.instruction = ''; | ||||
|     learningPathNode05.language = Language.English; | ||||
|     learningPathNode05.learningObjectHruid = 'id05'; | ||||
|     learningPathNode05.startNode = false; | ||||
|     learningPathNode05.transitions = [transitions05]; | ||||
|     learningPathNode05.version = 1; | ||||
| 
 | ||||
|     const nodes01: Array<LearningPathNode> = [ | ||||
|         // LearningPathNode01,
 | ||||
|         // LearningPathNode02,
 | ||||
|     ]; | ||||
|     const learningPath01 = em.create(LearningPath, { | ||||
|         hruid: 'id01', | ||||
|         language: Language.English, | ||||
|         admins: [], | ||||
|         title: 'repertoire Tool', | ||||
|         description: 'all about Tool', | ||||
|         image: '', | ||||
|         nodes: nodes01, | ||||
|     }); | ||||
| 
 | ||||
|     const nodes02: Array<LearningPathNode> = [ | ||||
|         // LearningPathNode03,
 | ||||
|         // LearningPathNode04,
 | ||||
|         // LearningPathNode05,
 | ||||
|     ]; | ||||
|     const learningPath02 = em.create(LearningPath, { | ||||
|         hruid: 'id02', | ||||
|         language: Language.English, | ||||
|         admins: [], | ||||
|         title: 'repertoire Dire Straits', | ||||
|         description: 'all about Dire Straits', | ||||
|         image: '', | ||||
|         nodes: nodes02, | ||||
|     }); | ||||
| 
 | ||||
|     return [learningPath01, learningPath02]; | ||||
| } | ||||
							
								
								
									
										32
									
								
								backend/tests/test_assets/questions/answers.testdata.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								backend/tests/test_assets/questions/answers.testdata.ts
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,32 @@ | |||
| import { Connection, EntityManager, IDatabaseDriver } from '@mikro-orm/core'; | ||||
| import { Answer } from '../../../src/entities/questions/answer.entity'; | ||||
| import { Teacher } from '../../../src/entities/users/teacher.entity'; | ||||
| import { Question } from '../../../src/entities/questions/question.entity'; | ||||
| 
 | ||||
| export function makeTestAnswers(em: EntityManager<IDatabaseDriver<Connection>>, teachers: Array<Teacher>, questions: Array<Question>): Array<Answer> { | ||||
|     const answer01 = em.create(Answer, { | ||||
|         author: teachers[0], | ||||
|         toQuestion: questions[1], | ||||
|         sequenceNumber: 1, | ||||
|         timestamp: new Date(), | ||||
|         content: 'answer', | ||||
|     }); | ||||
| 
 | ||||
|     const answer02 = em.create(Answer, { | ||||
|         author: teachers[0], | ||||
|         toQuestion: questions[1], | ||||
|         sequenceNumber: 2, | ||||
|         timestamp: new Date(), | ||||
|         content: 'answer2', | ||||
|     }); | ||||
| 
 | ||||
|     const answer03 = em.create(Answer, { | ||||
|         author: teachers[1], | ||||
|         toQuestion: questions[3], | ||||
|         sequenceNumber: 1, | ||||
|         timestamp: new Date(), | ||||
|         content: 'answer3', | ||||
|     }); | ||||
| 
 | ||||
|     return [answer01, answer02, answer03]; | ||||
| } | ||||
							
								
								
									
										48
									
								
								backend/tests/test_assets/questions/questions.testdata.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								backend/tests/test_assets/questions/questions.testdata.ts
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,48 @@ | |||
| import { Connection, EntityManager, IDatabaseDriver } from '@mikro-orm/core'; | ||||
| import { Question } from '../../../src/entities/questions/question.entity'; | ||||
| import { Language } from '../../../src/entities/content/language'; | ||||
| import { Student } from '../../../src/entities/users/student.entity'; | ||||
| 
 | ||||
| export function makeTestQuestions(em: EntityManager<IDatabaseDriver<Connection>>, students: Array<Student>): Array<Question> { | ||||
|     const question01 = em.create(Question, { | ||||
|         learningObjectLanguage: Language.English, | ||||
|         learningObjectVersion: '1', | ||||
|         learningObjectHruid: 'id05', | ||||
|         sequenceNumber: 1, | ||||
|         author: students[0], | ||||
|         timestamp: new Date(), | ||||
|         content: 'question', | ||||
|     }); | ||||
| 
 | ||||
|     const question02 = em.create(Question, { | ||||
|         learningObjectLanguage: Language.English, | ||||
|         learningObjectVersion: '1', | ||||
|         learningObjectHruid: 'id05', | ||||
|         sequenceNumber: 2, | ||||
|         author: students[2], | ||||
|         timestamp: new Date(), | ||||
|         content: 'question', | ||||
|     }); | ||||
| 
 | ||||
|     const question03 = em.create(Question, { | ||||
|         learningObjectLanguage: Language.English, | ||||
|         learningObjectVersion: '1', | ||||
|         learningObjectHruid: 'id04', | ||||
|         sequenceNumber: 1, | ||||
|         author: students[0], | ||||
|         timestamp: new Date(), | ||||
|         content: 'question', | ||||
|     }); | ||||
| 
 | ||||
|     const question04 = em.create(Question, { | ||||
|         learningObjectLanguage: Language.English, | ||||
|         learningObjectVersion: '1', | ||||
|         learningObjectHruid: 'id01', | ||||
|         sequenceNumber: 1, | ||||
|         author: students[1], | ||||
|         timestamp: new Date(), | ||||
|         content: 'question', | ||||
|     }); | ||||
| 
 | ||||
|     return [question01, question02, question03, question04]; | ||||
| } | ||||
							
								
								
									
										49
									
								
								backend/tests/test_assets/users/students.testdata.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								backend/tests/test_assets/users/students.testdata.ts
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,49 @@ | |||
| import { Connection, EntityManager, IDatabaseDriver } from '@mikro-orm/core'; | ||||
| import { Student } from '../../../src/entities/users/student.entity'; | ||||
| 
 | ||||
| export function makeTestStudents(em: EntityManager<IDatabaseDriver<Connection>>): Array<Student> { | ||||
|     const student01 = em.create(Student, { | ||||
|         username: 'Noordkaap', | ||||
|         firstName: 'Stijn', | ||||
|         lastName: 'Meuris', | ||||
|     }); | ||||
| 
 | ||||
|     const student02 = em.create(Student, { | ||||
|         username: 'DireStraits', | ||||
|         firstName: 'Mark', | ||||
|         lastName: 'Knopfler', | ||||
|     }); | ||||
| 
 | ||||
|     const student03 = em.create(Student, { | ||||
|         username: 'Tool', | ||||
|         firstName: 'Maynard', | ||||
|         lastName: 'Keenan', | ||||
|     }); | ||||
| 
 | ||||
|     const student04 = em.create(Student, { | ||||
|         username: 'SmashingPumpkins', | ||||
|         firstName: 'Billy', | ||||
|         lastName: 'Corgan', | ||||
|     }); | ||||
| 
 | ||||
|     const student05 = em.create(Student, { | ||||
|         username: 'PinkFloyd', | ||||
|         firstName: 'David', | ||||
|         lastName: 'Gilmoure', | ||||
|     }); | ||||
| 
 | ||||
|     const student06 = em.create(Student, { | ||||
|         username: 'TheDoors', | ||||
|         firstName: 'Jim', | ||||
|         lastName: 'Morisson', | ||||
|     }); | ||||
| 
 | ||||
|     // Do not use for any tests, gets deleted in a unit test
 | ||||
|     const student07 = em.create(Student, { | ||||
|         username: 'Nirvana', | ||||
|         firstName: 'Kurt', | ||||
|         lastName: 'Cobain', | ||||
|     }); | ||||
| 
 | ||||
|     return [student01, student02, student03, student04, student05, student06, student07]; | ||||
| } | ||||
							
								
								
									
										31
									
								
								backend/tests/test_assets/users/teachers.testdata.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								backend/tests/test_assets/users/teachers.testdata.ts
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,31 @@ | |||
| import { Teacher } from '../../../src/entities/users/teacher.entity'; | ||||
| import { Connection, EntityManager, IDatabaseDriver } from '@mikro-orm/core'; | ||||
| 
 | ||||
| export function makeTestTeachers(em: EntityManager<IDatabaseDriver<Connection>>): Array<Teacher> { | ||||
|     const teacher01 = em.create(Teacher, { | ||||
|         username: 'FooFighters', | ||||
|         firstName: 'Dave', | ||||
|         lastName: 'Grohl', | ||||
|     }); | ||||
| 
 | ||||
|     const teacher02 = em.create(Teacher, { | ||||
|         username: 'LimpBizkit', | ||||
|         firstName: 'Fred', | ||||
|         lastName: 'Durst', | ||||
|     }); | ||||
| 
 | ||||
|     const teacher03 = em.create(Teacher, { | ||||
|         username: 'Staind', | ||||
|         firstName: 'Aaron', | ||||
|         lastName: 'Lewis', | ||||
|     }); | ||||
| 
 | ||||
|     // Should not be used, gets deleted in a unit test
 | ||||
|     const teacher04 = em.create(Teacher, { | ||||
|         username: 'ZesdeMetaal', | ||||
|         firstName: 'Wannes', | ||||
|         lastName: 'Cappelle', | ||||
|     }); | ||||
| 
 | ||||
|     return [teacher01, teacher02, teacher03, teacher04]; | ||||
| } | ||||
|  | @ -2,10 +2,10 @@ | |||
|     import { ref } from "vue"; | ||||
|     import { useRoute } from "vue-router"; | ||||
|     import dwengoLogo from "../../../assets/img/dwengo-groen-zwart.svg"; | ||||
|     import {useI18n} from "vue-i18n"; | ||||
|     import { useI18n } from "vue-i18n"; | ||||
| 
 | ||||
|     const route = useRoute(); | ||||
|     const { t, locale } = useI18n() | ||||
|     const { t, locale } = useI18n(); | ||||
| 
 | ||||
|     // Instantiate variables to use in html to render right | ||||
|     // Links and content dependent on the role (student or teacher) | ||||
|  | @ -30,7 +30,7 @@ | |||
|     // Logic to change the language of the website to the selected language | ||||
|     const changeLanguage = (langCode: string) => { | ||||
|         locale.value = langCode; | ||||
|         localStorage.setItem('user-lang', langCode); | ||||
|         localStorage.setItem("user-lang", langCode); | ||||
|         console.log(langCode); | ||||
|     }; | ||||
| </script> | ||||
|  | @ -59,22 +59,22 @@ | |||
|                             :to="`/${role}/${userId}/assignment`" | ||||
|                             class="menu_item" | ||||
|                         > | ||||
|                             {{ t('assignments') }} | ||||
|                             {{ t("assignments") }} | ||||
|                         </router-link> | ||||
|                     </li> | ||||
|                     <li> | ||||
|                         <router-link | ||||
|                             :to="`/${role}/${userId}/class`" | ||||
|                             class="menu_item" | ||||
|                             >{{ t('classes') }}</router-link | ||||
|                             >{{ t("classes") }}</router-link | ||||
|                         > | ||||
|                     </li> | ||||
|                     <li> | ||||
|                         <router-link | ||||
|                             :to="`/${role}/${userId}/discussion`" | ||||
|                             class="menu_item" | ||||
|                             >{{ t('discussions') }} </router-link | ||||
|                         > | ||||
|                             >{{ t("discussions") }} | ||||
|                         </router-link> | ||||
|                     </li> | ||||
|                     <li> | ||||
|                         <v-menu open-on-hover> | ||||
|  |  | |||
|  | @ -1,4 +1,4 @@ | |||
| import { createI18n } from 'vue-i18n'; | ||||
| import { createI18n } from "vue-i18n"; | ||||
| 
 | ||||
| // Import translations
 | ||||
| import en from "@/i18n/locale/en.json"; | ||||
|  | @ -6,11 +6,11 @@ import nl from "@/i18n/locale/nl.json"; | |||
| import fr from "@/i18n/locale/fr.json"; | ||||
| import de from "@/i18n/locale/de.json"; | ||||
| 
 | ||||
| const savedLocale = localStorage.getItem('user-lang') || 'en'; | ||||
| const savedLocale = localStorage.getItem("user-lang") || "en"; | ||||
| 
 | ||||
| const i18n = createI18n({ | ||||
|     locale: savedLocale, | ||||
|     fallbackLocale: 'en', | ||||
|     fallbackLocale: "en", | ||||
|     messages: { | ||||
|         en: en, | ||||
|         nl: nl, | ||||
|  |  | |||
|  | @ -1,8 +1,8 @@ | |||
| import {createApp} from "vue"; | ||||
| import { createApp } from "vue"; | ||||
| 
 | ||||
| // Vuetify
 | ||||
| import "vuetify/styles"; | ||||
| import {createVuetify} from "vuetify"; | ||||
| import { createVuetify } from "vuetify"; | ||||
| import * as components from "vuetify/components"; | ||||
| import * as directives from "vuetify/directives"; | ||||
| import i18n from "./i18n/i18n.ts"; | ||||
|  | @ -11,7 +11,6 @@ import i18n from "./i18n/i18n.ts"; | |||
| import App from "./App.vue"; | ||||
| import router from "./router"; | ||||
| 
 | ||||
| 
 | ||||
| const app = createApp(App); | ||||
| 
 | ||||
| app.use(router); | ||||
|  |  | |||
							
								
								
									
										4104
									
								
								package-lock.json
									
										
									
										generated
									
									
									
								
							
							
						
						
									
										4104
									
								
								package-lock.json
									
										
									
										generated
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							
		Reference in a new issue