using System; using System.IO; using Microsoft.Data.Sqlite; using Notification.Core; using Xunit; using ytLive.Services; using ytLive.ViewModels; namespace ytLive.Tests; [Collection("RealApp")] public sealed class StickyNotificationIntegrationTests { private readonly RealAppHost _app; public StickyNotificationIntegrationTests(RealAppHost app) => _app = app; [Fact] public void StickyMode_Persists_AndMakesEverySeverityClickDismissible() => _app.Run(() => { var tempDb = Path.Combine(Path.GetTempPath(), $"ytLlive-sticky-toast-{Guid.NewGuid():N}.db"); MainViewModel.LayoutPathOverride = tempDb; MainWindow? window = null; try { window = new MainWindow(); window.Show(); var vm = (MainViewModel)window.DataContext; Assert.False(vm.StickyAlertsUntilDismissed, "sticky notifications should default off"); vm.StickyAlertsUntilDismissed = true; window.Close(); window = null; SqliteConnection.ClearAllPools(); window = new MainWindow(); window.Show(); var restored = (MainViewModel)window.DataContext; Assert.True(restored.StickyAlertsUntilDismissed); var service = new NotificationService(System.Windows.Application.Current?.Dispatcher, () => restored.StickyAlertsUntilDismissed); var sticky = service.BuildRequestForCurrentSettings("Upload", "Recovered", AppNotificationSeverity.Info); Assert.Equal(TimeSpan.MaxValue, sticky.ExpirationTime); Assert.True(sticky.CloseOnClick); restored.StickyAlertsUntilDismissed = false; var transient = service.BuildRequestForCurrentSettings("Upload", "Recovered", AppNotificationSeverity.Info); Assert.Equal(TimeSpan.FromSeconds(4), transient.ExpirationTime); Assert.False(transient.CloseOnClick, "disabling sticky mode restores timed, non-click-dismissable alerts"); var settings = SourceAssert.Text("Controls", "SettingsDrawer.xaml"); Assert.Contains("Content=\"Keep alerts until dismissed\"", settings); Assert.Contains("Binding StickyAlertsUntilDismissed", settings); } finally { window?.Close(); MainViewModel.LayoutPathOverride = null; SqliteConnection.ClearAllPools(); try { File.Delete(tempDb); } catch { /* best-effort cleanup */ } } }); }