From 01de1edf74b572efab61bf46c29f5b510a94319e Mon Sep 17 00:00:00 2001 From: StuartFerguson Date: Tue, 19 Aug 2025 23:03:58 +0100 Subject: [PATCH] Enhance estate management with error handling and tests - Updated `EstateDomainServiceTests.cs` to set up `AggregateService` for successful retrieval of `OperatorAggregate` and `EstateAggregate`. - Added `CreateEstate` method in `EstateDomainService.cs` for creating estates with error handling. - Removed `ApplyUpdates` method; integrated its functionality into `AddOperatorToEstate`. - Modified `CreateEstateUser` to include error handling and user addition to the estate aggregate. - Updated `RemoveOperatorFromEstate` to handle errors and ensure proper operator removal from estates. --- .../Services/EstateDomainServiceTests.cs | 3 + .../Services/EstateDomainService.cs | 158 +++++++++++------- 2 files changed, 99 insertions(+), 62 deletions(-) diff --git a/TransactionProcessor.BusinessLogic.Tests/Services/EstateDomainServiceTests.cs b/TransactionProcessor.BusinessLogic.Tests/Services/EstateDomainServiceTests.cs index 6e3386f..a0d5fb2 100644 --- a/TransactionProcessor.BusinessLogic.Tests/Services/EstateDomainServiceTests.cs +++ b/TransactionProcessor.BusinessLogic.Tests/Services/EstateDomainServiceTests.cs @@ -45,6 +45,9 @@ public async Task EstateDomainService_CreateEstate_EstateIsCreated() { [Fact] public async Task EstateDomainService_AddOperatorEstate_OperatorIsAdded() { + this.AggregateService.Setup(m => m.Get(It.IsAny(), It.IsAny())) + .ReturnsAsync(SimpleResults.Result.Success(TestData.Aggregates.CreatedOperatorAggregate())); + this.AggregateService.Setup(m => m.GetLatest(It.IsAny(), It.IsAny())) .ReturnsAsync(SimpleResults.Result.Success(TestData.Aggregates.CreatedEstateAggregate())); this.AggregateService.Setup(m => m.Save(It.IsAny(), It.IsAny())).ReturnsAsync(SimpleResults.Result.Success()); diff --git a/TransactionProcessor.BusinessLogic/Services/EstateDomainService.cs b/TransactionProcessor.BusinessLogic/Services/EstateDomainService.cs index 717689e..4ec0bca 100644 --- a/TransactionProcessor.BusinessLogic/Services/EstateDomainService.cs +++ b/TransactionProcessor.BusinessLogic/Services/EstateDomainService.cs @@ -52,20 +52,18 @@ public EstateDomainService(Func aggregateService, #endregion #region Methods + + public async Task CreateEstate(EstateCommands.CreateEstateCommand command, + CancellationToken cancellationToken) { + try { + Result estateResult = await DomainServiceHelper.GetAggregateOrFailure(ct => this.AggregateService.GetLatest(command.RequestDto.EstateId, ct), command.RequestDto.EstateId, cancellationToken, false); + if (estateResult.IsFailed) + return ResultHelpers.CreateFailure(estateResult); - private async Task ApplyUpdates(Action action, Guid estateId, CancellationToken cancellationToken, Boolean isNotFoundError = true) - { - try - { - Result getLatestVersionResult = await this.AggregateService.GetLatest(estateId, cancellationToken); - Result estateAggregateResult = - DomainServiceHelper.HandleGetAggregateResult(getLatestVersionResult, estateId, isNotFoundError); - if (estateAggregateResult.IsFailed) - return ResultHelpers.CreateFailure(estateAggregateResult); - - EstateAggregate estateAggregate = estateAggregateResult.Data; + EstateAggregate estateAggregate = estateResult.Data; - action(estateAggregate); + estateAggregate.Create(command.RequestDto.EstateName); + estateAggregate.GenerateReference(); Result saveResult = await this.AggregateService.Save(estateAggregate, cancellationToken); if (saveResult.IsFailed) @@ -73,78 +71,114 @@ private async Task ApplyUpdates(Action action, Guid est return Result.Success(); } - catch (Exception ex) - { + catch (Exception ex) { return Result.Failure(ex.GetExceptionMessages()); } } - - public async Task CreateEstate(EstateCommands.CreateEstateCommand command, CancellationToken cancellationToken) + public async Task AddOperatorToEstate(EstateCommands.AddOperatorToEstateCommand command, CancellationToken cancellationToken) { - Result result = await ApplyUpdates((estateAggregate) => { - estateAggregate.Create(command.RequestDto.EstateName); - estateAggregate.GenerateReference(); - }, command.RequestDto.EstateId, cancellationToken, false); + try + { + Result operatorResult = await DomainServiceHelper.GetAggregateOrFailure(ct => this.AggregateService.Get(command.RequestDto.OperatorId, ct), command.RequestDto.OperatorId, cancellationToken); + if (operatorResult.IsFailed) + return ResultHelpers.CreateFailure(operatorResult); - return result; - } + Result estateResult = await DomainServiceHelper.GetAggregateOrFailure(ct => this.AggregateService.GetLatest(command.EstateId, ct), command.EstateId, cancellationToken); + if (estateResult.IsFailed) + return ResultHelpers.CreateFailure(estateResult); + + EstateAggregate estateAggregate = estateResult.Data; - public async Task AddOperatorToEstate(EstateCommands.AddOperatorToEstateCommand command, CancellationToken cancellationToken) - { - Result result = await ApplyUpdates((estateAggregate) => { estateAggregate.AddOperator(command.RequestDto.OperatorId); - }, command.EstateId, cancellationToken); - return result; + Result saveResult = await this.AggregateService.Save(estateAggregate, cancellationToken); + if (saveResult.IsFailed) + return ResultHelpers.CreateFailure(saveResult); + + return Result.Success(); + } + catch (Exception ex) + { + return Result.Failure(ex.GetExceptionMessages()); + } } public async Task CreateEstateUser(EstateCommands.CreateEstateUserCommand command, CancellationToken cancellationToken) { - CreateUserRequest createUserRequest = new CreateUserRequest + try { - EmailAddress = command.RequestDto.EmailAddress, - FamilyName = command.RequestDto.FamilyName, - GivenName = command.RequestDto.GivenName, - MiddleName = command.RequestDto.MiddleName, - Password = command.RequestDto.Password, - PhoneNumber = "123456", // Is this really needed :| - Roles = new List(), - Claims = new Dictionary() - }; - - // Check if role has been overridden - String estateRoleName = Environment.GetEnvironmentVariable("EstateRoleName"); - createUserRequest.Roles.Add(String.IsNullOrEmpty(estateRoleName) ? "Estate" : estateRoleName); - createUserRequest.Claims.Add("estateId", command.EstateId.ToString()); - - Result createUserResult = await this.SecurityServiceClient.CreateUser(createUserRequest, cancellationToken); - if (createUserResult.IsFailed) - return ResultHelpers.CreateFailure(createUserResult); - - Result> userDetailsResult = await this.SecurityServiceClient.GetUsers(createUserRequest.EmailAddress, cancellationToken); - if (userDetailsResult.IsFailed) - return ResultHelpers.CreateFailure(userDetailsResult); - - UserDetails user = userDetailsResult.Data.SingleOrDefault(); - if (user == null) - return Result.Failure($"Unable to get user details for username {createUserRequest.EmailAddress}"); - - Result result = await ApplyUpdates((estateAggregate) => { - // Add the user to the aggregate + CreateUserRequest createUserRequest = new CreateUserRequest + { + EmailAddress = command.RequestDto.EmailAddress, + FamilyName = command.RequestDto.FamilyName, + GivenName = command.RequestDto.GivenName, + MiddleName = command.RequestDto.MiddleName, + Password = command.RequestDto.Password, + PhoneNumber = "123456", // Is this really needed :| + Roles = new List(), + Claims = new Dictionary() + }; + + // Check if role has been overridden + String estateRoleName = Environment.GetEnvironmentVariable("EstateRoleName"); + createUserRequest.Roles.Add(String.IsNullOrEmpty(estateRoleName) ? "Estate" : estateRoleName); + createUserRequest.Claims.Add("estateId", command.EstateId.ToString()); + + Result createUserResult = await this.SecurityServiceClient.CreateUser(createUserRequest, cancellationToken); + if (createUserResult.IsFailed) + return ResultHelpers.CreateFailure(createUserResult); + + Result> userDetailsResult = await this.SecurityServiceClient.GetUsers(createUserRequest.EmailAddress, cancellationToken); + if (userDetailsResult.IsFailed) + return ResultHelpers.CreateFailure(userDetailsResult); + + UserDetails user = userDetailsResult.Data.SingleOrDefault(); + if (user == null) + return Result.Failure($"Unable to get user details for username {createUserRequest.EmailAddress}"); + + Result estateResult = await DomainServiceHelper.GetAggregateOrFailure(ct => this.AggregateService.GetLatest(command.EstateId, ct), command.EstateId, cancellationToken); + if (estateResult.IsFailed) + return ResultHelpers.CreateFailure(estateResult); + + EstateAggregate estateAggregate = estateResult.Data; + estateAggregate.AddSecurityUser(user.UserId, command.RequestDto.EmailAddress); - }, command.EstateId, cancellationToken); - return result; + Result saveResult = await this.AggregateService.Save(estateAggregate, cancellationToken); + if (saveResult.IsFailed) + return ResultHelpers.CreateFailure(saveResult); + + return Result.Success(); + } + catch (Exception ex) + { + return Result.Failure(ex.GetExceptionMessages()); + } } public async Task RemoveOperatorFromEstate(EstateCommands.RemoveOperatorFromEstateCommand command, CancellationToken cancellationToken) { - Result result = await ApplyUpdates((estateAggregate) => { + try + { + Result estateResult = await DomainServiceHelper.GetAggregateOrFailure(ct => this.AggregateService.GetLatest(command.EstateId, ct), command.EstateId, cancellationToken); + if (estateResult.IsFailed) + return ResultHelpers.CreateFailure(estateResult); + + EstateAggregate estateAggregate = estateResult.Data; + estateAggregate.RemoveOperator(command.OperatorId); - }, command.EstateId, cancellationToken); - return result; + Result saveResult = await this.AggregateService.Save(estateAggregate, cancellationToken); + if (saveResult.IsFailed) + return ResultHelpers.CreateFailure(saveResult); + + return Result.Success(); + } + catch (Exception ex) + { + return Result.Failure(ex.GetExceptionMessages()); + } } #endregion