Skip to content

Commit

Permalink
Merge branch 'main' into BC-5836-Add-News-to-KNLDeletion
Browse files Browse the repository at this point in the history
  • Loading branch information
sszafGCA authored Jan 15, 2024
2 parents 6a9ca23 + 22c0c76 commit dd2e239
Show file tree
Hide file tree
Showing 29 changed files with 585 additions and 499 deletions.
68 changes: 65 additions & 3 deletions apps/server/src/modules/board/repo/board-do.repo.spec.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
import { createMock } from '@golevelup/ts-jest';
import { MongoMemoryDatabaseModule } from '@infra/database';
import { NotFoundError } from '@mikro-orm/core';
import { EntityManager } from '@mikro-orm/mongodb';
import { EntityManager, ObjectId } from '@mikro-orm/mongodb';
import { FilesStorageClientAdapterService } from '@modules/files-storage-client';
import { DrawingElementAdapterService } from '@modules/tldraw-client/service/drawing-element-adapter.service';
import { ContextExternalToolService } from '@modules/tool/context-external-tool/service';
import { NotFoundException } from '@nestjs/common';
import { Test, TestingModule } from '@nestjs/testing';
import { AnyBoardDo, BoardExternalReferenceType, Card, Column, ColumnBoard } from '@shared/domain/domainobject';
import { CardNode, RichTextElementNode } from '@shared/domain/entity';
import { CardNode, ColumnBoardNode, ExternalToolElementNodeEntity, RichTextElementNode } from '@shared/domain/entity';
import { EntityId } from '@shared/domain/types';
import {
cardFactory,
cardNodeFactory,
Expand All @@ -16,12 +18,16 @@ import {
columnBoardNodeFactory,
columnFactory,
columnNodeFactory,
contextExternalToolEntityFactory,
contextExternalToolFactory,
courseFactory,
externalToolElementNodeFactory,
fileElementFactory,
richTextElementFactory,
richTextElementNodeFactory,
} from '@shared/testing';
import { DrawingElementAdapterService } from '@modules/tldraw-client/service/drawing-element-adapter.service';
import { ContextExternalToolEntity } from '../../tool';
import { ContextExternalTool } from '../../tool/context-external-tool/domain';
import { BoardDoRepo } from './board-do.repo';
import { BoardNodeRepo } from './board-node.repo';
import { RecursiveDeleteVisitor } from './recursive-delete.vistor';
Expand Down Expand Up @@ -267,6 +273,62 @@ describe(BoardDoRepo.name, () => {
});
});

describe('countBoardUsageForExternalTools', () => {
describe('when counting the amount of boards used by the selected tools', () => {
const setup = async () => {
const contextExternalToolId: EntityId = new ObjectId().toHexString();
const contextExternalTool: ContextExternalTool = contextExternalToolFactory.buildWithId(
undefined,
contextExternalToolId
);
const contextExternalToolEntity: ContextExternalToolEntity = contextExternalToolEntityFactory.buildWithId(
undefined,
contextExternalToolId
);
const otherContextExternalToolEntity: ContextExternalToolEntity =
contextExternalToolEntityFactory.buildWithId();

const board: ColumnBoardNode = columnBoardNodeFactory.buildWithId();
const otherBoard: ColumnBoardNode = columnBoardNodeFactory.buildWithId();
const card: CardNode = cardNodeFactory.buildWithId({ parent: board });
const otherCard: CardNode = cardNodeFactory.buildWithId({ parent: otherBoard });
const externalToolElements: ExternalToolElementNodeEntity[] = externalToolElementNodeFactory.buildListWithId(
2,
{
parent: card,
contextExternalTool: contextExternalToolEntity,
}
);
const otherExternalToolElement: ExternalToolElementNodeEntity = externalToolElementNodeFactory.buildWithId({
parent: otherCard,
contextExternalTool: otherContextExternalToolEntity,
});

await em.persistAndFlush([
board,
otherBoard,
card,
otherCard,
...externalToolElements,
otherExternalToolElement,
contextExternalToolEntity,
]);

return {
contextExternalTool,
};
};

it('should return the amount of boards used by the selected tools', async () => {
const { contextExternalTool } = await setup();

const result: number = await repo.countBoardUsageForExternalTools([contextExternalTool]);

expect(result).toEqual(1);
});
});
});

