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:
2026-08-13 11:05:06 +02:00
parent a8b8a40b52
commit 273f459119
15 changed files with 1558 additions and 14 deletions
+13 -8
View File
@@ -2,21 +2,26 @@ namespace LehrerApp.Core.Services;
public class SchoolYearService
{
public string CurrentSchoolYear()
{
var now = DateTime.Today;
return FormatSchoolYear(now.Month >= 8 ? now.Year : now.Year - 1);
}
/// <param name="today">Nur für Tests — Standard ist das heutige Datum.</param>
public string CurrentSchoolYear(DateOnly? today = null) =>
FormatSchoolYear(StartYearFor(today ?? DateOnly.FromDateTime(DateTime.Today)));
public string FormatSchoolYear(int startYear) =>
$"{startYear}/{(startYear + 1) % 100:D2}";
public DateOnly SchoolYearStart(string sy) =>
new(int.Parse(sy.Split('/')[0]), 8, 1);
public DateOnly SchoolYearEnd(string sy) =>
new(int.Parse(sy.Split('/')[0]) + 1, 7, 31);
public List<string> RecentSchoolYears(int count = 5)
/// <param name="today">Nur für Tests — Standard ist das heutige Datum.</param>
public List<string> RecentSchoolYears(int count = 5, DateOnly? today = null)
{
var now = DateTime.Today;
var cur = now.Month >= 8 ? now.Year : now.Year - 1;
var cur = StartYearFor(today ?? DateOnly.FromDateTime(DateTime.Today));
return Enumerable.Range(0, count).Select(i => FormatSchoolYear(cur - i)).ToList();
}
// Schuljahreswechsel liegt am 1. August: ab diesem Tag zählt das neue Schuljahr.
private static int StartYearFor(DateOnly date) => date.Month >= 8 ? date.Year : date.Year - 1;
}