CI / build-and-test (push) Canceled after 0s
Eine auf einem Gerät zurückgestellte Warnung stand auf den anderen weiter rot oben, weil DashboardWarningSnooze bewusst lokal gehalten war. Save löst jetzt db.OnChange aus, EventApplier übernimmt den Typ. Die Id wird aus (StudentId, WarningTag) abgeleitet, damit zwei Geräte denselben Datensatz beschreiben statt am Unique-Index ux_student_tag zu kollidieren; Schema-Migration 7 schlüsselt bestehende lokale Einträge um. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
103 lines
4.0 KiB
C#
103 lines
4.0 KiB
C#
using LehrerApp.Core.Models;
|
|
using LehrerApp.Data.Repositories;
|
|
using Xunit;
|
|
|
|
namespace LehrerApp.Data.Tests;
|
|
|
|
// Vorlage-Test für den OnChange-Hook (Baustein 2), den die übrigen Repositories in den
|
|
// Bausteinen 3/4 auf dieselbe Weise bekommen.
|
|
public sealed class ChangeHookTests
|
|
{
|
|
private static LiteDbContext NewInMemoryContext() => new(new MemoryStream());
|
|
|
|
[Fact]
|
|
public void StudentRepository_Save_LoestOnChangeMitKorrektenArgumentenAus()
|
|
{
|
|
using var db = NewInMemoryContext();
|
|
var calls = new List<(string EntityType, string EntityId, string Operation, object? Payload)>();
|
|
db.OnChange = (type, id, op, payload) => calls.Add((type, id, op, payload));
|
|
var repo = new StudentRepository(db);
|
|
var student = new Student { FirstName = "Anna", LastName = "Beispiel" };
|
|
|
|
repo.Save(student);
|
|
|
|
var call = Assert.Single(calls);
|
|
Assert.Equal("Student", call.EntityType);
|
|
Assert.Equal(student.Id.ToString(), call.EntityId);
|
|
Assert.Equal("Save", call.Operation);
|
|
Assert.Same(student, call.Payload);
|
|
}
|
|
|
|
[Fact]
|
|
public void StudentRepository_Delete_LoestOnChangeMitNullPayloadAus()
|
|
{
|
|
using var db = NewInMemoryContext();
|
|
var repo = new StudentRepository(db);
|
|
var student = new Student { FirstName = "Anna", LastName = "Beispiel" };
|
|
repo.Save(student);
|
|
var calls = new List<(string EntityType, string EntityId, string Operation, object? Payload)>();
|
|
db.OnChange = (type, id, op, payload) => calls.Add((type, id, op, payload));
|
|
|
|
repo.Delete(student.Id);
|
|
|
|
var call = Assert.Single(calls);
|
|
Assert.Equal("Student", call.EntityType);
|
|
Assert.Equal(student.Id.ToString(), call.EntityId);
|
|
Assert.Equal("Delete", call.Operation);
|
|
Assert.Null(call.Payload);
|
|
}
|
|
|
|
[Fact]
|
|
public void StudentRepository_Save_OhneGesetztenHook_WirftNicht()
|
|
{
|
|
using var db = NewInMemoryContext();
|
|
var repo = new StudentRepository(db);
|
|
|
|
var exception = Record.Exception(() => repo.Save(new Student { FirstName = "Anna", LastName = "Beispiel" }));
|
|
|
|
Assert.Null(exception);
|
|
}
|
|
|
|
// Kein eigener Fall in ChangeHookMatrixTests: UntisHubJobStateRepository kennt kein Delete
|
|
// (siehe IUntisHubJobStateRepository), passt also nicht in deren Save+Delete-Tabellenform.
|
|
[Fact]
|
|
public void UntisHubJobStateRepository_Save_LoestOnChangeAus()
|
|
{
|
|
using var db = NewInMemoryContext();
|
|
var calls = new List<(string EntityType, string EntityId, string Operation, object? Payload)>();
|
|
db.OnChange = (type, id, op, payload) => calls.Add((type, id, op, payload));
|
|
var repo = new UntisHubJobStateRepository(db);
|
|
var state = new UntisHubJobState { Kind = UntisHubJobKind.OffenePeriods, LastRunAt = DateTime.UtcNow };
|
|
|
|
repo.Save(state);
|
|
|
|
var call = Assert.Single(calls);
|
|
Assert.Equal(nameof(UntisHubJobState), call.EntityType);
|
|
Assert.Equal(state.Id.ToString(), call.EntityId);
|
|
Assert.Equal("Save", call.Operation);
|
|
Assert.Same(state, call.Payload);
|
|
}
|
|
|
|
[Fact]
|
|
public void DashboardWarningSnoozeRepository_Save_LoestOnChangeAus()
|
|
{
|
|
using var db = NewInMemoryContext();
|
|
var calls = new List<(string EntityType, string EntityId, string Operation, object? Payload)>();
|
|
db.OnChange = (type, id, op, payload) => calls.Add((type, id, op, payload));
|
|
var repo = new DashboardWarningSnoozeRepository(db);
|
|
var studentId = Guid.NewGuid();
|
|
var snooze = new DashboardWarningSnooze
|
|
{
|
|
StudentId = studentId, WarningTag = "Absentismus", SnoozedUntil = new DateOnly(2026, 10, 12),
|
|
};
|
|
|
|
repo.Save(snooze);
|
|
|
|
var call = Assert.Single(calls);
|
|
Assert.Equal(nameof(DashboardWarningSnooze), call.EntityType);
|
|
Assert.Equal(DashboardWarningSnooze.IdFor(studentId, "Absentismus").ToString(), call.EntityId);
|
|
Assert.Equal("Save", call.Operation);
|
|
Assert.Same(snooze, call.Payload);
|
|
}
|
|
}
|