Files
LehrerApp/LehrerApp.Desktop.Tests/UntisHubServiceTests.cs
T
adminandClaude Sonnet 5 ba52109eaa
CI / build-and-test (push) Canceled after 0s
feat: Untis-Hub für WebUntis-Sync-Gesundheitsstatus
Zeigt die Fälligkeit der vier bestehenden, manuell ausgelösten WebUntis-Abgleiche
(Fehlzeiten je Lerngruppe, offene Stunden, Klassenbuch-, Hausaufgabenabgleich) in
einem neuen Hub-Fenster, ohne selbst WebUntis anzufragen - nur gespeicherte
Zeitstempel werden ausgewertet. Konsolidiert die bisher verstreuten Einstiegspunkte
(Sidebar-Button, Dashboard-Buttons) in ein neues WebUntis-Menü plus einen
kompakten Gesundheits-Indikator auf dem Dashboard.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-10 23:41:12 +02:00

112 lines
4.2 KiB
C#

using LehrerApp.Core.Models;
using LehrerApp.Desktop.Services;
using Xunit;
namespace LehrerApp.Desktop.Tests;
public sealed class UntisHubServiceTests
{
private static readonly DateTime UtcNow = new(2026, 9, 10, 8, 0, 0, DateTimeKind.Utc);
private static LearningGroup Group(string name, int? webUntisLessonId, bool isActive = true) =>
new() { Name = name, WebUntisLessonId = webUntisLessonId, IsActive = isActive };
[Fact]
public void BuildRows_ProGruppeMitLessonId_ZweiFehlzeitenzeilenPlusDreiGlobaleZeilen()
{
var group = Group("9a", 42);
var rows = UntisHubService.BuildRows([group], [], UtcNow);
Assert.Equal(5, rows.Count);
Assert.Equal(2, rows.Count(r => r.GroupId == group.Id));
Assert.Contains(rows, r => r.Kind == UntisHubJobKind.FehlzeitenKurz && r.GroupId == group.Id);
Assert.Contains(rows, r => r.Kind == UntisHubJobKind.FehlzeitenLang && r.GroupId == group.Id);
Assert.Contains(rows, r => r.Kind == UntisHubJobKind.OffenePeriods && r.GroupId == null);
Assert.Contains(rows, r => r.Kind == UntisHubJobKind.Klassenbuchabgleich && r.GroupId == null);
Assert.Contains(rows, r => r.Kind == UntisHubJobKind.Hausaufgabenabgleich && r.GroupId == null);
}
[Fact]
public void BuildRows_NieGeprueft_GiltAlsUeberfaellig()
{
var rows = UntisHubService.BuildRows([], [], UtcNow);
Assert.All(rows, r => Assert.Equal(UntisHubDueState.Overdue, r.DueState));
}
[Fact]
public void BuildRows_FehlzeitenKurzVorSechsTagen_GiltAlsOk()
{
var group = Group("9a", 42);
var state = new UntisHubJobState
{
Kind = UntisHubJobKind.FehlzeitenKurz, GroupId = group.Id, LastRunAt = UtcNow.AddDays(-6),
};
var rows = UntisHubService.BuildRows([group], [state], UtcNow);
var row = rows.Single(r => r.Kind == UntisHubJobKind.FehlzeitenKurz);
Assert.Equal(UntisHubDueState.Ok, row.DueState);
}
[Fact]
public void BuildRows_FehlzeitenKurzVorSechzehnTagen_GiltAlsFaellig()
{
var group = Group("9a", 42);
var state = new UntisHubJobState
{
Kind = UntisHubJobKind.FehlzeitenKurz, GroupId = group.Id, LastRunAt = UtcNow.AddDays(-16),
};
var rows = UntisHubService.BuildRows([group], [state], UtcNow);
var row = rows.Single(r => r.Kind == UntisHubJobKind.FehlzeitenKurz);
Assert.Equal(UntisHubDueState.Due, row.DueState);
}
[Fact]
public void BuildRows_FehlzeitenKurzVorZweiundzwanzigTagen_GiltAlsUeberfaellig()
{
var group = Group("9a", 42);
var state = new UntisHubJobState
{
Kind = UntisHubJobKind.FehlzeitenKurz, GroupId = group.Id, LastRunAt = UtcNow.AddDays(-22),
};
var rows = UntisHubService.BuildRows([group], [state], UtcNow);
var row = rows.Single(r => r.Kind == UntisHubJobKind.FehlzeitenKurz);
Assert.Equal(UntisHubDueState.Overdue, row.DueState);
}
[Fact]
public void BuildRows_FehlzeitenLangHatDeutlichLaengereKadenzAlsKurz()
{
var group = Group("9a", 42);
var lastRunAt = UtcNow.AddDays(-40);
var states = new List<UntisHubJobState>
{
new() { Kind = UntisHubJobKind.FehlzeitenKurz, GroupId = group.Id, LastRunAt = lastRunAt },
new() { Kind = UntisHubJobKind.FehlzeitenLang, GroupId = group.Id, LastRunAt = lastRunAt },
};
var rows = UntisHubService.BuildRows([group], states, UtcNow);
Assert.Equal(UntisHubDueState.Overdue, rows.Single(r => r.Kind == UntisHubJobKind.FehlzeitenKurz).DueState);
Assert.Equal(UntisHubDueState.Ok, rows.Single(r => r.Kind == UntisHubJobKind.FehlzeitenLang).DueState);
}
[Fact]
public void BuildRows_GruppeOhneWebUntisLessonId_WirdVonAufrufseiteAusgeschlossen()
{
// GetRows() filtert vorab auf WebUntisLessonId != null (siehe UntisHubService.GetRows) -
// BuildRows selbst bekommt bereits nur die eligible-Gruppen übergeben.
var eligible = new List<LearningGroup> { Group("9a", 42) };
var rows = UntisHubService.BuildRows(eligible, [], UtcNow);
Assert.Equal(2, rows.Count(r => r.GroupId != null));
}
}