From f6470d7941e9d7067bc4100a52ab2c0555c4f225 Mon Sep 17 00:00:00 2001 From: WojciechGrancow Date: Tue, 30 Jan 2024 23:16:35 +0100 Subject: [PATCH] add new logging funct. to news module --- .../deletion/uc/deletion-request.uc.spec.ts | 17 ++++++++ .../deletion/uc/deletion-request.uc.ts | 9 +++- .../modules/news/service/news.service.spec.ts | 42 ++++++++++++++++--- .../src/modules/news/service/news.service.ts | 37 +++++++++------- 4 files changed, 84 insertions(+), 21 deletions(-) diff --git a/apps/server/src/modules/deletion/uc/deletion-request.uc.spec.ts b/apps/server/src/modules/deletion/uc/deletion-request.uc.spec.ts index 040496bf430..f82364a4e83 100644 --- a/apps/server/src/modules/deletion/uc/deletion-request.uc.spec.ts +++ b/apps/server/src/modules/deletion/uc/deletion-request.uc.spec.ts @@ -48,6 +48,7 @@ describe(DeletionRequestUc.name, () => { let filesStorageClientAdapterService: DeepMocked; let dashboardService: DeepMocked; let taskService: DeepMocked; + let newsService: DeepMocked; beforeAll(async () => { module = await Test.createTestingModule({ @@ -147,6 +148,7 @@ describe(DeletionRequestUc.name, () => { filesStorageClientAdapterService = module.get(FilesStorageClientAdapterService); dashboardService = module.get(DashboardService); taskService = module.get(TaskService); + newsService = module.get(NewsService); await setupEntities(); }); @@ -243,6 +245,10 @@ describe(DeletionRequestUc.name, () => { new ObjectId().toHexString(), ]); + const newsUpdated = DomainOperationBuilder.build(DomainName.LESSONS, OperationType.UPDATE, 1, [ + new ObjectId().toHexString(), + ]); + const parentEmail = 'parent@parent.eu'; const pseudonymsDeleted = DomainOperationBuilder.build(DomainName.PSEUDONYMS, OperationType.DELETE, 1, [ @@ -309,6 +315,7 @@ describe(DeletionRequestUc.name, () => { taskService.removeCreatorIdFromTasks.mockResolvedValueOnce(tasksModifiedByRemoveCreatorId); taskService.removeUserFromFinished.mockResolvedValueOnce(tasksModifiedByRemoveUserFromFinished); taskService.deleteTasksByOnlyCreator.mockResolvedValueOnce(tasksDeleted); + newsService.deleteCreatorOrUpdaterReference.mockResolvedValueOnce(newsUpdated); return { deletionRequestToExecute, @@ -536,6 +543,16 @@ describe(DeletionRequestUc.name, () => { expect(taskService.removeUserFromFinished).toHaveBeenCalledWith(deletionRequestToExecute.targetRefId); }); + it('should call newsService.deleteCreatorOrUpdaterReference to update News without creatorId', async () => { + const { deletionRequestToExecute } = setup(); + + deletionRequestService.findAllItemsToExecute.mockResolvedValueOnce([deletionRequestToExecute]); + + await uc.executeDeletionRequests(); + + expect(newsService.deleteCreatorOrUpdaterReference).toHaveBeenCalledWith(deletionRequestToExecute.targetRefId); + }); + it('should call deletionLogService.createDeletionLog to create logs for deletionRequest', async () => { const { deletionRequestToExecute } = setup(); diff --git a/apps/server/src/modules/deletion/uc/deletion-request.uc.ts b/apps/server/src/modules/deletion/uc/deletion-request.uc.ts index d21436809c8..a7a1620d4e2 100644 --- a/apps/server/src/modules/deletion/uc/deletion-request.uc.ts +++ b/apps/server/src/modules/deletion/uc/deletion-request.uc.ts @@ -375,8 +375,15 @@ export class DeletionRequestUc { } private async removeUsersDataFromNews(deletionRequest: DeletionRequest) { + this.logger.debug({ action: 'removeUsersDataFromNews', deletionRequest }); const newsesModified = await this.newsService.deleteCreatorOrUpdaterReference(deletionRequest.targetRefId); - await this.logDeletion(deletionRequest, DomainModel.NEWS, DeletionOperationModel.UPDATE, newsesModified, 0); + await this.logDeletion( + deletionRequest, + newsesModified.domain, + newsesModified.operation, + newsesModified.count, + newsesModified.refs + ); } } diff --git a/apps/server/src/modules/news/service/news.service.spec.ts b/apps/server/src/modules/news/service/news.service.spec.ts index 860028baa9b..53ff087e537 100644 --- a/apps/server/src/modules/news/service/news.service.spec.ts +++ b/apps/server/src/modules/news/service/news.service.spec.ts @@ -4,6 +4,8 @@ import { createMock, DeepMocked } from '@golevelup/ts-jest'; import { setupEntities, teamNewsFactory, userFactory } from '@shared/testing'; import { Logger } from '@src/core/logger'; import { NewsRepo } from '@shared/repo'; +import { DomainOperationBuilder } from '@shared/domain/builder'; +import { DomainName, OperationType } from '@shared/domain/types'; import { NewsService } from './news.service'; describe(NewsService.name, () => { @@ -45,6 +47,7 @@ describe(NewsService.name, () => { const setup = () => { const user = userFactory.build(); const user2 = userFactory.build(); + const anotherUserId = new ObjectId().toHexString(); const news1 = teamNewsFactory.build({ creator: user, @@ -59,24 +62,51 @@ describe(NewsService.name, () => { updater: user, }); - return { user, news1, news2, news3 }; + const expectedResultWithUpdatedNews = DomainOperationBuilder.build(DomainName.NEWS, OperationType.UPDATE, 3, [ + news1.id, + news2.id, + news3.id, + ]); + + const expectedResultWithoutUpdatedNews = DomainOperationBuilder.build( + DomainName.NEWS, + OperationType.UPDATE, + 0, + [] + ); + + return { + anotherUserId, + expectedResultWithUpdatedNews, + expectedResultWithoutUpdatedNews, + user, + news1, + news2, + news3, + }; }; it('should successfully delete creator or updater reference from news', async () => { - const { user, news1, news2, news3 } = setup(); + const { expectedResultWithUpdatedNews, user, news1, news2, news3 } = setup(); + repo.findByCreatorOrUpdaterId.mockResolvedValueOnce([[news1, news2, news3], 3]); + const result = await service.deleteCreatorOrUpdaterReference(user.id); + expect(news1.creator).toBeUndefined(); expect(news1.updater).toBeUndefined(); expect(news2.creator).toBeUndefined(); expect(news3.updater).toBeUndefined(); - expect(result).toBe(3); + expect(result).toEqual(expectedResultWithUpdatedNews); }); it('should return 0 if news not found', async () => { - const anotherUser = new ObjectId().toHexString(); + const { anotherUserId, expectedResultWithoutUpdatedNews } = setup(); + repo.findByCreatorOrUpdaterId.mockResolvedValueOnce([[], 0]); - const result = await service.deleteCreatorOrUpdaterReference(anotherUser); - expect(result).toBe(0); + + const result = await service.deleteCreatorOrUpdaterReference(anotherUserId); + + expect(result).toEqual(expectedResultWithoutUpdatedNews); }); }); }); diff --git a/apps/server/src/modules/news/service/news.service.ts b/apps/server/src/modules/news/service/news.service.ts index 012ca495a13..5a2482886d5 100644 --- a/apps/server/src/modules/news/service/news.service.ts +++ b/apps/server/src/modules/news/service/news.service.ts @@ -1,8 +1,11 @@ import { Injectable } from '@nestjs/common'; -import { DomainModel, EntityId, StatusModel } from '@shared/domain/types'; +import { DomainName, EntityId, OperationType, StatusModel } from '@shared/domain/types'; import { Logger } from '@src/core/logger'; import { DataDeletionDomainOperationLoggable } from '@shared/common/loggable'; import { NewsRepo } from '@shared/repo'; +import { DomainOperationBuilder } from '@shared/domain/builder'; +import { DomainOperation } from '@shared/domain/interface'; +import { News } from '@shared/domain/entity'; @Injectable() export class NewsService { @@ -10,40 +13,46 @@ export class NewsService { this.logger.setContext(NewsService.name); } - public async deleteCreatorOrUpdaterReference(userId: EntityId): Promise { + public async deleteCreatorOrUpdaterReference(userId: EntityId): Promise { this.logger.info( new DataDeletionDomainOperationLoggable( 'Deleting user data from News', - DomainModel.NEWS, + DomainName.NEWS, userId, StatusModel.PENDING ) ); - const news = await this.newsRepo.findByCreatorOrUpdaterId(userId); + const [newsWithUserData, counterOfNews] = await this.newsRepo.findByCreatorOrUpdaterId(userId); - const newsCount = news[1]; - if (newsCount === 0) { - return 0; - } - - news[0].forEach((newsEntity) => { + newsWithUserData.forEach((newsEntity) => { newsEntity.removeCreatorReference(userId); newsEntity.removeUpdaterReference(userId); }); - await this.newsRepo.save(news[0]); + await this.newsRepo.save(newsWithUserData); + + const result = DomainOperationBuilder.build( + DomainName.NEWS, + OperationType.UPDATE, + counterOfNews, + this.getNewsId(newsWithUserData) + ); this.logger.info( new DataDeletionDomainOperationLoggable( 'Successfully removed user data from News', - DomainModel.NEWS, + DomainName.NEWS, userId, StatusModel.FINISHED, - newsCount, + counterOfNews, 0 ) ); - return newsCount; + return result; + } + + private getNewsId(news: News[]): EntityId[] { + return news.map((item) => item.id); } }