refactor: tests adriaan

This commit is contained in:
Gabriellvl 2025-05-10 20:02:51 +02:00
parent ded1a5908e
commit 2d841e7955
7 changed files with 99 additions and 178 deletions

View file

@ -25,7 +25,7 @@ app.use(responseTime(responseTimeLogger));
app.use('/api', apiRouter); app.use('/api', apiRouter);
// Swagger // Swagger
app.use('/api-docs', swaggerUi.serve, swaggerMiddleware); // app.use('/api-docs', swaggerUi.serve, swaggerMiddleware);
app.use(errorHandler); app.use(errorHandler);

View file

@ -62,6 +62,11 @@ export async function getAllSubmissionsHandler(req: Request, res: Response): Pro
// TODO: gerald moet nog dingen toevoegen aan de databank voor dat dit gefinaliseerd kan worden // TODO: gerald moet nog dingen toevoegen aan de databank voor dat dit gefinaliseerd kan worden
export async function createSubmissionHandler(req: Request, res: Response): Promise<void> { export async function createSubmissionHandler(req: Request, res: Response): Promise<void> {
const submitter = req.body.submitter;
const usernameSubmitter = req.body.submitter.username;
const group = req.body.group;
requireFields({ group, submitter, usernameSubmitter });
const submissionDTO = req.body as SubmissionDTO; const submissionDTO = req.body as SubmissionDTO;
const submission = await createSubmission(submissionDTO); const submission = await createSubmission(submissionDTO);

View file

@ -42,7 +42,7 @@ export async function fetchStudent(username: string): Promise<Student> {
const user = await studentRepository.findByUsername(username); const user = await studentRepository.findByUsername(username);
if (!user) { if (!user) {
throw new NotFoundException('Student with username not found'); throw new NotFoundException(`Student with username ${username} not found`);
} }
return user; return user;

View file

@ -3,6 +3,10 @@ import { describe, it, expect, beforeAll, beforeEach, vi, Mock } from 'vitest';
import { Request, Response } from 'express'; import { Request, Response } from 'express';
import { getAssignmentHandler, getAllAssignmentsHandler, getAssignmentsSubmissionsHandler } from '../../src/controllers/assignments.js'; import { getAssignmentHandler, getAllAssignmentsHandler, getAssignmentsSubmissionsHandler } from '../../src/controllers/assignments.js';
import { checkReturn404, checkReturnList } from './qol.js' import { checkReturn404, checkReturnList } from './qol.js'
import {getAnswerHandler} from "../../src/controllers/answers";
import {NotFoundException} from "../../src/exceptions/not-found-exception";
import {getClass01, getClass02, getClass03} from "../test_assets/classes/classes.testdata";
import {getAssignment01} from "../test_assets/assignments/assignments.testdata";
function createRequestObject(classid: string, assignmentid: string) { function createRequestObject(classid: string, assignmentid: string) {
return { return {
@ -35,50 +39,33 @@ describe('Assignment controllers', () => {
}; };
}); });
it('should return a 404 when trying to find a non-existent assignment', async () => { it('return error non-existing assignment', async () => {
req = createRequestObject('id01', '43000'); // should not exist req = createRequestObject('doesnotexist', '43000'); // should not exist
await getAssignmentHandler(req as Request, res as Response); await expect(async () => getAssignmentHandler(req as Request, res as Response)).rejects.toThrow(NotFoundException);
checkReturn404(jsonMock, statusMock);
});
it('should return a 404 when trying to find an assignment on a non-existing class', async () => {
req = createRequestObject('doesnotexist', '1'); // should not exist
await getAssignmentHandler(req as Request, res as Response);
checkReturn404(jsonMock, statusMock);
}); });
it('should return an assignment', async () => { it('should return an assignment', async () => {
req = createRequestObject('id01', '1'); const assignment = getAssignment01();
req = createRequestObject(assignment.within.classId as string, (assignment.id ?? 1).toString());
await getAssignmentHandler(req as Request, res as Response); await getAssignmentHandler(req as Request, res as Response);
expect(jsonMock).toHaveBeenCalledWith(expect.objectContaining({ assignment: expect.anything() }));
expect(jsonMock).toHaveBeenCalledWith({
id: 1,
class: 'id01',
title: 'dire straits',
description: 'reading',
learningPath: 'id02',
language: 'en'
});
}); });
it('should return a list of assignments', async () => { it('should return a list of assignments', async () => {
req = createRequestObject('id01', 'irrelevant'); req = createRequestObject(getClass01().classId as string, 'irrelevant');
await getAllAssignmentsHandler(req as Request, res as Response); await getAllAssignmentsHandler(req as Request, res as Response);
expect(jsonMock).toHaveBeenCalledWith(expect.objectContaining({ assignments: expect.anything() })); });
checkReturnList(jsonMock, "assignments");
});
it('should return a list of submissions for an assignment', async () => { it('should return a list of submissions for an assignment', async () => {
req = createRequestObject('id01', '1'); const assignment = getAssignment01();
req = createRequestObject(assignment.within.classId as string, (assignment.id ?? 1).toString());
await getAssignmentsSubmissionsHandler(req as Request, res as Response); await getAssignmentsSubmissionsHandler(req as Request, res as Response);
expect(jsonMock).toHaveBeenCalledWith(expect.objectContaining({ submissions: expect.anything() }));
checkReturnList(jsonMock, "submissions");
}) })
}) })

