general: test redux

This commit is contained in:
Michael Freno
2026-01-15 15:37:42 -05:00
parent 80edfa8e06
commit 9c6bdaed6a
23 changed files with 2452 additions and 35 deletions

View File

@@ -0,0 +1,135 @@
//
// EnforceModeServiceTests.swift
// GazeTests
//
// Unit tests for EnforceModeService.
//
import XCTest
@testable import Gaze
@MainActor
final class EnforceModeServiceTests: XCTestCase {
var service: EnforceModeService!
override func setUp() async throws {
service = EnforceModeService.shared
}
override func tearDown() async throws {
service.disableEnforceMode()
service = nil
}
// MARK: - Initialization Tests
func testServiceInitialization() {
XCTAssertNotNil(service)
}
func testInitialState() {
XCTAssertFalse(service.isEnforceModeEnabled)
XCTAssertFalse(service.isCameraActive)
XCTAssertFalse(service.userCompliedWithBreak)
}
// MARK: - Enable/Disable Tests
func testEnableEnforceMode() async {
await service.enableEnforceMode()
// May or may not be enabled depending on camera permissions
// Just verify the method doesn't crash
XCTAssertNotNil(service)
}
func testDisableEnforceMode() {
service.disableEnforceMode()
XCTAssertFalse(service.isEnforceModeEnabled)
XCTAssertFalse(service.isCameraActive)
}
func testEnableDisableCycle() async {
await service.enableEnforceMode()
service.disableEnforceMode()
XCTAssertFalse(service.isEnforceModeEnabled)
}
// MARK: - Timer Engine Integration Tests
func testSetTimerEngine() {
let testEnv = TestEnvironment()
let timerEngine = testEnv.container.timerEngine
service.setTimerEngine(timerEngine)
// Should not crash
XCTAssertNotNil(service)
}
// MARK: - Should Enforce Break Tests
func testShouldEnforceBreakWhenDisabled() {
service.disableEnforceMode()
let shouldEnforce = service.shouldEnforceBreak(for: .builtIn(.lookAway))
XCTAssertFalse(shouldEnforce)
}
// MARK: - Camera Tests
func testStopCamera() {
service.stopCamera()
XCTAssertFalse(service.isCameraActive)
}
// MARK: - Compliance Tests
func testCheckUserCompliance() {
service.checkUserCompliance()
// Should not crash
XCTAssertNotNil(service)
}
func testHandleReminderDismissed() {
service.handleReminderDismissed()
// Should not crash
XCTAssertNotNil(service)
}
// MARK: - Test Mode Tests
func testStartTestMode() async {
await service.startTestMode()
XCTAssertTrue(service.isTestMode)
}
func testStopTestMode() {
service.stopTestMode()
XCTAssertFalse(service.isTestMode)
}
func testTestModeCycle() async {
await service.startTestMode()
XCTAssertTrue(service.isTestMode)
service.stopTestMode()
XCTAssertFalse(service.isTestMode)
}
// MARK: - Protocol Conformance Tests
func testConformsToEnforceModeProviding() {
let providing: EnforceModeProviding = service
XCTAssertNotNil(providing)
XCTAssertFalse(providing.isEnforceModeEnabled)
}
}

View File

@@ -0,0 +1,68 @@
//
// FullscreenDetectionServiceTests.swift
// GazeTests
//
// Unit tests for FullscreenDetectionService.
//
import Combine
import XCTest
@testable import Gaze
@MainActor
final class FullscreenDetectionServiceTests: XCTestCase {
var service: FullscreenDetectionService!
var cancellables: Set<AnyCancellable>!
override func setUp() async throws {
service = FullscreenDetectionService()
cancellables = []
}
override func tearDown() async throws {
cancellables = nil
service = nil
}
// MARK: - Initialization Tests
func testServiceInitialization() {
XCTAssertNotNil(service)
}
func testInitialFullscreenState() {
// Initially should not be in fullscreen (unless actually in fullscreen)
XCTAssertNotNil(service.isFullscreenActive)
}
// MARK: - Publisher Tests
func testFullscreenStatePublisher() async throws {
let expectation = XCTestExpectation(description: "Fullscreen state published")
service.$isFullscreenActive
.sink { isFullscreen in
expectation.fulfill()
}
.store(in: &cancellables)
await fulfillment(of: [expectation], timeout: 0.1)
}
// MARK: - Force Update Tests
func testForceUpdate() {
// Should not crash
service.forceUpdate()
XCTAssertNotNil(service.isFullscreenActive)
}
// MARK: - Protocol Conformance Tests
func testConformsToFullscreenDetectionProviding() {
let providing: FullscreenDetectionProviding = service
XCTAssertNotNil(providing)
XCTAssertNotNil(providing.isFullscreenActive)
}
}

