Files
suixinkan_uikit/suixinkanTests/AppStoreModuleTests.swift
汉秋 c083f1d4b3 升级 AppStore 缓存 Key 并在覆盖安装时强制重新登录。
统一账号作用域 Key 对齐 Android,新增缓存 schema 迁移清理旧数据,并同步更新相关模块与单元测试。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-14 09:35:55 +08:00

212 lines
10 KiB
Swift

//
// AppStoreModuleTests.swift
// suixinkanTests
//
import XCTest
@testable import suixinkan
/// AppStore
final class AppStoreModuleTests: XCTestCase {
private var suiteName: String!
private var defaults: UserDefaults!
private var appStore: AppStore!
override func setUp() {
super.setUp()
suiteName = "AppStoreModuleTests.\(UUID().uuidString)"
defaults = UserDefaults(suiteName: suiteName)
defaults.removePersistentDomain(forName: suiteName)
appStore = AppStore(defaults: defaults)
}
override func tearDown() {
defaults.removePersistentDomain(forName: suiteName)
appStore = nil
defaults = nil
suiteName = nil
super.tearDown()
}
func testAccountTypeKnownAndUnknownRawValueRoundTrips() {
XCTAssertEqual(AppAccountType(rawValue: "scenic_user"), .scenicUser)
XCTAssertEqual(AppAccountType(rawValue: "store_user"), .storeUser)
XCTAssertEqual(AppAccountType(rawValue: "future_account"), .unknown("future_account"))
XCTAssertEqual(AppAccountType.scenicUser.rawValue, "scenic_user")
XCTAssertEqual(AppAccountType.storeUser.rawValue, "store_user")
XCTAssertEqual(AppAccountType.unknown("future_account").rawValue, "future_account")
}
func testSessionUsesGlobalIdentityAndScopedBusinessContext() {
defaults.set("legacy-token", forKey: "key_in_token")
defaults.set("future_account", forKey: "key_in_account_type")
XCTAssertEqual(appStore.session.token, "legacy-token")
XCTAssertEqual(appStore.session.accountType, .unknown("future_account"))
appStore.session.userId = "1001"
appStore.session.roleCode = "future_role"
appStore.session.currentScenicId = 22
appStore.session.currentScenicName = "测试景区"
appStore.session.currentStoreId = 31
XCTAssertEqual(defaults.string(forKey: "key_in_user_id"), "1001")
XCTAssertNil(defaults.object(forKey: "key_in_current_scenic_id"))
XCTAssertEqual(defaults.string(forKey: "future_account_1001_key_in_role_code"), "future_role")
XCTAssertEqual(defaults.string(forKey: "future_account_1001_key_in_current_scenic_id"), "22")
XCTAssertEqual(defaults.string(forKey: "future_account_1001_key_in_current_scenic_name"), "测试景区")
XCTAssertEqual(defaults.integer(forKey: "future_account_1001_scenic_22_scenic_store_id"), 31)
XCTAssertEqual(appStore.session.accountCachePrefix, "future_account_1001")
}
func testIncompleteAccountScopeDoesNotWriteBusinessCache() {
appStore.session.userId = "1001"
appStore.session.currentScenicId = 22
appStore.session.roleCode = "photographer"
appStore.permissions.savePermissionItems([HomePermissionItem(id: "1", name: "钱包", uri: "wallet")])
appStore.location.onlineStatus = true
appStore.payment.isOpenReceiveVoice = true
appStore.scenicQueue.punchSpotId = "33"
XCTAssertEqual(appStore.session.accountCachePrefix, "")
XCTAssertEqual(appStore.session.currentScenicId, 0)
XCTAssertEqual(appStore.session.roleCode, "")
XCTAssertTrue(appStore.permissions.permissionItems().isEmpty)
XCTAssertFalse(appStore.location.onlineStatus)
XCTAssertFalse(appStore.payment.isOpenReceiveVoice)
XCTAssertEqual(appStore.scenicQueue.punchSpotId, "")
XCTAssertFalse(defaults.dictionaryRepresentation().keys.contains { $0.contains("guest") })
}
func testFeatureStoresAreIsolatedByAccountAndDecodeSnapshots() {
selectAccount(userId: "1001", type: .scenicUser)
let permissions = [HomePermissionItem(id: "1", name: "钱包", uri: "wallet")]
let scenicList = [ScenicInfo(id: 22, name: "测试景区", status: 1)]
var queueSettings = ScenicQueueSettingsSnapshot()
queueSettings.shootMinute = 8
appStore.permissions.savePermissionItems(permissions)
appStore.permissions.saveRoleScenicList(scenicList)
appStore.location.onlineStatus = true
appStore.location.lastReportTime = 123_456
appStore.location.reminderMinutes = 10
appStore.payment.isOpenReceiveVoice = true
appStore.scenicQueue.punchSpotId = "33"
appStore.scenicQueue.punchSpotName = "东门"
appStore.scenicQueue.remark = "请提前准备"
appStore.scenicQueue.saveSettingsSnapshot(queueSettings)
appStore.scenicQueue.savePresetVoices([" A ", "", "B"])
XCTAssertTrue(appStore.scenicQueue.useOfflineTTS)
appStore.scenicQueue.useOfflineTTS = false
selectAccount(userId: "2002", type: .storeUser)
XCTAssertTrue(appStore.permissions.permissionItems().isEmpty)
XCTAssertTrue(appStore.permissions.roleScenicList().isEmpty)
XCTAssertFalse(appStore.location.onlineStatus)
XCTAssertEqual(appStore.location.lastReportTime, 0)
XCTAssertEqual(appStore.location.reminderMinutes, 0)
XCTAssertFalse(appStore.payment.isOpenReceiveVoice)
XCTAssertEqual(appStore.scenicQueue.punchSpotId, "")
XCTAssertNil(appStore.scenicQueue.settingsSnapshot())
XCTAssertTrue(appStore.scenicQueue.useOfflineTTS)
selectAccount(userId: "1001", type: .scenicUser)
XCTAssertEqual(appStore.permissions.permissionItems(), permissions)
XCTAssertEqual(appStore.permissions.roleScenicList(), scenicList)
XCTAssertTrue(appStore.location.onlineStatus)
XCTAssertEqual(appStore.location.lastReportTime, 123_456)
XCTAssertEqual(appStore.location.reminderMinutes, 10)
XCTAssertTrue(appStore.payment.isOpenReceiveVoice)
XCTAssertTrue(appStore.scenicQueue.hasPunchSpotSaved())
XCTAssertEqual(appStore.scenicQueue.punchSpotName, "东门")
XCTAssertEqual(appStore.scenicQueue.remark, "请提前准备")
XCTAssertEqual(appStore.scenicQueue.settingsSnapshot(), queueSettings)
XCTAssertEqual(appStore.scenicQueue.presetVoices(), ["A", "B"])
XCTAssertFalse(appStore.scenicQueue.useOfflineTTS)
}
func testStoreAndQueueCachesAreIsolatedByScenicAndSpot() {
selectAccount(userId: "1001", type: .scenicUser, scenicId: 22)
appStore.session.currentStoreId = 220
appStore.scenicQueue.punchSpotId = "33"
appStore.scenicQueue.punchSpotName = "东门"
appStore.scenicQueue.remark = "东门备注"
appStore.scenicQueue.useOfflineTTS = false
appStore.scenicQueue.punchSpotId = "44"
XCTAssertEqual(appStore.scenicQueue.punchSpotName, "")
XCTAssertEqual(appStore.scenicQueue.remark, "")
appStore.scenicQueue.punchSpotName = "西门"
appStore.scenicQueue.remark = "西门备注"
appStore.scenicQueue.punchSpotId = "33"
XCTAssertEqual(appStore.scenicQueue.punchSpotName, "东门")
XCTAssertEqual(appStore.scenicQueue.remark, "东门备注")
appStore.session.currentScenicId = 23
XCTAssertEqual(appStore.session.currentStoreId, 0)
XCTAssertEqual(appStore.scenicQueue.punchSpotId, "")
XCTAssertTrue(appStore.scenicQueue.useOfflineTTS)
appStore.session.currentStoreId = 230
appStore.scenicQueue.punchSpotId = "55"
appStore.scenicQueue.punchSpotName = "南门"
appStore.session.currentScenicId = 22
XCTAssertEqual(appStore.session.currentStoreId, 220)
XCTAssertEqual(appStore.scenicQueue.punchSpotId, "33")
XCTAssertEqual(appStore.scenicQueue.punchSpotName, "东门")
XCTAssertFalse(appStore.scenicQueue.useOfflineTTS)
XCTAssertEqual(defaults.string(forKey: "scenic_user_1001_scenic_22_scenic_queue_punch_spot_id"), "33")
XCTAssertEqual(defaults.string(forKey: "scenic_user_1001_scenic_22_spot_33_scenic_queue_punch_spot_name"), "东门")
XCTAssertEqual(defaults.string(forKey: "scenic_user_1001_scenic_22_spot_33_scenic_queue_remark"), "东门备注")
XCTAssertFalse(defaults.dictionaryRepresentation().keys.contains { $0.contains("__scenic_queue") })
}
func testLogoutClearsCurrentAccountModulesAndPreservesLoginPreferences() {
appStore.session.lastLoginUsername = "13800000000"
appStore.session.privacyAgreementAccepted = true
selectAccount(userId: "other", type: .storeUser, scenicId: 22)
appStore.scenicQueue.punchSpotId = "99"
selectAccount(userId: "current", type: .scenicUser, scenicId: 22)
appStore.session.token = "token"
appStore.permissions.legacyRoleId = 41
appStore.permissions.savePermissionItems([HomePermissionItem(id: "1", name: "钱包", uri: "wallet")])
appStore.location.onlineStatus = true
appStore.payment.isOpenReceiveVoice = true
appStore.scenicQueue.punchSpotId = "33"
appStore.scenicQueue.punchSpotName = "东门"
appStore.session.currentScenicId = 23
appStore.scenicQueue.punchSpotId = "44"
appStore.scenicQueue.punchSpotName = "西门"
appStore.logout()
XCTAssertFalse(appStore.session.isLoggedIn)
XCTAssertEqual(appStore.session.userId, "")
XCTAssertEqual(appStore.session.lastLoginUsername, "13800000000")
XCTAssertTrue(appStore.session.privacyAgreementAccepted)
selectAccount(userId: "current", type: .scenicUser, scenicId: 22)
XCTAssertEqual(appStore.permissions.legacyRoleId, 0)
XCTAssertTrue(appStore.permissions.permissionItems().isEmpty)
XCTAssertFalse(appStore.location.onlineStatus)
XCTAssertFalse(appStore.payment.isOpenReceiveVoice)
XCTAssertEqual(appStore.scenicQueue.punchSpotId, "")
appStore.session.currentScenicId = 23
XCTAssertEqual(appStore.scenicQueue.punchSpotId, "")
selectAccount(userId: "other", type: .storeUser, scenicId: 22)
XCTAssertEqual(appStore.scenicQueue.punchSpotId, "99")
}
private func selectAccount(userId: String, type: AppAccountType, scenicId: Int = 22) {
appStore.session.userId = userId
appStore.session.accountType = type
appStore.session.currentScenicId = scenicId
}
}