Files
suixinkan_uikit/suixinkanTests/HomeLocationStateStoreTests.swift

152 lines
5.4 KiB
Swift

//
// 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 {}