View file

@ -2,6 +2,9 @@ import { setupTestApp } from '../setup-tests.js';
import { describe, it, expect, beforeAll, beforeEach, vi, Mock } from 'vitest'; import { describe, it, expect, beforeAll, beforeEach, vi, Mock } from 'vitest';
import { createClassHandler, deleteClassHandler, getAllClassesHandler, getClassHandler, getClassStudentsHandler, getTeacherInvitationsHandler } from '../../src/controllers/classes.js'; import { createClassHandler, deleteClassHandler, getAllClassesHandler, getClassHandler, getClassStudentsHandler, getTeacherInvitationsHandler } from '../../src/controllers/classes.js';
import { Request, Response } from 'express'; import { Request, Response } from 'express';
import {NotFoundException} from "../../src/exceptions/not-found-exception";
import {BadRequestException} from "../../src/exceptions/bad-request-exception";
import {getClass01} from "../test_assets/classes/classes.testdata";
describe('Class controllers', () => { describe('Class controllers', () => {
let req: Partial<Request>; let req: Partial<Request>;
let res: Partial<Response>; let res: Partial<Response>;
@ -44,107 +47,61 @@ describe('Class controllers', () => {
expect(jsonMock).toHaveBeenCalledWith(expect.objectContaining({ class: expect.anything() })); expect(jsonMock).toHaveBeenCalledWith(expect.objectContaining({ class: expect.anything() }));
}); });
it('should return 404 and error if class is not found', async () => { it('Error class not found', async () => {
req = { req = {
params: { id: 'doesnotexist'}, params: { id: 'doesnotexist'},
} }
await getClassHandler(req as Request, res as Response); await expect(async () => getClassHandler(req as Request, res as Response)).rejects.toThrow(NotFoundException);
expect(statusMock).toHaveBeenCalledWith(404);
expect(jsonMock).toHaveBeenCalledWith({ error: 'Class not found' });
}); });
it('should return 200 if class is not found', async () => { it('Error create a class without name', async () => {
req = {
params: { id: 'id01'},
}
await getClassHandler(req as Request, res as Response);
// status can either not be called or called with code 200
expect(
statusMock.mock.calls.length === 0 || statusMock.mock.calls.some(([arg]) => arg === 200)
).toBe(true);
});
it('should return 201 for creating a new class', async () => {
req = {
body: { displayName: 'coolenieuweklas' },
};
await createClassHandler(req as Request, res as Response);
expect(statusMock).toHaveBeenCalledWith(201);
// TODO: return json should be a classDTO and not named (fixed in #130)
//expect(jsonMock).toHaveBeenCalledWith();
// TODO: check if class is actually added to db
});
it.todo('return json should be a classDTO and not named (fixed in #130)')
it.todo('check if class is actually added to db');
it('should return 400 for trying to create a class without name', async () => {
req = { req = {
body: {}, body: {},
}; };
await createClassHandler(req as Request, res as Response); await expect(async () => createClassHandler(req as Request, res as Response)).rejects.toThrow(BadRequestException);
expect(statusMock).toHaveBeenCalledWith(400);
expect(jsonMock).toHaveBeenCalledWith({ error: 'Missing one or more required fields: displayName' });
}); });
it('should return a list of students when calling getClassStudentsHandler', async () => { it('return list of students', async () => {
req = { req = {
params: { id: 'id01' }, params: { id: getClass01().classId as string },
query: {}, query: {},
}; };
await getClassStudentsHandler(req as Request, res as Response); await getClassStudentsHandler(req as Request, res as Response);
checkReturnList(jsonMock, 'students'); expect(jsonMock).toHaveBeenCalledWith(expect.objectContaining({ students: expect.anything() }));
}); });
it('should return 404 not found when calling getClassStudentsHandler on a non-existent class', async () => { it('Error students on a non-existent class', async () => {
req = { req = {
params: { id: 'doesnotexist' }, params: { id: 'doesnotexist' },
query: {}, query: {},
}; };
await getClassStudentsHandler(req as Request, res as Response); await expect(async () => getClassStudentsHandler(req as Request, res as Response)).rejects.toThrow(NotFoundException);
expect(statusMock).toHaveBeenCalledWith(404);
expect(jsonMock).toHaveBeenCalledWith({ error: 'Class not found' });
}); });
it('should return 200 and a list of teacher-invitations', async () => { it('should return 200 and a list of teacher-invitations', async () => {
const classId = getClass01().classId as string;
req = { req = {
params: { id: 'id01' }, params: { id: classId },
query: {}, query: {},
}; };
await getTeacherInvitationsHandler(req as Request, res as Response); await getTeacherInvitationsHandler(req as Request, res as Response);
expect(jsonMock).toHaveBeenCalledWith({"invitations": [ expect(jsonMock).toHaveBeenCalledWith(expect.objectContaining({ invitations: expect.anything() }));
{
"class": "id01",
"receiver": "LimpBizkit",
"sender": "FooFighters",
}
]});
}); });
it('should return 404 not found when calling teacher-invitations on a non-existent class', async () => { it('Error teacher-invitations on a non-existent class', async () => {
req = { req = {
params: { id: 'doesnotexist' }, params: { id: 'doesnotexist' },
query: {}, query: {},
}; };
await getTeacherInvitationsHandler(req as Request, res as Response); await expect(async () => getTeacherInvitationsHandler(req as Request, res as Response)).rejects.toThrow(NotFoundException);
expect(jsonMock).toHaveBeenCalledWith({ error: 'Class not found' });
expect(statusMock).toHaveBeenCalledWith(404);
}); });
it('should return a list of classes', async () => { it('should return a list of classes', async () => {
@ -154,11 +111,7 @@ describe('Class controllers', () => {
await getAllClassesHandler(req as Request, res as Response); await getAllClassesHandler(req as Request, res as Response);
expect(jsonMock).toHaveBeenCalled(); expect(jsonMock).toHaveBeenCalledWith(expect.objectContaining({ classes: expect.anything() }));
const result = jsonMock.mock.lastCall![0];
expect("classes" in result).toBeTruthy();
}) })
}); });