View File

@@ -0,0 +1,89 @@
//
// IdleMonitoringServiceTests.swift
// GazeTests
//
// Unit tests for IdleMonitoringService.
//
import Combine
import XCTest
@testable import Gaze
@MainActor
final class IdleMonitoringServiceTests: XCTestCase {
var service: IdleMonitoringService!
var cancellables: Set<AnyCancellable>!
override func setUp() async throws {
service = IdleMonitoringService(idleThresholdMinutes: 5)
cancellables = []
}
override func tearDown() async throws {
cancellables = nil
service = nil
}
// MARK: - Initialization Tests
func testServiceInitialization() {
XCTAssertNotNil(service)
}
func testInitialIdleState() {
// Initially should not be idle
XCTAssertFalse(service.isIdle)
}
func testInitializationWithCustomThreshold() {
let customService = IdleMonitoringService(idleThresholdMinutes: 10)
XCTAssertNotNil(customService)
}
// MARK: - Threshold Tests
func testUpdateThreshold() {
service.updateThreshold(minutes: 15)
// Should not crash
XCTAssertNotNil(service)
}
func testUpdateThresholdMultipleTimes() {
service.updateThreshold(minutes: 5)
service.updateThreshold(minutes: 10)
service.updateThreshold(minutes: 3)
XCTAssertNotNil(service)
}
// MARK: - Publisher Tests
func testIdleStatePublisher() async throws {
let expectation = XCTestExpectation(description: "Idle state published")
service.$isIdle
.sink { isIdle in
expectation.fulfill()
}
.store(in: &cancellables)
await fulfillment(of: [expectation], timeout: 0.1)
}
// MARK: - Force Update Tests
func testForceUpdate() {
service.forceUpdate()
XCTAssertNotNil(service.isIdle)
}
// MARK: - Protocol Conformance Tests
func testConformsToIdleMonitoringProviding() {
let providing: IdleMonitoringProviding = service
XCTAssertNotNil(providing)
XCTAssertNotNil(providing.isIdle)
}
}

View File

@@ -0,0 +1,61 @@
//
// LoggingManagerTests.swift
// GazeTests
//
// Unit tests for LoggingManager.
//
import os.log
import XCTest
@testable import Gaze
final class LoggingManagerTests: XCTestCase {
var loggingManager: LoggingManager!
override func setUp() {
loggingManager = LoggingManager.shared
}
override func tearDown() {
loggingManager = nil
}
// MARK: - Initialization Tests
func testLoggingManagerInitialization() {
XCTAssertNotNil(loggingManager)
}
func testLoggersExist() {
XCTAssertNotNil(loggingManager.appLogger)
XCTAssertNotNil(loggingManager.timerLogger)
XCTAssertNotNil(loggingManager.systemLogger)
}
// MARK: - Configuration Tests
func testConfigureLogging() {
// Should not crash
loggingManager.configureLogging()
XCTAssertNotNil(loggingManager)
}
// MARK: - Logger Usage Tests
func testAppLoggerLogging() {
// Should not crash
loggingManager.appLogger.info("Test app log")
XCTAssertNotNil(loggingManager.appLogger)
}
func testTimerLoggerLogging() {
loggingManager.timerLogger.info("Test timer log")
XCTAssertNotNil(loggingManager.timerLogger)
}
func testSystemLoggerLogging() {
loggingManager.systemLogger.info("Test system log")
XCTAssertNotNil(loggingManager.systemLogger)
}
}

View File

