diff --git a/src/SanctionsSearch.Worker.Tests/Integration/DatabaseMaintainerTests.cs b/src/SanctionsSearch.Worker.Tests/Integration/DatabaseMaintainerTests.cs index a1f653a..653be14 100644 --- a/src/SanctionsSearch.Worker.Tests/Integration/DatabaseMaintainerTests.cs +++ b/src/SanctionsSearch.Worker.Tests/Integration/DatabaseMaintainerTests.cs @@ -1,6 +1,6 @@ namespace SanctionsSearch.Worker.Tests.Integration; -public class DatabaseMaintainerTests : DatabaseTest +public class DatabaseMaintainerTests : DatabaseTest, IDisposable { private const string TestSdnCsv = """ 6906,"AL-IRAQI, Abd al-Hadi","individual","SDGT",-0- ,-0- ,-0- ,-0- ,-0- ,-0- ,-0- ,"DOB 1961; POB Mosul, Iraq; nationality Iraq; Gender Male." @@ -279,4 +279,12 @@ public class DatabaseMaintainerTests : DatabaseTest } }); } + + public void Dispose() + { + _databaseMaintainer.Dispose(); + _mockHttp.Dispose(); + + GC.SuppressFinalize(this); + } } \ No newline at end of file diff --git a/src/SanctionsSearch.Worker.Tests/Integration/DatabaseTest.cs b/src/SanctionsSearch.Worker.Tests/Integration/DatabaseTest.cs index 2f62df1..b3a4c01 100644 --- a/src/SanctionsSearch.Worker.Tests/Integration/DatabaseTest.cs +++ b/src/SanctionsSearch.Worker.Tests/Integration/DatabaseTest.cs @@ -25,6 +25,7 @@ public class DatabaseTest : IAsyncLifetime public virtual async Task DisposeAsync() { await _appDbContext.DisposeAsync(); + _loggerFactory.Dispose(); SqliteConnection.ClearAllPools(); diff --git a/src/SanctionsSearch.Worker.Tests/Unit/AddressRepositoryTests.cs b/src/SanctionsSearch.Worker.Tests/Unit/AddressRepositoryTests.cs index 8cb4941..bff3840 100644 --- a/src/SanctionsSearch.Worker.Tests/Unit/AddressRepositoryTests.cs +++ b/src/SanctionsSearch.Worker.Tests/Unit/AddressRepositoryTests.cs @@ -2,14 +2,14 @@ namespace SanctionsSearch.Worker.Tests.Unit; public class AddressRepositoryTests { - private readonly Mock _context = new(); - private readonly Mock> _logger = new(); + private readonly Mock _contextMock = new(); + private readonly Mock> _loggerMock = new(); private readonly AddressFaker _faker = new(); private readonly AddressRepository _repository; public AddressRepositoryTests() { - _repository = new AddressRepository(_context.Object, _logger.Object); + _repository = new AddressRepository(_contextMock.Object, _loggerMock.Object); } [Fact] @@ -22,13 +22,13 @@ public class AddressRepositoryTests .Setup(x => x.FindAsync(entity.Id)) .Throws(); - _context + _contextMock .Setup(x => x.Set
()) .Returns(mockSet.Object); await _repository.Upsert(entity); - _logger.Verify( + _loggerMock.Verify( x => x.Log( LogLevel.Error, It.IsAny(), @@ -42,7 +42,7 @@ public class AddressRepositoryTests [Fact] public async Task Find_WhenExceptionIsThrown_ItShouldReturnEmptyListAndLogError() { - _context + _contextMock .Setup(x => x.Set
()) .Throws(); @@ -50,7 +50,7 @@ public class AddressRepositoryTests result.Should().BeEmpty(); - _logger.Verify( + _loggerMock.Verify( x => x.Log( LogLevel.Error, It.IsAny(), diff --git a/src/SanctionsSearch.Worker.Tests/Unit/AliasRepositoryTests.cs b/src/SanctionsSearch.Worker.Tests/Unit/AliasRepositoryTests.cs index 294e8bb..84ddb0c 100644 --- a/src/SanctionsSearch.Worker.Tests/Unit/AliasRepositoryTests.cs +++ b/src/SanctionsSearch.Worker.Tests/Unit/AliasRepositoryTests.cs @@ -2,14 +2,14 @@ namespace SanctionsSearch.Worker.Tests.Unit; public class AliasRepositoryTests { - private readonly Mock _context = new(); - private readonly Mock> _logger = new(); + private readonly Mock _contextMock = new(); + private readonly Mock> _loggerMock = new(); private readonly AliasFaker _faker = new(); private readonly AliasRepository _repository; public AliasRepositoryTests() { - _repository = new AliasRepository(_context.Object, _logger.Object); + _repository = new AliasRepository(_contextMock.Object, _loggerMock.Object); } [Fact] @@ -22,13 +22,13 @@ public class AliasRepositoryTests .Setup(x => x.FindAsync(entity.Id)) .Throws(); - _context + _contextMock .Setup(x => x.Set()) .Returns(mockSet.Object); await _repository.Upsert(entity); - _logger.Verify( + _loggerMock.Verify( x => x.Log( LogLevel.Error, It.IsAny(), @@ -42,7 +42,7 @@ public class AliasRepositoryTests [Fact] public async Task Find_WhenExceptionIsThrown_ItShouldReturnEmptyListAndLogError() { - _context + _contextMock .Setup(x => x.Set()) .Throws(); @@ -50,7 +50,7 @@ public class AliasRepositoryTests result.Should().BeEmpty(); - _logger.Verify( + _loggerMock.Verify( x => x.Log( LogLevel.Error, It.IsAny(), diff --git a/src/SanctionsSearch.Worker.Tests/Unit/CommentRepositoryTests.cs b/src/SanctionsSearch.Worker.Tests/Unit/CommentRepositoryTests.cs index daaa826..0d3cdf9 100644 --- a/src/SanctionsSearch.Worker.Tests/Unit/CommentRepositoryTests.cs +++ b/src/SanctionsSearch.Worker.Tests/Unit/CommentRepositoryTests.cs @@ -2,14 +2,14 @@ namespace SanctionsSearch.Worker.Tests.Unit; public class CommentRepositoryTests { - private readonly Mock _context = new(); - private readonly Mock> _logger = new(); + private readonly Mock _contextMock = new(); + private readonly Mock> _loggerMock = new(); private readonly CommentFaker _faker = new(); private readonly CommentRepository _repository; public CommentRepositoryTests() { - _repository = new CommentRepository(_context.Object, _logger.Object); + _repository = new CommentRepository(_contextMock.Object, _loggerMock.Object); } [Fact] @@ -22,13 +22,13 @@ public class CommentRepositoryTests .Setup(x => x.FindAsync(entity.Id)) .Throws(); - _context + _contextMock .Setup(x => x.Set()) .Returns(mockSet.Object); await _repository.Upsert(entity); - _logger.Verify( + _loggerMock.Verify( x => x.Log( LogLevel.Error, It.IsAny(), @@ -42,7 +42,7 @@ public class CommentRepositoryTests [Fact] public async Task Find_WhenExceptionIsThrown_ItShouldReturnEmptyListAndLogError() { - _context + _contextMock .Setup(x => x.Set()) .Throws(); @@ -50,7 +50,7 @@ public class CommentRepositoryTests result.Should().BeEmpty(); - _logger.Verify( + _loggerMock.Verify( x => x.Log( LogLevel.Error, It.IsAny(), diff --git a/src/SanctionsSearch.Worker.Tests/Unit/DatabaseMaintainerTests.cs b/src/SanctionsSearch.Worker.Tests/Unit/DatabaseMaintainerTests.cs new file mode 100644 index 0000000..9175376 --- /dev/null +++ b/src/SanctionsSearch.Worker.Tests/Unit/DatabaseMaintainerTests.cs @@ -0,0 +1,103 @@ +using FluentResults; + +namespace SanctionsSearch.Worker.Tests.Unit; + +public class DatabaseMaintainerTests : IDisposable +{ + private readonly Mock _unitOfWorkMock = new(); + private readonly Mock _ofacFileServiceMock = new(); + private readonly Mock> _loggerMock = new(); + private readonly DatabaseMaintainer _databaseMaintainer; + + public DatabaseMaintainerTests() + { + _databaseMaintainer = new(_unitOfWorkMock.Object, _ofacFileServiceMock.Object, _loggerMock.Object); + } + + [Fact] + public async Task BuildSdnTableAsync_WhenUnableToRetrieveCsvFile_ItShouldLogError() + { + _ofacFileServiceMock + .Setup(x => x.GetSdnFileAsync()) + .ReturnsAsync(Result.Fail("Error")); + + await _databaseMaintainer.BuildSdnTableAsync(); + + _loggerMock.Verify( + x => x.Log( + LogLevel.Error, + It.IsAny(), + It.IsAny(), + It.IsAny(), + It.IsAny>() + ) + ); + } + + [Fact] + public async Task BuildAddressTableAsync_WhenUnableToRetrieveCsvFile_ItShouldLogError() + { + _ofacFileServiceMock + .Setup(x => x.GetAddressFileAsync()) + .ReturnsAsync(Result.Fail("Error")); + + await _databaseMaintainer.BuildAddressTableAsync(); + + _loggerMock.Verify( + x => x.Log( + LogLevel.Error, + It.IsAny(), + It.IsAny(), + It.IsAny(), + It.IsAny>() + ) + ); + } + + [Fact] + public async Task BuildAliasTableAsync_WhenUnableToRetrieveCsvFile_ItShouldLogError() + { + _ofacFileServiceMock + .Setup(x => x.GetAltNamesFileAsync()) + .ReturnsAsync(Result.Fail("Error")); + + await _databaseMaintainer.BuiltAliasTableAsync(); + + _loggerMock.Verify( + x => x.Log( + LogLevel.Error, + It.IsAny(), + It.IsAny(), + It.IsAny(), + It.IsAny>() + ) + ); + } + + [Fact] + public async Task BuildCommentsTableAsync_WhenUnableToRetrieveCsvFile_ItShouldLogError() + { + _ofacFileServiceMock + .Setup(x => x.GetCommentsFileAsync()) + .ReturnsAsync(Result.Fail("Error")); + + await _databaseMaintainer.BuildCommentTableAsync(); + + _loggerMock.Verify( + x => x.Log( + LogLevel.Error, + It.IsAny(), + It.IsAny(), + It.IsAny(), + It.IsAny>() + ) + ); + } + + public void Dispose() + { + _databaseMaintainer.Dispose(); + + GC.SuppressFinalize(this); + } +} \ No newline at end of file diff --git a/src/SanctionsSearch.Worker.Tests/Unit/EfUnitOfWorkTests.cs b/src/SanctionsSearch.Worker.Tests/Unit/EfUnitOfWorkTests.cs index f0cb2d1..1bf6865 100644 --- a/src/SanctionsSearch.Worker.Tests/Unit/EfUnitOfWorkTests.cs +++ b/src/SanctionsSearch.Worker.Tests/Unit/EfUnitOfWorkTests.cs @@ -2,13 +2,13 @@ namespace SanctionsSearch.Worker.Tests.Unit; public class EfUnitOfWorkTests { - private readonly Mock _context = new(); - private readonly Mock _loggerFactory = new(); + private readonly Mock _contextMock = new(); + private readonly Mock _loggerFactoryMock = new(); private readonly EfUnitOfWork _unitOfWork; public EfUnitOfWorkTests() { - _unitOfWork = new(_context.Object, _loggerFactory.Object); + _unitOfWork = new(_contextMock.Object, _loggerFactoryMock.Object); } [Fact] @@ -34,4 +34,40 @@ public class EfUnitOfWorkTests { _unitOfWork.Comments.Should().BeOfType(); } + + [Fact] + public void SaveChangesAsync_WhenADatabaseUpdateExceptionIsThrown_ItShouldBeCaughtAndLogged() + { + _contextMock + .Setup(x => x.SaveChangesAsync(It.IsAny())) + .ThrowsAsync(new DbUpdateException()); + + var action = _unitOfWork.SaveChangesAsync; + + action.Should().NotThrowAsync(); + } + + [Fact] + public void SaveChangesAsync_WhenExceptionIsThrown_ItShouldNotBeCaught() + { + _contextMock + .Setup(x => x.SaveChangesAsync(It.IsAny())) + .ThrowsAsync(new Exception()); + + var action = _unitOfWork.SaveChangesAsync; + + action.Should().ThrowAsync(); + } + + [Fact] + public void DisposeAsync_WhenExceptionIsThrown_ItShouldBeCaught() + { + _contextMock + .Setup(x => x.DisposeAsync()) + .Throws(new Exception()); + + var action = _unitOfWork.DisposeAsync; + + action.Should().NotThrow(); + } } \ No newline at end of file diff --git a/src/SanctionsSearch.Worker.Tests/Unit/OfacFileServiceTests.cs b/src/SanctionsSearch.Worker.Tests/Unit/OfacFileServiceTests.cs index dd24bac..11670da 100644 --- a/src/SanctionsSearch.Worker.Tests/Unit/OfacFileServiceTests.cs +++ b/src/SanctionsSearch.Worker.Tests/Unit/OfacFileServiceTests.cs @@ -1,6 +1,6 @@ namespace SanctionsSearch.Worker.Tests.Unit; -public class OfacFileServiceTests +public class OfacFileServiceTests : IDisposable { private const string TestCsv = "Name,Address\nJohn Doe,123 Main St\n"; private static Stream TestStream => new MemoryStream(Encoding.UTF8.GetBytes(TestCsv)); @@ -286,4 +286,11 @@ public class OfacFileServiceTests result.IsFailed.Should().BeTrue(); } + + public void Dispose() + { + _mockHttp.Dispose(); + + GC.SuppressFinalize(this); + } } \ No newline at end of file diff --git a/src/SanctionsSearch.Worker.Tests/Unit/SdnRepositoryTests.cs b/src/SanctionsSearch.Worker.Tests/Unit/SdnRepositoryTests.cs index 0bb3496..5d02f9e 100644 --- a/src/SanctionsSearch.Worker.Tests/Unit/SdnRepositoryTests.cs +++ b/src/SanctionsSearch.Worker.Tests/Unit/SdnRepositoryTests.cs @@ -2,14 +2,14 @@ namespace SanctionsSearch.Worker.Tests.Unit; public class SdnRepositoryTests { - private readonly Mock _context = new(); - private readonly Mock> _logger = new(); + private readonly Mock _contextMock = new(); + private readonly Mock> _loggerMock = new(); private readonly SdnFaker _faker = new(); private readonly SdnRepository _repository; public SdnRepositoryTests() { - _repository = new SdnRepository(_context.Object, _logger.Object); + _repository = new SdnRepository(_contextMock.Object, _loggerMock.Object); } [Fact] @@ -22,13 +22,13 @@ public class SdnRepositoryTests .Setup(x => x.FindAsync(entity.Id)) .Throws(); - _context + _contextMock .Setup(x => x.Set()) .Returns(mockSet.Object); await _repository.Upsert(entity); - _logger.Verify( + _loggerMock.Verify( x => x.Log( LogLevel.Error, It.IsAny(), @@ -42,7 +42,7 @@ public class SdnRepositoryTests [Fact] public async Task Find_WhenExceptionIsThrown_ItShouldReturnEmptyListAndLogError() { - _context + _contextMock .Setup(x => x.Set()) .Throws(); @@ -50,7 +50,7 @@ public class SdnRepositoryTests result.Should().BeEmpty(); - _logger.Verify( + _loggerMock.Verify( x => x.Log( LogLevel.Error, It.IsAny(), diff --git a/src/SanctionsSearch.Worker.Tests/Usings.cs b/src/SanctionsSearch.Worker.Tests/Usings.cs index e129387..3573f5b 100644 --- a/src/SanctionsSearch.Worker.Tests/Usings.cs +++ b/src/SanctionsSearch.Worker.Tests/Usings.cs @@ -19,3 +19,5 @@ global using SanctionsSearch.Worker.Options; global using SanctionsSearch.Worker.Persistence; global using SanctionsSearch.Worker.Services; global using SanctionsSearch.Worker.Tests.Faker; +global using SanctionsSearch.Worker.Interfaces; +