Skip to content

Commit 20d1840

Browse files
Merge pull request #66 from DilmurodDeveloper/users/DilmurodDeveloper/foundations-reader-remove
FOUNDATIONS: Remove Reader
2 parents 19483cf + d71e9d4 commit 20d1840

File tree

5 files changed

+320
-0
lines changed

5 files changed

+320
-0
lines changed
Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
//-----------------------------------------------------------
2+
// Copyright (c) Coalition of Good-Hearted Engineers
3+
// Free To Use To Build Reliable Library Management Solutions
4+
//-----------------------------------------------------------
5+
6+
using FluentAssertions;
7+
using LibraryManagement.Api.Models.Foundations.Readers;
8+
using LibraryManagement.Api.Models.Foundations.Readers.Exceptions;
9+
using Microsoft.Data.SqlClient;
10+
using Microsoft.EntityFrameworkCore;
11+
using Moq;
12+
13+
namespace LibraryManagement.Api.Tests.Unit.Services.Foundations.Readers
14+
{
15+
public partial class ReaderServiceTests
16+
{
17+
[Fact]
18+
public async Task ShouldThrowDependencyValidationOnRemoveIfDatabaseUpdateConcurrencyErrorOccursAndLogItAsync()
19+
{
20+
// given
21+
Guid someReaderId = Guid.NewGuid();
22+
var dbUpdateConcurrencyException = new DbUpdateConcurrencyException();
23+
24+
var lockedReaderException =
25+
new LockedReaderException(dbUpdateConcurrencyException);
26+
27+
var expectedReaderDependencyValidationException =
28+
new ReaderDependencyValidationException(lockedReaderException);
29+
30+
this.storageBrokerMock.Setup(broker =>
31+
broker.SelectReaderByIdAsync(It.IsAny<Guid>()))
32+
.ThrowsAsync(dbUpdateConcurrencyException);
33+
34+
// when
35+
ValueTask<Reader> removeReaderById =
36+
this.readerService.RemoveReaderByIdAsync(someReaderId);
37+
38+
ReaderDependencyValidationException actualReaderDependencyValidationException =
39+
await Assert.ThrowsAsync<ReaderDependencyValidationException>(() =>
40+
removeReaderById.AsTask());
41+
42+
// then
43+
actualReaderDependencyValidationException.Should()
44+
.BeEquivalentTo(expectedReaderDependencyValidationException);
45+
46+
this.storageBrokerMock.Verify(broker =>
47+
broker.SelectReaderByIdAsync(It.IsAny<Guid>()),
48+
Times.Once);
49+
50+
this.loggingBrokerMock.Verify(broker =>
51+
broker.LogError(It.Is(SameExceptionAs(
52+
expectedReaderDependencyValidationException))),
53+
Times.Once);
54+
55+
this.storageBrokerMock.Verify(broker =>
56+
broker.DeleteReaderAsync(It.IsAny<Reader>()),
57+
Times.Never);
58+
59+
this.storageBrokerMock.VerifyNoOtherCalls();
60+
this.loggingBrokerMock.VerifyNoOtherCalls();
61+
}
62+
63+
[Fact]
64+
public async Task ShouldThrowDependencyExceptionOnRemoveWhenSqlExceptionOccursAndLogItAsync()
65+
{
66+
// given
67+
Guid someLocationId = Guid.NewGuid();
68+
SqlException sqlException = GetSqlError();
69+
70+
var failedReaderStorageException =
71+
new FailedReaderStorageException(sqlException);
72+
73+
var expectedReaderDependencyException =
74+
new ReaderDependencyException(failedReaderStorageException);
75+
76+
this.storageBrokerMock.Setup(broker =>
77+
broker.SelectReaderByIdAsync(It.IsAny<Guid>()))
78+
.ThrowsAsync(sqlException);
79+
80+
// when
81+
ValueTask<Reader> deleteReaderTask =
82+
this.readerService.RemoveReaderByIdAsync(someLocationId);
83+
84+
ReaderDependencyException actualReaderDependencyException =
85+
await Assert.ThrowsAsync<ReaderDependencyException>(() =>
86+
deleteReaderTask.AsTask());
87+
88+
// then
89+
actualReaderDependencyException.Should()
90+
.BeEquivalentTo(expectedReaderDependencyException);
91+
92+
this.storageBrokerMock.Verify(broker =>
93+
broker.SelectReaderByIdAsync(It.IsAny<Guid>()),
94+
Times.Once);
95+
96+
this.loggingBrokerMock.Verify(broker =>
97+
broker.LogCritical(It.Is(SameExceptionAs(
98+
expectedReaderDependencyException))),
99+
Times.Once);
100+
101+
this.storageBrokerMock.VerifyNoOtherCalls();
102+
this.loggingBrokerMock.VerifyNoOtherCalls();
103+
}
104+
105+
[Fact]
106+
public async Task ShouldThrowServiceExceptionOnRemoveIfExceptionOccursAndLogItAsync()
107+
{
108+
// given
109+
Guid someReaderId = Guid.NewGuid();
110+
var serviceException = new Exception();
111+
112+
var failedReaderServiceException =
113+
new FailedReaderServiceException(serviceException);
114+
115+
var expectedReaderServiceException =
116+
new ReaderServiceException(failedReaderServiceException);
117+
118+
this.storageBrokerMock.Setup(broker =>
119+
broker.SelectReaderByIdAsync(It.IsAny<Guid>()))
120+
.ThrowsAsync(serviceException);
121+
122+
// when
123+
ValueTask<Reader> removeReaderByIdTask =
124+
this.readerService.RemoveReaderByIdAsync(someReaderId);
125+
126+
ReaderServiceException actualReaderServiceException =
127+
await Assert.ThrowsAsync<ReaderServiceException>(() =>
128+
removeReaderByIdTask.AsTask());
129+
130+
// then
131+
actualReaderServiceException.Should()
132+
.BeEquivalentTo(expectedReaderServiceException);
133+
134+
this.storageBrokerMock.Verify(broker =>
135+
broker.SelectReaderByIdAsync(It.IsAny<Guid>()),
136+
Times.Once);
137+
138+
this.loggingBrokerMock.Verify(broker =>
139+
broker.LogError(It.Is(SameExceptionAs(
140+
expectedReaderServiceException))),
141+
Times.Once);
142+
143+
this.storageBrokerMock.VerifyNoOtherCalls();
144+
this.loggingBrokerMock.VerifyNoOtherCalls();
145+
}
146+
}
147+
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
//-----------------------------------------------------------
2+
// Copyright (c) Coalition of Good-Hearted Engineers
3+
// Free To Use To Build Reliable Library Management Solutions
4+
//-----------------------------------------------------------
5+
6+
using FluentAssertions;
7+
using Force.DeepCloner;
8+
using LibraryManagement.Api.Models.Foundations.Readers;
9+
using Moq;
10+
11+
namespace LibraryManagement.Api.Tests.Unit.Services.Foundations.Readers
12+
{
13+
public partial class ReaderServiceTests
14+
{
15+
[Fact]
16+
public async Task ShouldRemoveReaderByIdAsync()
17+
{
18+
// given
19+
Guid randomId = Guid.NewGuid();
20+
Guid inputReaderId = randomId;
21+
Reader randomReader = CreateRandomReader();
22+
Reader storageReader = randomReader;
23+
Reader expectedInputReader = storageReader;
24+
Reader deletedReader = expectedInputReader;
25+
Reader expectedReader = deletedReader.DeepClone();
26+
27+
this.storageBrokerMock.Setup(broker =>
28+
broker.SelectReaderByIdAsync(inputReaderId))
29+
.ReturnsAsync(storageReader);
30+
31+
this.storageBrokerMock.Setup(broker =>
32+
broker.DeleteReaderAsync(expectedInputReader))
33+
.ReturnsAsync(deletedReader);
34+
35+
// when
36+
Reader actualReader =
37+
await this.readerService.RemoveReaderByIdAsync(randomId);
38+
39+
// then
40+
actualReader.Should().BeEquivalentTo(expectedReader);
41+
42+
this.storageBrokerMock.Verify(broker =>
43+
broker.SelectReaderByIdAsync(inputReaderId),
44+
Times.Once);
45+
46+
this.storageBrokerMock.Verify(broker =>
47+
broker.DeleteReaderAsync(expectedInputReader),
48+
Times.Once);
49+
50+
this.storageBrokerMock.VerifyNoOtherCalls();
51+
this.loggingBrokerMock.VerifyNoOtherCalls();
52+
}
53+
}
54+
}
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
//-----------------------------------------------------------
2+
// Copyright (c) Coalition of Good-Hearted Engineers
3+
// Free To Use To Build Reliable Library Management Solutions
4+
//-----------------------------------------------------------
5+
6+
using FluentAssertions;
7+
using LibraryManagement.Api.Models.Foundations.Readers;
8+
using LibraryManagement.Api.Models.Foundations.Readers.Exceptions;
9+
using Moq;
10+
11+
namespace LibraryManagement.Api.Tests.Unit.Services.Foundations.Readers
12+
{
13+
public partial class ReaderServiceTests
14+
{
15+
[Fact]
16+
public async Task ShouldThrowValidationExceptionOnRemoveIfIdIsInvalidAndLogItAsync()
17+
{
18+
// given
19+
Guid invalidReaderId = Guid.Empty;
20+
21+
var invalidReaderException = new InvalidReaderException();
22+
23+
invalidReaderException.AddData(
24+
key: nameof(Reader.ReaderId),
25+
values: "Id is required");
26+
27+
var expectedReaderValidationException =
28+
new ReaderValidationException(invalidReaderException);
29+
30+
// when
31+
ValueTask<Reader> removeReaderById =
32+
this.readerService.RemoveReaderByIdAsync(invalidReaderId);
33+
34+
ReaderValidationException actualReaderValidationException =
35+
await Assert.ThrowsAsync<ReaderValidationException>(() =>
36+
removeReaderById.AsTask());
37+
38+
// then
39+
actualReaderValidationException.Should()
40+
.BeEquivalentTo(expectedReaderValidationException);
41+
42+
this.loggingBrokerMock.Verify(broker =>
43+
broker.LogError(It.Is(SameExceptionAs(
44+
expectedReaderValidationException))),
45+
Times.Once);
46+
47+
this.storageBrokerMock.Verify(broker =>
48+
broker.SelectReaderByIdAsync(It.IsAny<Guid>()),
49+
Times.Never);
50+
51+
this.storageBrokerMock.Verify(broker =>
52+
broker.DeleteReaderAsync(It.IsAny<Reader>()),
53+
Times.Never);
54+
55+
this.loggingBrokerMock.VerifyNoOtherCalls();
56+
this.storageBrokerMock.VerifyNoOtherCalls();
57+
}
58+
59+
[Fact]
60+
public async Task ShouldThrowNotFoundExceptionOnRemoveReaderByIdIsNotFoundAndLogItAsync()
61+
{
62+
// given
63+
Guid inputReaderId = Guid.NewGuid();
64+
Reader noReader = null;
65+
66+
var notFoundReaderException =
67+
new NotFoundReaderException(inputReaderId);
68+
69+
var expectedReaderValidationException =
70+
new ReaderValidationException(notFoundReaderException);
71+
72+
this.storageBrokerMock.Setup(broker =>
73+
broker.SelectReaderByIdAsync(It.IsAny<Guid>()))
74+
.ReturnsAsync(noReader);
75+
76+
// when
77+
ValueTask<Reader> removeReaderById =
78+
this.readerService.RemoveReaderByIdAsync(inputReaderId);
79+
80+
var actualReaderValidationException =
81+
await Assert.ThrowsAsync<ReaderValidationException>(() =>
82+
removeReaderById.AsTask());
83+
84+
// then
85+
actualReaderValidationException.Should()
86+
.BeEquivalentTo(expectedReaderValidationException);
87+
88+
this.storageBrokerMock.Verify(broker =>
89+
broker.SelectReaderByIdAsync(It.IsAny<Guid>()),
90+
Times.Once);
91+
92+
this.loggingBrokerMock.Verify(broker =>
93+
broker.LogError(It.Is(SameExceptionAs(
94+
expectedReaderValidationException))),
95+
Times.Once);
96+
97+
this.storageBrokerMock.Verify(broker =>
98+
broker.DeleteReaderAsync(It.IsAny<Reader>()),
99+
Times.Never);
100+
101+
this.storageBrokerMock.VerifyNoOtherCalls();
102+
this.loggingBrokerMock.VerifyNoOtherCalls();
103+
}
104+
}
105+
}

LibraryManagement.Api/Services/Foundations/Readers/IReaderService.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,6 @@ public interface IReaderService
1313
IQueryable<Reader> RetrieveAllReaders();
1414
ValueTask<Reader> RetrieveReaderByIdAsync(Guid readerId);
1515
ValueTask<Reader> ModifyReaderAsync(Reader reader);
16+
ValueTask<Reader> RemoveReaderByIdAsync(Guid readerId);
1617
}
1718
}

LibraryManagement.Api/Services/Foundations/Readers/ReaderService.cs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,5 +58,18 @@ public ValueTask<Reader> ModifyReaderAsync(Reader reader) =>
5858

5959
return await this.storageBroker.UpdateReaderAsync(reader);
6060
});
61+
62+
public ValueTask<Reader> RemoveReaderByIdAsync(Guid readerId) =>
63+
TryCatch(async () =>
64+
{
65+
ValidateReaderId(readerId);
66+
67+
Reader maybeReader =
68+
await this.storageBroker.SelectReaderByIdAsync(readerId);
69+
70+
ValidateStorageReader(maybeReader, readerId);
71+
72+
return await this.storageBroker.DeleteReaderAsync(maybeReader);
73+
});
6174
}
6275
}

0 commit comments

Comments
 (0)