diff --git a/GitFyle.Core.Api.Tests.Unit/Services/Foundations/Repositories/RepositoryServiceTests.Exceptions.Add.cs b/GitFyle.Core.Api.Tests.Unit/Services/Foundations/Repositories/RepositoryServiceTests.Exceptions.Add.cs index 8bbddf81..fa645600 100644 --- a/GitFyle.Core.Api.Tests.Unit/Services/Foundations/Repositories/RepositoryServiceTests.Exceptions.Add.cs +++ b/GitFyle.Core.Api.Tests.Unit/Services/Foundations/Repositories/RepositoryServiceTests.Exceptions.Add.cs @@ -177,6 +177,62 @@ await Assert.ThrowsAsync( this.storageBrokerMock.VerifyNoOtherCalls(); } + [Fact] + public async Task ShouldThrowDependencyValidationExceptionOnAddIfForeignKeyExceptionOccursAndLogItAsync() + { + // given + Repository someRepository = CreateRandomRepository(); + string someMessage = GetRandomString(); + + var foreignKeyConstraintConflictException = + new ForeignKeyConstraintConflictException(someMessage); + + var invalidRepositoryReferenceException = + new InvalidRepositoryReferenceException( + message: "Invalid repository reference error occurred.", + innerException: foreignKeyConstraintConflictException, + data: foreignKeyConstraintConflictException.Data); + + var expectedRepositoryDependencyValidationException = + new RepositoryDependencyValidationException( + message: "Repository validation error occurred, fix errors and try again.", + innerException: invalidRepositoryReferenceException, + data: invalidRepositoryReferenceException.Data); + + this.dateTimeBrokerMock.Setup(broker => + broker.GetCurrentDateTimeOffsetAsync()) + .ThrowsAsync(foreignKeyConstraintConflictException); + + // when + ValueTask addRepositoryTask = + this.repositoryService.AddRepositoryAsync(someRepository); + + RepositoryDependencyValidationException actualRepositoryDependencyValidationException = + await Assert.ThrowsAsync( + addRepositoryTask.AsTask); + + // then + actualRepositoryDependencyValidationException.Should() + .BeEquivalentTo(expectedRepositoryDependencyValidationException); + + this.dateTimeBrokerMock.Verify(broker => + broker.GetCurrentDateTimeOffsetAsync(), + Times.Once); + + this.loggingBrokerMock.Verify(broker => + broker.LogErrorAsync(It.Is(SameExceptionAs( + expectedRepositoryDependencyValidationException))), + Times.Once); + + this.storageBrokerMock.Verify(broker => + broker.InsertRepositoryAsync(It.IsAny()), + Times.Never); + + this.dateTimeBrokerMock.VerifyNoOtherCalls(); + this.loggingBrokerMock.VerifyNoOtherCalls(); + this.storageBrokerMock.VerifyNoOtherCalls(); + } + [Fact] public async Task ShouldThrowServiceExceptionOnAddIfServiceErrorOccurredAndLogItAsync() { diff --git a/GitFyle.Core.Api.Tests.Unit/Services/Foundations/Repositories/RepositoryServiceTests.Exceptions.Modify.cs b/GitFyle.Core.Api.Tests.Unit/Services/Foundations/Repositories/RepositoryServiceTests.Exceptions.Modify.cs index 39396c07..4b51cd98 100644 --- a/GitFyle.Core.Api.Tests.Unit/Services/Foundations/Repositories/RepositoryServiceTests.Exceptions.Modify.cs +++ b/GitFyle.Core.Api.Tests.Unit/Services/Foundations/Repositories/RepositoryServiceTests.Exceptions.Modify.cs @@ -4,6 +4,7 @@ using System; using System.Threading.Tasks; +using EFxceptions.Models.Exceptions; using FluentAssertions; using GitFyle.Core.Api.Models.Foundations.Repositories; using GitFyle.Core.Api.Models.Foundations.Repositories.Exceptions; @@ -189,6 +190,63 @@ await Assert.ThrowsAsync( this.storageBrokerMock.VerifyNoOtherCalls(); } + [Fact] + public async Task ShouldThrowDependencyValidationExceptionOnModifyIfForeignKeyErrorOccursAndLogItAsync() + { + // given + Repository someRepository = CreateRandomRepository(); + string someMessage = GetRandomString(); + string exceptionMessage = someMessage; + + var foreignKeyConstraintConflictException = + new ForeignKeyConstraintConflictException(exceptionMessage); + + var invalidRepositoryReferenceException = + new InvalidRepositoryReferenceException( + message: "Invalid repository reference error occurred.", + innerException: foreignKeyConstraintConflictException, + data: foreignKeyConstraintConflictException.Data); + + var expectedRepositoryDependencyValidationException = + new RepositoryDependencyValidationException( + message: "Repository validation error occurred, fix errors and try again.", + innerException: invalidRepositoryReferenceException, + data: invalidRepositoryReferenceException.Data); + + this.dateTimeBrokerMock.Setup(broker => + broker.GetCurrentDateTimeOffsetAsync()) + .ThrowsAsync(foreignKeyConstraintConflictException); + + // when + ValueTask modifyRepositoryTask = + this.repositoryService.ModifyRepositoryAsync(someRepository); + + RepositoryDependencyValidationException actualRepositoryDependencyValidationException = + await Assert.ThrowsAsync( + modifyRepositoryTask.AsTask); + + // then + actualRepositoryDependencyValidationException.Should() + .BeEquivalentTo(expectedRepositoryDependencyValidationException); + + this.dateTimeBrokerMock.Verify(broker => + broker.GetCurrentDateTimeOffsetAsync(), + Times.Once); + + this.loggingBrokerMock.Verify(broker => + broker.LogErrorAsync(It.Is(SameExceptionAs( + expectedRepositoryDependencyValidationException))), + Times.Once); + + this.storageBrokerMock.Verify(broker => + broker.InsertRepositoryAsync(It.IsAny()), + Times.Never); + + this.dateTimeBrokerMock.VerifyNoOtherCalls(); + this.loggingBrokerMock.VerifyNoOtherCalls(); + this.storageBrokerMock.VerifyNoOtherCalls(); + } + [Fact] public async Task ShouldThrowServiceExceptionOnModifyIfServiceErrorOccursAndLogItAsync() { diff --git a/GitFyle.Core.Api/Models/Foundations/Repositories/Exceptions/InvalidRepositoryReferenceException.cs b/GitFyle.Core.Api/Models/Foundations/Repositories/Exceptions/InvalidRepositoryReferenceException.cs new file mode 100644 index 00000000..1777f435 --- /dev/null +++ b/GitFyle.Core.Api/Models/Foundations/Repositories/Exceptions/InvalidRepositoryReferenceException.cs @@ -0,0 +1,17 @@ +// ---------------------------------------------------------------------------------- +// Copyright (c) The Standard Organization: A coalition of the Good-Hearted Engineers +// ---------------------------------------------------------------------------------- + +using System; +using System.Collections; +using Xeptions; + +namespace GitFyle.Core.Api.Models.Foundations.Repositories.Exceptions +{ + public class InvalidRepositoryReferenceException : Xeption + { + public InvalidRepositoryReferenceException(string message, Exception innerException, IDictionary data) + : base(message, innerException, data) + { } + } +} \ No newline at end of file diff --git a/GitFyle.Core.Api/Services/Foundations/Repositories/RepositoryService.Exceptions.cs b/GitFyle.Core.Api/Services/Foundations/Repositories/RepositoryService.Exceptions.cs index 145e9472..e469983b 100644 --- a/GitFyle.Core.Api/Services/Foundations/Repositories/RepositoryService.Exceptions.cs +++ b/GitFyle.Core.Api/Services/Foundations/Repositories/RepositoryService.Exceptions.cs @@ -55,6 +55,16 @@ private async ValueTask TryCatch(ReturningRepositoryFunction returni throw await CreateAndLogDependencyValidationExceptionAsync(alreadyExistsRepositoryException); } + catch (ForeignKeyConstraintConflictException foreignKeyConstraintConflictException) + { + var invalidRepositoryReferenceException = + new InvalidRepositoryReferenceException( + message: "Invalid repository reference error occurred.", + innerException: foreignKeyConstraintConflictException, + data: foreignKeyConstraintConflictException.Data); + + throw await CreateAndLogDependencyValidationExceptionAsync(invalidRepositoryReferenceException); + } catch (DbUpdateConcurrencyException dbUpdateConcurrencyException) { var concurrencyGemException =