// // HomeLocationStateStoreTests.swift // suixinkanTests // import XCTest @testable import suixinkan /// 首页在线状态存储测试。 final class HomeLocationStateStoreTests: XCTestCase { private var appStore: AppStore! private var defaults: UserDefaults! override func setUp() { defaults = UserDefaults(suiteName: "HomeLocationStateStoreTests")! defaults.removePersistentDomain(forName: "HomeLocationStateStoreTests") appStore = AppStore(defaults: defaults) appStore.userId = "1001" appStore.accountType = "scenic_user" } override func tearDown() { appStore.logout() super.tearDown() } func testExpiredOnlineSessionIsClearedOnRestore() { let expiredTimestamp = Int64(Date().timeIntervalSince1970 * 1000) - HomeLocationStateStore.onlineDurationMillis - 1_000 appStore.onlineStatus = true appStore.lastLocationReportTime = expiredTimestamp let stateStore = HomeLocationStateStore(store: appStore) stateStore.restoreStateIfNeeded() XCTAssertFalse(stateStore.isOnline) XCTAssertFalse(appStore.onlineStatus) XCTAssertEqual(appStore.lastLocationReportTime, 0) } func testActiveOnlineSessionRestoresCountdown() { let recentTimestamp = Int64(Date().timeIntervalSince1970 * 1000) - 60_000 appStore.onlineStatus = true appStore.lastLocationReportTime = recentTimestamp let stateStore = HomeLocationStateStore(store: appStore) stateStore.restoreStateIfNeeded() XCTAssertTrue(stateStore.isOnline) XCTAssertGreaterThan(stateStore.nextReportCountdownSeconds, 0) } func testFormattedCountdownText() { let stateStore = HomeLocationStateStore(store: appStore) XCTAssertEqual(stateStore.formattedCountdown(from: 3661), "01:01:01") } func testShouldTriggerTimeoutReminderWithinWindow() { appStore.locationReminderMinutes = 10 let stateStore = HomeLocationStateStore(store: appStore) stateStore.startLocationReport(at: Int64(Date().timeIntervalSince1970 * 1000)) stateStore.updateReminderMinutes(10) // Force countdown into reminder window via reflection of internal state is not available; // verify helper with manual expectation on threshold logic. XCTAssertFalse(stateStore.shouldTriggerTimeoutReminder()) } func testMultipleObserversReceiveStateChanges() { let stateStore = HomeLocationStateStore(store: appStore) let firstOwner = StateObserverOwner() let secondOwner = StateObserverOwner() var firstChangeCount = 0 var secondChangeCount = 0 stateStore.observe(firstOwner) { firstChangeCount += 1 } stateStore.observe(secondOwner) { secondChangeCount += 1 } stateStore.updateReminderMinutes(5) XCTAssertEqual(firstChangeCount, 1) XCTAssertEqual(secondChangeCount, 1) stateStore.removeObserver(firstOwner) stateStore.updateReminderMinutes(10) XCTAssertEqual(firstChangeCount, 1) XCTAssertEqual(secondChangeCount, 2) } func testViewModelsShareReminderMinutesWhenUsingSameStateStore() { let stateStore = HomeLocationStateStore(store: appStore) let homeViewModel = HomeViewModel(appStore: appStore, locationStateStore: stateStore) let reportViewModel = LocationReportViewModel( locationStateStore: stateStore, locationProvider: MockLocationProvider() ) homeViewModel.updateReminderMinutes(15) XCTAssertEqual(reportViewModel.reminderMinutes, 15) reportViewModel.updateReminderMinutes(5) XCTAssertEqual(homeViewModel.reminderMinutes, 5) } func testViewModelsShareOnlineStateWhenUsingSameStateStore() { let stateStore = HomeLocationStateStore(store: appStore) let homeViewModel = HomeViewModel(appStore: appStore, locationStateStore: stateStore) let reportViewModel = LocationReportViewModel( locationStateStore: stateStore, locationProvider: MockLocationProvider() ) stateStore.startLocationReport(at: Int64(Date().timeIntervalSince1970 * 1000)) XCTAssertTrue(homeViewModel.isOnline) XCTAssertTrue(reportViewModel.isOnline) XCTAssertGreaterThan(stateStore.nextReportCountdownSeconds, 0) stateStore.updateOnlineStatus(false) XCTAssertFalse(homeViewModel.isOnline) XCTAssertFalse(reportViewModel.isOnline) } func testRestoreClearsOnlineStateWhenStoredLastReportTimeIsMissing() { appStore.onlineStatus = true appStore.lastLocationReportTime = 0 let stateStore = HomeLocationStateStore(store: appStore) stateStore.restoreStateIfNeeded() XCTAssertFalse(stateStore.isOnline) XCTAssertFalse(appStore.onlineStatus) XCTAssertEqual(appStore.lastLocationReportTime, 0) XCTAssertEqual(stateStore.nextReportCountdownSeconds, 0) } func testRestoreClearsRuntimeStateWhenPersistedOffline() { let stateStore = HomeLocationStateStore(store: appStore) stateStore.startLocationReport(at: Int64(Date().timeIntervalSince1970 * 1000)) appStore.onlineStatus = false stateStore.restoreStateIfNeeded() XCTAssertFalse(stateStore.isOnline) XCTAssertEqual(stateStore.nextReportCountdownSeconds, 0) } } private final class StateObserverOwner {}