Files
monorepo/LCU.API.Internal.Document/OwnerNumberMigrationTest/Logging/AttributeMigrationLoggingDecoratorTest.cs
T
2026-03-13 09:11:35 -05:00

94 lines
3.4 KiB
C#

using System.Text.RegularExpressions;
using LCU.API.Internal.DocumentLib.Containers;
using Microsoft.Extensions.Logging;
using Moq;
using OwnerNumberMigration;
using OwnerNumberMigration.Logging;
using OwnerNumberMigrationTest.TestDataFactories;
using OwnerNumberMigrationTest.TestDoubles;
namespace OwnerNumberMigrationTest.Logging;
public class AttributeMigrationLoggingDecoratorTest : IDisposable
{
private readonly IAttributeMigration _decoratedMigration;
private readonly string _attributeName = Guid.NewGuid().ToString();
private readonly string _destinationAttributeName = Guid.NewGuid().ToString();
private readonly Mock<IAttributeMigration> _rawMigration = new();
private readonly FakeLogger _logger = new();
private readonly FakeMongoCollectionFactory _collectionFactory = new();
private readonly FakeDocumentFilterFactory _filterFactory = new();
public AttributeMigrationLoggingDecoratorTest()
{
_decoratedMigration = new AttributeMigrationLoggingDecorator
(
_rawMigration.Object,
_logger,
_collectionFactory,
_attributeName,
_destinationAttributeName,
_filterFactory
);
}
[Test]
public async Task Migrate_AllCases_LogsCountToMigrate()
{
var documentCount = new Random(DateTime.Now.Millisecond).Next(3, 10);
var documents = EnumerableDataSeriesFactory
.CreateSeries(DocumentInformationFactory.CreateDocumentInformation, documentCount)
.ToArray();
await _collectionFactory.GetCollection<DocumentInformation>().InsertManyAsync(documents);
_filterFactory.ApplicableDocuments[(_attributeName, _destinationAttributeName)] = documents;
await _decoratedMigration.Migrate(new CancellationToken());
Func<Log, bool> logMatch = l => l.LogLevel == LogLevel.Information
&& l.Message.Contains(_attributeName)
&& new Regex($"\\b{documentCount}\\b").IsMatch(l.Message);
Assert.IsTrue(_logger.Logs.Count(logMatch) == 1);
}
[Test]
public async Task Migrate_AllCases_InvokesInnerMigration()
{
var cancellation = new CancellationToken();
await _decoratedMigration.Migrate(cancellation);
_rawMigration.Verify(m => m.Migrate(cancellation), Times.Once);
}
[Test]
public async Task Migrate_InnerMigrationCompletes_LogsElapsedTime()
{
var migrationDuration = TimeSpan.FromMilliseconds(100);
_rawMigration
.Setup(m => m.Migrate(It.IsAny<CancellationToken>()))
.Returns(() => Task.Delay(migrationDuration));
var actionStart = DateTime.Now;
await _decoratedMigration.Migrate(new CancellationToken());
var elapsed = DateTime.Now - actionStart;
Func<Log, bool> logMatch = l =>
{
var timespan = Regex.Match(l.Message, "\\d\\d:\\d\\d:\\d\\d\\.\\d\\d\\d\\d\\d\\d\\d");
if (!timespan.Success) return false;
var duration = TimeSpan.Parse(timespan.ValueSpan);
return l.LogLevel == LogLevel.Information
&& l.Message.Contains(_attributeName)
&& duration >= migrationDuration
&& duration <= elapsed;
};
Assert.IsTrue(_logger.Logs.Count(logMatch) == 1);
}
public void Dispose()
{
_collectionFactory.Dispose();
}
}