diff --git a/backend/src/data/assignments/submission-repository.ts b/backend/src/data/assignments/submission-repository.ts index 89832899..a79dc417 100644 --- a/backend/src/data/assignments/submission-repository.ts +++ b/backend/src/data/assignments/submission-repository.ts @@ -82,12 +82,19 @@ export class SubmissionRepository extends DwengoEntityRepository { } public async findAllSubmissionsForStudent(student: Student): Promise { - return this.find( + const result = await this.find( { submitter: student }, { - populate: ["onBehalfOf.members"] + populate: [ + "onBehalfOf.members" + ] } ); + + // Workaround: For some reason, without this MikroORM generates an UPDATE query with a syntax error in some tests + this.em.clear(); + + return result; } public async deleteSubmissionByLearningObjectAndSubmissionNumber(loId: LearningObjectIdentifier, submissionNumber: number): Promise { diff --git a/backend/src/interfaces/group.ts b/backend/src/interfaces/group.ts index d21762db..d3785137 100644 --- a/backend/src/interfaces/group.ts +++ b/backend/src/interfaces/group.ts @@ -1,7 +1,7 @@ import { Group } from '../entities/assignments/group.entity.js'; -import {mapToAssignment, mapToAssignmentDTO} from './assignment.js'; +import {mapToAssignment, mapToAssignmentDTO, mapToAssignmentDTOId} from './assignment.js'; import {mapToStudent, mapToStudentDTO} from './student.js'; -import { GroupDTO } from '@dwengo-1/common/interfaces/group'; +import {GroupDTO} from '@dwengo-1/common/interfaces/group'; import {getGroupRepository} from "../data/repositories"; import {AssignmentDTO} from "@dwengo-1/common/interfaces/assignment"; import {Class} from "../entities/classes/class.entity"; @@ -13,7 +13,7 @@ export function mapToGroup(groupDto: GroupDTO, clazz: Class): Group { return getGroupRepository().create({ groupNumber: groupDto.groupNumber, assignment: mapToAssignment(assignmentDto, clazz), - members: groupDto.members.map(studentDto => mapToStudent(studentDto as StudentDTO)) + members: groupDto.members!.map(studentDto => mapToStudent(studentDto as StudentDTO)) }); } @@ -26,6 +26,16 @@ export function mapToGroupDTO(group: Group): GroupDTO { } export function mapToGroupDTOId(group: Group): GroupDTO { + return { + assignment: mapToAssignmentDTOId(group.assignment), + groupNumber: group.groupNumber!, + }; +} + +/** + * Map to group DTO where other objects are only referenced by their id. + */ +export function mapToShallowGroupDTO(group: Group): GroupDTO { return { assignment: group.assignment.id!, groupNumber: group.groupNumber!, diff --git a/backend/src/interfaces/question.ts b/backend/src/interfaces/question.ts index 91b90796..5419618a 100644 --- a/backend/src/interfaces/question.ts +++ b/backend/src/interfaces/question.ts @@ -2,7 +2,7 @@ import { Question } from '../entities/questions/question.entity.js'; import { mapToStudentDTO } from './student.js'; import { QuestionDTO, QuestionId } from '@dwengo-1/common/interfaces/question'; import { LearningObjectIdentifier } from '@dwengo-1/common/interfaces/learning-content'; -import {mapToGroupDTO} from "./group"; +import { mapToGroupDTOId } from "./group"; function getLearningObjectIdentifier(question: Question): LearningObjectIdentifier { return { @@ -22,7 +22,7 @@ export function mapToQuestionDTO(question: Question): QuestionDTO { learningObjectIdentifier, sequenceNumber: question.sequenceNumber!, author: mapToStudentDTO(question.author), - inGroup: mapToGroupDTO(question.inGroup), + inGroup: mapToGroupDTOId(question.inGroup), timestamp: question.timestamp.toISOString(), content: question.content, }; diff --git a/backend/src/services/groups.ts b/backend/src/services/groups.ts index 346c1ee1..b009e772 100644 --- a/backend/src/services/groups.ts +++ b/backend/src/services/groups.ts @@ -6,7 +6,7 @@ import { getSubmissionRepository, } from '../data/repositories.js'; import { Group } from '../entities/assignments/group.entity.js'; -import { mapToGroupDTO, mapToGroupDTOId } from '../interfaces/group.js'; +import { mapToGroupDTO, mapToShallowGroupDTO } from '../interfaces/group.js'; import { mapToSubmissionDTO, mapToSubmissionDTOId } from '../interfaces/submission.js'; import { GroupDTO } from '@dwengo-1/common/interfaces/group'; import { SubmissionDTO, SubmissionDTOId } from '@dwengo-1/common/interfaces/submission'; @@ -38,7 +38,7 @@ export async function getGroup(classId: string, assignmentNumber: number, groupN return mapToGroupDTO(group); } - return mapToGroupDTOId(group); + return mapToShallowGroupDTO(group); } export async function createGroup(groupData: GroupDTO, classid: string, assignmentNumber: number): Promise { @@ -103,7 +103,7 @@ export async function getAllGroups(classId: string, assignmentNumber: number, fu return groups.map(mapToGroupDTO); } - return groups.map(mapToGroupDTOId); + return groups.map(mapToShallowGroupDTO); } export async function getGroupSubmissions( diff --git a/backend/src/services/students.ts b/backend/src/services/students.ts index dc40e468..be2d270b 100644 --- a/backend/src/services/students.ts +++ b/backend/src/services/students.ts @@ -7,7 +7,7 @@ import { getSubmissionRepository, } from '../data/repositories.js'; import { mapToClassDTO } from '../interfaces/class.js'; -import { mapToGroupDTO, mapToGroupDTOId } from '../interfaces/group.js'; +import { mapToGroupDTO, mapToShallowGroupDTO } from '../interfaces/group.js'; import { mapToStudent, mapToStudentDTO } from '../interfaces/student.js'; import { mapToSubmissionDTO, mapToSubmissionDTOId } from '../interfaces/submission.js'; import { getAllAssignments } from './assignments.js'; @@ -23,6 +23,7 @@ import { GroupDTO } from '@dwengo-1/common/interfaces/group'; import { SubmissionDTO, SubmissionDTOId } from '@dwengo-1/common/interfaces/submission'; import { QuestionDTO, QuestionId } from '@dwengo-1/common/interfaces/question'; import { ClassJoinRequestDTO } from '@dwengo-1/common/interfaces/class-join-request'; +import {Submission} from "../entities/assignments/submission.entity"; export async function getAllStudents(full: boolean): Promise { const studentRepository = getStudentRepository(); @@ -100,14 +101,15 @@ export async function getStudentGroups(username: string, full: boolean): Promise return groups.map(mapToGroupDTO); } - return groups.map(mapToGroupDTOId); + return groups.map(mapToShallowGroupDTO); } export async function getStudentSubmissions(username: string, full: boolean): Promise { const student = await fetchStudent(username); const submissionRepository = getSubmissionRepository(); - const submissions = await submissionRepository.findAllSubmissionsForStudent(student); + + const submissions: Submission[] = await submissionRepository.findAllSubmissionsForStudent(student); if (full) { return submissions.map(mapToSubmissionDTO); diff --git a/backend/tests/controllers/students.test.ts b/backend/tests/controllers/students.test.ts index 93f35c48..35f9a9cf 100644 --- a/backend/tests/controllers/students.test.ts +++ b/backend/tests/controllers/students.test.ts @@ -147,6 +147,7 @@ describe('Student controllers', () => { const result = jsonMock.mock.lastCall?.[0]; expect(result.submissions).to.have.length.greaterThan(0); + }); it('Student questions', async () => { diff --git a/common/src/interfaces/group.ts b/common/src/interfaces/group.ts index ca95770a..16e22780 100644 --- a/common/src/interfaces/group.ts +++ b/common/src/interfaces/group.ts @@ -4,5 +4,5 @@ import { StudentDTO } from './student'; export interface GroupDTO { assignment: number | AssignmentDTO; groupNumber: number; - members: string[] | StudentDTO[]; + members?: string[] | StudentDTO[]; }