feat(gehege): Reinigungszyklus (Maße, Kapazität, letzte/nächste Reinigung)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-22 22:43:19 +02:00
parent 5e14124322
commit 4e7cd21b70
15 changed files with 2071 additions and 14 deletions

View File

@@ -0,0 +1,118 @@
using System.Net;
using System.Net.Http.Json;
using System.Text.Json;
namespace GerbilManager.Tests;
/// <summary>
/// Gehege-Reinigungszyklus (RennmausPro becken_tb): Enclosure trägt Maße (Size),
/// Kapazität (Capacity), letzte Reinigung (LastCleanedDate) und Reinigungsintervall
/// (CleaningCycleDays). NextCleaningDate = LastCleanedDate + CleaningCycleDays wird
/// berechnet ausgegeben. "mark-cleaned" setzt die letzte Reinigung auf heute.
/// </summary>
public class EnclosureEndpointTests : IClassFixture<ApiFactory>
{
private readonly ApiFactory _factory;
public EnclosureEndpointTests(ApiFactory factory) => _factory = factory;
[Fact]
public async Task Post_persists_cleaning_fields_and_computes_next_cleaning()
{
var client = _factory.CreateClient();
var resp = await client.PostAsJsonAsync("/enclosures", new
{
name = "Reinigungs-Becken",
notes = "Test",
size = "120×50 cm",
capacity = 6,
lastCleanedDate = "2026-06-01",
cleaningCycleDays = 14,
});
Assert.Equal(HttpStatusCode.Created, resp.StatusCode);
var dto = JsonDocument.Parse(await resp.Content.ReadAsStringAsync()).RootElement;
Assert.Equal("120×50 cm", dto.GetProperty("size").GetString());
Assert.Equal(6, dto.GetProperty("capacity").GetInt32());
Assert.Equal("2026-06-01", dto.GetProperty("lastCleanedDate").GetString());
Assert.Equal(14, dto.GetProperty("cleaningCycleDays").GetInt32());
// 2026-06-01 + 14 Tage = 2026-06-15
Assert.Equal("2026-06-15", dto.GetProperty("nextCleaningDate").GetString());
}
[Fact]
public async Task NextCleaning_is_null_without_cycle_or_lastCleaned()
{
var client = _factory.CreateClient();
// Nur letzte Reinigung, kein Zyklus -> keine nächste fällige Reinigung.
var resp = await client.PostAsJsonAsync("/enclosures", new
{
name = "Becken ohne Zyklus",
lastCleanedDate = "2026-06-01",
});
var dto = JsonDocument.Parse(await resp.Content.ReadAsStringAsync()).RootElement;
Assert.Equal(JsonValueKind.Null, dto.GetProperty("nextCleaningDate").ValueKind);
Assert.Equal(JsonValueKind.Null, dto.GetProperty("cleaningCycleDays").ValueKind);
}
[Fact]
public async Task Put_updates_cleaning_fields()
{
var client = _factory.CreateClient();
var created = JsonDocument.Parse(await (await client.PostAsJsonAsync("/enclosures", new
{
name = "Becken-Edit",
cleaningCycleDays = 7,
})).Content.ReadAsStringAsync()).RootElement;
var id = created.GetProperty("id").GetString();
var put = await client.PutAsJsonAsync($"/enclosures/{id}", new
{
name = "Becken-Edit",
size = "80×40 cm",
capacity = 4,
lastCleanedDate = "2026-05-20",
cleaningCycleDays = 10,
});
Assert.Equal(HttpStatusCode.NoContent, put.StatusCode);
var dto = JsonDocument.Parse(await client.GetStringAsync($"/enclosures/{id}")).RootElement;
Assert.Equal("80×40 cm", dto.GetProperty("size").GetString());
Assert.Equal(4, dto.GetProperty("capacity").GetInt32());
Assert.Equal("2026-05-20", dto.GetProperty("lastCleanedDate").GetString());
Assert.Equal(10, dto.GetProperty("cleaningCycleDays").GetInt32());
Assert.Equal("2026-05-30", dto.GetProperty("nextCleaningDate").GetString());
}
[Fact]
public async Task MarkCleaned_sets_lastCleaned_to_today()
{
var client = _factory.CreateClient();
var created = JsonDocument.Parse(await (await client.PostAsJsonAsync("/enclosures", new
{
name = "Becken-Mark",
cleaningCycleDays = 21,
lastCleanedDate = "2020-01-01",
})).Content.ReadAsStringAsync()).RootElement;
var id = created.GetProperty("id").GetString();
var resp = await client.PostAsync($"/enclosures/{id}/mark-cleaned", null);
Assert.Equal(HttpStatusCode.OK, resp.StatusCode);
var dto = JsonDocument.Parse(await resp.Content.ReadAsStringAsync()).RootElement;
var today = DateOnly.FromDateTime(DateTime.Today);
Assert.Equal(today.ToString("yyyy-MM-dd"), dto.GetProperty("lastCleanedDate").GetString());
Assert.Equal(today.AddDays(21).ToString("yyyy-MM-dd"), dto.GetProperty("nextCleaningDate").GetString());
}
[Fact]
public async Task MarkCleaned_unknown_id_returns_404()
{
var client = _factory.CreateClient();
var resp = await client.PostAsync($"/enclosures/{Guid.NewGuid()}/mark-cleaned", null);
Assert.Equal(HttpStatusCode.NotFound, resp.StatusCode);
}
}