View file

@ -1,7 +1,18 @@
import { setupTestApp } from '../setup-tests.js'; import { setupTestApp } from '../setup-tests.js';
import { describe, it, expect, beforeAll, beforeEach, vi, Mock } from 'vitest'; import { describe, it, expect, beforeAll, beforeEach, vi, Mock } from 'vitest';
import { Request, Response } from 'express'; import { Request, Response } from 'express';
import { createGroupHandler, getAllGroupsHandler, getGroupHandler, getGroupSubmissionsHandler } from '../../src/controllers/groups.js'; import {
createGroupHandler,
deleteGroupHandler,
getAllGroupsHandler,
getGroupHandler,
getGroupSubmissionsHandler
} from '../../src/controllers/groups.js';
import {getAnswerHandler} from "../../src/controllers/answers";
import {NotFoundException} from "../../src/exceptions/not-found-exception";
import {getClass01} from "../test_assets/classes/classes.testdata";
import {getAssignment01, getAssignment02} from "../test_assets/assignments/assignments.testdata";
import {getTestGroup01} from "../test_assets/assignments/groups.testdata";
function createRequestObject(classid: string, assignmentid: string, groupNumber: string) { function createRequestObject(classid: string, assignmentid: string, groupNumber: string) {
return { return {
@ -35,20 +46,18 @@ describe('Group controllers', () => {
}; };
}); });
it('should return 404 not found on a non-existing group', async () => { it('Error not found on a non-existing group', async () => {
req = { req = {
params: { params: {
classid: 'id01', classid: 'id01',
assignmentid: '1', assignmentid: '1',
groupid: '42000', // should not exist groupid: '154981', // should not exist
}, },
query: {}, query: {},
}; };
await getGroupHandler(req as Request, res as Response); await expect(async () => getGroupHandler(req as Request, res as Response)).rejects.toThrow(NotFoundException);
expect(statusMock).toHaveBeenCalledWith(404);
expect(jsonMock).toHaveBeenCalled();
}); });
it('should return 404 not found on a non-existing assignment', async () => { it('should return 404 not found on a non-existing assignment', async () => {
@ -61,10 +70,7 @@ describe('Group controllers', () => {
query: {}, query: {},
}; };
await getGroupHandler(req as Request, res as Response); await expect(async () => getGroupHandler(req as Request, res as Response)).rejects.toThrow(NotFoundException);
expect(statusMock).toHaveBeenCalledWith(404);
expect(jsonMock).toHaveBeenCalled();
}); });
it('should return 404 not found ont a non-existing class', async () => { it('should return 404 not found ont a non-existing class', async () => {
@ -77,68 +83,55 @@ describe('Group controllers', () => {
query: {}, query: {},
}; };
await getGroupHandler(req as Request, res as Response); await expect(async () => getGroupHandler(req as Request, res as Response)).rejects.toThrow(NotFoundException);
expect(statusMock).toHaveBeenCalledWith(404);
expect(jsonMock).toHaveBeenCalled();
}); });
it('should return an existing group', async () => { it('should return an existing group', async () => {
req = createRequestObject('id01', '1', '1'); const group = getTestGroup01();
const classId = getClass01().classId as string;
req = createRequestObject(classId, (group.assignment.id ?? 1).toString(), (group.groupNumber ?? 1).toString());
await getGroupHandler(req as Request, res as Response); await getGroupHandler(req as Request, res as Response);
expect(jsonMock).toHaveBeenCalledWith({ expect(jsonMock).toHaveBeenCalledWith(expect.objectContaining({ group: expect.anything() }));
assignment: 1,
groupNumber: 1,
members: [ 'DireStraits', 'Noordkaap' ]
});
}); });
it('should return a 201 when creating a group', async () => { it('Create and delete', async () => {
req = createRequestObject('id01', '1', 'irrelevant'); const assignment = getAssignment02();
const classId = assignment.within.classId as string;
req = createRequestObject(classId, (assignment.id ?? 1).toString(), '1');
req.body = { req.body = {
members: [ members: [
'NoordKaap', 'Noordkaap',
'DireStraits', 'DireStraits',
] ]
}; };
await createGroupHandler(req as Request, res as Response); await createGroupHandler(req as Request, res as Response);
expect(statusMock).toHaveBeenCalledWith(201); await deleteGroupHandler(req as Request, res as Response);
expect(jsonMock).toHaveBeenCalled();
const result = jsonMock.mock.lastCall![0]; expect(jsonMock).toHaveBeenCalledWith(expect.objectContaining({ group: expect.anything() }));
expect("assignment" in result).toBeTruthy();
expect("groupNumber" in result).toBeTruthy();
expect("members" in result).toBeTruthy();
}); });
it('should return the submissions for a group', async () => { it('should return the submissions for a group', async () => {
req = createRequestObject('id01', '1', '1'); const group = getTestGroup01();
const classId = getClass01().classId as string;
req = createRequestObject(classId, (group.assignment.id ?? 1).toString(), (group.groupNumber ?? 1).toString());
await getGroupSubmissionsHandler(req as Request, res as Response); await getGroupSubmissionsHandler(req as Request, res as Response);
expect(jsonMock).toHaveBeenCalled(); expect(jsonMock).toHaveBeenCalledWith(expect.objectContaining({ submissions: expect.anything() }));
const result = jsonMock.mock.lastCall![0];
expect("submissions" in result).toBeTruthy();
expect(typeof(result.submissions)).toBe(typeof([]));
}); });
it('should return a list of groups for an assignment', async () => { it('should return a list of groups for an assignment', async () => {
req = createRequestObject('id01', '1', '1'); const assignment = getAssignment01();
const classId = assignment.within.classId as string;
req = createRequestObject(classId, (assignment.id ?? 1).toString(), '1');
await getAllGroupsHandler(req as Request, res as Response); await getAllGroupsHandler(req as Request, res as Response);
expect(jsonMock).toHaveBeenCalled(); expect(jsonMock).toHaveBeenCalledWith(expect.objectContaining({ groups: expect.anything() }));
const result = jsonMock.mock.lastCall![0];
expect("groups" in result).toBeTruthy();
}); });
}); });

