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() 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); } } }