using LehrerApp.Core.Services; using Xunit; namespace LehrerApp.Tests; public class SchoolYearServiceTests { private readonly SchoolYearService _sut = new(); // ── FormatSchoolYear ────────────────────────────────────────────────────── [Fact] public void FormatSchoolYear_NormalerJahrgang() { Assert.Equal("2025/26", _sut.FormatSchoolYear(2025)); } [Fact] public void FormatSchoolYear_JahrhundertwechselWirdZweistelligDargestellt() { // 1999 -> 2000, aber zweistellig als "00", nicht "100" oder leer. Assert.Equal("1999/00", _sut.FormatSchoolYear(1999)); } // ── CurrentSchoolYear: Jahreswechsel am 1. August ──────────────────────── [Fact] public void CurrentSchoolYear_AmSchuljahreswechsel_ZaehltBereitsDasNeueJahr() { // 1. August ist der erste Tag des neuen Schuljahres. var result = _sut.CurrentSchoolYear(new DateOnly(2025, 8, 1)); Assert.Equal("2025/26", result); } [Fact] public void CurrentSchoolYear_TagVorDemWechsel_GehoertNochZumAltenSchuljahr() { // 31. Juli ist der letzte Tag des alten Schuljahres. var result = _sut.CurrentSchoolYear(new DateOnly(2025, 7, 31)); Assert.Equal("2024/25", result); } [Fact] public void CurrentSchoolYear_MittenImHerbst_GehoertZumLaufendenSchuljahr() { var result = _sut.CurrentSchoolYear(new DateOnly(2025, 11, 15)); Assert.Equal("2025/26", result); } [Fact] public void CurrentSchoolYear_ImJanuar_GehoertNochZumImVorjahrBegonnenenSchuljahr() { // Der Kalenderjahreswechsel (1. Januar) ist NICHT der Schuljahreswechsel. var result = _sut.CurrentSchoolYear(new DateOnly(2026, 1, 15)); Assert.Equal("2025/26", result); } [Fact] public void CurrentSchoolYear_OhneParameter_VerwendetHeutigesDatum() { var expectedStartYear = DateTime.Today.Month >= 8 ? DateTime.Today.Year : DateTime.Today.Year - 1; Assert.Equal(_sut.FormatSchoolYear(expectedStartYear), _sut.CurrentSchoolYear()); } // ── SchoolYearStart / SchoolYearEnd ────────────────────────────────────── [Fact] public void SchoolYearStart_ErsterAugust() { Assert.Equal(new DateOnly(2025, 8, 1), _sut.SchoolYearStart("2025/26")); } [Fact] public void SchoolYearEnd_EinunddreissigsterJuliDesFolgejahres() { Assert.Equal(new DateOnly(2026, 7, 31), _sut.SchoolYearEnd("2025/26")); } [Fact] public void SchoolYearStartUndEnd_SchliessenLueckenlosAneinanderAn() { // Kein Tag darf zwischen zwei aufeinanderfolgenden Schuljahren fehlen oder sich überlappen. var endeAlt = _sut.SchoolYearEnd("2025/26"); var startNeu = _sut.SchoolYearStart("2026/27"); Assert.Equal(startNeu, endeAlt.AddDays(1)); } // ── RecentSchoolYears ───────────────────────────────────────────────────── [Fact] public void RecentSchoolYears_GibtAnzahlWieAngefordertZurueck() { var result = _sut.RecentSchoolYears(3, new DateOnly(2025, 9, 1)); Assert.Equal(["2025/26", "2024/25", "2023/24"], result); } [Fact] public void RecentSchoolYears_StandardanzahlIstFuenf() { var result = _sut.RecentSchoolYears(today: new DateOnly(2025, 9, 1)); Assert.Equal(5, result.Count); } [Fact] public void RecentSchoolYears_ErsterEintragIstDasAktuelleSchuljahr() { var today = new DateOnly(2025, 3, 1); // Januar-Fall: gehört noch zu 2024/25 Assert.Equal(_sut.CurrentSchoolYear(today), _sut.RecentSchoolYears(today: today)[0]); } }