diff --git a/services/domain/Big.Tests/Fakes.cs b/services/domain/Big.Tests/Fakes.cs index cf0a37d..bfd0a54 100644 --- a/services/domain/Big.Tests/Fakes.cs +++ b/services/domain/Big.Tests/Fakes.cs @@ -41,6 +41,29 @@ internal sealed class FakeWorkflowClient(string processInstanceId = "proc-1", Ac } } +/// A fake user-task client for the werkbak/decision use cases: returns a scripted set of +/// open beoordeling tasks and records claim/complete calls. +internal sealed class FakeUserTaskClient(IReadOnlyList open) : IUserTaskClient +{ + public (string TaskId, string Behandelaar)? Claimed { get; private set; } + public (string TaskId, BeoordelingsBesluit Besluit)? Completed { get; private set; } + + public Task> GetOpenBeoordelingenAsync(CancellationToken ct = default) + => Task.FromResult(open); + + public Task ClaimAsync(string taskId, string behandelaar, CancellationToken ct = default) + { + Claimed = (taskId, behandelaar); + return Task.CompletedTask; + } + + public Task CompleteBeoordelingAsync(string taskId, BeoordelingsBesluit besluit, CancellationToken ct = default) + { + Completed = (taskId, besluit); + return Task.CompletedTask; + } +} + /// A fake ACL client that records the bsn it was asked to open a zaak for and returns a /// fixed zaak URL. internal sealed class FakeAclClient(Uri? zaakUrl = null) : IAclClient diff --git a/services/domain/Big.Tests/WerkbakTests.cs b/services/domain/Big.Tests/WerkbakTests.cs new file mode 100644 index 0000000..bfbf182 --- /dev/null +++ b/services/domain/Big.Tests/WerkbakTests.cs @@ -0,0 +1,49 @@ +using Big.Application; +using Big.Domain; + +namespace Big.Tests; + +/// +/// The werkbak query (S-12c): the behandelaar's list of registrations awaiting beoordeling. It reads +/// the open Beoordelen tasks from the workflow engine (ยง8.2) and enriches each with its registration +/// (bsn + status) from the store. A task whose registration is unknown is skipped defensively. +/// +public class WerkbakTests +{ + [Fact] + public async Task Lists_an_item_per_open_beoordeling_enriched_from_the_registration() + { + var store = new FakeRegistrationStore(); + var registration = Registration.Submit("123456782"); + registration.AttachZaak(FakeAclClient.DefaultZaakUrl); + registration.TakeIntoBehandeling(); + store.Seed(registration); + var tasks = new FakeUserTaskClient([new BeoordelingTask("task-1", registration.Id)]); + var werkbak = new Werkbak(tasks, store); + + var items = await werkbak.GetAsync(); + + var item = Assert.Single(items); + Assert.Equal(registration.Id.ToString(), item.RegistrationId); + Assert.Equal("123456782", item.Bsn); + Assert.Equal("InBehandeling", item.Status); + } + + [Fact] + public async Task Is_empty_when_no_beoordelingen_are_open() + { + var werkbak = new Werkbak(new FakeUserTaskClient([]), new FakeRegistrationStore()); + + Assert.Empty(await werkbak.GetAsync()); + } + + [Fact] + public async Task Skips_a_task_whose_registration_is_unknown() + { + // Defensive: the werkbak never invents an item for a task the domain has no aggregate for. + var tasks = new FakeUserTaskClient([new BeoordelingTask("task-1", RegistrationId.New())]); + var werkbak = new Werkbak(tasks, new FakeRegistrationStore()); + + Assert.Empty(await werkbak.GetAsync()); + } +}