Testabdeckung Kapitel 13.1 (Tests, Fehlerbehandlung)
Vier neue xUnit-Testprojekte (LehrerApp.Tests, .Data.Tests, .Desktop.Tests, .Sync.Tests) mit zusammen 104 Tests: GradingService, SchoolYearService, Repositories gegen In-Memory-LiteDB, Mitarbeits-Aggregation (3.2), Zeugnisnotenberechnung (2.4) und ConflictResolver. Dabei zwei echte Fehler in der Sync-Schicht gefunden und behoben: - SyncEvent.EventId fehlte [BsonId], wodurch EventQueue.Acknowledge() nie etwas aus der Queue löschte. - ConflictResolver verglich Zeitstempel unterschiedlicher DateTimeKind direkt (LiteDB liefert Local statt Utc zurück), was die Gleichstand- Regel außerhalb von UTC+0 verfälschte. SchoolYearService.CurrentSchoolYear()/RecentSchoolYears() um ein optionales today-Argument erweitert, um den Schuljahreswechsel deterministisch zu testen; LiteDbContext um einen Stream-Konstruktor für In-Memory-Tests.
This commit is contained in:
@@ -0,0 +1,110 @@
|
||||
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]);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user