Skip to content

Commit

Permalink
begin injection of course rule and reference loader
Browse files Browse the repository at this point in the history
  • Loading branch information
Metauriel committed Sep 27, 2024
1 parent 1a53e92 commit 8408a74
Show file tree
Hide file tree
Showing 6 changed files with 110 additions and 11 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import { createMock, DeepMocked } from '@golevelup/ts-jest';
import { Test, TestingModule } from '@nestjs/testing';
import { AuthorizableReferenceType, AuthorizationInjectionService } from '@src/modules/authorization';
import { CourseReferenceLoader } from './course.reference-loader';

Check failure on line 4 in apps/server/src/modules/authorization/domain/reference-loader/course.reference-loader.spec.ts

View workflow job for this annotation

GitHub Actions / nest_lint

`./course.reference-loader` import should occur after import of `@src/modules/learnroom/testing`
import { CourseDoService } from '@src/modules/learnroom';
import { courseFactory } from '@src/modules/learnroom/testing';

describe('Course Reference Loader', () => {
let module: TestingModule;
let service: CourseReferenceLoader;

let courseDoService: DeepMocked<CourseDoService>;
let injectionService: DeepMocked<AuthorizationInjectionService>;

beforeAll(async () => {
module = await Test.createTestingModule({
providers: [
CourseReferenceLoader,
{
provide: CourseDoService,
useValue: createMock<CourseDoService>(),
},
{
provide: AuthorizationInjectionService,
useValue: createMock<AuthorizationInjectionService>(),
},
],
}).compile();

service = module.get(CourseReferenceLoader);
courseDoService = module.get(CourseDoService);
injectionService = module.get(AuthorizationInjectionService);
});

afterAll(async () => {
await module.close();
});

afterEach(() => {
jest.resetAllMocks();
});

describe('constructor', () => {
it('should inject itself into the AuthorizationInjectionService', () => {
expect(injectionService.injectReferenceLoader).toHaveBeenCalledWith(AuthorizableReferenceType.Course, service);
});
});

describe('findById', () => {
describe('when id is given', () => {
const setup = () => {
const course = courseFactory.buildWithId();
courseDoService.findById.mockResolvedValue(course);

return {
course,
};
};

it('should return a contextExternalTool', async () => {
const { course } = setup();

const result = await service.findById(course.id);

expect(result).toEqual(course);
});
});
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import {
AuthorizableReferenceType,
AuthorizationInjectionService,
AuthorizationLoaderServiceGeneric,
} from '@modules/authorization';
import { Injectable } from '@nestjs/common';
import { EntityId } from '@shared/domain/types';
import { CourseDoService } from '@src/modules/learnroom';
import { Course } from '@src/modules/learnroom/domain';

@Injectable()
export class CourseReferenceLoader implements AuthorizationLoaderServiceGeneric<Course> {
constructor(private readonly courseService: CourseDoService, injectionService: AuthorizationInjectionService) {
injectionService.injectReferenceLoader(AuthorizableReferenceType.User, this);
}

public async findById(courseId: EntityId): Promise<Course> {
const course: Course = await this.courseService.findById(courseId);

return course;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,15 @@ import { Test, TestingModule } from '@nestjs/testing';
import { Course, User } from '@shared/domain/entity';
import { Permission } from '@shared/domain/interface';
import { courseFactory as courseEntityFactory, roleFactory, setupEntities, userFactory } from '@shared/testing';
import { AuthorizationHelper } from '../service/authorization.helper';
import { Action } from '../type';
import { CourseRule } from './course.rule';
import { AuthorizationHelper, AuthorizationInjectionService } from '../service';
import { Action } from '../type';

describe('CourseRule', () => {
let module: TestingModule;
let service: CourseRule;
let authorizationHelper: AuthorizationHelper;
let injectionService: AuthorizationInjectionService;
let user: User;
let entity: Course;
const permissionA = 'a' as Permission;
Expand All @@ -21,11 +22,12 @@ describe('CourseRule', () => {
await setupEntities();

module = await Test.createTestingModule({
providers: [AuthorizationHelper, CourseRule],
providers: [AuthorizationHelper, CourseRule, AuthorizationInjectionService],
}).compile();

service = await module.get(CourseRule);
authorizationHelper = await module.get(AuthorizationHelper);
injectionService = await module.get(AuthorizationInjectionService);
});

beforeEach(() => {
Expand All @@ -41,6 +43,12 @@ describe('CourseRule', () => {
await module.close();
});

describe('constructor', () => {
it('should inject into AuthorizationInjectionService', () => {
expect(injectionService.getAuthorizationRules()).toContain(service);
});
});

describe('when validating an entity', () => {
it('should call hasAllPermissions on AuthorizationHelper', () => {
entity = courseEntityFactory.build({ teachers: [user] });
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,17 @@ import { Course } from '@modules/learnroom/domain';
import { Injectable } from '@nestjs/common';
import { Course as CourseEntity, User } from '@shared/domain/entity';
import { Permission } from '@shared/domain/interface';
import { AuthorizationHelper } from '../service/authorization.helper';
import { Action, AuthorizationContext, Rule } from '../type';
import { AuthorizationHelper, AuthorizationInjectionService } from '../service';

Check failure on line 6 in apps/server/src/modules/authorization/domain/rules/course.rule.ts

View workflow job for this annotation

GitHub Actions / nest_lint

Dependency cycle via ./rule-manager:3=>../rules:19

@Injectable()
export class CourseRule implements Rule<CourseEntity | Course> {
constructor(private readonly authorizationHelper: AuthorizationHelper) {}
constructor(
private readonly authorizationHelper: AuthorizationHelper,
authorisationInjectionService: AuthorizationInjectionService
) {
authorisationInjectionService.injectAuthorizationRule(this);
}

public isApplicable(user: User, object: unknown): boolean {
const isMatched = object instanceof CourseEntity || object instanceof Course;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,14 @@ import { Injectable, NotImplementedException } from '@nestjs/common';
import { AuthorizableObject } from '@shared/domain/domain-object';
import { BaseDO } from '@shared/domain/domainobject';
import { EntityId } from '@shared/domain/types';
import { CourseGroupRepo, CourseRepo, LegacySchoolRepo, SubmissionRepo, TaskRepo, UserRepo } from '@shared/repo';
import { CourseGroupRepo, CourseRepo, LegacySchoolRepo, SubmissionRepo, TaskRepo } from '@shared/repo';
import { InstanceService } from '../../../instance';
import { AuthorizableReferenceType, AuthorizationLoaderService } from '../type';
import { AuthorizationInjectionService } from './authorization-injection.service';

@Injectable()
export class ReferenceLoader {
constructor(
private readonly userRepo: UserRepo,
private readonly courseRepo: CourseRepo,
private readonly courseGroupRepo: CourseGroupRepo,
private readonly taskRepo: TaskRepo,
Expand All @@ -29,7 +28,6 @@ export class ReferenceLoader {
service.injectReferenceLoader(AuthorizableReferenceType.Task, this.taskRepo);
service.injectReferenceLoader(AuthorizableReferenceType.Course, this.courseRepo);
service.injectReferenceLoader(AuthorizableReferenceType.CourseGroup, this.courseGroupRepo);
service.injectReferenceLoader(AuthorizableReferenceType.User, this.userRepo);
service.injectReferenceLoader(AuthorizableReferenceType.School, this.schoolRepo);
service.injectReferenceLoader(AuthorizableReferenceType.Lesson, this.lessonService);
service.injectReferenceLoader(AuthorizableReferenceType.Team, this.teamAuthorisableService);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import { BaseDO } from '@shared/domain/domainobject';
import { User } from '@shared/domain/entity';
import {
CourseGroupRule,
CourseRule,
GroupRule,
InstanceRule,
LegacySchoolRule,
Expand All @@ -25,7 +24,6 @@ import { AuthorizationInjectionService } from './authorization-injection.service
export class RuleManager {
constructor(
courseGroupRule: CourseGroupRule,
courseRule: CourseRule,
groupRule: GroupRule,
legaySchoolRule: LegacySchoolRule,
lessonRule: LessonRule,
Expand All @@ -41,7 +39,6 @@ export class RuleManager {
private readonly authorizationInjectionService: AuthorizationInjectionService
) {
this.authorizationInjectionService.injectAuthorizationRule(courseGroupRule);
this.authorizationInjectionService.injectAuthorizationRule(courseRule);
this.authorizationInjectionService.injectAuthorizationRule(groupRule);
this.authorizationInjectionService.injectAuthorizationRule(legaySchoolRule);
this.authorizationInjectionService.injectAuthorizationRule(lessonRule);
Expand Down

0 comments on commit 8408a74

Please sign in to comment.