96 lines
4.1 KiB
C#
96 lines
4.1 KiB
C#
using FictionArchive.Common.Enums;
|
|
using FictionArchive.Service.NovelService.Sagas;
|
|
using FictionArchive.Service.Shared.Contracts.Events;
|
|
using FluentAssertions;
|
|
using MassTransit;
|
|
using MassTransit.Testing;
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
using NodaTime;
|
|
using NodaTime.Testing;
|
|
using Xunit;
|
|
|
|
namespace FictionArchive.Service.NovelService.Tests.Sagas;
|
|
|
|
public class NovelImportSagaTests
|
|
{
|
|
private readonly FakeClock _clock = new(Instant.FromUtc(2026, 1, 27, 12, 0, 0));
|
|
|
|
[Fact]
|
|
public async Task Should_transition_to_importing_on_import_requested()
|
|
{
|
|
await using var provider = CreateTestProvider();
|
|
var harness = provider.GetRequiredService<ITestHarness>();
|
|
await harness.Start();
|
|
|
|
var importId = Guid.NewGuid();
|
|
await harness.Bus.Publish<INovelImportRequested>(new NovelImportRequested(importId, "https://example.com/novel"));
|
|
|
|
var sagaHarness = harness.GetSagaStateMachineHarness<NovelImportSaga, NovelImportSagaState>();
|
|
(await sagaHarness.Exists(importId, x => x.Importing)).HasValue.Should().BeTrue();
|
|
}
|
|
|
|
[Fact]
|
|
public async Task Should_transition_to_completed_when_no_chapters()
|
|
{
|
|
await using var provider = CreateTestProvider();
|
|
var harness = provider.GetRequiredService<ITestHarness>();
|
|
await harness.Start();
|
|
|
|
var importId = Guid.NewGuid();
|
|
await harness.Bus.Publish<INovelImportRequested>(new NovelImportRequested(importId, "https://example.com/novel"));
|
|
await harness.Bus.Publish<INovelMetadataImported>(new NovelMetadataImported(importId, 1, 0));
|
|
|
|
var sagaHarness = harness.GetSagaStateMachineHarness<NovelImportSaga, NovelImportSagaState>();
|
|
(await sagaHarness.Exists(importId, x => x.Completed)).HasValue.Should().BeTrue();
|
|
|
|
(await harness.Published.Any<INovelImportCompleted>(x =>
|
|
x.Context.Message.ImportId == importId && x.Context.Message.Success)).Should().BeTrue();
|
|
}
|
|
|
|
[Fact]
|
|
public async Task Should_transition_to_processing_when_chapters_pending()
|
|
{
|
|
await using var provider = CreateTestProvider();
|
|
var harness = provider.GetRequiredService<ITestHarness>();
|
|
await harness.Start();
|
|
|
|
var importId = Guid.NewGuid();
|
|
await harness.Bus.Publish<INovelImportRequested>(new NovelImportRequested(importId, "https://example.com/novel"));
|
|
await harness.Bus.Publish<INovelMetadataImported>(new NovelMetadataImported(importId, 1, 2));
|
|
|
|
var sagaHarness = harness.GetSagaStateMachineHarness<NovelImportSaga, NovelImportSagaState>();
|
|
(await sagaHarness.Exists(importId, x => x.Processing)).HasValue.Should().BeTrue();
|
|
}
|
|
|
|
[Fact]
|
|
public async Task Should_complete_when_all_chapters_pulled_and_images_uploaded()
|
|
{
|
|
await using var provider = CreateTestProvider();
|
|
var harness = provider.GetRequiredService<ITestHarness>();
|
|
await harness.Start();
|
|
|
|
var importId = Guid.NewGuid();
|
|
await harness.Bus.Publish<INovelImportRequested>(new NovelImportRequested(importId, "https://example.com/novel"));
|
|
await harness.Bus.Publish<INovelMetadataImported>(new NovelMetadataImported(importId, 1, 2));
|
|
await harness.Bus.Publish<IChapterPullCompleted>(new ChapterPullCompleted(importId, 1, 1));
|
|
await harness.Bus.Publish<IChapterPullCompleted>(new ChapterPullCompleted(importId, 2, 0));
|
|
await harness.Bus.Publish<IFileUploadRequestStatusUpdate>(new FileUploadRequestStatusUpdate(
|
|
importId, Guid.NewGuid(), RequestStatus.Success, "https://cdn.example.com/image.jpg", null));
|
|
|
|
var sagaHarness = harness.GetSagaStateMachineHarness<NovelImportSaga, NovelImportSagaState>();
|
|
(await sagaHarness.Exists(importId, x => x.Completed)).HasValue.Should().BeTrue();
|
|
}
|
|
|
|
private ServiceProvider CreateTestProvider()
|
|
{
|
|
return new ServiceCollection()
|
|
.AddSingleton<IClock>(_clock)
|
|
.AddMassTransitTestHarness(cfg =>
|
|
{
|
|
cfg.AddSagaStateMachine<NovelImportSaga, NovelImportSagaState>()
|
|
.InMemoryRepository();
|
|
})
|
|
.BuildServiceProvider(true);
|
|
}
|
|
}
|