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
Loading…
Add table
Add a link
Reference in a new issue