Skip to content

Commit

Permalink
Merge pull request #488 from GulchexrasGithub/users/GulchexrasGithub/…
Browse files Browse the repository at this point in the history
…foundations/groupmembership-retrieve-byid

FOUNDATIONS: Retrieve GroupMembership By Id
  • Loading branch information
glhays authored Aug 14, 2023
2 parents e091330 + ec3bdd9 commit 7302783
Show file tree
Hide file tree
Showing 8 changed files with 300 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
// ---------------------------------------------------------------
// Copyright (c) Coalition of the Good-Hearted Engineers
// FREE TO USE TO CONNECT THE WORLD
// ---------------------------------------------------------------

using System;
using System.Threading.Tasks;
using FluentAssertions;
using Microsoft.Data.SqlClient;
using Moq;
using Taarafo.Core.Models.GroupMemberships;
using Taarafo.Core.Models.GroupMemberships.Exceptions;
using Xunit;

namespace Taarafo.Core.Tests.Unit.Services.Foundations.GroupMemberships
{
public partial class GroupMembershipServiceTests
{
[Fact]
public async Task ShouldThrowCriticalDependencyExceptionOnRetrieveByIdIfSqlErrorOccursAndLogItAsync()
{
// given
Guid someId = Guid.NewGuid();
SqlException sqlException = GetSqlException();

var failedGroupMembershipStorageException =
new FailedGroupMembershipStorageException(sqlException);

var expectedGroupMembershipDependencyException =
new GroupMembershipDependencyException(failedGroupMembershipStorageException);

this.storageBrokerMock.Setup(broker =>
broker.SelectGroupMembershipByIdAsync(It.IsAny<Guid>()))
.ThrowsAsync(sqlException);

// when
ValueTask<GroupMembership> retrieveGroupMembershipByIdTask =
this.groupMembershipService.RetrieveGroupMembershipByIdAsync(someId);

GroupMembershipDependencyException actualGroupMembershipDependencyException =
await Assert.ThrowsAsync<GroupMembershipDependencyException>(
retrieveGroupMembershipByIdTask.AsTask);

// then
actualGroupMembershipDependencyException.Should().BeEquivalentTo(
expectedGroupMembershipDependencyException);

this.storageBrokerMock.Verify(broker =>
broker.SelectGroupMembershipByIdAsync(It.IsAny<Guid>()),
Times.Once);

this.loggingBrokerMock.Verify(broker =>
broker.LogCritical(It.Is(SameExceptionAs(
expectedGroupMembershipDependencyException))),
Times.Once);

this.storageBrokerMock.VerifyNoOtherCalls();
this.loggingBrokerMock.VerifyNoOtherCalls();
this.dateTimeBrokerMock.VerifyNoOtherCalls();
}

[Fact]
public async Task ShouldThrowServiceExceptionOnRetrieveByIdIfServiceErrorOccursAndLogItAsync()
{
// given
Guid someId = Guid.NewGuid();
var serviceException = new Exception();

var failedGroupMembershipServiceException =
new FailedGroupMembershipServiceException(serviceException);

var expectedGroupMembershipServiceException =
new GroupMembershipServiceException(failedGroupMembershipServiceException);

this.storageBrokerMock.Setup(broker =>
broker.SelectGroupMembershipByIdAsync(It.IsAny<Guid>()))
.ThrowsAsync(serviceException);

// when
ValueTask<GroupMembership> retrieveGroupMembershipByIdTask =
this.groupMembershipService.RetrieveGroupMembershipByIdAsync(someId);

GroupMembershipServiceException actualGroupMembershipServiceException =
await Assert.ThrowsAsync<GroupMembershipServiceException>(
retrieveGroupMembershipByIdTask.AsTask);

// then
actualGroupMembershipServiceException.Should().BeEquivalentTo(
expectedGroupMembershipServiceException);

this.storageBrokerMock.Verify(broker =>
broker.SelectGroupMembershipByIdAsync(It.IsAny<Guid>()),
Times.Once);

this.loggingBrokerMock.Verify(broker =>
broker.LogError(It.Is(SameExceptionAs(
expectedGroupMembershipServiceException))),
Times.Once);

this.storageBrokerMock.VerifyNoOtherCalls();
this.loggingBrokerMock.VerifyNoOtherCalls();
this.dateTimeBrokerMock.VerifyNoOtherCalls();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// ---------------------------------------------------------------
// Copyright (c) Coalition of the Good-Hearted Engineers
// FREE TO USE TO CONNECT THE WORLD
// ---------------------------------------------------------------

using System.Threading.Tasks;
using FluentAssertions;
using Force.DeepCloner;
using Moq;
using Taarafo.Core.Models.GroupMemberships;
using Xunit;

namespace Taarafo.Core.Tests.Unit.Services.Foundations.GroupMemberships
{
public partial class GroupMembershipServiceTests
{
[Fact]
public async Task ShouldRetrieveGroupMembershipByIdAsync()
{
// given
GroupMembership randomGroupMembership = CreateRandomGroupMembership();
GroupMembership storageGroupMembership = randomGroupMembership;
GroupMembership expectedGroupMembership = storageGroupMembership.DeepClone();

this.storageBrokerMock.Setup(broker =>
broker.SelectGroupMembershipByIdAsync(randomGroupMembership.Id))
.ReturnsAsync(storageGroupMembership);

// when
GroupMembership actualGroupMembership =
await this.groupMembershipService.RetrieveGroupMembershipByIdAsync(randomGroupMembership.Id);

// then
actualGroupMembership.Should().BeEquivalentTo(expectedGroupMembership);

this.storageBrokerMock.Verify(broker =>
broker.SelectGroupMembershipByIdAsync(randomGroupMembership.Id),
Times.Once);

this.storageBrokerMock.VerifyNoOtherCalls();
this.dateTimeBrokerMock.VerifyNoOtherCalls();
this.loggingBrokerMock.VerifyNoOtherCalls();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
// ---------------------------------------------------------------
// Copyright (c) Coalition of the Good-Hearted Engineers
// FREE TO USE TO CONNECT THE WORLD
// ---------------------------------------------------------------

using System;
using System.Threading.Tasks;
using FluentAssertions;
using Moq;
using Taarafo.Core.Models.GroupMemberships;
using Taarafo.Core.Models.GroupMemberships.Exceptions;
using Xunit;

namespace Taarafo.Core.Tests.Unit.Services.Foundations.GroupMemberships
{
public partial class GroupMembershipServiceTests
{
[Fact]
public async Task ShouldThrowValidationExceptionOnRetrieveByIdIfIdIsInvalidAndLogItAsync()
{
// given
var invalidGroupMembershipId = Guid.Empty;

var invalidGroupMembershipException =
new InvalidGroupMembershipException();
invalidGroupMembershipException.AddData(
key: nameof(GroupMembership.Id),
values: "Id is required");

var expectedGroupMembershipValidationException =
new GroupMembershipValidationException(invalidGroupMembershipException);

// when
ValueTask<GroupMembership> retrieveGroupMembershipByIdTask =
this.groupMembershipService.RetrieveGroupMembershipByIdAsync(invalidGroupMembershipId);

GroupMembershipValidationException actualGroupMembershipValidationException =
await Assert.ThrowsAsync<GroupMembershipValidationException>(
retrieveGroupMembershipByIdTask.AsTask);

// then
actualGroupMembershipValidationException.Should().BeEquivalentTo(
expectedGroupMembershipValidationException);

this.loggingBrokerMock.Verify(broker =>
broker.LogError(It.Is(SameExceptionAs(
expectedGroupMembershipValidationException))),
Times.Once);

this.storageBrokerMock.Verify(broker =>
broker.SelectGroupMembershipByIdAsync(It.IsAny<Guid>()),
Times.Never);

this.loggingBrokerMock.VerifyNoOtherCalls();
this.storageBrokerMock.VerifyNoOtherCalls();
this.dateTimeBrokerMock.VerifyNoOtherCalls();
}

[Fact]
public async Task ShouldThrowNotFoundExceptionOnRetrieveByIdIfGroupMembershipIsNotFoundAndLogItAsync()
{
//given
Guid someGroupMembershipId = Guid.NewGuid();
GroupMembership noGroupMembership = null;

var notFoundGroupMembershipException =
new NotFoundGroupMembershipException(someGroupMembershipId);

var expectedGroupMembershipValidationException =
new GroupMembershipValidationException(notFoundGroupMembershipException);

this.storageBrokerMock.Setup(broker =>
broker.SelectGroupMembershipByIdAsync(It.IsAny<Guid>()))
.ReturnsAsync(noGroupMembership);

//when
ValueTask<GroupMembership> retrieveGroupMembershipByIdTask =
this.groupMembershipService.RetrieveGroupMembershipByIdAsync(someGroupMembershipId);

GroupMembershipValidationException actualGroupMembershipValidationException =
await Assert.ThrowsAsync<GroupMembershipValidationException>(
retrieveGroupMembershipByIdTask.AsTask);

// then
actualGroupMembershipValidationException.Should().BeEquivalentTo(
expectedGroupMembershipValidationException);

this.storageBrokerMock.Verify(broker =>
broker.SelectGroupMembershipByIdAsync(It.IsAny<Guid>()),
Times.Once());

this.loggingBrokerMock.Verify(broker =>
broker.LogError(It.Is(SameExceptionAs(
expectedGroupMembershipValidationException))),
Times.Once);

this.storageBrokerMock.VerifyNoOtherCalls();
this.loggingBrokerMock.VerifyNoOtherCalls();
this.dateTimeBrokerMock.VerifyNoOtherCalls();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// ---------------------------------------------------------------
// Copyright (c) Coalition of the Good-Hearted Engineers
// FREE TO USE TO CONNECT THE WORLD
// ---------------------------------------------------------------

using System;
using Xeptions;

namespace Taarafo.Core.Models.GroupMemberships.Exceptions
{
public class NotFoundGroupMembershipException : Xeption
{
public NotFoundGroupMembershipException(Guid groupMembershipId)
: base(message: $"Couldn't find GroupMembership with id: {groupMembershipId}.")
{ }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@ private async ValueTask<GroupMembership> TryCatch(ReturningGroupMembershipFuncti

throw CreateAndLogCriticalDependencyException(failedGroupMembershipStorageException);
}
catch (NotFoundGroupMembershipException notFoundGroupMembershipException)
{
throw CreateAndLogValidationException(notFoundGroupMembershipException);
}
catch (DuplicateKeyException duplicateKeyException)
{
var alreadyExistsGroupMembershipException =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ public void ValidateGroupMembershipOnAdd(GroupMembership groupMembership)
(Rule: IsNotRecent(groupMembership.MembershipDate), Parameter: nameof(GroupMembership.MembershipDate)));
}

public void ValidateGroupMembershipId(Guid groupMembershipId) =>
Validate((Rule: IsInvalid(groupMembershipId), Parameter: nameof(GroupMembership.Id)));

private void ValidateGroupMembershipIsNotNull(GroupMembership groupMembership)
{
if (groupMembership is null)
Expand All @@ -31,6 +34,14 @@ private void ValidateGroupMembershipIsNotNull(GroupMembership groupMembership)
}
}

private static void ValidateStorageGroupMembership(GroupMembership maybeGroupMembership, Guid groupMembershipId)
{
if (maybeGroupMembership is null)
{
throw new NotFoundGroupMembershipException(groupMembershipId);
}
}

private static dynamic IsInvalid(Guid id) => new
{
Condition = id == Guid.Empty,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
// FREE TO USE TO CONNECT THE WORLD
// ---------------------------------------------------------------

using System;
using System.Threading.Tasks;
using Taarafo.Core.Brokers.DateTimes;
using Taarafo.Core.Brokers.Loggings;
Expand Down Expand Up @@ -34,5 +35,18 @@ public ValueTask<GroupMembership> AddGroupMembershipAsync(GroupMembership groupM
return await this.storageBroker.InsertGroupMembershipAsync(groupMembership);
});

public ValueTask<GroupMembership> RetrieveGroupMembershipByIdAsync(Guid groupMembershipId) =>
TryCatch(async () =>
{
ValidateGroupMembershipId(groupMembershipId);
GroupMembership maybeGroupMembership =
await this.storageBroker.SelectGroupMembershipByIdAsync(groupMembershipId);
ValidateStorageGroupMembership(maybeGroupMembership, groupMembershipId);
return maybeGroupMembership;
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
// FREE TO USE TO CONNECT THE WORLD
// ---------------------------------------------------------------

using System;
using System.Threading.Tasks;
using Taarafo.Core.Models.GroupMemberships;

Expand All @@ -11,5 +12,6 @@ namespace Taarafo.Core.Services.Foundations.GroupMemberships
public interface IGroupMembershipService
{
ValueTask<GroupMembership> AddGroupMembershipAsync(GroupMembership groupMembership);
ValueTask<GroupMembership> RetrieveGroupMembershipByIdAsync(Guid groupMembershipId);
}
}

0 comments on commit 7302783

Please sign in to comment.