View file

@ -1,10 +1,13 @@
import { setupTestApp } from '../setup-tests.js'; import { setupTestApp } from '../setup-tests.js';
import { describe, it, expect, beforeAll, beforeEach, vi, Mock } from 'vitest'; import { describe, it, expect, beforeAll, beforeEach, vi, Mock } from 'vitest';
import { getSubmissionHandler, getAllSubmissionsHandler } from '../../src/controllers/submissions.js'; import {
getSubmissionHandler,
getAllSubmissionsHandler,
deleteSubmissionHandler, createSubmissionHandler
} from '../../src/controllers/submissions.js';
import { Request, Response } from 'express'; import { Request, Response } from 'express';
import { checkReturn404, checkReturnList } from './qol.js'; import {NotFoundException} from "../../src/exceptions/not-found-exception";
import { getSubmission } from '../../src/services/submissions.js'; import {getClass01, getClass02} from "../test_assets/classes/classes.testdata";
import { Language } from '../../src/entities/content/language.js';
function createRequestObject(hruid: string, submissionNumber: string) { function createRequestObject(hruid: string, submissionNumber: string) {
@ -41,38 +44,18 @@ describe('Submission controllers', () => {
}; };
}); });
it('should return a 404 and error if submission is not found', async () => { it('error submission is not found', async () => {
req = createRequestObject('id01', '1000000'); req = createRequestObject('id01', '1000000');
await getSubmissionHandler(req as Request, res as Response); await expect(async () => getSubmissionHandler(req as Request, res as Response)).rejects.toThrow(NotFoundException);
checkReturn404(jsonMock, statusMock);
});
it('should return a 404 and error if learningobject is not found', async () => {
req = createRequestObject('doesnotexist', '1000000');
await getSubmissionHandler(req as Request, res as Response);
checkReturn404(jsonMock, statusMock);
});
it('should return an existing submission', async () => {
req = createRequestObject('id01', '1');
await getSubmissionHandler(req as Request, res as Response);
const expectedResult = await getSubmission('id01', Language.English, 1, 1);
expect(jsonMock.mock.lastCall![0]).toStrictEqual(expectedResult);
}); });
it('should return a list of submissions for a learning object', async () => { it('should return a list of submissions for a learning object', async () => {
req = createRequestObject('id02', 'irrelevant'); req = createRequestObject(getClass02().classId as string, 'irrelevant');
await getAllSubmissionsHandler(req as Request, res as Response); await getAllSubmissionsHandler(req as Request, res as Response);
checkReturnList(jsonMock, 'submissions', 2); expect(jsonMock).toHaveBeenCalledWith(expect.objectContaining({ submissions: expect.anything() }));
}); });
}); });