@@ -0,0 +1,187 @@
//
// SettingsManagerTests.swift
// GazeTests
//
// Unit tests for SettingsManager service.
//
import Combine
import XCTest
@testable import Gaze
@MainActor
final class SettingsManagerTests: XCTestCase {
var settingsManager: SettingsManager!
var cancellables: Set<AnyCancellable>!
override func setUp() async throws {
settingsManager = SettingsManager.shared
cancellables = []
// Reset to defaults for testing
settingsManager.resetToDefaults()
}
override func tearDown() async throws {
cancellables = nil
settingsManager = nil
}
// MARK: - Initialization Tests
func testSettingsManagerInitialization() {
XCTAssertNotNil(settingsManager)
XCTAssertNotNil(settingsManager.settings)
}
func testDefaultSettingsValues() {
let defaults = AppSettings.defaults
XCTAssertTrue(defaults.lookAwayTimer.enabled)
XCTAssertTrue(defaults.blinkTimer.enabled)
XCTAssertTrue(defaults.postureTimer.enabled)
XCTAssertFalse(defaults.hasCompletedOnboarding)
}
// MARK: - Timer Configuration Tests
func testGetTimerConfiguration() {
let lookAwayConfig = settingsManager.timerConfiguration(for: .lookAway)
XCTAssertNotNil(lookAwayConfig)
XCTAssertTrue(lookAwayConfig.enabled)
}
func testUpdateTimerConfiguration() {
var config = settingsManager.timerConfiguration(for: .lookAway)
config.intervalSeconds = 1500
config.enabled = false
settingsManager.updateTimerConfiguration(for: .lookAway, configuration: config)
let updated = settingsManager.timerConfiguration(for: .lookAway)
XCTAssertEqual(updated.intervalSeconds, 1500)
XCTAssertFalse(updated.enabled)
}
func testAllTimerConfigurations() {
let allConfigs = settingsManager.allTimerConfigurations()
XCTAssertEqual(allConfigs.count, 3)
XCTAssertNotNil(allConfigs[.lookAway])
XCTAssertNotNil(allConfigs[.blink])
XCTAssertNotNil(allConfigs[.posture])
}
func testUpdateMultipleTimerConfigurations() {
var lookAway = settingsManager.timerConfiguration(for: .lookAway)
lookAway.intervalSeconds = 1000
settingsManager.updateTimerConfiguration(for: .lookAway, configuration: lookAway)
var blink = settingsManager.timerConfiguration(for: .blink)
blink.intervalSeconds = 250
settingsManager.updateTimerConfiguration(for: .blink, configuration: blink)
XCTAssertEqual(settingsManager.timerConfiguration(for: .lookAway).intervalSeconds, 1000)
XCTAssertEqual(settingsManager.timerConfiguration(for: .blink).intervalSeconds, 250)
}
// MARK: - Settings Publisher Tests
func testSettingsPublisherEmitsChanges() async throws {
let expectation = XCTestExpectation(description: "Settings changed")
var receivedSettings: AppSettings?
settingsManager.$settings
.dropFirst() // Skip initial value
.sink { settings in
receivedSettings = settings
expectation.fulfill()
}
.store(in: &cancellables)
// Trigger change
settingsManager.settings.playSounds = !settingsManager.settings.playSounds
await fulfillment(of: [expectation], timeout: 1.0)
XCTAssertNotNil(receivedSettings)
}
// MARK: - Save/Load Tests
func testSave() {
settingsManager.settings.playSounds = false
settingsManager.save()
// Save is debounced, so just verify it doesn't crash
XCTAssertFalse(settingsManager.settings.playSounds)
}
func testSaveImmediately() {
settingsManager.settings.launchAtLogin = true
settingsManager.saveImmediately()
// Verify the setting persisted
XCTAssertTrue(settingsManager.settings.launchAtLogin)
}
func testLoad() {
// Load should restore settings from UserDefaults
settingsManager.load()
XCTAssertNotNil(settingsManager.settings)
}
// MARK: - Reset Tests
func testResetToDefaults() {
// Modify settings
settingsManager.settings.playSounds = false
settingsManager.settings.launchAtLogin = true
var config = settingsManager.timerConfiguration(for: .lookAway)
config.intervalSeconds = 5000
settingsManager.updateTimerConfiguration(for: .lookAway, configuration: config)
// Reset
settingsManager.resetToDefaults()
// Verify reset to defaults
let defaults = AppSettings.defaults
XCTAssertEqual(settingsManager.settings.playSounds, defaults.playSounds)
XCTAssertEqual(settingsManager.settings.launchAtLogin, defaults.launchAtLogin)
}
// MARK: - Onboarding Tests
func testOnboardingCompletion() {
XCTAssertFalse(settingsManager.settings.hasCompletedOnboarding)
settingsManager.settings.hasCompletedOnboarding = true
XCTAssertTrue(settingsManager.settings.hasCompletedOnboarding)
}
// MARK: - General Settings Tests
func testPlaySoundsToggle() {
let initial = settingsManager.settings.playSounds
settingsManager.settings.playSounds = !initial
XCTAssertNotEqual(settingsManager.settings.playSounds, initial)
}
func testLaunchAtLoginToggle() {
let initial = settingsManager.settings.launchAtLogin
settingsManager.settings.launchAtLogin = !initial
XCTAssertNotEqual(settingsManager.settings.launchAtLogin, initial)
}
// MARK: - Smart Mode Settings Tests
func testSmartModeSettings() {
settingsManager.settings.smartMode.autoPauseOnFullscreen = true
settingsManager.settings.smartMode.autoPauseOnIdle = true
settingsManager.settings.smartMode.idleThresholdMinutes = 10
XCTAssertTrue(settingsManager.settings.smartMode.autoPauseOnFullscreen)
XCTAssertTrue(settingsManager.settings.smartMode.autoPauseOnIdle)
XCTAssertEqual(settingsManager.settings.smartMode.idleThresholdMinutes, 10)
}
}

