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

170 lines
5.2 KiB
C#

using Microsoft.Extensions.Hosting;
using Moq;
using OwnerNumberMigration;
using OwnerNumberMigration.Migrations;
using OwnerNumberMigration.ValueParsing;
using OwnerNumberMigrationTest.TestDoubles;
namespace OwnerNumberMigrationTest.Migrations;
public abstract class AttributeMigrationTaskTest<T>
{
protected abstract IHostedService MigrationTaskFactory
(
AttributeMigrationFactory<T> factory,
IParsingStrategyFactory strategyFactory,
IMigrationManager manager
);
private IHostedService MigrationServiceFactory() => MigrationTaskFactory
(
(_, _, _) => _migration.Object,
StrategyFactory.Object,
_manager.Object
);
protected abstract string SourceAttribute { get; }
protected abstract string DestinationAttribute { get; }
protected readonly Mock<IParsingStrategyFactory> StrategyFactory = new();
private readonly FakeParsingStrategy<T> _parsingStrategy;
private readonly Mock<IAttributeMigration> _migration = new();
private readonly Mock<IMigrationManager> _manager = new();
protected AttributeMigrationTaskTest(Func<T> newT)
{
_parsingStrategy = new FakeParsingStrategy<T>(newT);
}
[SetUp]
public void SetUp()
{
StrategyFactory
.Setup(f => f.CreateParsingStrategy<T>(SourceAttribute))
.Returns((IValueParsingStrategy<T>)_parsingStrategy);
_migration.Reset();
}
[Test]
public void Constructor_AllCases_CreatesMigrationWithJobTypeAttributes()
{
string? sourceAttribute = null;
string? destinationAttribute = null;
IValueParsingStrategy<T>? parsingStrategy = null;
MigrationTaskFactory
(
(source, strategy, destination) =>
{
sourceAttribute = source;
parsingStrategy = strategy;
destinationAttribute = destination;
return _migration.Object;
},
StrategyFactory.Object,
_manager.Object
);
Assert.AreEqual(SourceAttribute, sourceAttribute);
Assert.AreSame(_parsingStrategy, parsingStrategy);
Assert.AreEqual(DestinationAttribute, destinationAttribute);
}
[Test]
public async Task StartAsync_TokenCancelled_DoesNotStartMigration()
{
var cancellation = new CancellationToken(true);
var migration = MigrationServiceFactory();
await migration.StartAsync(cancellation);
_migration.Verify(m => m.Migrate(It.IsAny<CancellationToken>()), Times.Never);
}
[Test]
public async Task StartAsync_NotCanceled_StartsMigrationTaskAndReturns()
{
var cancellation = new CancellationToken();
_migration
.Setup(m => m.Migrate(It.IsAny<CancellationToken>()))
.Returns<CancellationToken>(async token =>
{
await Task.Delay(TimeSpan.MaxValue, token);
}
);
var migration = MigrationServiceFactory();
await migration.StartAsync(cancellation);
_migration.Verify(m => m.Migrate(It.IsAny<CancellationToken>()), Times.Once);
}
[Test]
public async Task StartAsync_NotCanceled_RegistersMigrationTaskWithManager()
{
var cancellation = new CancellationToken();
var migrationTask = Task.Run(() => { });
_migration
.Setup(m => m.Migrate(It.IsAny<CancellationToken>()))
.Returns(migrationTask);
var migration = MigrationServiceFactory();
await migration.StartAsync(cancellation);
_manager.Verify(m => m.Start(migrationTask), Times.Once);
}
[Test]
public async Task StopAsync_NotStarted_ReturnsWithoutError()
{
var cancellation = new CancellationToken();
var migration = MigrationServiceFactory();
Assert.DoesNotThrowAsync(() => migration.StopAsync(cancellation));
}
[Test]
public async Task StopAsync_AlreadyCompleted_CleansUpMigrationTask()
{
var cancellation = new CancellationToken();
Task? migrationTask = null;
_migration
.Setup(m => m.Migrate(It.IsAny<CancellationToken>()))
.Returns<CancellationToken>(token => migrationTask = Task.Run
(
() => { },
token
));
var migration = MigrationServiceFactory();
await migration.StartAsync(cancellation);
await migrationTask;
await migration.StopAsync(cancellation);
Assert.AreEqual(TaskStatus.RanToCompletion, migrationTask.Status);
}
[Test]
public async Task StopAsync_NotCompleted_CancelsMigrationTaskThenCleansUp()
{
var cancellation = new CancellationToken();
Task? migrationTask = null;
_migration
.Setup(m => m.Migrate(It.IsAny<CancellationToken>()))
.Returns<CancellationToken>(token => migrationTask = Task.Run
(
async () =>
{
await Task.Delay(-1, token);
},
token
));
var migration = MigrationServiceFactory();
await migration.StartAsync(cancellation);
await migration.StopAsync(cancellation);
Assert.AreEqual(TaskStatus.Canceled, migrationTask.Status);
}
}