using System.Net; using System.Net.Http.Headers; using System.Net.Http.Json; namespace Bff.Tests; public class SelfServiceEndpointTests { private static HttpRequestMessage Submit(string? bearer) { var request = new HttpRequestMessage(HttpMethod.Post, "/self-service/registrations") { Content = JsonContent.Create(new { }), }; if (bearer is not null) request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", bearer); return request; } [Fact] public async Task Rejects_a_request_without_a_token() { using var factory = new BffFactory(); var client = factory.CreateClient(); var response = await client.SendAsync(Submit(bearer: null)); Assert.Equal(HttpStatusCode.Unauthorized, response.StatusCode); Assert.Null(factory.Domain.SubmittedBsn); } [Theory] [InlineData("not-a-jwt")] public async Task Rejects_a_malformed_token(string bearer) { using var factory = new BffFactory(); var response = await factory.CreateClient().SendAsync(Submit(bearer)); Assert.Equal(HttpStatusCode.Unauthorized, response.StatusCode); } [Fact] public async Task Rejects_a_token_signed_with_the_wrong_key() { using var factory = new BffFactory(); var response = await factory.CreateClient().SendAsync(Submit(TestTokens.WrongKey("123456782"))); Assert.Equal(HttpStatusCode.Unauthorized, response.StatusCode); } [Fact] public async Task Rejects_an_expired_token() { using var factory = new BffFactory(); var response = await factory.CreateClient().SendAsync(Submit(TestTokens.Expired("123456782"))); Assert.Equal(HttpStatusCode.Unauthorized, response.StatusCode); } [Fact] public async Task Accepts_a_valid_token_and_forwards_the_bsn_to_the_domain() { using var factory = new BffFactory(); var client = factory.CreateClient(); var response = await client.SendAsync(Submit(TestTokens.Valid("123456782"))); Assert.Equal(HttpStatusCode.Accepted, response.StatusCode); Assert.Equal("123456782", factory.Domain.SubmittedBsn); var body = await response.Content.ReadFromJsonAsync(); Assert.Equal("reg-123", body!.RegistrationId); } private static HttpRequestMessage Withdraw(string? bearer, string id = "reg-123") { var request = new HttpRequestMessage(HttpMethod.Post, $"/self-service/registrations/{id}/withdraw"); if (bearer is not null) request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", bearer); return request; } [Fact] public async Task Rejects_a_withdrawal_without_a_token() { using var factory = new BffFactory(); var response = await factory.CreateClient().SendAsync(Withdraw(bearer: null)); Assert.Equal(HttpStatusCode.Unauthorized, response.StatusCode); Assert.Null(factory.Domain.Withdrawn); } [Fact] public async Task Withdraws_the_callers_registration_forwarding_the_id_and_bsn() { using var factory = new BffFactory(); var response = await factory.CreateClient().SendAsync(Withdraw(TestTokens.Valid("123456782"), "reg-9")); Assert.Equal(HttpStatusCode.NoContent, response.StatusCode); Assert.Equal(("reg-9", "123456782"), factory.Domain.Withdrawn); } [Fact] public async Task Relays_not_found_when_the_registration_is_unknown_or_not_the_callers() { using var factory = new BffFactory(); factory.Domain.WithdrawSucceeds = false; var response = await factory.CreateClient().SendAsync(Withdraw(TestTokens.Valid("123456782"))); Assert.Equal(HttpStatusCode.NotFound, response.StatusCode); } private static HttpRequestMessage ProvideDocuments(string? bearer, string id = "reg-123") { var request = new HttpRequestMessage(HttpMethod.Post, $"/self-service/registrations/{id}/documents") { // The portal base64-encodes the file client-side and posts it as JSON (S-10b); the bsn is // never in the body — it comes from the DigiD token. Content = JsonContent.Create(new { contentBase64 = Convert.ToBase64String([1, 2, 3]), fileName = "diploma.pdf", contentType = "application/pdf", }), }; if (bearer is not null) request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", bearer); return request; } [Fact] public async Task Rejects_providing_documents_without_a_token() { using var factory = new BffFactory(); var response = await factory.CreateClient().SendAsync(ProvideDocuments(bearer: null)); Assert.Equal(HttpStatusCode.Unauthorized, response.StatusCode); Assert.Null(factory.Domain.DocumentsProvidedFor); } [Fact] public async Task Provides_documents_for_the_callers_registration_forwarding_id_bsn_and_file() { using var factory = new BffFactory(); var response = await factory.CreateClient().SendAsync(ProvideDocuments(TestTokens.Valid("123456782"), "reg-9")); Assert.Equal(HttpStatusCode.NoContent, response.StatusCode); var provided = factory.Domain.DocumentsProvidedFor; Assert.NotNull(provided); Assert.Equal("reg-9", provided!.Value.RegistrationId); Assert.Equal("123456782", provided.Value.Bsn); Assert.Equal(Convert.ToBase64String([1, 2, 3]), provided.Value.ContentBase64); Assert.Equal("diploma.pdf", provided.Value.FileName); } [Fact] public async Task Relays_not_found_providing_documents_for_an_unknown_or_not_owned_registration() { using var factory = new BffFactory(); factory.Domain.ProvideDocumentsSucceeds = false; var response = await factory.CreateClient().SendAsync(ProvideDocuments(TestTokens.Valid("123456782"))); Assert.Equal(HttpStatusCode.NotFound, response.StatusCode); } private sealed record SubmitAcceptedDto(string RegistrationId, string Status); }