From 52be2c7fa39559b7bbd95e8b43f207a604af896a Mon Sep 17 00:00:00 2001 From: Arne Gnisa Date: Mon, 10 Jun 2024 08:31:54 +0200 Subject: [PATCH] N21-2020 fixes media board error when tool was deleted --- .../media-available-line.service.spec.ts | 96 +++++++++++++++---- .../media-available-line.service.ts | 10 +- 2 files changed, 81 insertions(+), 25 deletions(-) diff --git a/apps/server/src/modules/board/service/media-board/media-available-line.service.spec.ts b/apps/server/src/modules/board/service/media-board/media-available-line.service.spec.ts index fe772450e75..998a0eade26 100644 --- a/apps/server/src/modules/board/service/media-board/media-available-line.service.spec.ts +++ b/apps/server/src/modules/board/service/media-board/media-available-line.service.spec.ts @@ -1,4 +1,5 @@ import { createMock, DeepMocked } from '@golevelup/ts-jest'; +import { ObjectId } from '@mikro-orm/mongodb'; import { ExternalToolService } from '@modules/tool'; import { CustomParameterScope, ToolContextType } from '@modules/tool/common/enum'; import { ContextExternalToolService } from '@modules/tool/context-external-tool'; @@ -66,32 +67,35 @@ describe(MediaAvailableLineService.name, () => { }); describe('getUnusedAvailableSchoolExternalTools', () => { - const setup = () => { - const user: User = userFactory.build(); + describe('when there are unused tools', () => { + const setup = () => { + const user: User = userFactory.build(); - const schoolExternalTool: SchoolExternalTool = schoolExternalToolFactory - .withSchoolId(user.school.id) - .buildWithId(); - const usedSchoolExternalTool: SchoolExternalTool = schoolExternalToolFactory - .withSchoolId(user.school.id) - .buildWithId(); + const schoolExternalTool: SchoolExternalTool = schoolExternalToolFactory + .withSchoolId(user.school.id) + .buildWithId(); + const usedSchoolExternalTool: SchoolExternalTool = schoolExternalToolFactory + .withSchoolId(user.school.id) + .buildWithId(); - const usedContextExternalTool: ContextExternalTool = contextExternalToolFactory - .withSchoolExternalToolRef(usedSchoolExternalTool.id, user.school.id) - .buildWithId(); + const usedContextExternalTool: ContextExternalTool = contextExternalToolFactory + .withSchoolExternalToolRef(usedSchoolExternalTool.id, user.school.id) + .buildWithId(); - const mediaExternalToolElement: MediaExternalToolElement = mediaExternalToolElementFactory.build({ - contextExternalToolId: usedContextExternalTool.id, - }); - const board: MediaBoard = mediaBoardFactory.addChild(mediaExternalToolElement).build(); + const mediaExternalToolElement: MediaExternalToolElement = mediaExternalToolElementFactory.build({ + contextExternalToolId: usedContextExternalTool.id, + }); + const board: MediaBoard = mediaBoardFactory.addChild(mediaExternalToolElement).build(); - schoolExternalToolService.findSchoolExternalTools.mockResolvedValue([schoolExternalTool, usedSchoolExternalTool]); - contextExternalToolService.findByIdOrFail.mockResolvedValueOnce(usedContextExternalTool); + schoolExternalToolService.findSchoolExternalTools.mockResolvedValue([ + schoolExternalTool, + usedSchoolExternalTool, + ]); + contextExternalToolService.findById.mockResolvedValueOnce(usedContextExternalTool); - return { user, board, mediaExternalToolElement, schoolExternalTool }; - }; + return { user, board, mediaExternalToolElement, schoolExternalTool }; + }; - describe('when there are unused tools', () => { it('should call the service to get school external tools for users school', async () => { const { user, board } = setup(); @@ -108,7 +112,7 @@ describe(MediaAvailableLineService.name, () => { await service.getUnusedAvailableSchoolExternalTools(user, board); - expect(contextExternalToolService.findByIdOrFail).toHaveBeenCalledWith( + expect(contextExternalToolService.findById).toHaveBeenCalledWith( mediaExternalToolElement.contextExternalToolId ); }); @@ -124,6 +128,56 @@ describe(MediaAvailableLineService.name, () => { expect(schoolExternalTools).toEqual([schoolExternalTool]); }); }); + + describe('when there are elements on board which has deleted context external tool', () => { + const setup = () => { + const user: User = userFactory.build(); + + const schoolExternalTool: SchoolExternalTool = schoolExternalToolFactory + .withSchoolId(user.school.id) + .buildWithId(); + const usedSchoolExternalTool: SchoolExternalTool = schoolExternalToolFactory + .withSchoolId(user.school.id) + .buildWithId(); + + const usedContextExternalTool: ContextExternalTool = contextExternalToolFactory + .withSchoolExternalToolRef(usedSchoolExternalTool.id, user.school.id) + .buildWithId(); + + const mediaExternalToolElement: MediaExternalToolElement = mediaExternalToolElementFactory.build({ + contextExternalToolId: usedContextExternalTool.id, + }); + const mediaExternalToolElementWithDeletedTool: MediaExternalToolElement = mediaExternalToolElementFactory.build( + { + contextExternalToolId: new ObjectId().toHexString(), + } + ); + const board: MediaBoard = mediaBoardFactory + .addChild(mediaExternalToolElement) + .addChild(mediaExternalToolElementWithDeletedTool) + .build(); + + schoolExternalToolService.findSchoolExternalTools.mockResolvedValue([ + schoolExternalTool, + usedSchoolExternalTool, + ]); + contextExternalToolService.findById.mockResolvedValueOnce(usedContextExternalTool); + contextExternalToolService.findById.mockResolvedValueOnce(null); + + return { user, board, mediaExternalToolElement, schoolExternalTool }; + }; + + it('should return the available tools', async () => { + const { user, board, schoolExternalTool } = setup(); + + const schoolExternalTools: SchoolExternalTool[] = await service.getUnusedAvailableSchoolExternalTools( + user, + board + ); + + expect(schoolExternalTools).toEqual([schoolExternalTool]); + }); + }); }); describe('getAvailableExternalToolsForSchool', () => { diff --git a/apps/server/src/modules/board/service/media-board/media-available-line.service.ts b/apps/server/src/modules/board/service/media-board/media-available-line.service.ts index f886658c5d4..855ae0ee8ea 100644 --- a/apps/server/src/modules/board/service/media-board/media-available-line.service.ts +++ b/apps/server/src/modules/board/service/media-board/media-available-line.service.ts @@ -92,15 +92,17 @@ export class MediaAvailableLineService { } private async getContextExternalToolsByBoard(board: MediaBoard): Promise { - const contextExternalTools: Promise[] = board + const contextExternalTools: Promise[] = board .getChildrenOfType(MediaExternalToolElement) .map((element: MediaExternalToolElement) => - this.contextExternalToolService.findByIdOrFail(element.contextExternalToolId) + this.contextExternalToolService.findById(element.contextExternalToolId) ); - const allContextExternalTools: ContextExternalTool[] = await Promise.all(contextExternalTools); + const notNullContextExternalTools: ContextExternalTool[] = (await Promise.all(contextExternalTools)).filter( + (tool): tool is ContextExternalTool => tool !== null + ); - return allContextExternalTools; + return notNullContextExternalTools; } public matchTools(