View File

@@ -0,0 +1,302 @@
//
// TimerEngineTests.swift
// GazeTests
//
// Unit tests for TimerEngine service.
//
import Combine
import XCTest
@testable import Gaze
@MainActor
final class TimerEngineTests: XCTestCase {
var testEnv: TestEnvironment!
var timerEngine: TimerEngine!
var cancellables: Set<AnyCancellable>!
override func setUp() async throws {
testEnv = TestEnvironment(settings: .defaults)
timerEngine = testEnv.container.timerEngine
cancellables = []
}
override func tearDown() async throws {
timerEngine?.stop()
cancellables = nil
timerEngine = nil
testEnv = nil
}
// MARK: - Initialization Tests
func testTimerEngineInitialization() {
XCTAssertNotNil(timerEngine)
XCTAssertEqual(timerEngine.timerStates.count, 0)
XCTAssertNil(timerEngine.activeReminder)
}
func testTimerEngineWithCustomTimeProvider() {
let timeProvider = MockTimeProvider()
let engine = TimerEngine(
settingsManager: testEnv.settingsManager,
timeProvider: timeProvider
)
XCTAssertNotNil(engine)
}
// MARK: - Start/Stop Tests
func testStartTimers() {
timerEngine.start()
// Should create timer states for enabled timers
XCTAssertGreaterThan(timerEngine.timerStates.count, 0)
}
func testStopTimers() {
timerEngine.start()
let initialCount = timerEngine.timerStates.count
XCTAssertGreaterThan(initialCount, 0)
timerEngine.stop()
// Timers should be cleared
XCTAssertEqual(timerEngine.timerStates.count, 0)
}
func testRestartTimers() {
timerEngine.start()
let firstCount = timerEngine.timerStates.count
timerEngine.stop()
XCTAssertEqual(timerEngine.timerStates.count, 0)
timerEngine.start()
let secondCount = timerEngine.timerStates.count
XCTAssertEqual(firstCount, secondCount)
}
// MARK: - Pause/Resume Tests
func testPauseAllTimers() {
timerEngine.start()
timerEngine.pause()
for (_, state) in timerEngine.timerStates {
XCTAssertTrue(state.isPaused)
}
}
func testResumeAllTimers() {
timerEngine.start()
timerEngine.pause()
timerEngine.resume()
for (_, state) in timerEngine.timerStates {
XCTAssertFalse(state.isPaused)
}
}
func testPauseSpecificTimer() {
timerEngine.start()
guard let firstTimer = timerEngine.timerStates.keys.first else {
XCTFail("No timers available")
return
}
timerEngine.pauseTimer(identifier: firstTimer)
let state = timerEngine.timerStates[firstTimer]
XCTAssertTrue(state?.isPaused ?? false)
}
func testResumeSpecificTimer() {
timerEngine.start()
guard let firstTimer = timerEngine.timerStates.keys.first else {
XCTFail("No timers available")
return
}
timerEngine.pauseTimer(identifier: firstTimer)
XCTAssertTrue(timerEngine.isTimerPaused(firstTimer))
timerEngine.resumeTimer(identifier: firstTimer)
XCTAssertFalse(timerEngine.isTimerPaused(firstTimer))
}
// MARK: - Skip Tests
func testSkipNext() {
timerEngine.start()
guard let firstTimer = timerEngine.timerStates.keys.first else {
XCTFail("No timers available")
return
}
timerEngine.skipNext(identifier: firstTimer)
// Timer should be reset
XCTAssertNotNil(timerEngine.timerStates[firstTimer])
}
// MARK: - Reminder Tests
func testTriggerReminder() async throws {
timerEngine.start()
guard let firstTimer = timerEngine.timerStates.keys.first else {
XCTFail("No timers available")
return
}
timerEngine.triggerReminder(for: firstTimer)
// Give time for async operations
try await Task.sleep(nanoseconds: 50_000_000)
XCTAssertNotNil(timerEngine.activeReminder)
}
func testDismissReminder() {
timerEngine.start()
guard let firstTimer = timerEngine.timerStates.keys.first else {
XCTFail("No timers available")
return
}
timerEngine.triggerReminder(for: firstTimer)
XCTAssertNotNil(timerEngine.activeReminder)
timerEngine.dismissReminder()
XCTAssertNil(timerEngine.activeReminder)
}
// MARK: - Time Remaining Tests
func testGetTimeRemaining() {
timerEngine.start()
guard let firstTimer = timerEngine.timerStates.keys.first else {
XCTFail("No timers available")
return
}
let remaining = timerEngine.getTimeRemaining(for: firstTimer)
XCTAssertGreaterThan(remaining, 0)
}
func testGetFormattedTimeRemaining() {
timerEngine.start()
guard let firstTimer = timerEngine.timerStates.keys.first else {
XCTFail("No timers available")
return
}
let formatted = timerEngine.getFormattedTimeRemaining(for: firstTimer)
XCTAssertFalse(formatted.isEmpty)
XCTAssertTrue(formatted.contains(":"))
}
// MARK: - Timer State Publisher Tests
func testTimerStatesPublisher() async throws {
let expectation = XCTestExpectation(description: "Timer states changed")
timerEngine.$timerStates
.dropFirst()
.sink { states in
if !states.isEmpty {
expectation.fulfill()
}
}
.store(in: &cancellables)
timerEngine.start()
await fulfillment(of: [expectation], timeout: 1.0)
}
func testActiveReminderPublisher() async throws {
let expectation = XCTestExpectation(description: "Active reminder changed")
timerEngine.$activeReminder
.dropFirst()
.sink { reminder in
if reminder != nil {
expectation.fulfill()
}
}
.store(in: &cancellables)
timerEngine.start()
guard let firstTimer = timerEngine.timerStates.keys.first else {
XCTFail("No timers available")
return
}
timerEngine.triggerReminder(for: firstTimer)
await fulfillment(of: [expectation], timeout: 1.0)
}
// MARK: - System Sleep/Wake Tests
func testHandleSystemSleep() {
timerEngine.start()
let statesBefore = timerEngine.timerStates.count
timerEngine.handleSystemSleep()
// States should still exist
XCTAssertEqual(timerEngine.timerStates.count, statesBefore)
}
func testHandleSystemWake() {
timerEngine.start()
timerEngine.handleSystemSleep()
timerEngine.handleSystemWake()
// Should handle wake event without crashing
XCTAssertGreaterThan(timerEngine.timerStates.count, 0)
}
// MARK: - Disabled Timer Tests
func testDisabledTimersNotInitialized() {
var settings = AppSettings.defaults
settings.lookAwayTimer.enabled = false
settings.blinkTimer.enabled = false
settings.postureTimer.enabled = false
let settingsManager = EnhancedMockSettingsManager(settings: settings)
let engine = TimerEngine(settingsManager: settingsManager)
engine.start()
XCTAssertEqual(engine.timerStates.count, 0)
}
func testPartiallyEnabledTimers() {
var settings = AppSettings.defaults
settings.lookAwayTimer.enabled = true
settings.blinkTimer.enabled = false
settings.postureTimer.enabled = false
let settingsManager = EnhancedMockSettingsManager(settings: settings)
let engine = TimerEngine(settingsManager: settingsManager)
engine.start()
XCTAssertEqual(engine.timerStates.count, 1)
}
}

