feat: added Sdn repo and added some initial tests
This commit is contained in:
@@ -1,5 +1,3 @@
|
||||
using Bogus;
|
||||
|
||||
namespace SanctionsSearch.Worker.Tests.Fakes;
|
||||
|
||||
class SdnFaker : Faker<Sdn>
|
||||
|
||||
@@ -1,77 +0,0 @@
|
||||
using Microsoft.Data.Sqlite;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
using SanctionsSearch.Worker.Tests.Fakes;
|
||||
|
||||
namespace SanctionsSearch.Worker.Tests.Integration;
|
||||
|
||||
public class EfRepositoryTests : IAsyncLifetime
|
||||
{
|
||||
private readonly AppDbContext _context;
|
||||
private readonly EfRepository<Sdn> _sdnRepository;
|
||||
private readonly SdnFaker _sdnFaker = new();
|
||||
|
||||
public EfRepositoryTests()
|
||||
{
|
||||
var loggerFactory = LoggerFactory.Create(builder => builder.ClearProviders());
|
||||
|
||||
_context = new AppDbContext(new DbOptions { DatabaseName = $"{Guid.NewGuid()}.db" });
|
||||
_sdnRepository = new EfRepository<Sdn>(_context, loggerFactory.CreateLogger<EfRepository<Sdn>>());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Upsert_WithNewEntity_ShouldAddEntityToDatabase()
|
||||
{
|
||||
var sdn = _sdnFaker.Generate();
|
||||
|
||||
await _sdnRepository.Upsert(sdn);
|
||||
await _context.SaveChangesAsync();
|
||||
|
||||
var result = await _context.Sdns.FindAsync(sdn.Id);
|
||||
|
||||
result.Should().BeEquivalentTo(sdn);
|
||||
result!.CreatedAt.Should().BeCloseTo(DateTime.UtcNow, TimeSpan.FromSeconds(1));
|
||||
result.UpdatedAt.Should().BeCloseTo(DateTime.UtcNow, TimeSpan.FromSeconds(1));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Upsert_WithExistingEntity_ShouldUpdateEntityInDatabase()
|
||||
{
|
||||
var sdn = _sdnFaker.Generate();
|
||||
|
||||
await _sdnRepository.Upsert(sdn);
|
||||
await _context.SaveChangesAsync();
|
||||
|
||||
var createdSdn = await _context.Sdns.FindAsync(sdn.Id);
|
||||
|
||||
createdSdn.Should().BeEquivalentTo(sdn);
|
||||
createdSdn!.CreatedAt.Should().BeCloseTo(DateTime.UtcNow, TimeSpan.FromSeconds(1));
|
||||
createdSdn.UpdatedAt.Should().BeCloseTo(DateTime.UtcNow, TimeSpan.FromSeconds(1));
|
||||
|
||||
var updatedSdn = _sdnFaker.Generate();
|
||||
updatedSdn.Id = sdn.Id;
|
||||
|
||||
await _sdnRepository.Upsert(updatedSdn);
|
||||
await _context.SaveChangesAsync();
|
||||
|
||||
var result = await _context.Sdns.FindAsync(sdn.Id);
|
||||
|
||||
result.Should().BeEquivalentTo(updatedSdn);
|
||||
result!.CreatedAt.Should().BeSameDateAs(createdSdn.CreatedAt);
|
||||
result.UpdatedAt.Should().BeAfter(createdSdn.UpdatedAt);
|
||||
}
|
||||
|
||||
public async Task InitializeAsync()
|
||||
{
|
||||
await _context.Database.MigrateAsync();
|
||||
}
|
||||
|
||||
public async Task DisposeAsync()
|
||||
{
|
||||
await _context.DisposeAsync();
|
||||
|
||||
SqliteConnection.ClearAllPools();
|
||||
|
||||
File.Delete(_context.DatabasePath);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
namespace SanctionsSearch.Worker.Tests.Integration;
|
||||
|
||||
public class SdnRepositoryTests : IAsyncLifetime
|
||||
{
|
||||
private readonly AppDbContext _context;
|
||||
private readonly SdnRepository _sdnRepository;
|
||||
private readonly SdnFaker _sdnFaker = new();
|
||||
private readonly Mock<TimeProvider> _timeProvider = new();
|
||||
|
||||
public SdnRepositoryTests()
|
||||
{
|
||||
var loggerFactory = LoggerFactory.Create(builder => builder.ClearProviders());
|
||||
var options = new DbOptions { DatabaseName = $"{Guid.NewGuid()}.db" };
|
||||
|
||||
_context = new AppDbContext(options, _timeProvider.Object);
|
||||
_sdnRepository = new SdnRepository(_context, new Logger<SdnRepository>(loggerFactory));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Upsert_WithNewEntity_ShouldAddEntityToDatabase()
|
||||
{
|
||||
var now = DateTimeOffset.UtcNow;
|
||||
_timeProvider.Setup(x => x.GetUtcNow()).Returns(now);
|
||||
|
||||
var sdn = _sdnFaker.Generate();
|
||||
|
||||
await _sdnRepository.Upsert(sdn);
|
||||
await _context.SaveChangesAsync();
|
||||
|
||||
var result = await _context.Sdns.FindAsync(sdn.Id);
|
||||
|
||||
result.Should().BeEquivalentTo(sdn);
|
||||
result!.CreatedAt.Should().Be(now.DateTime);
|
||||
result.UpdatedAt.Should().Be(now.DateTime);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Upsert_WithExistingEntity_ShouldUpdateEntityInDatabase()
|
||||
{
|
||||
var createdTimeStamp = DateTimeOffset.UtcNow;
|
||||
var updatedTimeStamp = createdTimeStamp.AddSeconds(2);
|
||||
|
||||
_timeProvider.Setup(x => x.GetUtcNow()).Returns(createdTimeStamp);
|
||||
|
||||
var sdn = _sdnFaker.Generate();
|
||||
|
||||
// Insert the entity
|
||||
await _sdnRepository.Upsert(sdn);
|
||||
await _context.SaveChangesAsync();
|
||||
|
||||
// Assert the entity was created
|
||||
var createdSdn = await _context.Sdns.FindAsync(sdn.Id);
|
||||
|
||||
createdSdn.Should().BeEquivalentTo(sdn);
|
||||
createdSdn!.CreatedAt.Should().Be(createdTimeStamp.DateTime);
|
||||
createdSdn.UpdatedAt.Should().Be(createdTimeStamp.DateTime);
|
||||
|
||||
_timeProvider.Setup(x => x.GetUtcNow()).Returns(updatedTimeStamp);
|
||||
|
||||
// Update the entity
|
||||
sdn.Name = "Updated";
|
||||
await _sdnRepository.Upsert(sdn);
|
||||
await _context.SaveChangesAsync();
|
||||
|
||||
// Assert the entity was updated
|
||||
var result = await _context.Sdns.FindAsync(sdn.Id);
|
||||
|
||||
result.Should().BeEquivalentTo(sdn);
|
||||
result!.CreatedAt.Should().BeSameDateAs(createdTimeStamp.DateTime);
|
||||
result.UpdatedAt.Should().BeSameDateAs(updatedTimeStamp.DateTime);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Find_WithPredicate_ShouldReturnEntitiesMatchingPredicate()
|
||||
{
|
||||
var sdn1 = _sdnFaker.Generate();
|
||||
var sdn2 = _sdnFaker.Generate();
|
||||
var sdn3 = _sdnFaker.Generate();
|
||||
|
||||
await _sdnRepository.Upsert(sdn1);
|
||||
await _sdnRepository.Upsert(sdn2);
|
||||
await _sdnRepository.Upsert(sdn3);
|
||||
await _context.SaveChangesAsync();
|
||||
|
||||
var result = await _sdnRepository.Find(x => x.Id == sdn2.Id);
|
||||
|
||||
result.Should().HaveCount(1);
|
||||
result.First().Should().BeEquivalentTo(sdn2);
|
||||
}
|
||||
|
||||
public async Task InitializeAsync()
|
||||
{
|
||||
await _context.Database.MigrateAsync();
|
||||
}
|
||||
|
||||
public async Task DisposeAsync()
|
||||
{
|
||||
await _context.DisposeAsync();
|
||||
|
||||
SqliteConnection.ClearAllPools();
|
||||
|
||||
File.Delete(_context.DatabasePath);
|
||||
}
|
||||
}
|
||||
@@ -31,6 +31,7 @@
|
||||
<CoverletOutput>./TestResults/coverage/</CoverletOutput>
|
||||
<CoverletOutputFormat>cobertura</CoverletOutputFormat>
|
||||
<Include>[SanctionsSearch.Worker]*</Include>
|
||||
<Exclude>[SanctionsSearch.Worker]SanctionsSearch.Worker.Migrations*</Exclude>
|
||||
</PropertyGroup>
|
||||
|
||||
<Target Name="GenerateHtmlCoverageReport" AfterTargets="GenerateCoverageResultAfterTest">
|
||||
|
||||
@@ -1,6 +1,3 @@
|
||||
using System.Net;
|
||||
using System.Text;
|
||||
|
||||
namespace SanctionsSearch.Worker.Tests.Unit;
|
||||
|
||||
public class OfacFileServiceTests
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
namespace SanctionsSearch.Worker.Tests.Unit;
|
||||
|
||||
public class SdnRepositoryTests
|
||||
{
|
||||
private readonly Mock<DbContext> _context = new();
|
||||
private readonly Mock<ILogger<SdnRepository>> _logger = new();
|
||||
private readonly SdnFaker _sdnFaker = new();
|
||||
private readonly SdnRepository _sdnRepository;
|
||||
|
||||
public SdnRepositoryTests()
|
||||
{
|
||||
_sdnRepository = new SdnRepository(_context.Object, _logger.Object);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Upsert_WhenExceptionIsThrown_ItShouldLogError()
|
||||
{
|
||||
var sdn = _sdnFaker.Generate();
|
||||
var mockSet = new Mock<DbSet<Sdn>>();
|
||||
|
||||
mockSet
|
||||
.Setup(x => x.FindAsync(sdn.Id))
|
||||
.Throws<Exception>();
|
||||
|
||||
_context
|
||||
.Setup(x => x.Set<Sdn>())
|
||||
.Returns(mockSet.Object);
|
||||
|
||||
await _sdnRepository.Upsert(sdn);
|
||||
|
||||
_logger.Verify(
|
||||
x => x.Log(
|
||||
LogLevel.Error,
|
||||
It.IsAny<EventId>(),
|
||||
It.IsAny<It.IsAnyType>(),
|
||||
It.IsAny<Exception>(),
|
||||
It.IsAny<Func<It.IsAnyType, Exception?, string>>()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Find_WhenExceptionIsThrown_ItShouldReturnEmptyListAndLogError()
|
||||
{
|
||||
_context
|
||||
.Setup(x => x.Set<Sdn>())
|
||||
.Throws<Exception>();
|
||||
|
||||
var result = await _sdnRepository.Find(x => x.Id == 1);
|
||||
|
||||
result.Should().BeEmpty();
|
||||
|
||||
_logger.Verify(
|
||||
x => x.Log(
|
||||
LogLevel.Error,
|
||||
It.IsAny<EventId>(),
|
||||
It.IsAny<It.IsAnyType>(),
|
||||
It.IsAny<Exception>(),
|
||||
It.IsAny<Func<It.IsAnyType, Exception?, string>>()
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,12 @@
|
||||
global using System.Net;
|
||||
global using System.Text;
|
||||
|
||||
global using Bogus;
|
||||
|
||||
global using FluentAssertions;
|
||||
|
||||
global using Microsoft.Data.Sqlite;
|
||||
global using Microsoft.EntityFrameworkCore;
|
||||
global using Microsoft.Extensions.Logging;
|
||||
global using Microsoft.Extensions.Options;
|
||||
|
||||
@@ -7,7 +14,8 @@ global using Moq;
|
||||
|
||||
global using RichardSzalay.MockHttp;
|
||||
|
||||
global using SanctionsSearch.Worker.Services;
|
||||
global using SanctionsSearch.Worker.Options;
|
||||
global using SanctionsSearch.Worker.Models;
|
||||
global using SanctionsSearch.Worker.Persistence;
|
||||
global using SanctionsSearch.Worker.Options;
|
||||
global using SanctionsSearch.Worker.Persistence;
|
||||
global using SanctionsSearch.Worker.Services;
|
||||
global using SanctionsSearch.Worker.Tests.Fakes;
|
||||
|
||||
Reference in New Issue
Block a user