feat(domain,bff): current-registration lookup for self-service resume (refs #111)
Backend half of S-26. The domain gains IRegistrationStore.FindOpenByBsnAsync (the citizen's non-terminal INGEDIEND/IN_BEHANDELING registration) + GET /registrations/current?bsn=; the BFF adds owner-scoped GET /self-service/registrations (bsn from the DigiD token) returning that registration or 204 when none. Regenerated services/bff/openapi.json for the new endpoint (the api-client is generated from it). Store + BFF endpoint unit tests; acceptance/BFF fakes updated for the new members. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -82,6 +82,18 @@ internal sealed class FakeDomainClient : IDomainClient
|
||||
return Task.FromResult(Result);
|
||||
}
|
||||
|
||||
public string? CurrentQueriedBsn { get; private set; }
|
||||
|
||||
/// <summary>The current open registration the fake domain returns (null → the citizen has none in
|
||||
/// flight, so the BFF replies 204). Tests set this to exercise resume.</summary>
|
||||
public CurrentRegistration? Current { get; set; }
|
||||
|
||||
public Task<CurrentRegistration?> GetCurrentRegistrationAsync(string bsn, CancellationToken ct = default)
|
||||
{
|
||||
CurrentQueriedBsn = bsn;
|
||||
return Task.FromResult(Current);
|
||||
}
|
||||
|
||||
public (string RegistrationId, string Bsn)? Withdrawn { get; private set; }
|
||||
|
||||
/// <summary>Whether the fake domain reports the withdrawal as done (true → 204) or not-found/not-owned
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System.Net;
|
||||
using System.Net.Http.Headers;
|
||||
using System.Net.Http.Json;
|
||||
using Bff.Api;
|
||||
|
||||
namespace Bff.Tests;
|
||||
|
||||
@@ -168,5 +169,52 @@ public class SelfServiceEndpointTests
|
||||
Assert.Equal(HttpStatusCode.NotFound, response.StatusCode);
|
||||
}
|
||||
|
||||
private static HttpRequestMessage Current(string? bearer)
|
||||
{
|
||||
var request = new HttpRequestMessage(HttpMethod.Get, "/self-service/registrations");
|
||||
if (bearer is not null)
|
||||
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", bearer);
|
||||
return request;
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Rejects_the_current_registration_lookup_without_a_token()
|
||||
{
|
||||
using var factory = new BffFactory();
|
||||
|
||||
var response = await factory.CreateClient().SendAsync(Current(bearer: null));
|
||||
|
||||
Assert.Equal(HttpStatusCode.Unauthorized, response.StatusCode);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Returns_no_content_when_the_caller_has_no_open_registration()
|
||||
{
|
||||
using var factory = new BffFactory();
|
||||
factory.Domain.Current = null;
|
||||
|
||||
var response = await factory.CreateClient().SendAsync(Current(TestTokens.Valid("123456782")));
|
||||
|
||||
Assert.Equal(HttpStatusCode.NoContent, response.StatusCode);
|
||||
Assert.Equal("123456782", factory.Domain.CurrentQueriedBsn);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Returns_the_callers_current_registration_when_one_is_open()
|
||||
{
|
||||
using var factory = new BffFactory();
|
||||
factory.Domain.Current = new CurrentRegistration("reg-77", "Ingediend");
|
||||
|
||||
var response = await factory.CreateClient().SendAsync(Current(TestTokens.Valid("123456782")));
|
||||
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
Assert.Equal("123456782", factory.Domain.CurrentQueriedBsn);
|
||||
var body = await response.Content.ReadFromJsonAsync<CurrentRegistrationDto>();
|
||||
Assert.Equal("reg-77", body!.RegistrationId);
|
||||
Assert.Equal("Ingediend", body.Status);
|
||||
}
|
||||
|
||||
private sealed record SubmitAcceptedDto(string RegistrationId, string Status);
|
||||
|
||||
private sealed record CurrentRegistrationDto(string RegistrationId, string Status);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user