View File

@@ -0,0 +1,62 @@
//
// UsageTrackingServiceTests.swift
// GazeTests
//
// Unit tests for UsageTrackingService.
//
import XCTest
@testable import Gaze
@MainActor
final class UsageTrackingServiceTests: XCTestCase {
var service: UsageTrackingService!
override func setUp() async throws {
service = UsageTrackingService(resetThresholdMinutes: 60)
}
override func tearDown() async throws {
service = nil
}
// MARK: - Initialization Tests
func testServiceInitialization() {
XCTAssertNotNil(service)
}
func testInitializationWithCustomThreshold() {
let customService = UsageTrackingService(resetThresholdMinutes: 120)
XCTAssertNotNil(customService)
}
// MARK: - Threshold Tests
func testUpdateResetThreshold() {
service.updateResetThreshold(minutes: 90)
// Should not crash
XCTAssertNotNil(service)
}
func testUpdateThresholdMultipleTimes() {
service.updateResetThreshold(minutes: 30)
service.updateResetThreshold(minutes: 60)
service.updateResetThreshold(minutes: 120)
XCTAssertNotNil(service)
}
// MARK: - Idle Monitoring Integration Tests
func testSetupIdleMonitoring() {
let idleService = IdleMonitoringService(idleThresholdMinutes: 5)
service.setupIdleMonitoring(idleService)
// Should not crash
XCTAssertNotNil(service)
}
}

