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.
111 lines
3.9 KiB
C#
111 lines
3.9 KiB
C#
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]);
|
|
}
|
|
}
|