From 58f92b744e6fc41eac12a5fc9e0b736511d39f7f Mon Sep 17 00:00:00 2001 From: Marius Kaczmarek Date: Tue, 10 Dec 2024 17:51:56 +0100 Subject: [PATCH] incorporated LoadAvatarConfigUseCase into UpdateAvatarConfigUseCase --- .../IUpdateAvatarConfigUseCase.ts | 4 +-- .../UpdateAvatarConfigUseCase.ts | 21 +++++------- .../UseCases/USECASE_TYPES.ts | 2 +- .../UseCases/UseCaseDIConatiner.ts | 2 +- .../AvatarEditor/AvatarEditorController.ts | 9 ++--- .../UpdateAvatarConfigUseCase.test.ts | 34 ++++++++++++------- 6 files changed, 37 insertions(+), 35 deletions(-) diff --git a/src/Components/Core/Application/UseCases/UpdateAvatarConfig/IUpdateAvatarConfigUseCase.ts b/src/Components/Core/Application/UseCases/UpdateAvatarConfig/IUpdateAvatarConfigUseCase.ts index 2e26efe3..0c10b32e 100644 --- a/src/Components/Core/Application/UseCases/UpdateAvatarConfig/IUpdateAvatarConfigUseCase.ts +++ b/src/Components/Core/Application/UseCases/UpdateAvatarConfig/IUpdateAvatarConfigUseCase.ts @@ -1,5 +1,5 @@ -import { ISynchronousUsecase } from "../../Abstract/ISynchronousUsecase"; +import { IAsyncUsecase } from "../../Abstract/IAsyncUsecase"; import AvatarConfigTO from "../../DataTransferObjects/AvatarConfigTO"; export default interface IUpdateAvatarConfigUseCase - extends ISynchronousUsecase, void> {} + extends IAsyncUsecase, void> {} diff --git a/src/Components/Core/Application/UseCases/UpdateAvatarConfig/UpdateAvatarConfigUseCase.ts b/src/Components/Core/Application/UseCases/UpdateAvatarConfig/UpdateAvatarConfigUseCase.ts index f77d8bee..54b34adc 100644 --- a/src/Components/Core/Application/UseCases/UpdateAvatarConfig/UpdateAvatarConfigUseCase.ts +++ b/src/Components/Core/Application/UseCases/UpdateAvatarConfig/UpdateAvatarConfigUseCase.ts @@ -5,10 +5,11 @@ import type IEntityContainer from "../../../Domain/EntityContainer/IEntityContai import AvatarConfigTO from "../../DataTransferObjects/AvatarConfigTO"; import PORT_TYPES from "~DependencyInjection/Ports/PORT_TYPES"; import type IAvatarPort from "../../Ports/Interfaces/IAvatarPort"; -import AvatarEntity from "src/Components/Core/Domain/Entities/AvatarEntity"; import UserDataEntity from "src/Components/Core/Domain/Entities/UserDataEntity"; import type ILoggerPort from "../../Ports/Interfaces/ILoggerPort"; import { LogLevelTypes } from "src/Components/Core/Domain/Types/LogLevelTypes"; +import USECASE_TYPES from "~DependencyInjection/UseCases/USECASE_TYPES"; +import type ILoadAvatarConfigUseCase from "../LoadAvatarConfig/ILoadAvatarConfigUseCase"; @injectable() export default class UpdateAvatarConfigUseCase @@ -21,9 +22,11 @@ export default class UpdateAvatarConfigUseCase private avatarPort: IAvatarPort, @inject(CORE_TYPES.ILogger) private logger: ILoggerPort, + @inject(USECASE_TYPES.ILoadAvatarConfigUseCase) + private loadAvatarUseCase: ILoadAvatarConfigUseCase, ) {} - execute(newAvatarConfig: Partial): void { + async executeAsync(newAvatarConfig: Partial): Promise { let userDataEntities = this.entityContainer.getEntitiesOfType(UserDataEntity); if (userDataEntities.length === 0) { @@ -34,17 +37,9 @@ export default class UpdateAvatarConfigUseCase return; } - // TODO: this is a workaround when no config is available, remove when loading initial avatar config is implemented - if (!userDataEntities[0].avatar) { - userDataEntities[0].avatar = Object.assign( - new AvatarEntity(), - newAvatarConfig, - ); - this.avatarPort.onAvatarConfigChanged( - Object.assign({}, userDataEntities[0].avatar), // clone to prevent changes to propagate - newAvatarConfig, - ); - } + // load avatar config if not already loaded + if (!userDataEntities[0].avatar) + await this.loadAvatarUseCase.executeAsync(); // compute difference between new and current avatar config let difference: any = {}; // actually Partial, but TS doesn't like that diff --git a/src/Components/Core/DependencyInjection/UseCases/USECASE_TYPES.ts b/src/Components/Core/DependencyInjection/UseCases/USECASE_TYPES.ts index 12fe5bb0..ffbe48a2 100644 --- a/src/Components/Core/DependencyInjection/UseCases/USECASE_TYPES.ts +++ b/src/Components/Core/DependencyInjection/UseCases/USECASE_TYPES.ts @@ -9,7 +9,7 @@ const USECASE_TYPES = { "ISetWorldCompletionModalToShownUseCase", ), ILoadLearningWorldUseCase: Symbol("ILoadLearningWorldUseCase"), - ILoadAvatarUseCase: Symbol("ILoadAvatarUseCase"), + ILoadAvatarConfigUseCase: Symbol("ILoadAvatarConfigUseCase"), ILoadLearningElementUseCase: Symbol("ILoadLearningElementUseCase"), IScoreLearningElementUseCase: Symbol("IScoreLearningElementUseCase"), ICalculateLearningSpaceScoreUseCase: Symbol( diff --git a/src/Components/Core/DependencyInjection/UseCases/UseCaseDIConatiner.ts b/src/Components/Core/DependencyInjection/UseCases/UseCaseDIConatiner.ts index d0d49c2c..9fbc2eba 100644 --- a/src/Components/Core/DependencyInjection/UseCases/UseCaseDIConatiner.ts +++ b/src/Components/Core/DependencyInjection/UseCases/UseCaseDIConatiner.ts @@ -94,7 +94,7 @@ const UseCaseDIContainer = new ContainerModule((bind) => { .to(SetWorldCompletionModalToShownUseCase) .inSingletonScope(); - bind(USECASE_TYPES.ILoadAvatarUseCase) + bind(USECASE_TYPES.ILoadAvatarConfigUseCase) .to(LoadAvatarConfigUseCase) .inSingletonScope(); diff --git a/src/Components/Core/Presentation/AvatarEditor/AvatarEditorController.ts b/src/Components/Core/Presentation/AvatarEditor/AvatarEditorController.ts index 73a49b7c..6f7f91dc 100644 --- a/src/Components/Core/Presentation/AvatarEditor/AvatarEditorController.ts +++ b/src/Components/Core/Presentation/AvatarEditor/AvatarEditorController.ts @@ -6,11 +6,8 @@ import USECASE_TYPES from "~DependencyInjection/UseCases/USECASE_TYPES"; export default class AvatarEditorController implements IAvatarEditorController { onAvatarConfigChanged(changes: Partial): void { - const updateAvatarConfigUseCase = - CoreDIContainer.get( - USECASE_TYPES.IUpdateAvatarConfigUseCase, - ); - - updateAvatarConfigUseCase.execute(changes); + CoreDIContainer.get( + USECASE_TYPES.IUpdateAvatarConfigUseCase, + ).executeAsync(changes); } } diff --git a/src/Components/CoreTest/Application/UseCases/UpdateAvatarConfig/UpdateAvatarConfigUseCase.test.ts b/src/Components/CoreTest/Application/UseCases/UpdateAvatarConfig/UpdateAvatarConfigUseCase.test.ts index 42503299..9a9a9996 100644 --- a/src/Components/CoreTest/Application/UseCases/UpdateAvatarConfig/UpdateAvatarConfigUseCase.test.ts +++ b/src/Components/CoreTest/Application/UseCases/UpdateAvatarConfig/UpdateAvatarConfigUseCase.test.ts @@ -39,10 +39,10 @@ describe("UpdateAvatarConfigUseCase", () => { CoreDIContainer.restore(); }); - test("logs error if no user data entity found", () => { + test("logs error if no user data entity found", async () => { entityContainerMock.getEntitiesOfType.mockReturnValue([]); - systemUnderTest.execute({}); + await systemUnderTest.executeAsync({}); expect(loggerMock.log).toHaveBeenCalledWith( LogLevelTypes.ERROR, @@ -50,10 +50,10 @@ describe("UpdateAvatarConfigUseCase", () => { ); }); - test("logs error if multiple user data entities found", () => { + test("logs error if multiple user data entities found", async () => { entityContainerMock.getEntitiesOfType.mockReturnValue([{}, {}]); - systemUnderTest.execute({}); + await systemUnderTest.executeAsync({}); expect(loggerMock.log).toHaveBeenCalledWith( LogLevelTypes.ERROR, @@ -61,7 +61,17 @@ describe("UpdateAvatarConfigUseCase", () => { ); }); - test("updates avatar config in user data entity", () => { + test("calls loadAvatarConfigUseCase if avatar config not loaded", async () => { + const userDataEntity = {}; + + entityContainerMock.getEntitiesOfType.mockReturnValue([userDataEntity]); + + await systemUnderTest.executeAsync({}); + + expect(avatarPortMock.onAvatarConfigLoaded).toHaveBeenCalledTimes(1); + }); + + test("updates avatar config in user data entity", async () => { const avatarConfig: Partial = { roundness: 0.5, }; @@ -74,7 +84,7 @@ describe("UpdateAvatarConfigUseCase", () => { entityContainerMock.getEntitiesOfType.mockReturnValue([userDataEntity]); - systemUnderTest.execute(avatarConfig); + await systemUnderTest.executeAsync(avatarConfig); expect(userDataEntity.avatar.roundness).toEqual(0.5); expect(userDataEntity.avatar.hair).toEqual( @@ -82,7 +92,7 @@ describe("UpdateAvatarConfigUseCase", () => { ); }); - test("calls onAvatarConfigChanged on avatar port", () => { + test("calls onAvatarConfigChanged on avatar port", async () => { const avatarConfig: Partial = { roundness: 0.5, }; @@ -95,7 +105,7 @@ describe("UpdateAvatarConfigUseCase", () => { entityContainerMock.getEntitiesOfType.mockReturnValue([userDataEntity]); - systemUnderTest.execute(avatarConfig); + await systemUnderTest.executeAsync(avatarConfig); expect(avatarPortMock.onAvatarConfigChanged).toHaveBeenCalledWith( userDataEntity.avatar, @@ -103,7 +113,7 @@ describe("UpdateAvatarConfigUseCase", () => { ); }); - test("doesn't call onAvatarConfigChanged when change is already present in current config", () => { + test("doesn't call onAvatarConfigChanged when change is already present in current config", async () => { const avatarConfig: Partial = { roundness: 0.5, }; @@ -116,12 +126,12 @@ describe("UpdateAvatarConfigUseCase", () => { entityContainerMock.getEntitiesOfType.mockReturnValue([userDataEntity]); - systemUnderTest.execute(avatarConfig); + await systemUnderTest.executeAsync(avatarConfig); expect(avatarPortMock.onAvatarConfigChanged).not.toHaveBeenCalled(); }); - test("diff and new avatar config passed to onAvatarConfigChanged do match", () => { + test("diff and new avatar config passed to onAvatarConfigChanged do match", async () => { const avatarConfig: Partial = { roundness: 0.5, }; @@ -129,7 +139,7 @@ describe("UpdateAvatarConfigUseCase", () => { entityContainerMock.getEntitiesOfType.mockReturnValue([userDataEntity]); - systemUnderTest.execute(avatarConfig); + await systemUnderTest.executeAsync(avatarConfig); expect( avatarPortMock.onAvatarConfigChanged.mock.lastCall![0],