describe('getAncestorIds', () => {
describe('when having only a root boardnode', () => {
const setup = async () => {
Expand Down
18 changes: 17 additions & 1 deletion apps/server/src/modules/board/repo/board-do.repo.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { Utils } from '@mikro-orm/core';
import { EntityManager, ObjectId } from '@mikro-orm/mongodb';
import type { ContextExternalTool } from '@modules/tool/context-external-tool/domain';
import { Injectable, NotFoundException } from '@nestjs/common';
import { AnyBoardDo, BoardExternalReference } from '@shared/domain/domainobject';
import { BoardNode, ColumnBoardNode } from '@shared/domain/entity';
import { BoardNode, ColumnBoardNode, ExternalToolElementNodeEntity } from '@shared/domain/entity';
import { EntityId } from '@shared/domain/types';
import { BoardDoBuilderImpl } from './board-do.builder-impl';
import { BoardNodeRepo } from './board-node.repo';
Expand Down Expand Up @@ -81,6 +82,21 @@ export class BoardDoRepo {
return domainObject;
}

async countBoardUsageForExternalTools(contextExternalTools: ContextExternalTool[]) {
const toolIds: EntityId[] = contextExternalTools
.map((tool: ContextExternalTool): EntityId | undefined => tool.id)
.filter((id: EntityId | undefined): id is EntityId => !!id);

const boardNodes: ExternalToolElementNodeEntity[] = await this.em.find(ExternalToolElementNodeEntity, {
contextExternalTool: { $in: toolIds },
});

const boardIds: EntityId[] = boardNodes.map((node: ExternalToolElementNodeEntity): EntityId => node.ancestorIds[0]);
const boardCount: number = new Set(boardIds).size;

return boardCount;
}

async getAncestorIds(boardDo: AnyBoardDo): Promise<EntityId[]> {
const boardNode = await this.boardNodeRepo.findById(boardDo.id);
return boardNode.ancestorIds;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { createMock, DeepMocked } from '@golevelup/ts-jest';
import { ContextExternalTool } from '@modules/tool/context-external-tool/domain';
import { BadRequestException, NotFoundException } from '@nestjs/common';
import { Test, TestingModule } from '@nestjs/testing';
import {
Expand All @@ -9,14 +10,16 @@ import {
SubmissionContainerElement,
} from '@shared/domain/domainobject';
import { InputFormat } from '@shared/domain/types';
import { drawingElementFactory, setupEntities } from '@shared/testing';
import {
cardFactory,
contextExternalToolFactory,
drawingElementFactory,
fileElementFactory,
linkElementFactory,
richTextElementFactory,
setupEntities,
submissionContainerElementFactory,
} from '@shared/testing/factory/domainobject';
} from '@shared/testing';
import {
DrawingContentBody,
FileContentBody,
Expand Down Expand Up @@ -118,7 +121,7 @@ describe(ContentElementService.name, () => {
});

describe('findParentOfId', () => {
describe('when parent is a vaid node', () => {
describe('when parent is a valid node', () => {
const setup = () => {
const card = cardFactory.build();
const element = richTextElementFactory.build();
Expand Down Expand Up @@ -154,6 +157,36 @@ describe(ContentElementService.name, () => {
});
});

describe('countBoardUsageForExternalTools', () => {
describe('when counting the amount of boards used by tools', () => {
const setup = () => {
const contextExternalTools: ContextExternalTool[] = contextExternalToolFactory.buildListWithId(3);

boardDoRepo.countBoardUsageForExternalTools.mockResolvedValueOnce(3);

return {
contextExternalTools,
};
};

it('should count the usages', async () => {
const { contextExternalTools } = setup();

await service.countBoardUsageForExternalTools(contextExternalTools);

expect(boardDoRepo.countBoardUsageForExternalTools).toHaveBeenCalledWith(contextExternalTools);
});

it('should return the amount of boards', async () => {
const { contextExternalTools } = setup();

const result: number = await service.countBoardUsageForExternalTools(contextExternalTools);

expect(result).toEqual(3);
});
});
});

describe('create', () => {
describe('when creating a content element of type', () => {
const setup = () => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import type { ContextExternalTool } from '@modules/tool/context-external-tool/domain';
import { Injectable, NotFoundException } from '@nestjs/common';
import {
AnyBoardDo,
Expand Down Expand Up @@ -40,10 +41,18 @@ export class ContentElementService {
return parent;
}

async countBoardUsageForExternalTools(contextExternalTools: ContextExternalTool[]): Promise<number> {
const count: number = await this.boardDoRepo.countBoardUsageForExternalTools(contextExternalTools);

return count;
}

async create(parent: Card | SubmissionItem, type: ContentElementType): Promise<AnyContentElementDo> {
const element = this.contentElementFactory.build(type);
parent.addChild(element);

await this.boardDoRepo.save(parent.children, parent);

return element;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { DomainModel } from '@shared/domain/types';
import { DeletionLogStatisticBuilder, DeletionRequestLogResponseBuilder, DeletionTargetRefBuilder } from '.';
import { DeletionStatusModel } from '../domain/types';

describe(DeletionRequestLogResponseBuilder, () => {
afterAll(() => {
Expand All @@ -12,15 +13,17 @@ describe(DeletionRequestLogResponseBuilder, () => {
const targetRefId = '653e4833cc39e5907a1e18d2';
const targetRef = DeletionTargetRefBuilder.build(targetRefDomain, targetRefId);
const deletionPlannedAt = new Date();
const status = DeletionStatusModel.SUCCESS;
const modifiedCount = 0;
const deletedCount = 2;
const statistics = [DeletionLogStatisticBuilder.build(targetRefDomain, modifiedCount, deletedCount)];

const result = DeletionRequestLogResponseBuilder.build(targetRef, deletionPlannedAt, statistics);
const result = DeletionRequestLogResponseBuilder.build(targetRef, deletionPlannedAt, status, statistics);

// Assert
expect(result.targetRef).toEqual(targetRef);
expect(result.deletionPlannedAt).toEqual(deletionPlannedAt);
expect(result.status).toEqual(status);
expect(result.statistics).toEqual(statistics);
});
});
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
import { DomainOperation } from '@shared/domain/interface';
import { DeletionRequestLogResponse } from '../controller/dto';
import { DeletionStatusModel } from '../domain/types';
import { DeletionTargetRef } from '../interface';

export class DeletionRequestLogResponseBuilder {
static build(
targetRef: DeletionTargetRef,
deletionPlannedAt: Date,
status: DeletionStatusModel,
statistics?: DomainOperation[]
): DeletionRequestLogResponse {
const deletionRequestLog = { targetRef, deletionPlannedAt, statistics };
const deletionRequestLog = { targetRef, deletionPlannedAt, status, statistics };

return deletionRequestLog;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { ObjectId } from 'bson';
import { DomainModel } from '@shared/domain/types';
import { DeletionLogStatisticBuilder, DeletionTargetRefBuilder } from '../../builder';
import { DeletionRequestLogResponse } from './index';
import { DeletionStatusModel } from '../../domain/types';

describe(DeletionRequestLogResponse.name, () => {
describe('constructor', () => {
Expand All @@ -10,21 +11,23 @@ describe(DeletionRequestLogResponse.name, () => {
const targetRefDomain = DomainModel.PSEUDONYMS;
const targetRefId = new ObjectId().toHexString();
const targetRef = DeletionTargetRefBuilder.build(targetRefDomain, targetRefId);
const status = DeletionStatusModel.SUCCESS;
const deletionPlannedAt = new Date();
const modifiedCount = 0;
const deletedCount = 2;
const statistics = [DeletionLogStatisticBuilder.build(targetRefDomain, modifiedCount, deletedCount)];

return { targetRef, deletionPlannedAt, statistics };
return { targetRef, deletionPlannedAt, status, statistics };
};

it('should set the id', () => {
const { targetRef, deletionPlannedAt, statistics } = setup();
const { targetRef, deletionPlannedAt, status, statistics } = setup();

const deletionRequestLog = new DeletionRequestLogResponse({ targetRef, deletionPlannedAt, statistics });
const deletionRequestLog = new DeletionRequestLogResponse({ targetRef, deletionPlannedAt, status, statistics });

expect(deletionRequestLog.targetRef).toEqual(targetRef);
expect(deletionRequestLog.deletionPlannedAt).toEqual(deletionPlannedAt);
expect(deletionRequestLog.status).toEqual(status);
expect(deletionRequestLog.statistics).toEqual(statistics);
});
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { ApiProperty } from '@nestjs/swagger';
import { IsOptional } from 'class-validator';
import { DomainOperation } from '@shared/domain/interface';
import { DeletionTargetRef } from '../../interface';
import { DeletionStatusModel } from '../../domain/types';

export class DeletionRequestLogResponse {
@ApiProperty()
Expand All @@ -10,13 +11,17 @@ export class DeletionRequestLogResponse {
@ApiProperty()
deletionPlannedAt: Date;

@ApiProperty()
status: DeletionStatusModel;

@ApiProperty()
@IsOptional()
statistics?: DomainOperation[];

constructor(response: DeletionRequestLogResponse) {
this.targetRef = response.targetRef;
this.deletionPlannedAt = response.deletionPlannedAt;
this.status = response.status;
this.statistics = response.statistics;
}
}
Loading

0 comments on commit dd2e239

Please sign in to comment.