SyncEngine feuert sein erstes StatusChanged bereits im eigenen Konstruktor. Da SyncEngine und SyncStatusViewModel beide DI-Singletons sind und Letzterer Ersteren erst innerhalb der eigenen Factory aus dem Container holt, lief dieser erste Broadcast ab, bevor SyncStatusViewModel überhaupt abonniert hatte - der Status ging verloren, StatusText blieb bis zum nächsten Auto-Sync oder manuellen Sync beim hartcodierten Default "Kein Server konfiguriert". Fix: Konstruktor ruft nach dem Abonnieren zusätzlich einmal OnStatus(engine.Status) mit dem bereits vorhandenen aktuellen Zustand auf. Regressionstest ergänzt - dabei fehlte LehrerApp.Desktop.Tests das DisableTestParallelization-Attribut (gleicher bekannter LiteDB-BsonMapper.Global-Bug wie in den anderen Testprojekten, sobald zwei Testklassen parallel LiteDbContext konstruieren). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
63 lines
2.2 KiB
C#
63 lines
2.2 KiB
C#
using LehrerApp.Data;
|
|
using LehrerApp.Desktop.ViewModels;
|
|
using LehrerApp.Sync;
|
|
using LehrerApp.Sync.Crypto;
|
|
using Xunit;
|
|
|
|
namespace LehrerApp.Desktop.Tests;
|
|
|
|
public sealed class SyncStatusViewModelTests
|
|
{
|
|
[Fact]
|
|
public void Konstruktor_EngineBereitsVorhanden_ZeigtNichtDenNichtKonfiguriertText()
|
|
{
|
|
// SyncEngine feuert sein erstes StatusChanged schon im eigenen Konstruktor - läuft der vor
|
|
// dem Abonnieren in SyncStatusViewModel (z.B. weil beide DI-Singletons sind und
|
|
// GetService<SyncEngine>() den Engine-Konstruktor erst innerhalb der VM-Factory auslöst),
|
|
// ginge dieser erste Status verloren und StatusText bliebe fälschlich beim Default.
|
|
using var temp = new TempSyncEngine();
|
|
|
|
var vm = new SyncStatusViewModel(temp.Engine);
|
|
|
|
Assert.True(vm.IsServerConfigured);
|
|
Assert.NotEqual("Kein Server konfiguriert", vm.StatusText);
|
|
Assert.Equal("Synchronisiert", vm.StatusText);
|
|
}
|
|
|
|
[Fact]
|
|
public void Konstruktor_KeineEngine_ZeigtNichtKonfiguriertText()
|
|
{
|
|
var vm = new SyncStatusViewModel(null);
|
|
|
|
Assert.False(vm.IsServerConfigured);
|
|
Assert.Equal("Kein Server konfiguriert", vm.StatusText);
|
|
}
|
|
|
|
private sealed class TempSyncEngine : IDisposable
|
|
{
|
|
private readonly string _queuePath = Path.Combine(
|
|
Path.GetTempPath(), $"lehrerapp-desktop-tests-{Guid.NewGuid():N}.db");
|
|
private readonly LiteDbContext _db = new(new MemoryStream());
|
|
private readonly HttpClient _http = new();
|
|
public SyncEngine Engine { get; }
|
|
|
|
public TempSyncEngine()
|
|
{
|
|
var queue = new EventQueue(_queuePath);
|
|
var key = SyncCrypto.GenerateKey();
|
|
Engine = new SyncEngine(
|
|
queue, new ConflictResolver(queue), new EventApplier(_db, key),
|
|
new AttachmentSyncer(_db, _http, key), _http,
|
|
new SyncConfig { AutoSyncIntervalMinutes = 5 });
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
Engine.Dispose(); // disposed auch die EventQueue
|
|
_db.Dispose();
|
|
_http.Dispose();
|
|
if (File.Exists(_queuePath)) File.Delete(_queuePath);
|
|
}
|
|
}
|
|
}
|