test(domain): store finds inscriptions due for a herregistratie reminder (refs #18)
New IRegistrationStore.FindDueForHerregistratieReminderAsync — the sweep's candidate set. The production store is stubbed to an empty list so the new test fails; the green commit filters on the aggregate's own reminder-due rule. refs #18
This commit is contained in:
@@ -107,6 +107,13 @@ public interface IRegistrationStore
|
|||||||
/// registration, or <c>null</c> if they have none in flight. Lets the self-service portal resume
|
/// registration, or <c>null</c> if they have none in flight. Lets the self-service portal resume
|
||||||
/// an existing registration after a refresh (S-26); terminal registrations are not resumed.</summary>
|
/// an existing registration after a refresh (S-26); terminal registrations are not resumed.</summary>
|
||||||
Task<Registration?> FindOpenByBsnAsync(string bsn, CancellationToken ct = default);
|
Task<Registration?> FindOpenByBsnAsync(string bsn, CancellationToken ct = default);
|
||||||
|
|
||||||
|
/// <summary>The inscriptions whose herregistratie reminder is due as of <paramref name="asOf"/> and
|
||||||
|
/// not yet sent — the herregistratie reminder sweep's candidate set (S-17). The predicate is the
|
||||||
|
/// aggregate's own <see cref="Registration.HerregistratieReminderDue"/> rule, so the store never
|
||||||
|
/// duplicates the herregistratie policy.</summary>
|
||||||
|
Task<IReadOnlyList<Registration>> FindDueForHerregistratieReminderAsync(
|
||||||
|
DateTimeOffset asOf, CancellationToken ct = default);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -26,4 +26,8 @@ public sealed class InMemoryRegistrationStore : IRegistrationStore
|
|||||||
public Task<Registration?> FindOpenByBsnAsync(string bsn, CancellationToken ct = default)
|
public Task<Registration?> FindOpenByBsnAsync(string bsn, CancellationToken ct = default)
|
||||||
=> Task.FromResult(_byId.Values.FirstOrDefault(r =>
|
=> Task.FromResult(_byId.Values.FirstOrDefault(r =>
|
||||||
r.Bsn == bsn && r.Status is RegistrationStatus.Ingediend or RegistrationStatus.InBehandeling));
|
r.Bsn == bsn && r.Status is RegistrationStatus.Ingediend or RegistrationStatus.InBehandeling));
|
||||||
|
|
||||||
|
public Task<IReadOnlyList<Registration>> FindDueForHerregistratieReminderAsync(
|
||||||
|
DateTimeOffset asOf, CancellationToken ct = default)
|
||||||
|
=> Task.FromResult<IReadOnlyList<Registration>>([]); // RED stub
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,6 +26,11 @@ internal sealed class FakeRegistrationStore : IRegistrationStore
|
|||||||
=> Task.FromResult(_byId.Values.FirstOrDefault(r =>
|
=> Task.FromResult(_byId.Values.FirstOrDefault(r =>
|
||||||
r.Bsn == bsn && r.Status is RegistrationStatus.Ingediend or RegistrationStatus.InBehandeling));
|
r.Bsn == bsn && r.Status is RegistrationStatus.Ingediend or RegistrationStatus.InBehandeling));
|
||||||
|
|
||||||
|
public Task<IReadOnlyList<Registration>> FindDueForHerregistratieReminderAsync(
|
||||||
|
DateTimeOffset asOf, CancellationToken ct = default)
|
||||||
|
=> Task.FromResult<IReadOnlyList<Registration>>(
|
||||||
|
_byId.Values.Where(r => r.HerregistratieReminderDue(asOf)).ToList());
|
||||||
|
|
||||||
public void Seed(Registration registration) => _byId[registration.Id] = registration;
|
public void Seed(Registration registration) => _byId[registration.Id] = registration;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -96,4 +96,27 @@ public class InMemoryRegistrationStoreTests
|
|||||||
|
|
||||||
Assert.Null(await store.FindOpenByBsnAsync("123456782"));
|
Assert.Null(await store.FindOpenByBsnAsync("123456782"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task Finds_only_the_inscriptions_due_for_a_herregistratie_reminder()
|
||||||
|
{
|
||||||
|
var now = new DateTimeOffset(2026, 7, 23, 0, 0, 0, TimeSpan.Zero);
|
||||||
|
var store = new InMemoryRegistrationStore();
|
||||||
|
|
||||||
|
var due = Registration.Submit("123456782");
|
||||||
|
due.AttachZaak(new Uri("http://openzaak/zaken/api/v1/zaken/abc"));
|
||||||
|
due.Approve(now - Registration.HerregistratieGeldigheid + Registration.Herinneringstermijn);
|
||||||
|
await store.SaveAsync(due);
|
||||||
|
|
||||||
|
var freshlyInscribed = Registration.Submit("111111110");
|
||||||
|
freshlyInscribed.AttachZaak(new Uri("http://openzaak/zaken/api/v1/zaken/def"));
|
||||||
|
freshlyInscribed.Approve(now);
|
||||||
|
await store.SaveAsync(freshlyInscribed);
|
||||||
|
|
||||||
|
await store.SaveAsync(Registration.Submit("222222222")); // still INGEDIEND — never inscribed
|
||||||
|
|
||||||
|
var result = await store.FindDueForHerregistratieReminderAsync(now);
|
||||||
|
|
||||||
|
Assert.Equal([due.Id], result.Select(r => r.Id).ToArray());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user