Baustein 2: Outbound-Hook-Infrastruktur (Kapitel 10)
LiteDbContext.OnChange-Hook (Sync-agnostisch, kein Verweis auf LehrerApp.Sync aus LehrerApp.Data), damit Repositories lokale Schreibvorgaenge signalisieren koennen, ohne dass Data von Sync abhaengt. StudentRepository als Vorlage verdrahtet. GroupRepository.Delete-Kaskade (14 betroffene Collections) nach LiteDbContext.CascadeDeleteGroup extrahiert - reine Verschiebung, kein Verhaltensunterschied, macht sie aber von einem spaeter eingehenden Sync-Ereignis (Baustein 5) wiederverwendbar, ohne ueber Repository-Save/Delete (und damit erneut ueber OnChange) zu laufen. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,60 @@
|
||||
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);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user