View File

@@ -0,0 +1,129 @@
//
// WindowManagerTests.swift
// GazeTests
//
// Unit tests for WindowManager service.
//
import SwiftUI
import XCTest
@testable import Gaze
@MainActor
final class WindowManagerTests: XCTestCase {
var windowManager: WindowManager!
override func setUp() async throws {
windowManager = WindowManager.shared
}
override func tearDown() async throws {
windowManager.dismissAllReminders()
windowManager = nil
}
// MARK: - Initialization Tests
func testWindowManagerInitialization() {
XCTAssertNotNil(windowManager)
}
func testInitialState() {
XCTAssertFalse(windowManager.isOverlayReminderVisible)
XCTAssertFalse(windowManager.isSubtleReminderVisible)
}
// MARK: - Window Visibility Tests
func testOverlayReminderVisibility() {
XCTAssertFalse(windowManager.isOverlayReminderVisible)
let view = Text("Test Overlay")
windowManager.showReminderWindow(view, windowType: .overlay)
XCTAssertTrue(windowManager.isOverlayReminderVisible)
windowManager.dismissOverlayReminder()
XCTAssertFalse(windowManager.isOverlayReminderVisible)
}
func testSubtleReminderVisibility() {
XCTAssertFalse(windowManager.isSubtleReminderVisible)
let view = Text("Test Subtle")
windowManager.showReminderWindow(view, windowType: .subtle)
XCTAssertTrue(windowManager.isSubtleReminderVisible)
windowManager.dismissSubtleReminder()
XCTAssertFalse(windowManager.isSubtleReminderVisible)
}
// MARK: - Multiple Window Tests
func testShowBothWindowTypes() {
let overlayView = Text("Overlay")
let subtleView = Text("Subtle")
windowManager.showReminderWindow(overlayView, windowType: .overlay)
windowManager.showReminderWindow(subtleView, windowType: .subtle)
XCTAssertTrue(windowManager.isOverlayReminderVisible)
XCTAssertTrue(windowManager.isSubtleReminderVisible)
}
func testDismissAllReminders() {
let overlayView = Text("Overlay")
let subtleView = Text("Subtle")
windowManager.showReminderWindow(overlayView, windowType: .overlay)
windowManager.showReminderWindow(subtleView, windowType: .subtle)
windowManager.dismissAllReminders()
XCTAssertFalse(windowManager.isOverlayReminderVisible)
XCTAssertFalse(windowManager.isSubtleReminderVisible)
}
// MARK: - Window Replacement Tests
func testReplaceOverlayWindow() {
let firstView = Text("First Overlay")
let secondView = Text("Second Overlay")
windowManager.showReminderWindow(firstView, windowType: .overlay)
XCTAssertTrue(windowManager.isOverlayReminderVisible)
// Showing a new overlay should replace the old one
windowManager.showReminderWindow(secondView, windowType: .overlay)
XCTAssertTrue(windowManager.isOverlayReminderVisible)
}
func testReplaceSubtleWindow() {
let firstView = Text("First Subtle")
let secondView = Text("Second Subtle")
windowManager.showReminderWindow(firstView, windowType: .subtle)
XCTAssertTrue(windowManager.isSubtleReminderVisible)
windowManager.showReminderWindow(secondView, windowType: .subtle)
XCTAssertTrue(windowManager.isSubtleReminderVisible)
}
// MARK: - Integration with Settings Tests
func testShowSettingsWithSettingsManager() {
let settingsManager = SettingsManager.shared
// Should not crash
windowManager.showSettings(settingsManager: settingsManager, initialTab: 0)
}
func testShowOnboardingWithSettingsManager() {
let settingsManager = SettingsManager.shared
// Should not crash
windowManager.showOnboarding(settingsManager: settingsManager)
}
}