fix: Merge dev into feat/assignment-page
This commit is contained in:
commit
bb3a242bf9
20 changed files with 207 additions and 37 deletions
|
@ -11,3 +11,10 @@ DWENGO_PORT=3000
|
|||
|
||||
DWENGO_DB_NAME=":memory:"
|
||||
DWENGO_DB_UPDATE=true
|
||||
|
||||
DWENGO_AUTH_STUDENT_URL=http://localhost:7080/realms/student
|
||||
DWENGO_AUTH_STUDENT_JWKS_ENDPOINT=http://localhost:7080/realms/student/protocol/openid-connect/certs
|
||||
DWENGO_AUTH_TEACHER_URL=http://localhost:7080/realms/teacher
|
||||
DWENGO_AUTH_TEACHER_JWKS_ENDPOINT=http://localhost:7080/realms/teacher/protocol/openid-connect/certs
|
||||
|
||||
DWENGO_CORS_ALLOWED_ORIGINS=http://localhost:5173,http://localhost:3000
|
||||
|
|
|
@ -7,7 +7,8 @@
|
|||
"main": "dist/app.js",
|
||||
"scripts": {
|
||||
"build": "cross-env NODE_ENV=production tsc --build",
|
||||
"dev": "cross-env NODE_ENV=development tsx tool/seed.ts; tsx watch --env-file=.env.development.local src/app.ts",
|
||||
"predev": "tsc --build ../common/tsconfig.json",
|
||||
"dev": "cross-env NODE_ENV=development tsx tool/seed.ts && tsx watch --env-file=.env.development.local src/app.ts",
|
||||
"start": "cross-env NODE_ENV=production node --env-file=.env dist/app.js",
|
||||
"format": "prettier --write src/",
|
||||
"format-check": "prettier --check src/",
|
||||
|
|
|
@ -3,8 +3,6 @@ import { createGroup, deleteGroup, getAllGroups, getGroup, getGroupSubmissions,
|
|||
import { GroupDTO } from '@dwengo-1/common/interfaces/group';
|
||||
import { requireFields } from './error-helper.js';
|
||||
import { BadRequestException } from '../exceptions/bad-request-exception.js';
|
||||
import { EntityDTO } from '@mikro-orm/core';
|
||||
import { Group } from '../entities/assignments/group.entity.js';
|
||||
|
||||
function checkGroupFields(classId: string, assignmentId: number, groupId: number): void {
|
||||
requireFields({ classId, assignmentId, groupId });
|
||||
|
@ -35,7 +33,11 @@ export async function putGroupHandler(req: Request, res: Response): Promise<void
|
|||
const groupId = parseInt(req.params.groupid);
|
||||
checkGroupFields(classId, assignmentId, groupId);
|
||||
|
||||
const group = await putGroup(classId, assignmentId, groupId, req.body as Partial<EntityDTO<Group>>);
|
||||
// Only members field can be changed
|
||||
const members = req.body.members;
|
||||
requireFields({ members });
|
||||
|
||||
const group = await putGroup(classId, assignmentId, groupId, { members } as Partial<GroupDTO>);
|
||||
|
||||
res.json({ group });
|
||||
}
|
||||
|
|
|
@ -26,13 +26,15 @@ function initializeLogger(): Logger {
|
|||
|
||||
const consoleTransport = new transports.Console({
|
||||
level: getEnvVar(envVars.LogLevel),
|
||||
format: format.combine(format.cli(), format.colorize()),
|
||||
format: format.combine(format.cli(), format.simple()),
|
||||
});
|
||||
|
||||
if (getEnvVar(envVars.RunMode) === 'dev') {
|
||||
return createLogger({
|
||||
logger = createLogger({
|
||||
transports: [consoleTransport],
|
||||
});
|
||||
logger.debug(`Logger initialized with level ${logLevel} to console`);
|
||||
return logger;
|
||||
}
|
||||
|
||||
const lokiHost = getEnvVar(envVars.LokiHost);
|
||||
|
|
|
@ -11,7 +11,7 @@ export class MikroOrmLogger extends DefaultLogger {
|
|||
};
|
||||
|
||||
let message: string;
|
||||
if (context?.label) {
|
||||
if (context !== undefined && context.labels !== undefined) {
|
||||
message = `[${namespace}] (${context.label}) ${messageArg}`;
|
||||
} else {
|
||||
message = `[${namespace}] ${messageArg}`;
|
||||
|
|
|
@ -7,8 +7,17 @@ import { GroupDTO, GroupDTOId } from '@dwengo-1/common/interfaces/group';
|
|||
import { SubmissionDTO, SubmissionDTOId } from '@dwengo-1/common/interfaces/submission';
|
||||
import { fetchAssignment } from './assignments.js';
|
||||
import { NotFoundException } from '../exceptions/not-found-exception.js';
|
||||
import { putObject } from './service-helper.js';
|
||||
import { fetchStudents } from './students.js';
|
||||
import { fetchClass } from './classes.js';
|
||||
import { BadRequestException } from '../exceptions/bad-request-exception.js';
|
||||
import { Student } from '../entities/users/student.entity.js';
|
||||
import { Class } from '../entities/classes/class.entity.js';
|
||||
|
||||
async function assertMembersInClass(members: Student[], cls: Class): Promise<void> {
|
||||
if (!members.every((student) => cls.students.contains(student))) {
|
||||
throw new BadRequestException('Student does not belong to class');
|
||||
}
|
||||
}
|
||||
|
||||
export async function fetchGroup(classId: string, assignmentNumber: number, groupNumber: number): Promise<Group> {
|
||||
const assignment = await fetchAssignment(classId, assignmentNumber);
|
||||
|
@ -28,15 +37,18 @@ export async function getGroup(classId: string, assignmentNumber: number, groupN
|
|||
return mapToGroupDTO(group, group.assignment.within);
|
||||
}
|
||||
|
||||
export async function putGroup(
|
||||
classId: string,
|
||||
assignmentNumber: number,
|
||||
groupNumber: number,
|
||||
groupData: Partial<EntityDTO<Group>>
|
||||
): Promise<GroupDTO> {
|
||||
export async function putGroup(classId: string, assignmentNumber: number, groupNumber: number, groupData: Partial<GroupDTO>): Promise<GroupDTO> {
|
||||
const group = await fetchGroup(classId, assignmentNumber, groupNumber);
|
||||
|
||||
await putObject<Group>(group, groupData, getGroupRepository());
|
||||
const memberUsernames = groupData.members as string[];
|
||||
const members = await fetchStudents(memberUsernames);
|
||||
|
||||
const cls = await fetchClass(classId);
|
||||
await assertMembersInClass(members, cls);
|
||||
|
||||
const groupRepository = getGroupRepository();
|
||||
groupRepository.assign(group, { members } as Partial<EntityDTO<Group>>);
|
||||
await groupRepository.getEntityManager().persistAndFlush(group);
|
||||
|
||||
return mapToGroupDTO(group, group.assignment.within);
|
||||
}
|
||||
|
@ -63,6 +75,9 @@ export async function createGroup(groupData: GroupDTO, classid: string, assignme
|
|||
const memberUsernames = (groupData.members as string[]) || [];
|
||||
const members = await fetchStudents(memberUsernames);
|
||||
|
||||
const cls = await fetchClass(classid);
|
||||
await assertMembersInClass(members, cls);
|
||||
|
||||
const assignment = await fetchAssignment(classid, assignmentNumber);
|
||||
|
||||
const groupRepository = getGroupRepository();
|
||||
|
|
|
@ -61,7 +61,7 @@ export function makeTestGroups(em: EntityManager, students: Student[], assignmen
|
|||
*/
|
||||
group1ConditionalLearningPath = em.create(Group, {
|
||||
assignment: getConditionalPathAssignment(),
|
||||
groupNumber: 1,
|
||||
groupNumber: 21005,
|
||||
members: [getTestleerling1()],
|
||||
});
|
||||
|
||||
|
|
|
@ -14,14 +14,12 @@ import { makeTestQuestions } from '../tests/test_assets/questions/questions.test
|
|||
import { makeTestStudents } from '../tests/test_assets/users/students.testdata.js';
|
||||
import { makeTestTeachers } from '../tests/test_assets/users/teachers.testdata.js';
|
||||
import { getLogger, Logger } from '../src/logging/initalize.js';
|
||||
import { Collection } from '@mikro-orm/core';
|
||||
import { Collection, MikroORM } from '@mikro-orm/core';
|
||||
import { Group } from '../src/entities/assignments/group.entity';
|
||||
|
||||
const logger: Logger = getLogger();
|
||||
|
||||
export async function seedDatabase(): Promise<void> {
|
||||
dotenv.config({ path: '.env.development.local' });
|
||||
const orm = await initORM();
|
||||
export async function seedORM(orm: MikroORM): Promise<void> {
|
||||
await orm.schema.clearDatabase();
|
||||
|
||||
const em = forkEntityManager();
|
||||
|
@ -68,8 +66,17 @@ export async function seedDatabase(): Promise<void> {
|
|||
]);
|
||||
|
||||
logger.info('Development database seeded successfully!');
|
||||
}
|
||||
|
||||
export async function seedDatabase(envFile = '.env.development.local', testMode = false): Promise<void> {
|
||||
dotenv.config({ path: envFile });
|
||||
const orm = await initORM(testMode);
|
||||
|
||||
await seedORM(orm);
|
||||
|
||||
await orm.close();
|
||||
}
|
||||
|
||||
seedDatabase().catch(logger.error);
|
||||
seedDatabase().catch((err) => {
|
||||
logger.error(err);
|
||||
});
|
||||
|
|
29
backend/tool/startTestApp.ts
Normal file
29
backend/tool/startTestApp.ts
Normal file
|
@ -0,0 +1,29 @@
|
|||
import express, { Express } from 'express';
|
||||
import { initORM } from '../src/orm.js';
|
||||
import apiRouter from '../src/routes/router.js';
|
||||
import { errorHandler } from '../src/middleware/error-handling/error-handler.js';
|
||||
import dotenv from 'dotenv';
|
||||
import cors from '../src/middleware/cors';
|
||||
import { authenticateUser } from '../src/middleware/auth/auth';
|
||||
import { seedORM } from './seed';
|
||||
|
||||
const envFile = '../.env.test';
|
||||
|
||||
dotenv.config({ path: envFile });
|
||||
|
||||
const app: Express = express();
|
||||
|
||||
app.use(express.json());
|
||||
app.use(cors);
|
||||
app.use(authenticateUser);
|
||||
|
||||
app.use('/api', apiRouter);
|
||||
app.use(errorHandler);
|
||||
|
||||
async function startServer(): Promise<void> {
|
||||
await seedORM(await initORM(true));
|
||||
|
||||
app.listen(9876);
|
||||
}
|
||||
|
||||
await startServer();
|
Loading…
Add table
Add a link
Reference in a new issue