From d7ae60f0ac171115b4cf1731daf847864a9b079c Mon Sep 17 00:00:00 2001 From: Thomas Feldtkeller Date: Mon, 20 Nov 2023 13:07:41 +0100 Subject: [PATCH] BC-5803 lesson refactorings (#4562) * isolate lesson repo * fix missing module imports * move lesson repo in lesson module --- .../authorization-reference.module.ts | 19 +++++--- .../authorization/authorization.module.ts | 10 ++--- .../domain/service/reference.loader.spec.ts | 20 ++++----- .../domain/service/reference.loader.ts | 16 +++---- .../server/src/modules/authorization/index.ts | 14 +++--- .../src/modules/files-storage-client/index.ts | 2 +- apps/server/src/modules/learnroom/index.ts | 3 +- .../modules/learnroom/learnroom-api.module.ts | 5 +-- .../src/modules/learnroom/learnroom.module.ts | 7 ++- .../learnroom/service/rooms.service.spec.ts | 19 ++++---- .../learnroom/service/rooms.service.ts | 11 ++--- .../modules/learnroom/uc/course.uc.spec.ts | 6 +-- .../learnroom/uc/lesson-copy.uc.spec.ts | 36 +++++++-------- .../modules/learnroom/uc/lesson-copy.uc.ts | 15 +++---- .../src/modules/learnroom/uc/rooms.uc.spec.ts | 10 +---- apps/server/src/modules/lesson/index.ts | 2 + .../src/modules/lesson/lesson.module.ts | 6 +-- .../lesson/repository}/index.ts | 0 .../lesson/repository}/lesson-scope.ts | 2 +- .../lesson.repo.integration.spec.ts | 0 .../lesson/repository}/lesson.repo.ts | 4 +- .../service/lesson-copy.service.spec.ts | 8 ++-- .../lesson/service/lesson-copy.service.ts | 9 ++-- .../lesson/service/lesson.service.spec.ts | 24 +++++++--- .../modules/lesson/service/lesson.service.ts | 11 ++--- .../modules/sharing/uc/share-token.uc.spec.ts | 25 +++++------ apps/server/src/modules/task/index.ts | 3 ++ .../src/modules/task/task-api.module.ts | 9 ++-- apps/server/src/modules/task/task.module.ts | 4 +- .../src/modules/task/uc/task-copy.uc.spec.ts | 27 +++++------ .../src/modules/task/uc/task-copy.uc.ts | 11 ++--- .../src/modules/task/uc/task.uc.spec.ts | 45 ++++++++++--------- apps/server/src/modules/task/uc/task.uc.ts | 11 ++--- apps/server/src/modules/tool/index.ts | 5 ++- apps/server/src/shared/repo/index.ts | 1 - 35 files changed, 202 insertions(+), 198 deletions(-) rename apps/server/src/{shared/repo/lesson => modules/lesson/repository}/index.ts (100%) rename apps/server/src/{shared/repo/lesson => modules/lesson/repository}/lesson-scope.ts (90%) rename apps/server/src/{shared/repo/lesson => modules/lesson/repository}/lesson.repo.integration.spec.ts (100%) rename apps/server/src/{shared/repo/lesson => modules/lesson/repository}/lesson.repo.ts (97%) diff --git a/apps/server/src/modules/authorization/authorization-reference.module.ts b/apps/server/src/modules/authorization/authorization-reference.module.ts index e253587af7b..a115d0433c3 100644 --- a/apps/server/src/modules/authorization/authorization-reference.module.ts +++ b/apps/server/src/modules/authorization/authorization-reference.module.ts @@ -1,20 +1,20 @@ +import { BoardModule } from '@modules/board'; +import { ToolModule } from '@modules/tool'; import { forwardRef, Module } from '@nestjs/common'; import { CourseGroupRepo, CourseRepo, - LessonRepo, - SchoolExternalToolRepo, LegacySchoolRepo, + SchoolExternalToolRepo, SubmissionRepo, TaskRepo, TeamsRepo, UserRepo, } from '@shared/repo'; -import { ToolModule } from '@modules/tool'; import { LoggerModule } from '@src/core/logger'; -import { BoardModule } from '@modules/board'; -import { ReferenceLoader, AuthorizationReferenceService, AuthorizationHelper } from './domain'; +import { LessonModule } from '../lesson'; import { AuthorizationModule } from './authorization.module'; +import { AuthorizationHelper, AuthorizationReferenceService, ReferenceLoader } from './domain'; /** * This module is part of an intermediate state. In the future it should be replaced by an AuthorizationApiModule. @@ -23,7 +23,13 @@ import { AuthorizationModule } from './authorization.module'; */ @Module({ // TODO: remove forwardRef to TooModule N21-1055 - imports: [AuthorizationModule, forwardRef(() => ToolModule), forwardRef(() => BoardModule), LoggerModule], + imports: [ + AuthorizationModule, + LessonModule, + forwardRef(() => ToolModule), + forwardRef(() => BoardModule), + LoggerModule, + ], providers: [ AuthorizationHelper, ReferenceLoader, @@ -32,7 +38,6 @@ import { AuthorizationModule } from './authorization.module'; CourseGroupRepo, TaskRepo, LegacySchoolRepo, - LessonRepo, TeamsRepo, SubmissionRepo, SchoolExternalToolRepo, diff --git a/apps/server/src/modules/authorization/authorization.module.ts b/apps/server/src/modules/authorization/authorization.module.ts index d01cd9363f4..f734a72ed8a 100644 --- a/apps/server/src/modules/authorization/authorization.module.ts +++ b/apps/server/src/modules/authorization/authorization.module.ts @@ -1,23 +1,23 @@ +import { FeathersModule } from '@infra/feathers'; import { Module } from '@nestjs/common'; import { UserRepo } from '@shared/repo'; import { LoggerModule } from '@src/core/logger'; -import { FeathersModule } from '@infra/feathers'; +import { AuthorizationHelper, AuthorizationService, RuleManager } from './domain'; import { BoardDoRule, ContextExternalToolRule, CourseGroupRule, CourseRule, + GroupRule, + LegacySchoolRule, LessonRule, SchoolExternalToolRule, SubmissionRule, TaskRule, TeamRule, - UserRule, UserLoginMigrationRule, - LegacySchoolRule, - GroupRule, + UserRule, } from './domain/rules'; -import { AuthorizationHelper, AuthorizationService, RuleManager } from './domain'; import { FeathersAuthorizationService, FeathersAuthProvider } from './feathers'; @Module({ diff --git a/apps/server/src/modules/authorization/domain/service/reference.loader.spec.ts b/apps/server/src/modules/authorization/domain/service/reference.loader.spec.ts index e2e77212cab..11f553423b6 100644 --- a/apps/server/src/modules/authorization/domain/service/reference.loader.spec.ts +++ b/apps/server/src/modules/authorization/domain/service/reference.loader.spec.ts @@ -1,24 +1,24 @@ import { createMock, DeepMocked } from '@golevelup/ts-jest'; import { ObjectId } from '@mikro-orm/mongodb'; +import { BoardDoAuthorizableService } from '@modules/board'; +import { ContextExternalToolAuthorizableService } from '@modules/tool'; import { NotImplementedException } from '@nestjs/common'; import { Test, TestingModule } from '@nestjs/testing'; import { EntityId } from '@shared/domain'; import { CourseGroupRepo, CourseRepo, - LessonRepo, - SchoolExternalToolRepo, LegacySchoolRepo, + SchoolExternalToolRepo, SubmissionRepo, TaskRepo, TeamsRepo, UserRepo, } from '@shared/repo'; import { setupEntities, userFactory } from '@shared/testing'; -import { BoardDoAuthorizableService } from '@modules/board'; -import { ContextExternalToolAuthorizableService } from '@modules/tool/context-external-tool/service/context-external-tool-authorizable.service'; -import { ReferenceLoader } from './reference.loader'; +import { LessonService } from '@modules/lesson'; import { AuthorizableReferenceType } from '../type'; +import { ReferenceLoader } from './reference.loader'; describe('reference.loader', () => { let service: ReferenceLoader; @@ -27,7 +27,7 @@ describe('reference.loader', () => { let courseGroupRepo: DeepMocked; let taskRepo: DeepMocked; let schoolRepo: DeepMocked; - let lessonRepo: DeepMocked; + let lessonService: DeepMocked; let teamsRepo: DeepMocked; let submissionRepo: DeepMocked; let schoolExternalToolRepo: DeepMocked; @@ -62,8 +62,8 @@ describe('reference.loader', () => { useValue: createMock(), }, { - provide: LessonRepo, - useValue: createMock(), + provide: LessonService, + useValue: createMock(), }, { provide: TeamsRepo, @@ -94,7 +94,7 @@ describe('reference.loader', () => { courseGroupRepo = await module.get(CourseGroupRepo); taskRepo = await module.get(TaskRepo); schoolRepo = await module.get(LegacySchoolRepo); - lessonRepo = await module.get(LessonRepo); + lessonService = await module.get(LessonService); teamsRepo = await module.get(TeamsRepo); submissionRepo = await module.get(SubmissionRepo); schoolExternalToolRepo = await module.get(SchoolExternalToolRepo); @@ -144,7 +144,7 @@ describe('reference.loader', () => { it('should call lessonRepo.findById', async () => { await service.loadAuthorizableObject(AuthorizableReferenceType.Lesson, entityId); - expect(lessonRepo.findById).toBeCalledWith(entityId); + expect(lessonService.findById).toBeCalledWith(entityId); }); it('should call teamsRepo.findById', async () => { diff --git a/apps/server/src/modules/authorization/domain/service/reference.loader.ts b/apps/server/src/modules/authorization/domain/service/reference.loader.ts index d584561be9e..c0ea22212a0 100644 --- a/apps/server/src/modules/authorization/domain/service/reference.loader.ts +++ b/apps/server/src/modules/authorization/domain/service/reference.loader.ts @@ -1,19 +1,19 @@ +import { BoardDoAuthorizableService } from '@modules/board'; +import { ContextExternalToolAuthorizableService } from '@modules/tool'; import { Injectable, NotImplementedException } from '@nestjs/common'; import { BaseDO, EntityId } from '@shared/domain'; import { AuthorizableObject } from '@shared/domain/domain-object'; import { CourseGroupRepo, CourseRepo, - LessonRepo, - SchoolExternalToolRepo, LegacySchoolRepo, + SchoolExternalToolRepo, SubmissionRepo, TaskRepo, TeamsRepo, UserRepo, } from '@shared/repo'; -import { BoardDoAuthorizableService } from '@modules/board'; -import { ContextExternalToolAuthorizableService } from '@modules/tool/context-external-tool/service'; +import { LessonService } from '@modules/lesson'; import { AuthorizableReferenceType } from '../type'; type RepoType = @@ -21,13 +21,13 @@ type RepoType = | CourseRepo | UserRepo | LegacySchoolRepo - | LessonRepo | TeamsRepo | CourseGroupRepo | SubmissionRepo | SchoolExternalToolRepo | BoardDoAuthorizableService - | ContextExternalToolAuthorizableService; + | ContextExternalToolAuthorizableService + | LessonService; interface IRepoLoader { repo: RepoType; @@ -44,7 +44,7 @@ export class ReferenceLoader { private readonly courseGroupRepo: CourseGroupRepo, private readonly taskRepo: TaskRepo, private readonly schoolRepo: LegacySchoolRepo, - private readonly lessonRepo: LessonRepo, + private readonly lessonService: LessonService, private readonly teamsRepo: TeamsRepo, private readonly submissionRepo: SubmissionRepo, private readonly schoolExternalToolRepo: SchoolExternalToolRepo, @@ -56,7 +56,7 @@ export class ReferenceLoader { this.repos.set(AuthorizableReferenceType.CourseGroup, { repo: this.courseGroupRepo }); this.repos.set(AuthorizableReferenceType.User, { repo: this.userRepo }); this.repos.set(AuthorizableReferenceType.School, { repo: this.schoolRepo }); - this.repos.set(AuthorizableReferenceType.Lesson, { repo: this.lessonRepo }); + this.repos.set(AuthorizableReferenceType.Lesson, { repo: this.lessonService }); this.repos.set(AuthorizableReferenceType.Team, { repo: this.teamsRepo, populate: true }); this.repos.set(AuthorizableReferenceType.Submission, { repo: this.submissionRepo }); this.repos.set(AuthorizableReferenceType.SchoolExternalToolEntity, { repo: this.schoolExternalToolRepo }); diff --git a/apps/server/src/modules/authorization/index.ts b/apps/server/src/modules/authorization/index.ts index e129df2cd11..13ae209f13d 100644 --- a/apps/server/src/modules/authorization/index.ts +++ b/apps/server/src/modules/authorization/index.ts @@ -1,15 +1,17 @@ export { AuthorizationModule } from './authorization.module'; export { - AuthorizationService, - AuthorizationHelper, - AuthorizationContextBuilder, - ForbiddenLoggableException, - Rule, - AuthorizationContext, // Action should not be exported, but hard to solve for now. The AuthorizationContextBuilder is the prefared way Action, + AuthorizableReferenceType, + AuthorizationContext, + AuthorizationContextBuilder, + AuthorizationHelper, AuthorizationLoaderService, AuthorizationLoaderServiceGeneric, + AuthorizationReferenceService, + AuthorizationService, + ForbiddenLoggableException, + Rule, } from './domain'; // Should not used anymore export { FeathersAuthorizationService } from './feathers'; diff --git a/apps/server/src/modules/files-storage-client/index.ts b/apps/server/src/modules/files-storage-client/index.ts index 7b242946d8f..19248d129de 100644 --- a/apps/server/src/modules/files-storage-client/index.ts +++ b/apps/server/src/modules/files-storage-client/index.ts @@ -2,5 +2,5 @@ export { FileDto } from './dto'; export * from './files-storage-client.module'; export { IFilesStorageClientConfig } from './interfaces'; export { FileParamBuilder } from './mapper/files-storage-param.builder'; -export { CopyFilesService } from './service/copy-files.service'; +export * from './service/copy-files.service'; export { FilesStorageClientAdapterService } from './service/files-storage-client.service'; diff --git a/apps/server/src/modules/learnroom/index.ts b/apps/server/src/modules/learnroom/index.ts index e4d907784d5..9fe9c100886 100644 --- a/apps/server/src/modules/learnroom/index.ts +++ b/apps/server/src/modules/learnroom/index.ts @@ -1,3 +1,2 @@ export * from './learnroom.module'; -export * from './service/course-copy.service'; -export { CourseService } from './service'; +export { CommonCartridgeExportService, CourseCopyService, CourseService, RoomsService } from './service'; diff --git a/apps/server/src/modules/learnroom/learnroom-api.module.ts b/apps/server/src/modules/learnroom/learnroom-api.module.ts index 5cfaada65b8..a2a407daf21 100644 --- a/apps/server/src/modules/learnroom/learnroom-api.module.ts +++ b/apps/server/src/modules/learnroom/learnroom-api.module.ts @@ -1,9 +1,9 @@ -import { Module } from '@nestjs/common'; -import { BoardRepo, CourseRepo, DashboardModelMapper, DashboardRepo, LessonRepo, UserRepo } from '@shared/repo'; import { AuthorizationModule } from '@modules/authorization'; import { AuthorizationReferenceModule } from '@modules/authorization/authorization-reference.module'; import { CopyHelperModule } from '@modules/copy-helper'; import { LessonModule } from '@modules/lesson'; +import { Module } from '@nestjs/common'; +import { BoardRepo, CourseRepo, DashboardModelMapper, DashboardRepo, UserRepo } from '@shared/repo'; import { CourseController } from './controller/course.controller'; import { DashboardController } from './controller/dashboard.controller'; import { RoomsController } from './controller/rooms.controller'; @@ -42,7 +42,6 @@ import { CourseRepo, UserRepo, BoardRepo, - LessonRepo, ], }) export class LearnroomApiModule {} diff --git a/apps/server/src/modules/learnroom/learnroom.module.ts b/apps/server/src/modules/learnroom/learnroom.module.ts index c84310ba05e..02071369766 100644 --- a/apps/server/src/modules/learnroom/learnroom.module.ts +++ b/apps/server/src/modules/learnroom/learnroom.module.ts @@ -1,10 +1,10 @@ -import { Module } from '@nestjs/common'; -import { BoardRepo, CourseRepo, DashboardModelMapper, DashboardRepo, LessonRepo, UserRepo } from '@shared/repo'; -import { LoggerModule } from '@src/core/logger'; import { BoardModule } from '@modules/board'; import { CopyHelperModule } from '@modules/copy-helper'; import { LessonModule } from '@modules/lesson'; import { TaskModule } from '@modules/task'; +import { Module } from '@nestjs/common'; +import { BoardRepo, CourseRepo, DashboardModelMapper, DashboardRepo, UserRepo } from '@shared/repo'; +import { LoggerModule } from '@src/core/logger'; import { BoardCopyService, ColumnBoardTargetService, @@ -23,7 +23,6 @@ import { }, DashboardModelMapper, CourseRepo, - LessonRepo, BoardRepo, UserRepo, BoardCopyService, diff --git a/apps/server/src/modules/learnroom/service/rooms.service.spec.ts b/apps/server/src/modules/learnroom/service/rooms.service.spec.ts index 2358e2b2067..ef161ce179a 100644 --- a/apps/server/src/modules/learnroom/service/rooms.service.spec.ts +++ b/apps/server/src/modules/learnroom/service/rooms.service.spec.ts @@ -2,19 +2,20 @@ import { createMock, DeepMocked } from '@golevelup/ts-jest'; import { Configuration } from '@hpi-schul-cloud/commons/lib'; import { IConfig } from '@hpi-schul-cloud/commons/lib/interfaces/IConfig'; import { ObjectId } from '@mikro-orm/mongodb'; +import { CardService, ColumnBoardService, ColumnService, ContentElementService } from '@modules/board'; +import { LessonService } from '@modules/lesson'; +import { TaskService } from '@modules/task'; import { Test, TestingModule } from '@nestjs/testing'; import { BoardExternalReference, BoardExternalReferenceType, EntityId } from '@shared/domain'; -import { BoardRepo, LessonRepo } from '@shared/repo'; +import { BoardRepo } from '@shared/repo'; import { boardFactory, courseFactory, lessonFactory, setupEntities, taskFactory, userFactory } from '@shared/testing'; -import { CardService, ColumnBoardService, ColumnService, ContentElementService } from '@modules/board'; -import { TaskService } from '@modules/task/service'; import { ColumnBoardTargetService } from './column-board-target.service'; import { RoomsService } from './rooms.service'; describe('rooms service', () => { let module: TestingModule; let roomsService: RoomsService; - let lessonRepo: DeepMocked; + let lessonService: DeepMocked; let taskService: DeepMocked; let boardRepo: DeepMocked; let columnBoardService: DeepMocked; @@ -32,8 +33,8 @@ describe('rooms service', () => { providers: [ RoomsService, { - provide: LessonRepo, - useValue: createMock(), + provide: LessonService, + useValue: createMock(), }, { provide: TaskService, @@ -66,7 +67,7 @@ describe('rooms service', () => { ], }).compile(); roomsService = module.get(RoomsService); - lessonRepo = module.get(LessonRepo); + lessonService = module.get(LessonService); taskService = module.get(TaskService); boardRepo = module.get(BoardRepo); columnBoardService = module.get(ColumnBoardService); @@ -90,7 +91,7 @@ describe('rooms service', () => { board.syncBoardElementReferences([...tasks, ...lessons]); const tasksSpy = taskService.findBySingleParent.mockResolvedValue([tasks, 3]); - const lessonsSpy = lessonRepo.findAllByCourseIds.mockResolvedValue([lessons, 3]); + const lessonsSpy = lessonService.findByCourseIds.mockResolvedValue([lessons, 3]); const syncBoardElementReferencesSpy = jest.spyOn(board, 'syncBoardElementReferences'); const saveSpy = boardRepo.save.mockResolvedValue(); @@ -134,7 +135,7 @@ describe('rooms service', () => { describe('for column boards', () => { const setup = () => { - lessonRepo.findAllByCourseIds.mockResolvedValueOnce([[], 0]); + lessonService.findByCourseIds.mockResolvedValueOnce([[], 0]); taskService.findBySingleParent.mockResolvedValueOnce([[], 0]); const user = userFactory.buildWithId(); diff --git a/apps/server/src/modules/learnroom/service/rooms.service.ts b/apps/server/src/modules/learnroom/service/rooms.service.ts index cc8b95e09b0..19ddfd57be8 100644 --- a/apps/server/src/modules/learnroom/service/rooms.service.ts +++ b/apps/server/src/modules/learnroom/service/rooms.service.ts @@ -1,23 +1,24 @@ import { Configuration } from '@hpi-schul-cloud/commons/lib'; +import { ColumnBoardService } from '@modules/board'; +import { LessonService } from '@modules/lesson'; +import { TaskService } from '@modules/task'; import { Injectable } from '@nestjs/common'; import { Board, BoardExternalReferenceType, ColumnBoardTarget, EntityId } from '@shared/domain'; -import { BoardRepo, LessonRepo } from '@shared/repo'; -import { ColumnBoardService } from '@modules/board'; -import { TaskService } from '@modules/task/service'; +import { BoardRepo } from '@shared/repo'; import { ColumnBoardTargetService } from './column-board-target.service'; @Injectable() export class RoomsService { constructor( private readonly taskService: TaskService, - private readonly lessonRepo: LessonRepo, + private readonly lessonService: LessonService, private readonly boardRepo: BoardRepo, private readonly columnBoardService: ColumnBoardService, private readonly columnBoardTargetService: ColumnBoardTargetService ) {} async updateBoard(board: Board, roomId: EntityId, userId: EntityId): Promise { - const [courseLessons] = await this.lessonRepo.findAllByCourseIds([roomId]); + const [courseLessons] = await this.lessonService.findByCourseIds([roomId]); const [courseTasks] = await this.taskService.findBySingleParent(userId, roomId); const courseColumnBoardTargets = await this.handleColumnBoardIntegration(roomId); diff --git a/apps/server/src/modules/learnroom/uc/course.uc.spec.ts b/apps/server/src/modules/learnroom/uc/course.uc.spec.ts index 750c9b1a287..3ab86b82c65 100644 --- a/apps/server/src/modules/learnroom/uc/course.uc.spec.ts +++ b/apps/server/src/modules/learnroom/uc/course.uc.spec.ts @@ -1,7 +1,7 @@ import { createMock, DeepMocked } from '@golevelup/ts-jest'; import { Test, TestingModule } from '@nestjs/testing'; import { SortOrder } from '@shared/domain'; -import { CourseRepo, LessonRepo } from '@shared/repo'; +import { CourseRepo } from '@shared/repo'; import { courseFactory, setupEntities } from '@shared/testing'; import { CourseUc } from './course.uc'; @@ -19,10 +19,6 @@ describe('CourseUc', () => { provide: CourseRepo, useValue: createMock(), }, - { - provide: LessonRepo, - useValue: createMock(), - }, ], }).compile(); diff --git a/apps/server/src/modules/learnroom/uc/lesson-copy.uc.spec.ts b/apps/server/src/modules/learnroom/uc/lesson-copy.uc.spec.ts index 49c7c53435c..6f148abc94f 100644 --- a/apps/server/src/modules/learnroom/uc/lesson-copy.uc.spec.ts +++ b/apps/server/src/modules/learnroom/uc/lesson-copy.uc.spec.ts @@ -1,21 +1,21 @@ import { createMock, DeepMocked } from '@golevelup/ts-jest'; import { Configuration } from '@hpi-schul-cloud/commons'; import { ObjectId } from '@mikro-orm/mongodb'; +import { AuthorizationContextBuilder, AuthorizationService } from '@modules/authorization'; +import { CopyElementType, CopyHelperService, CopyStatusEnum } from '@modules/copy-helper'; +import { LessonCopyService, LessonService } from '@modules/lesson'; import { ForbiddenException, InternalServerErrorException } from '@nestjs/common'; import { Test, TestingModule } from '@nestjs/testing'; import { Permission } from '@shared/domain'; -import { CourseRepo, LessonRepo, UserRepo } from '@shared/repo'; +import { CourseRepo, UserRepo } from '@shared/repo'; import { courseFactory, lessonFactory, setupEntities, userFactory } from '@shared/testing'; -import { AuthorizationContextBuilder, AuthorizationService } from '@modules/authorization'; -import { CopyElementType, CopyHelperService, CopyStatusEnum } from '@modules/copy-helper'; -import { EtherpadService, LessonCopyService } from '@modules/lesson/service'; import { LessonCopyUC } from './lesson-copy.uc'; describe('lesson copy uc', () => { let module: TestingModule; let uc: LessonCopyUC; let userRepo: DeepMocked; - let lessonRepo: DeepMocked; + let lessonService: DeepMocked; let courseRepo: DeepMocked; let authorisation: DeepMocked; let lessonCopyService: DeepMocked; @@ -35,8 +35,8 @@ describe('lesson copy uc', () => { useValue: createMock(), }, { - provide: LessonRepo, - useValue: createMock(), + provide: LessonService, + useValue: createMock(), }, { provide: CourseRepo, @@ -54,16 +54,12 @@ describe('lesson copy uc', () => { provide: CopyHelperService, useValue: createMock(), }, - { - provide: EtherpadService, - useValue: createMock(), - }, ], }).compile(); uc = module.get(LessonCopyUC); userRepo = module.get(UserRepo); - lessonRepo = module.get(LessonRepo); + lessonService = module.get(LessonService); authorisation = module.get(AuthorizationService); courseRepo = module.get(CourseRepo); lessonCopyService = module.get(LessonCopyService); @@ -128,8 +124,8 @@ describe('lesson copy uc', () => { authorisation.getUserWithPermissions.mockResolvedValueOnce(user); authorisation.hasPermission.mockReturnValue(true); - lessonRepo.findById.mockResolvedValueOnce(lesson); - lessonRepo.findAllByCourseIds.mockResolvedValueOnce([allLessons, allLessons.length]); + lessonService.findById.mockResolvedValueOnce(lesson); + lessonService.findByCourseIds.mockResolvedValueOnce([allLessons, allLessons.length]); courseRepo.findById.mockResolvedValueOnce(course); lessonCopyService.copyLesson.mockResolvedValueOnce(status); @@ -185,8 +181,8 @@ describe('lesson copy uc', () => { authorisation.getUserWithPermissions.mockResolvedValueOnce(user); authorisation.hasPermission.mockReturnValue(true); - lessonRepo.findById.mockResolvedValueOnce(lesson); - lessonRepo.findAllByCourseIds.mockResolvedValueOnce([allLessons, allLessons.length]); + lessonService.findById.mockResolvedValueOnce(lesson); + lessonService.findByCourseIds.mockResolvedValueOnce([allLessons, allLessons.length]); courseRepo.findById.mockResolvedValueOnce(course); lessonCopyService.copyLesson.mockResolvedValueOnce(status); @@ -221,7 +217,7 @@ describe('lesson copy uc', () => { await uc.copyLesson(userId, lessonId, parentParams); - expect(lessonRepo.findById).toBeCalledWith(lessonId); + expect(lessonService.findById).toBeCalledWith(lessonId); }); it('should fetch destination course', async () => { @@ -285,7 +281,7 @@ describe('lesson copy uc', () => { await uc.copyLesson(userId, lessonId, parentParams); - expect(lessonRepo.findAllByCourseIds).toHaveBeenCalledWith([courseId]); + expect(lessonService.findByCourseIds).toHaveBeenCalledWith([courseId]); }); }); @@ -300,7 +296,7 @@ describe('lesson copy uc', () => { const parentParams = { courseId: course.id, userId: new ObjectId().toHexString() }; userRepo.findById.mockResolvedValueOnce(user); - lessonRepo.findById.mockResolvedValueOnce(lesson); + lessonService.findById.mockResolvedValueOnce(lesson); courseRepo.findById.mockResolvedValueOnce(course); authorisation.hasPermission.mockReturnValueOnce(false); @@ -331,7 +327,7 @@ describe('lesson copy uc', () => { const parentParams = { courseId: course.id, userId: new ObjectId().toHexString() }; userRepo.findById.mockResolvedValueOnce(user); - lessonRepo.findById.mockResolvedValueOnce(lesson); + lessonService.findById.mockResolvedValueOnce(lesson); courseRepo.findById.mockResolvedValueOnce(course); authorisation.checkPermission.mockImplementationOnce(() => { throw new ForbiddenException(); diff --git a/apps/server/src/modules/learnroom/uc/lesson-copy.uc.ts b/apps/server/src/modules/learnroom/uc/lesson-copy.uc.ts index ae41fb6881b..c5c75a6e011 100644 --- a/apps/server/src/modules/learnroom/uc/lesson-copy.uc.ts +++ b/apps/server/src/modules/learnroom/uc/lesson-copy.uc.ts @@ -1,19 +1,18 @@ import { Configuration } from '@hpi-schul-cloud/commons'; +import { AuthorizationContextBuilder, AuthorizationService } from '@modules/authorization'; +import { CopyHelperService, CopyStatus } from '@modules/copy-helper'; +import { LessonCopyParentParams, LessonCopyService, LessonService } from '@modules/lesson'; import { ForbiddenException, Injectable, InternalServerErrorException } from '@nestjs/common'; import { Course, EntityId, LessonEntity, User } from '@shared/domain'; import { Permission } from '@shared/domain/interface/permission.enum'; -import { CourseRepo, LessonRepo } from '@shared/repo'; -import { AuthorizationContextBuilder, AuthorizationService } from '@modules/authorization'; -import { CopyHelperService, CopyStatus } from '@modules/copy-helper'; -import { LessonCopyParentParams } from '@modules/lesson'; -import { LessonCopyService } from '@modules/lesson/service'; +import { CourseRepo } from '@shared/repo'; @Injectable() export class LessonCopyUC { constructor( private readonly authorisation: AuthorizationService, private readonly lessonCopyService: LessonCopyService, - private readonly lessonRepo: LessonRepo, + private readonly lessonService: LessonService, private readonly courseRepo: CourseRepo, private readonly copyHelperService: CopyHelperService ) {} @@ -23,7 +22,7 @@ export class LessonCopyUC { const [user, originalLesson]: [User, LessonEntity] = await Promise.all([ this.authorisation.getUserWithPermissions(userId), - this.lessonRepo.findById(lessonId), + this.lessonService.findById(lessonId), ]); this.checkOriginalLessonAuthorization(user, originalLesson); @@ -37,7 +36,7 @@ export class LessonCopyUC { this.checkDestinationCourseAuthorization(user, destinationCourse); // should be a seperate private method - const [existingLessons] = await this.lessonRepo.findAllByCourseIds([originalLesson.course.id]); + const [existingLessons] = await this.lessonService.findByCourseIds([originalLesson.course.id]); const existingNames = existingLessons.map((l) => l.name); const copyName = this.copyHelperService.deriveCopyName(originalLesson.name, existingNames); diff --git a/apps/server/src/modules/learnroom/uc/rooms.uc.spec.ts b/apps/server/src/modules/learnroom/uc/rooms.uc.spec.ts index 7c6b82aad84..69faa5c8fd7 100644 --- a/apps/server/src/modules/learnroom/uc/rooms.uc.spec.ts +++ b/apps/server/src/modules/learnroom/uc/rooms.uc.spec.ts @@ -1,7 +1,7 @@ import { createMock, DeepMocked } from '@golevelup/ts-jest'; import { ForbiddenException } from '@nestjs/common'; import { Test, TestingModule } from '@nestjs/testing'; -import { BoardRepo, CourseRepo, LessonRepo, TaskRepo, UserRepo } from '@shared/repo'; +import { BoardRepo, CourseRepo, TaskRepo, UserRepo } from '@shared/repo'; import { boardFactory, courseFactory, lessonFactory, setupEntities, taskFactory, userFactory } from '@shared/testing'; import { RoomsService } from '../service/rooms.service'; import { RoomBoardDTOFactory } from './room-board-dto.factory'; @@ -11,7 +11,6 @@ import { RoomsUc } from './rooms.uc'; describe('rooms usecase', () => { let uc: RoomsUc; let courseRepo: DeepMocked; - let lessonRepo: DeepMocked; let taskRepo: DeepMocked; let userRepo: DeepMocked; let boardRepo: DeepMocked; @@ -33,10 +32,6 @@ describe('rooms usecase', () => { provide: CourseRepo, useValue: createMock(), }, - { - provide: LessonRepo, - useValue: createMock(), - }, { provide: TaskRepo, useValue: createMock(), @@ -66,7 +61,6 @@ describe('rooms usecase', () => { uc = module.get(RoomsUc); courseRepo = module.get(CourseRepo); - lessonRepo = module.get(LessonRepo); taskRepo = module.get(TaskRepo); userRepo = module.get(UserRepo); boardRepo = module.get(BoardRepo); @@ -97,7 +91,6 @@ describe('rooms usecase', () => { const roomSpy = courseRepo.findOne.mockResolvedValue(room); const boardSpy = boardRepo.findByCourseId.mockResolvedValue(board); const tasksSpy = taskRepo.findBySingleParent.mockResolvedValue([tasks, 3]); - const lessonsSpy = lessonRepo.findAllByCourseIds.mockResolvedValue([lessons, 3]); const syncBoardElementReferencesSpy = jest.spyOn(board, 'syncBoardElementReferences'); const mapperSpy = factory.createDTO.mockReturnValue(roomBoardDTO); const saveSpy = boardRepo.save.mockResolvedValue(); @@ -114,7 +107,6 @@ describe('rooms usecase', () => { roomSpy, boardSpy, tasksSpy, - lessonsSpy, syncBoardElementReferencesSpy, mapperSpy, saveSpy, diff --git a/apps/server/src/modules/lesson/index.ts b/apps/server/src/modules/lesson/index.ts index 61e512d84b7..b552bf9c988 100644 --- a/apps/server/src/modules/lesson/index.ts +++ b/apps/server/src/modules/lesson/index.ts @@ -1,3 +1,5 @@ export * from './lesson.module'; +export * from './service/lesson-copy.service'; +export * from './service/lesson.service'; export * from './types/lesson-copy-parent.params'; export * from './types/lesson-copy.params'; diff --git a/apps/server/src/modules/lesson/lesson.module.ts b/apps/server/src/modules/lesson/lesson.module.ts index dde1eb157ec..3a009550010 100644 --- a/apps/server/src/modules/lesson/lesson.module.ts +++ b/apps/server/src/modules/lesson/lesson.module.ts @@ -1,10 +1,10 @@ -import { Module } from '@nestjs/common'; import { FeathersServiceProvider } from '@infra/feathers'; -import { LessonRepo } from '@shared/repo'; -import { LoggerModule } from '@src/core/logger'; import { CopyHelperModule } from '@modules/copy-helper'; import { FilesStorageClientModule } from '@modules/files-storage-client'; import { TaskModule } from '@modules/task'; +import { Module } from '@nestjs/common'; +import { LoggerModule } from '@src/core/logger'; +import { LessonRepo } from './repository'; import { EtherpadService, LessonCopyService, LessonService, NexboardService } from './service'; @Module({ diff --git a/apps/server/src/shared/repo/lesson/index.ts b/apps/server/src/modules/lesson/repository/index.ts similarity index 100% rename from apps/server/src/shared/repo/lesson/index.ts rename to apps/server/src/modules/lesson/repository/index.ts diff --git a/apps/server/src/shared/repo/lesson/lesson-scope.ts b/apps/server/src/modules/lesson/repository/lesson-scope.ts similarity index 90% rename from apps/server/src/shared/repo/lesson/lesson-scope.ts rename to apps/server/src/modules/lesson/repository/lesson-scope.ts index ef99b7624c1..81529b03f88 100644 --- a/apps/server/src/shared/repo/lesson/lesson-scope.ts +++ b/apps/server/src/modules/lesson/repository/lesson-scope.ts @@ -1,5 +1,5 @@ import { EntityId, LessonEntity } from '@shared/domain'; -import { Scope } from '../scope'; +import { Scope } from '@shared/repo'; export class LessonScope extends Scope { byCourseIds(courseIds: EntityId[]): LessonScope { diff --git a/apps/server/src/shared/repo/lesson/lesson.repo.integration.spec.ts b/apps/server/src/modules/lesson/repository/lesson.repo.integration.spec.ts similarity index 100% rename from apps/server/src/shared/repo/lesson/lesson.repo.integration.spec.ts rename to apps/server/src/modules/lesson/repository/lesson.repo.integration.spec.ts diff --git a/apps/server/src/shared/repo/lesson/lesson.repo.ts b/apps/server/src/modules/lesson/repository/lesson.repo.ts similarity index 97% rename from apps/server/src/shared/repo/lesson/lesson.repo.ts rename to apps/server/src/modules/lesson/repository/lesson.repo.ts index 26f66e9587d..c2fc2f0269e 100644 --- a/apps/server/src/shared/repo/lesson/lesson.repo.ts +++ b/apps/server/src/modules/lesson/repository/lesson.repo.ts @@ -1,7 +1,7 @@ +import { EntityDictionary } from '@mikro-orm/core'; import { Injectable } from '@nestjs/common'; import { Counted, EntityId, LessonEntity, SortOrder } from '@shared/domain'; -import { EntityDictionary } from '@mikro-orm/core'; -import { BaseRepo } from '../base.repo'; +import { BaseRepo } from '@shared/repo'; import { LessonScope } from './lesson-scope'; @Injectable() diff --git a/apps/server/src/modules/lesson/service/lesson-copy.service.spec.ts b/apps/server/src/modules/lesson/service/lesson-copy.service.spec.ts index 34392c91c0c..5e7c1aa3e59 100644 --- a/apps/server/src/modules/lesson/service/lesson-copy.service.spec.ts +++ b/apps/server/src/modules/lesson/service/lesson-copy.service.spec.ts @@ -1,5 +1,8 @@ import { createMock, DeepMocked } from '@golevelup/ts-jest'; import { Configuration } from '@hpi-schul-cloud/commons'; +import { CopyElementType, CopyHelperService, CopyStatus, CopyStatusEnum } from '@modules/copy-helper'; +import { CopyFilesService } from '@modules/files-storage-client'; +import { TaskCopyService } from '@modules/task'; import { Test, TestingModule } from '@nestjs/testing'; import { BaseEntity, @@ -15,7 +18,6 @@ import { Material, } from '@shared/domain'; import { AuthorizableObject } from '@shared/domain/domain-object'; -import { LessonRepo } from '@shared/repo'; import { courseFactory, lessonFactory, @@ -24,9 +26,7 @@ import { taskFactory, userFactory, } from '@shared/testing'; -import { CopyElementType, CopyHelperService, CopyStatus, CopyStatusEnum } from '@modules/copy-helper'; -import { CopyFilesService } from '@modules/files-storage-client'; -import { TaskCopyService } from '@modules/task/service'; +import { LessonRepo } from '../repository'; import { EtherpadService } from './etherpad.service'; import { LessonCopyService } from './lesson-copy.service'; import { NexboardService } from './nexboard.service'; diff --git a/apps/server/src/modules/lesson/service/lesson-copy.service.ts b/apps/server/src/modules/lesson/service/lesson-copy.service.ts index b6d7e7849c7..0ea5110b424 100644 --- a/apps/server/src/modules/lesson/service/lesson-copy.service.ts +++ b/apps/server/src/modules/lesson/service/lesson-copy.service.ts @@ -1,4 +1,7 @@ import { Configuration } from '@hpi-schul-cloud/commons'; +import { CopyDictionary, CopyElementType, CopyHelperService, CopyStatus, CopyStatusEnum } from '@modules/copy-helper'; +import { CopyFilesService, FileUrlReplacement } from '@modules/files-storage-client'; +import { TaskCopyService } from '@modules/task'; import { Injectable } from '@nestjs/common'; import { ComponentType, @@ -11,12 +14,8 @@ import { LessonEntity, Material, } from '@shared/domain'; -import { LessonRepo } from '@shared/repo'; -import { CopyDictionary, CopyElementType, CopyHelperService, CopyStatus, CopyStatusEnum } from '@modules/copy-helper'; -import { CopyFilesService } from '@modules/files-storage-client'; -import { FileUrlReplacement } from '@modules/files-storage-client/service/copy-files.service'; -import { TaskCopyService } from '@modules/task/service/task-copy.service'; import { randomBytes } from 'crypto'; +import { LessonRepo } from '../repository'; import { LessonCopyParams } from '../types'; import { EtherpadService } from './etherpad.service'; import { NexboardService } from './nexboard.service'; diff --git a/apps/server/src/modules/lesson/service/lesson.service.spec.ts b/apps/server/src/modules/lesson/service/lesson.service.spec.ts index a94ecfe9c8b..b82875d7c1f 100644 --- a/apps/server/src/modules/lesson/service/lesson.service.spec.ts +++ b/apps/server/src/modules/lesson/service/lesson.service.spec.ts @@ -1,10 +1,10 @@ import { createMock, DeepMocked } from '@golevelup/ts-jest'; -import { Test, TestingModule } from '@nestjs/testing'; -import { LessonRepo } from '@shared/repo'; -import { lessonFactory, setupEntities } from '@shared/testing'; -import { FilesStorageClientAdapterService } from '@modules/files-storage-client'; import { ObjectId } from '@mikro-orm/mongodb'; +import { FilesStorageClientAdapterService } from '@modules/files-storage-client'; +import { Test, TestingModule } from '@nestjs/testing'; import { ComponentType, IComponentProperties } from '@shared/domain'; +import { lessonFactory, setupEntities } from '@shared/testing'; +import { LessonRepo } from '../repository'; import { LessonService } from './lesson.service'; describe('LessonService', () => { @@ -71,9 +71,19 @@ describe('LessonService', () => { const courseIds = ['course-1', 'course-2']; lessonRepo.findAllByCourseIds.mockResolvedValueOnce([[], 0]); - await expect(lessonService.findByCourseIds(courseIds)).resolves.not.toThrow(); - expect(lessonRepo.findAllByCourseIds).toBeCalledTimes(1); - expect(lessonRepo.findAllByCourseIds).toBeCalledWith(courseIds); + await lessonService.findByCourseIds(courseIds); + + expect(lessonRepo.findAllByCourseIds).toBeCalledWith(courseIds, undefined); + }); + + it('should pass filters', async () => { + const courseIds = ['course-1', 'course-2']; + lessonRepo.findAllByCourseIds.mockResolvedValueOnce([[], 0]); + const filters = { hidden: false }; + + await lessonService.findByCourseIds(courseIds, filters); + + expect(lessonRepo.findAllByCourseIds).toBeCalledWith(courseIds, filters); }); }); diff --git a/apps/server/src/modules/lesson/service/lesson.service.ts b/apps/server/src/modules/lesson/service/lesson.service.ts index 2dee6f05563..c98e633469e 100644 --- a/apps/server/src/modules/lesson/service/lesson.service.ts +++ b/apps/server/src/modules/lesson/service/lesson.service.ts @@ -1,10 +1,11 @@ +import { FilesStorageClientAdapterService } from '@modules/files-storage-client'; import { Injectable } from '@nestjs/common'; import { Counted, EntityId, IComponentProperties, LessonEntity } from '@shared/domain'; -import { LessonRepo } from '@shared/repo'; -import { FilesStorageClientAdapterService } from '@modules/files-storage-client'; +import { AuthorizationLoaderService } from '@src/modules/authorization'; +import { LessonRepo } from '../repository'; @Injectable() -export class LessonService { +export class LessonService implements AuthorizationLoaderService { constructor( private readonly lessonRepo: LessonRepo, private readonly filesStorageClientAdapterService: FilesStorageClientAdapterService @@ -20,8 +21,8 @@ export class LessonService { return this.lessonRepo.findById(lessonId); } - async findByCourseIds(courseIds: EntityId[]): Promise> { - return this.lessonRepo.findAllByCourseIds(courseIds); + async findByCourseIds(courseIds: EntityId[], filters?: { hidden?: boolean }): Promise> { + return this.lessonRepo.findAllByCourseIds(courseIds, filters); } async findAllLessonsByUserId(userId: EntityId): Promise { diff --git a/apps/server/src/modules/sharing/uc/share-token.uc.spec.ts b/apps/server/src/modules/sharing/uc/share-token.uc.spec.ts index 72d2a824327..9ad71462008 100644 --- a/apps/server/src/modules/sharing/uc/share-token.uc.spec.ts +++ b/apps/server/src/modules/sharing/uc/share-token.uc.spec.ts @@ -3,8 +3,17 @@ import { Configuration } from '@hpi-schul-cloud/commons/lib'; import { BadRequestException, InternalServerErrorException, NotImplementedException } from '@nestjs/common'; import { Test, TestingModule } from '@nestjs/testing'; import { Permission } from '@shared/domain'; -import { LessonRepo } from '@shared/repo'; +import { + Action, + AuthorizableReferenceType, + AuthorizationReferenceService, + AuthorizationService, +} from '@modules/authorization'; +import { CopyElementType, CopyStatus, CopyStatusEnum } from '@modules/copy-helper'; +import { CourseCopyService, CourseService } from '@modules/learnroom'; +import { LessonCopyService } from '@modules/lesson'; +import { TaskCopyService } from '@modules/task'; import { courseFactory, lessonFactory, @@ -15,13 +24,6 @@ import { userFactory, } from '@shared/testing'; import { LegacyLogger } from '@src/core/logger'; -import { Action, AuthorizationService } from '@modules/authorization'; -import { AuthorizableReferenceType, AuthorizationReferenceService } from '@modules/authorization/domain'; -import { CopyElementType, CopyStatus, CopyStatusEnum } from '@modules/copy-helper'; -import { CourseCopyService } from '@modules/learnroom'; -import { CourseService } from '@modules/learnroom/service'; -import { LessonCopyService } from '@modules/lesson/service'; -import { TaskCopyService } from '@modules/task/service'; import { ShareTokenContextType, ShareTokenParentType, ShareTokenPayload } from '../domainobject/share-token.do'; import { ShareTokenService } from '../service'; import { ShareTokenUC } from './share-token.uc'; @@ -36,7 +38,6 @@ describe('ShareTokenUC', () => { let authorization: DeepMocked; let authorizationReferenceService: DeepMocked; let courseService: DeepMocked; - let lessonRepo: DeepMocked; beforeAll(async () => { module = await Test.createTestingModule({ @@ -62,10 +63,6 @@ describe('ShareTokenUC', () => { provide: LessonCopyService, useValue: createMock(), }, - { - provide: LessonRepo, - useValue: createMock(), - }, { provide: CourseService, useValue: createMock(), @@ -89,7 +86,6 @@ describe('ShareTokenUC', () => { authorization = module.get(AuthorizationService); authorizationReferenceService = module.get(AuthorizationReferenceService); courseService = module.get(CourseService); - lessonRepo = module.get(LessonRepo); await setupEntities(); }); @@ -729,7 +725,6 @@ describe('ShareTokenUC', () => { const course = courseFactory.buildWithId(); courseService.findById.mockResolvedValue(course); const lesson = lessonFactory.buildWithId({ course }); - lessonRepo.findById.mockResolvedValue(lesson); const status: CopyStatus = { type: CopyElementType.LESSON, diff --git a/apps/server/src/modules/task/index.ts b/apps/server/src/modules/task/index.ts index 62ab8a69e94..8734b0eb623 100644 --- a/apps/server/src/modules/task/index.ts +++ b/apps/server/src/modules/task/index.ts @@ -1 +1,4 @@ +export * from './service/submission.service'; +export * from './service/task-copy.service'; +export * from './service/task.service'; export * from './task.module'; diff --git a/apps/server/src/modules/task/task-api.module.ts b/apps/server/src/modules/task/task-api.module.ts index cdb998eab4a..6085e426f6c 100644 --- a/apps/server/src/modules/task/task-api.module.ts +++ b/apps/server/src/modules/task/task-api.module.ts @@ -1,14 +1,15 @@ -import { Module } from '@nestjs/common'; -import { CourseRepo, LessonRepo, TaskRepo } from '@shared/repo'; import { AuthorizationModule } from '@modules/authorization'; import { CopyHelperModule } from '@modules/copy-helper/copy-helper.module'; +import { Module } from '@nestjs/common'; +import { CourseRepo, TaskRepo } from '@shared/repo'; +import { LessonModule } from '@modules/lesson'; import { SubmissionController, TaskController } from './controller'; import { TaskModule } from './task.module'; import { SubmissionUc, TaskCopyUC, TaskUC } from './uc'; @Module({ - imports: [AuthorizationModule, CopyHelperModule, TaskModule], + imports: [AuthorizationModule, CopyHelperModule, TaskModule, LessonModule], controllers: [TaskController, SubmissionController], - providers: [TaskUC, TaskRepo, LessonRepo, CourseRepo, TaskCopyUC, SubmissionUc], + providers: [TaskUC, TaskRepo, CourseRepo, TaskCopyUC, SubmissionUc], }) export class TaskApiModule {} diff --git a/apps/server/src/modules/task/task.module.ts b/apps/server/src/modules/task/task.module.ts index 45a0fdb720a..87ecf144798 100644 --- a/apps/server/src/modules/task/task.module.ts +++ b/apps/server/src/modules/task/task.module.ts @@ -1,12 +1,12 @@ import { CopyHelperModule } from '@modules/copy-helper'; import { FilesStorageClientModule } from '@modules/files-storage-client'; import { Module } from '@nestjs/common'; -import { CourseRepo, LessonRepo, SubmissionRepo, TaskRepo } from '@shared/repo'; +import { CourseRepo, SubmissionRepo, TaskRepo } from '@shared/repo'; import { SubmissionService, TaskCopyService, TaskService } from './service'; @Module({ imports: [FilesStorageClientModule, CopyHelperModule], - providers: [TaskService, TaskCopyService, SubmissionService, TaskRepo, LessonRepo, CourseRepo, SubmissionRepo], + providers: [TaskService, TaskCopyService, SubmissionService, TaskRepo, CourseRepo, SubmissionRepo], exports: [TaskService, TaskCopyService, SubmissionService], }) export class TaskModule {} diff --git a/apps/server/src/modules/task/uc/task-copy.uc.spec.ts b/apps/server/src/modules/task/uc/task-copy.uc.spec.ts index dc381cda22e..182294cfd91 100644 --- a/apps/server/src/modules/task/uc/task-copy.uc.spec.ts +++ b/apps/server/src/modules/task/uc/task-copy.uc.spec.ts @@ -1,23 +1,24 @@ import { createMock, DeepMocked } from '@golevelup/ts-jest'; import { Configuration } from '@hpi-schul-cloud/commons'; import { ObjectId } from '@mikro-orm/mongodb'; -import { ForbiddenException, InternalServerErrorException, NotFoundException } from '@nestjs/common'; -import { Test, TestingModule } from '@nestjs/testing'; -import { CourseRepo, LessonRepo, TaskRepo, UserRepo } from '@shared/repo'; -import { courseFactory, lessonFactory, setupEntities, taskFactory, userFactory } from '@shared/testing'; import { Action, AuthorizationContextBuilder, AuthorizationService } from '@modules/authorization'; import { CopyElementType, CopyHelperService, CopyStatusEnum } from '@modules/copy-helper'; import { FilesStorageClientAdapterService } from '@modules/files-storage-client'; +import { LessonService } from '@modules/lesson'; +import { ForbiddenException, InternalServerErrorException, NotFoundException } from '@nestjs/common'; +import { Test, TestingModule } from '@nestjs/testing'; +import { CourseRepo, TaskRepo, UserRepo } from '@shared/repo'; +import { courseFactory, lessonFactory, setupEntities, taskFactory, userFactory } from '@shared/testing'; import { TaskCopyService } from '../service'; -import { TaskCopyUC } from './task-copy.uc'; import { TaskCopyParentParams } from '../types'; +import { TaskCopyUC } from './task-copy.uc'; describe('task copy uc', () => { let uc: TaskCopyUC; let userRepo: DeepMocked; let taskRepo: DeepMocked; let courseRepo: DeepMocked; - let lessonRepo: DeepMocked; + let lessonService: DeepMocked; let authorisation: DeepMocked; let taskCopyService: DeepMocked; let copyHelperService: DeepMocked; @@ -42,8 +43,8 @@ describe('task copy uc', () => { useValue: createMock(), }, { - provide: LessonRepo, - useValue: createMock(), + provide: LessonService, + useValue: createMock(), }, { provide: AuthorizationService, @@ -69,7 +70,7 @@ describe('task copy uc', () => { taskRepo = module.get(TaskRepo); authorisation = module.get(AuthorizationService); courseRepo = module.get(CourseRepo); - lessonRepo = module.get(LessonRepo); + lessonService = module.get(LessonService); taskCopyService = module.get(TaskCopyService); copyHelperService = module.get(CopyHelperService); }); @@ -104,7 +105,7 @@ describe('task copy uc', () => { authorisation.getUserWithPermissions.mockResolvedValueOnce(user); taskRepo.findById.mockResolvedValueOnce(task); - lessonRepo.findById.mockResolvedValueOnce(lesson); + lessonService.findById.mockResolvedValueOnce(lesson); taskRepo.findBySingleParent.mockResolvedValueOnce([allTasks, allTasks.length]); courseRepo.findById.mockResolvedValueOnce(course); authorisation.hasPermission.mockReturnValueOnce(true).mockReturnValueOnce(true); @@ -187,7 +188,7 @@ describe('task copy uc', () => { await uc.copyTask(user.id, task.id, { lessonId: lesson.id, userId }); - expect(lessonRepo.findById).toBeCalledWith(lesson.id); + expect(lessonService.findById).toBeCalledWith(lesson.id); }); it('should pass without destination lesson', async () => { @@ -195,7 +196,7 @@ describe('task copy uc', () => { await uc.copyTask(user.id, task.id, { userId }); - expect(lessonRepo.findById).not.toHaveBeenCalled(); + expect(lessonService.findById).not.toHaveBeenCalled(); }); }); @@ -365,7 +366,7 @@ describe('task copy uc', () => { userRepo.findById.mockResolvedValueOnce(user); taskRepo.findById.mockResolvedValueOnce(task); courseRepo.findById.mockResolvedValueOnce(course); - lessonRepo.findById.mockResolvedValueOnce(lesson); + lessonService.findById.mockResolvedValueOnce(lesson); // first canReadTask > second canWriteLesson authorisation.hasPermission.mockReturnValueOnce(true).mockReturnValueOnce(false); diff --git a/apps/server/src/modules/task/uc/task-copy.uc.ts b/apps/server/src/modules/task/uc/task-copy.uc.ts index 69fd99e224f..58316aa1972 100644 --- a/apps/server/src/modules/task/uc/task-copy.uc.ts +++ b/apps/server/src/modules/task/uc/task-copy.uc.ts @@ -1,9 +1,10 @@ import { Configuration } from '@hpi-schul-cloud/commons'; -import { ForbiddenException, Injectable, InternalServerErrorException, NotFoundException } from '@nestjs/common'; -import { Course, EntityId, Task, LessonEntity, User } from '@shared/domain'; -import { CourseRepo, LessonRepo, TaskRepo } from '@shared/repo'; import { AuthorizationContextBuilder, AuthorizationService } from '@modules/authorization'; import { CopyHelperService, CopyStatus } from '@modules/copy-helper'; +import { ForbiddenException, Injectable, InternalServerErrorException, NotFoundException } from '@nestjs/common'; +import { Course, EntityId, LessonEntity, Task, User } from '@shared/domain'; +import { CourseRepo, TaskRepo } from '@shared/repo'; +import { LessonService } from '@modules/lesson'; import { TaskCopyService } from '../service'; import { TaskCopyParentParams } from '../types'; @@ -11,7 +12,7 @@ import { TaskCopyParentParams } from '../types'; export class TaskCopyUC { constructor( private readonly courseRepo: CourseRepo, - private readonly lessonRepo: LessonRepo, + private readonly lessonService: LessonService, private readonly authorisation: AuthorizationService, private readonly taskCopyService: TaskCopyService, private readonly taskRepo: TaskRepo, @@ -104,7 +105,7 @@ export class TaskCopyUC { return undefined; } - const destinationLesson = await this.lessonRepo.findById(lessonId); + const destinationLesson = await this.lessonService.findById(lessonId); return destinationLesson; } diff --git a/apps/server/src/modules/task/uc/task.uc.spec.ts b/apps/server/src/modules/task/uc/task.uc.spec.ts index 90bb29db444..e836f907f26 100644 --- a/apps/server/src/modules/task/uc/task.uc.spec.ts +++ b/apps/server/src/modules/task/uc/task.uc.spec.ts @@ -1,9 +1,10 @@ import { createMock, DeepMocked } from '@golevelup/ts-jest'; +import { Action, AuthorizationService } from '@modules/authorization'; import { ForbiddenException, UnauthorizedException } from '@nestjs/common'; import { Test, TestingModule } from '@nestjs/testing'; import { PaginationParams } from '@shared/controller'; import { ITaskStatus, Permission, SortOrder } from '@shared/domain'; -import { CourseRepo, LessonRepo, TaskRepo } from '@shared/repo'; +import { CourseRepo, TaskRepo } from '@shared/repo'; import { courseFactory, lessonFactory, @@ -13,7 +14,7 @@ import { taskFactory, userFactory, } from '@shared/testing'; -import { Action, AuthorizationService } from '@modules/authorization'; +import { LessonService } from '@modules/lesson'; import { TaskService } from '../service'; import { TaskUC } from './task.uc'; @@ -22,7 +23,7 @@ describe('TaskUC', () => { let service: TaskUC; let taskRepo: DeepMocked; let courseRepo: DeepMocked; - let lessonRepo: DeepMocked; + let lessonService: DeepMocked; let authorizationService: DeepMocked; let taskService: DeepMocked; @@ -48,8 +49,8 @@ describe('TaskUC', () => { useValue: createMock(), }, { - provide: LessonRepo, - useValue: createMock(), + provide: LessonService, + useValue: createMock(), }, { provide: AuthorizationService, @@ -69,7 +70,7 @@ describe('TaskUC', () => { service = module.get(TaskUC); taskRepo = module.get(TaskRepo); courseRepo = module.get(CourseRepo); - lessonRepo = module.get(LessonRepo); + lessonService = module.get(LessonService); authorizationService = module.get(AuthorizationService); taskService = module.get(TaskService); }); @@ -90,8 +91,8 @@ describe('TaskUC', () => { const finishedTask = taskFactory.finished(user).build(); authorizationService.getUserWithPermissions.mockResolvedValueOnce(user); courseRepo.findAllByUserId.mockResolvedValueOnce([[], 0]); - lessonRepo.findAllByCourseIds.mockResolvedValueOnce([[], 0]); - lessonRepo.findAllByCourseIds.mockResolvedValueOnce([[], 0]); + lessonService.findByCourseIds.mockResolvedValueOnce([[], 0]); + lessonService.findByCourseIds.mockResolvedValueOnce([[], 0]); authorizationService.hasPermission.mockReturnValueOnce(false); taskRepo.findAllFinishedByParentIds.mockResolvedValueOnce([[finishedTask], 1]); @@ -204,8 +205,8 @@ describe('TaskUC', () => { authorizationService.getUserWithPermissions.mockResolvedValue(user); courseRepo.findAllByUserId.mockResolvedValue([[], 0]); - lessonRepo.findAllByCourseIds.mockResolvedValueOnce([[lesson], 1]); - lessonRepo.findAllByCourseIds.mockResolvedValueOnce([[], 0]); + lessonService.findByCourseIds.mockResolvedValueOnce([[lesson], 1]); + lessonService.findByCourseIds.mockResolvedValueOnce([[], 0]); authorizationService.hasPermission.mockReturnValueOnce(false); taskRepo.findAllFinishedByParentIds.mockResolvedValue([[task], 1]); @@ -240,8 +241,8 @@ describe('TaskUC', () => { authorizationService.getUserWithPermissions.mockResolvedValueOnce(user); courseRepo.findAllByUserId.mockResolvedValueOnce([[course], 1]); - lessonRepo.findAllByCourseIds.mockResolvedValueOnce([[], 0]); - lessonRepo.findAllByCourseIds.mockResolvedValueOnce([[], 0]); + lessonService.findByCourseIds.mockResolvedValueOnce([[], 0]); + lessonService.findByCourseIds.mockResolvedValueOnce([[], 0]); authorizationService.hasPermission.mockReturnValueOnce(false); taskRepo.findAllFinishedByParentIds.mockResolvedValueOnce([[task], 1]); @@ -276,8 +277,8 @@ describe('TaskUC', () => { authorizationService.getUserWithPermissions.mockResolvedValueOnce(user); courseRepo.findAllByUserId.mockResolvedValueOnce([[], 0]); - lessonRepo.findAllByCourseIds.mockResolvedValueOnce([[], 0]); - lessonRepo.findAllByCourseIds.mockResolvedValueOnce([[], 0]); + lessonService.findByCourseIds.mockResolvedValueOnce([[], 0]); + lessonService.findByCourseIds.mockResolvedValueOnce([[], 0]); authorizationService.hasPermission.mockReturnValueOnce(true); taskRepo.findAllFinishedByParentIds.mockResolvedValueOnce([[task], 1]); @@ -303,8 +304,8 @@ describe('TaskUC', () => { authorizationService.getUserWithPermissions.mockResolvedValueOnce(user); courseRepo.findAllByUserId.mockResolvedValueOnce([[course], 1]); - lessonRepo.findAllByCourseIds.mockResolvedValueOnce([[], 0]); - lessonRepo.findAllByCourseIds.mockResolvedValueOnce([[], 0]); + lessonService.findByCourseIds.mockResolvedValueOnce([[], 0]); + lessonService.findByCourseIds.mockResolvedValueOnce([[], 0]); authorizationService.hasPermission.mockReturnValueOnce(true); authorizationService.hasPermission.mockReturnValueOnce(true); taskRepo.findAllFinishedByParentIds.mockResolvedValueOnce([[task], 1]); @@ -389,8 +390,8 @@ describe('TaskUC', () => { authorizationService.hasAllPermissions.mockReturnValueOnce(true); courseRepo.findAllByUserId.mockResolvedValueOnce([[course], 1]); authorizationService.hasPermission.mockReturnValueOnce(false); - lessonRepo.findAllByCourseIds.mockResolvedValueOnce([[], 0]); - lessonRepo.findAllByCourseIds.mockResolvedValueOnce([[lesson], 1]); + lessonService.findByCourseIds.mockResolvedValueOnce([[], 0]); + lessonService.findByCourseIds.mockResolvedValueOnce([[lesson], 1]); taskRepo.findAllByParentIds.mockResolvedValueOnce([[task1, task2, task3], 3]); return { user, course, lesson, task1, paginationParams }; @@ -503,8 +504,8 @@ describe('TaskUC', () => { authorizationService.hasAllPermissions.mockReturnValueOnce(true); courseRepo.findAllForTeacherOrSubstituteTeacher.mockResolvedValueOnce([[course], 1]); authorizationService.hasPermission.mockReturnValueOnce(true); - lessonRepo.findAllByCourseIds.mockResolvedValueOnce([[lesson], 1]); - lessonRepo.findAllByCourseIds.mockResolvedValueOnce([[], 0]); + lessonService.findByCourseIds.mockResolvedValueOnce([[lesson], 1]); + lessonService.findByCourseIds.mockResolvedValueOnce([[], 0]); taskRepo.findAllByParentIds.mockResolvedValueOnce([[task], 1]); return { user, paginationParams }; @@ -538,8 +539,8 @@ describe('TaskUC', () => { authorizationService.hasAllPermissions.mockReturnValueOnce(true); courseRepo.findAllForTeacherOrSubstituteTeacher.mockResolvedValueOnce([[course], 1]); authorizationService.hasPermission.mockReturnValueOnce(true); - lessonRepo.findAllByCourseIds.mockResolvedValueOnce([[lesson], 1]); - lessonRepo.findAllByCourseIds.mockResolvedValueOnce([[], 0]); + lessonService.findByCourseIds.mockResolvedValueOnce([[lesson], 1]); + lessonService.findByCourseIds.mockResolvedValueOnce([[], 0]); taskRepo.findAllByParentIds.mockResolvedValueOnce([[task1, task2, task3], 3]); return { user, course, lesson, task1, paginationParams }; diff --git a/apps/server/src/modules/task/uc/task.uc.ts b/apps/server/src/modules/task/uc/task.uc.ts index a6e40dd3b6d..69ca7b32c8f 100644 --- a/apps/server/src/modules/task/uc/task.uc.ts +++ b/apps/server/src/modules/task/uc/task.uc.ts @@ -1,3 +1,4 @@ +import { Action, AuthorizationContextBuilder, AuthorizationService } from '@modules/authorization'; import { Injectable, UnauthorizedException } from '@nestjs/common'; import { Counted, @@ -11,8 +12,8 @@ import { TaskWithStatusVo, User, } from '@shared/domain'; -import { CourseRepo, LessonRepo, TaskRepo } from '@shared/repo'; -import { Action, AuthorizationContextBuilder, AuthorizationService } from '@modules/authorization'; +import { CourseRepo, TaskRepo } from '@shared/repo'; +import { LessonService } from '@modules/lesson'; import { TaskService } from '../service'; @Injectable() @@ -21,7 +22,7 @@ export class TaskUC { private readonly taskRepo: TaskRepo, private readonly authorizationService: AuthorizationService, private readonly courseRepo: CourseRepo, - private readonly lessonRepo: LessonRepo, + private readonly lessonService: LessonService, private readonly taskService: TaskService ) {} @@ -206,8 +207,8 @@ export class TaskUC { // idea as combined query: // [{courseIds: onlyWriteCoursesIds}, { courseIds: onlyReadCourses, filter: { hidden: false }}] const [[writeLessons], [readLessons]] = await Promise.all([ - this.lessonRepo.findAllByCourseIds(writeCourseIds), - this.lessonRepo.findAllByCourseIds(readCourseIds, { hidden: false }), + this.lessonService.findByCourseIds(writeCourseIds), + this.lessonService.findByCourseIds(readCourseIds, { hidden: false }), ]); const permittedLessons = [...writeLessons, ...readLessons]; diff --git a/apps/server/src/modules/tool/index.ts b/apps/server/src/modules/tool/index.ts index 5af54483f5b..a7a6c23ddab 100644 --- a/apps/server/src/modules/tool/index.ts +++ b/apps/server/src/modules/tool/index.ts @@ -1,6 +1,7 @@ -export * from './school-external-tool/entity/school-external-tool.entity'; export * from './common/entity/custom-parameter-entry.entity'; +export * from './common/interface'; export * from './context-external-tool/entity'; +export * from './context-external-tool/service/context-external-tool-authorizable.service'; export * from './external-tool'; +export * from './school-external-tool/entity/school-external-tool.entity'; export * from './tool.module'; -export * from './common/interface'; diff --git a/apps/server/src/shared/repo/index.ts b/apps/server/src/shared/repo/index.ts index 715a78ee420..ce9304ec7ef 100644 --- a/apps/server/src/shared/repo/index.ts +++ b/apps/server/src/shared/repo/index.ts @@ -12,7 +12,6 @@ export * from './coursegroup'; export * from './dashboard'; export * from './federalstate'; export * from './importuser'; -export * from './lesson'; export * from './ltitool'; export * from './materials'; export * from './mongo.patterns';