using System.Net; using System.Net.Http.Json; using System.Text.Json; namespace GerbilManager.Tests; /// /// 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. /// public class EnclosureEndpointTests : IClassFixture { 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); } }