Skip to content

Commit

Permalink
N21-1248 Configure External Tools in Boards (#4471)
Browse files Browse the repository at this point in the history
- move tool reference to context external tool module
- new endpoint for tool reference from context external tool id
- add new tool reference controller
- add board-element as context for context external tools
  • Loading branch information
MarvinOehlerkingCap authored Oct 19, 2023
1 parent 1f90ed1 commit f2f0b36
Show file tree
Hide file tree
Showing 73 changed files with 1,246 additions and 785 deletions.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
import { ApiProperty } from '@nestjs/swagger';
import { ContentElementType } from '@shared/domain';
import { TimestampsResponse } from '../timestamps.response';

Expand All @@ -7,8 +7,8 @@ export class ExternalToolElementContent {
this.contextExternalToolId = props.contextExternalToolId;
}

@ApiPropertyOptional()
contextExternalToolId?: string;
@ApiProperty({ type: String, required: true, nullable: true })
contextExternalToolId: string | null;
}

export class ExternalToolElementResponse {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export class ExternalToolElementResponseMapper implements BaseResponseMapper {
id: element.id,
timestamps: new TimestampsResponse({ lastUpdatedAt: element.updatedAt, createdAt: element.createdAt }),
type: ContentElementType.EXTERNAL_TOOL,
content: new ExternalToolElementContent({ contextExternalToolId: element.contextExternalToolId }),
content: new ExternalToolElementContent({ contextExternalToolId: element.contextExternalToolId ?? null }),
});

return result;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@ import { createMock, DeepMocked } from '@golevelup/ts-jest';
import { DatabaseObjectNotFoundException } from '@mikro-orm/core';
import { Test, TestingModule } from '@nestjs/testing';
import { NotFoundLoggableException } from '@shared/common/loggable-exception';
import { Course, Pseudonym, RoleName, LegacySchoolDo, UserDO, SchoolEntity } from '@shared/domain';
import { Course, LegacySchoolDo, Pseudonym, RoleName, SchoolEntity, UserDO } from '@shared/domain';
import {
contextExternalToolFactory,
courseFactory,
externalToolFactory,
pseudonymFactory,
legacySchoolDoFactory,
pseudonymFactory,
schoolExternalToolFactory,
schoolFactory,
setupEntities,
Expand Down Expand Up @@ -249,10 +249,10 @@ describe('FeathersRosterService', () => {
]);
contextExternalToolService.findAllByContext.mockResolvedValueOnce([otherContextExternalTool]);
contextExternalToolService.findAllByContext.mockResolvedValueOnce([]);
schoolExternalToolService.getSchoolExternalToolById.mockResolvedValueOnce(schoolExternalTool);
schoolExternalToolService.getSchoolExternalToolById.mockResolvedValueOnce(otherSchoolExternalTool);
externalToolService.findExternalToolById.mockResolvedValueOnce(externalTool);
externalToolService.findExternalToolById.mockResolvedValueOnce(otherExternalTool);
schoolExternalToolService.findById.mockResolvedValueOnce(schoolExternalTool);
schoolExternalToolService.findById.mockResolvedValueOnce(otherSchoolExternalTool);
externalToolService.findById.mockResolvedValueOnce(externalTool);
externalToolService.findById.mockResolvedValueOnce(otherExternalTool);

return {
pseudonym,
Expand Down Expand Up @@ -299,7 +299,7 @@ describe('FeathersRosterService', () => {

await service.getUserGroups(pseudonym.pseudonym, clientId);

expect(schoolExternalToolService.getSchoolExternalToolById.mock.calls).toEqual([
expect(schoolExternalToolService.findById.mock.calls).toEqual([
[schoolExternalTool.id],
[otherSchoolExternalTool.id],
]);
Expand All @@ -310,7 +310,7 @@ describe('FeathersRosterService', () => {

await service.getUserGroups(pseudonym.pseudonym, clientId);

expect(externalToolService.findExternalToolById.mock.calls).toEqual([[externalToolId], [otherExternalTool.id]]);
expect(externalToolService.findById.mock.calls).toEqual([[externalToolId], [otherExternalTool.id]]);
});

it('should return a group for each course where the tool of the users pseudonym is used', async () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -179,12 +179,10 @@ export class FeathersRosterService {
);

for await (const contextExternalTool of contextExternalTools) {
const schoolExternalTool: SchoolExternalTool = await this.schoolExternalToolService.getSchoolExternalToolById(
const schoolExternalTool: SchoolExternalTool = await this.schoolExternalToolService.findById(
contextExternalTool.schoolToolRef.schoolToolId
);
const externalTool: ExternalTool = await this.externalToolService.findExternalToolById(
schoolExternalTool.toolId
);
const externalTool: ExternalTool = await this.externalToolService.findById(schoolExternalTool.toolId);
const isRequiredTool: boolean = externalTool.id === externalToolId;

if (isRequiredTool) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export enum ToolContextType {
COURSE = 'course',
BOARD_ELEMENT = 'board-element',
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { ToolContextType } from '../enum';

const typeMapping: Record<ToolContextType, AuthorizableReferenceType> = {
[ToolContextType.COURSE]: AuthorizableReferenceType.Course,
[ToolContextType.BOARD_ELEMENT]: AuthorizableReferenceType.BoardNode,
};

export class ContextTypeMapper {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { ToolConfigurationStatusResponse } from '../../context-external-tool/controller/dto/tool-configuration-status.response';
import { ToolConfigurationStatus } from '../enum';

export const statusMapping: Record<ToolConfigurationStatus, ToolConfigurationStatusResponse> = {
[ToolConfigurationStatus.LATEST]: ToolConfigurationStatusResponse.LATEST,
[ToolConfigurationStatus.OUTDATED]: ToolConfigurationStatusResponse.OUTDATED,
[ToolConfigurationStatus.UNKNOWN]: ToolConfigurationStatusResponse.UNKNOWN,
};

export class ToolStatusResponseMapper {
static mapToResponse(status: ToolConfigurationStatus): ToolConfigurationStatusResponse {
return statusMapping[status];
}
}
Original file line number Diff line number Diff line change
@@ -1,25 +1,28 @@
import { forwardRef, Module } from '@nestjs/common';
import { Module } from '@nestjs/common';
import { LoggerModule } from '@src/core/logger';
import { AuthorizationModule } from '@src/modules/authorization';
import { CommonToolModule } from '../common';
import { ExternalToolModule } from '../external-tool';
import { SchoolExternalToolModule } from '../school-external-tool';
import {
ContextExternalToolAuthorizableService,
ContextExternalToolService,
ContextExternalToolValidationService,
ToolReferenceService,
} from './service';
import { CommonToolModule } from '../common';

@Module({
// TODO: remove authorization module here N21-1055
imports: [
CommonToolModule,
ExternalToolModule,
SchoolExternalToolModule,
LoggerModule,
forwardRef(() => AuthorizationModule),
imports: [CommonToolModule, ExternalToolModule, SchoolExternalToolModule, LoggerModule],
providers: [
ContextExternalToolService,
ContextExternalToolValidationService,
ContextExternalToolAuthorizableService,
ToolReferenceService,
],
exports: [
ContextExternalToolService,
ContextExternalToolValidationService,
ContextExternalToolAuthorizableService,
ToolReferenceService,
],
providers: [ContextExternalToolService, ContextExternalToolValidationService, ContextExternalToolAuthorizableService],
exports: [ContextExternalToolService, ContextExternalToolValidationService, ContextExternalToolAuthorizableService],
})
export class ContextExternalToolModule {}
Loading

0 comments on commit f2f0b36

Please sign in to comment.