Files
atomic-design-poc/backend/tests/BigRegister.Tests/StamdataEndpointTests.cs
T
ehoandClaude Sonnet 5 8560746d15 refactor: strip WP-/RB- ticket refs from backend (RD-19)
The backend half of the sweep RD-18 did for the front end. git blame
holds the provenance and stays correct when the code moves; the
comment names a closed ticket and tells the reader nothing the
sentence around it does not.

public/letter.css and LetterHtml.golden.html change together, because
the renderer inlines the CSS and the golden file snapshots the
result.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-04 21:48:08 +02:00

79 lines
3.1 KiB
C#

using System.Net;
using System.Net.Http.Json;
using BigRegister.Api.Contracts;
using Microsoft.AspNetCore.Mvc.Testing;
namespace BigRegister.Tests;
/// <summary>
/// The stamdata maintenance reads (ADR-0004): admin-only, generic (schema + rows), and the
/// valid-time peildatum filter. The editor consumes these; the edit itself lands as a PR.
/// </summary>
public class StamdataEndpointTests(TestWebApplicationFactory factory) : IClassFixture<TestWebApplicationFactory>
{
private readonly HttpClient _client = factory.CreateClient();
private HttpRequestMessage Req(HttpMethod method, string path, string? role = null)
{
var req = new HttpRequestMessage(method, path);
if (role is not null) req.Headers.Add("X-Role", role);
return req;
}
[Fact]
public async Task Stamdata_reads_are_admin_only()
{
Assert.Equal(HttpStatusCode.Forbidden, (await _client.SendAsync(Req(HttpMethod.Get, "/api/v1/stamdata"))).StatusCode);
Assert.Equal(HttpStatusCode.Forbidden, (await _client.SendAsync(Req(HttpMethod.Get, "/api/v1/stamdata/professions", role: "drafter"))).StatusCode);
}
[Fact]
public async Task Table_list_exposes_the_reflected_schema()
{
var res = await _client.SendAsync(Req(HttpMethod.Get, "/api/v1/stamdata", role: "admin"));
res.EnsureSuccessStatusCode();
var tables = (await res.Content.ReadFromJsonAsync<List<StamdataTableSummaryDto>>())!;
var professions = tables.Single(t => t.Id == "professions");
Assert.True(professions.Temporal);
Assert.True(professions.Columns[0].IsKey);
Assert.Equal("program", professions.Columns[0].Name);
Assert.Contains(professions.Columns, c => c.Name == "geldigVan" && c.Type == "date");
}
[Fact]
public async Task Table_returns_all_rows_without_a_peildatum()
{
var res = await _client.SendAsync(Req(HttpMethod.Get, "/api/v1/stamdata/professions", role: "admin"));
res.EnsureSuccessStatusCode();
var table = (await res.Content.ReadFromJsonAsync<StamdataTableDto>())!;
Assert.Equal(5, table.Rows.Count);
}
[Fact]
public async Task Peildatum_before_the_seed_windows_hides_every_row()
{
// Seed mappings start 2000-01-01; a 1999 peildatum yields none (valid-time filter works).
var res = await _client.SendAsync(Req(HttpMethod.Get, "/api/v1/stamdata/professions?peildatum=1999-01-01", role: "admin"));
res.EnsureSuccessStatusCode();
var table = (await res.Content.ReadFromJsonAsync<StamdataTableDto>())!;
Assert.Empty(table.Rows);
}
/// BIO-019: DateOnly.Parse used to throw FormatException on unparseable input,
/// surfacing as an unhandled 500 instead of the 400-with-problem-details every other
/// bad-input check in this endpoint file returns.
[Fact]
public async Task Unparseable_peildatum_is_400_not_500()
{
var res = await _client.SendAsync(Req(HttpMethod.Get, "/api/v1/stamdata/professions?peildatum=not-a-date", role: "admin"));
Assert.Equal(HttpStatusCode.BadRequest, res.StatusCode);
}
[Fact]
public async Task Unknown_table_is_404()
{
var res = await _client.SendAsync(Req(HttpMethod.Get, "/api/v1/stamdata/nope", role: "admin"));
Assert.Equal(HttpStatusCode.NotFound, res.StatusCode);
}
}