Update Sync

This commit is contained in:
2026-08-25 21:30:00 +02:00
parent 7245196689
commit 5e16ebf1bf
5 changed files with 154 additions and 17 deletions
+89
View File
@@ -229,6 +229,95 @@ public sealed class SyncEngineTests
Assert.Equal(0, temp.Queue.PendingCount());
}
[Fact]
public async Task SyncNowAsync_MehrAlsEinPushBatch_LeertQueueInEinemSync()
{
using var temp = new TempEventQueue();
for (var i = 0; i < SyncProtocol.PushBatchSize + 5; i++)
temp.Queue.Enqueue("this-device", DeviceType.Desktop,
"Lesson", Guid.NewGuid().ToString(), "Save", $"payload-{i}");
var pushedBatchSizes = new List<int>();
long serverSeq = 0;
var handler = new FakeHttpMessageHandler(req =>
{
if (req.RequestUri!.AbsolutePath == "/api/sync/push")
{
var events = req.Content!.ReadFromJsonAsync<List<SyncEvent>>().GetAwaiter().GetResult()!;
pushedBatchSizes.Add(events.Count);
var assigned = events.ToDictionary(e => e.EventId, _ => ++serverSeq);
return new HttpResponseMessage(HttpStatusCode.OK)
{
Content = JsonContent.Create(new PushResponse
{ ServerSequenceNr = serverSeq, AssignedServerSeqs = assigned }),
};
}
return new HttpResponseMessage(HttpStatusCode.OK)
{ Content = JsonContent.Create(new PullResponse()) };
});
var engine = MakeEngine(temp, handler);
var result = await engine.SyncNowAsync();
Assert.True(result.Success);
Assert.Equal(SyncProtocol.PushBatchSize + 5, result.EventsPushed);
Assert.Equal([SyncProtocol.PushBatchSize, 5], pushedBatchSizes);
Assert.Equal(0, temp.Queue.PendingCount());
}
[Fact]
public async Task SyncNowAsync_VollerPullBatch_LaedtFolgebatchImSelbenSync()
{
using var temp = new TempEventQueue();
using var db = NewInMemoryContext();
var allEvents = Enumerable.Range(1, SyncProtocol.PullBatchSize + 3)
.Select(sequence =>
{
var student = new Student { FirstName = $"Vorname-{sequence}", LastName = "Beispiel" };
return new SyncEvent
{
DeviceId = "other-device", DeviceType = DeviceType.Desktop,
EntityType = nameof(Student), EntityId = student.Id.ToString(),
Operation = "Save", Payload = SyncCrypto.EncryptObject(student, Key),
SequenceNr = sequence,
};
}).ToList();
var pullRequests = 0;
var handler = new FakeHttpMessageHandler(req =>
{
if (req.RequestUri!.AbsolutePath == "/api/sync/pull")
{
pullRequests++;
var since = long.Parse(req.RequestUri.Query.TrimStart('?').Split('&')
.Select(part => part.Split('=')).Single(part => part[0] == "since")[1]);
var events = allEvents.Where(e => e.SequenceNr > since)
.Take(SyncProtocol.PullBatchSize).ToList();
return new HttpResponseMessage(HttpStatusCode.OK)
{
Content = JsonContent.Create(new PullResponse
{
Events = events,
ServerSequenceNr = events.Count == 0 ? since : events[^1].SequenceNr,
}),
};
}
return new HttpResponseMessage(HttpStatusCode.OK)
{ Content = JsonContent.Create(new PushResponse()) };
});
var engine = MakeEngine(temp, handler, new EventApplier(db, Key, versions: temp.Queue));
var dataChangedCount = 0;
engine.DataChanged += () => dataChangedCount++;
var result = await engine.SyncNowAsync();
Assert.True(result.Success);
Assert.Equal(SyncProtocol.PullBatchSize + 3, result.EventsPulled);
Assert.Equal(2, pullRequests);
Assert.Equal(SyncProtocol.PullBatchSize + 3, db.Students.Count());
Assert.Equal(SyncProtocol.PullBatchSize + 3, temp.Queue.GetLastServerSeq());
Assert.Equal(1, dataChangedCount);
}
[Fact]
public async Task PushAsync_SetztBasedOnServerSeqAusLokalerVersionsverfolgung()
{