Files
atomic-design-poc/backend/tests/BigRegister.Tests/Domain/ProfessionsTests.cs
T
ehoandClaude Opus 5 9440ce1345 fix(stamdata): evaluate the profession validity window per call, not at type-load
Professions.ByProgram was a `static readonly` field filtered on
DateTime.Today, so it evaluated once when the type first loaded. Two
consequences, both real:

- A long-running process kept serving the answer it computed at startup. A
  mapping whose geldigVan fell after boot never appeared; one whose geldigTot
  passed never disappeared.
- Both branches of StamdataFile.ActiveOn were unreachable from this caller,
  which is why this table's validity window had no test at all. It is the
  cleanest single explanation for Stamdata's 71.7% branch coverage (BL-005).

Adds ByProgramOn(DateOnly) — the peildatum as an argument, matching
StamdataTable.RowsOn which already parameterizes it — and makes ByProgram a
property delegating to it with today's date. Call sites (DiplomaRules) are
unchanged and keep the same behaviour, now with a current date.

ProfessionsTests covers both ActiveOn branches plus the regression itself:
the same date must give the same answer, a different date a different one.

Found by the testability pass (TE-009).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-26 18:13:38 +02:00

48 lines
1.9 KiB
C#

using BigRegister.Stamdata;
namespace BigRegister.Tests.Domain;
/// <summary>
/// The profession↔program map's validity window (TE-009). `ByProgram` used to be a
/// `static readonly` field filtered on `DateTime.Today` at type-load, so both branches of
/// `StamdataFile.ActiveOn` were unreachable from here and nothing asserted the window at all.
/// Now that the peildatum is a parameter, these are the two branches.
/// </summary>
public class ProfessionsTests
{
[Fact]
public void A_mapping_is_absent_before_its_geldigVan()
{
// Every seeded row starts 2000-01-01; nothing is valid the day before.
Assert.Empty(Professions.ByProgramOn(new DateOnly(1999, 12, 31)));
}
[Fact]
public void A_mapping_is_present_on_and_after_its_geldigVan()
{
Assert.Equal("Arts", Professions.ByProgramOn(new DateOnly(2000, 1, 1))["geneeskunde"]);
Assert.Equal("Arts", Professions.ByProgramOn(new DateOnly(2026, 8, 26))["geneeskunde"]);
}
[Fact]
public void A_closed_mapping_is_absent_from_its_geldigTot_onwards()
{
// geldigTot is exclusive (`on < tot`), so the row drops out on the boundary date itself.
foreach (var m in Professions.Mappings.Where(m => m.GeldigTot is DateOnly))
{
var tot = m.GeldigTot!.Value;
Assert.True(Professions.ByProgramOn(tot.AddDays(-1)).ContainsKey(m.Program));
Assert.False(Professions.ByProgramOn(tot).ContainsKey(m.Program));
}
}
[Fact]
public void ByProgram_is_evaluated_per_call_not_captured_at_type_load()
{
// The regression this guards: a long-running process must not keep serving the answer
// it computed at startup. Same date in, same answer; different date in, different answer.
Assert.Equal(Professions.ByProgram.Count, Professions.ByProgramOn(DateOnly.FromDateTime(DateTime.Today)).Count);
Assert.NotEqual(Professions.ByProgram.Count, Professions.ByProgramOn(new DateOnly(1999, 12, 31)).Count);
}
}