// // AccountContextTests.swift // suixinkanTests // // Created by Codex on 2026/6/20. // import XCTest @testable import suixinkan @MainActor /// 账号上下文测试,覆盖景区、门店和角色权限的选择恢复。 final class AccountContextTests: XCTestCase { /// 测试 replaceScopes 能按缓存 ID 恢复当前景区和门店。 func testReplaceScopesRestoresCurrentSelectionsById() { let context = AccountContext() let scenicScopes = [ BusinessScope(id: 1, name: "默认景区", kind: .scenic), BusinessScope(id: 2, name: "缓存景区", kind: .scenic) ] let storeScopes = [ BusinessScope(id: 10, name: "默认门店", kind: .store), BusinessScope(id: 20, name: "缓存门店", kind: .store) ] context.replaceScopes( scenic: scenicScopes, stores: storeScopes, currentScenicId: 2, currentStoreId: 20 ) XCTAssertEqual(context.currentScenic?.id, 2) XCTAssertEqual(context.currentStore?.id, 20) } /// 测试缓存 ID 不存在时会回退到首个可用作用域。 func testReplaceScopesFallsBackToFirstScopeWhenCachedIdIsMissing() { let context = AccountContext() context.replaceScopes( scenic: [BusinessScope(id: 1, name: "默认景区", kind: .scenic)], stores: [BusinessScope(id: 10, name: "默认门店", kind: .store)], currentScenicId: 999, currentStoreId: 999 ) XCTAssertEqual(context.currentScenic?.id, 1) XCTAssertEqual(context.currentStore?.id, 10) } /// 测试切换景区时会优先选择同景区门店。 func testSelectScenicResolvesStoreWithinSelectedScenic() { let context = AccountContext() context.replaceScopes( scenic: [ BusinessScope(id: 1, name: "西湖景区", kind: .scenic), BusinessScope(id: 2, name: "东湖景区", kind: .scenic) ], stores: [ BusinessScope(id: 10, name: "西湖门店", kind: .store, parentScenicId: 1), BusinessScope(id: 20, name: "东湖门店", kind: .store, parentScenicId: 2) ], currentScenicId: 1, currentStoreId: 10 ) context.selectScenic(id: 2) XCTAssertEqual(context.currentScenic?.id, 2) XCTAssertEqual(context.currentStore?.id, 20) } /// 测试切换角色时会同步角色景区并重新匹配门店。 func testSelectRoleUpdatesScenicScopesAndStoreSelection() { let accountContext = AccountContext() let permissionContext = PermissionContext() accountContext.replaceScopes( scenic: [BusinessScope(id: 1, name: "旧景区", kind: .scenic)], stores: [ BusinessScope(id: 10, name: "旧门店", kind: .store, parentScenicId: 1), BusinessScope(id: 20, name: "新门店", kind: .store, parentScenicId: 2) ], currentScenicId: 1, currentStoreId: 10 ) permissionContext.replaceRolePermissions([ RolePermissionResponse( role: RoleInfo(id: 1, name: "旧角色"), scenic: [ScenicInfo(id: 1, name: "旧景区")] ), RolePermissionResponse( role: RoleInfo(id: 2, name: "新角色"), scenic: [ScenicInfo(id: 2, name: "新景区")] ) ]) permissionContext.selectRole(id: 2, accountContext: accountContext) XCTAssertEqual(permissionContext.currentRole?.id, 2) XCTAssertEqual(accountContext.scenicScopes.map(\.id), [2]) XCTAssertEqual(accountContext.currentScenic?.id, 2) XCTAssertEqual(accountContext.currentStore?.id, 20) } /// 测试权限上下文会递归展开权限 URI。 func testPermissionContextFlattensPermissionURIs() { let permissionContext = PermissionContext() permissionContext.replaceRolePermissions([ RolePermissionResponse( role: RoleInfo( id: 1, name: "运营", permission: [ PermissionItem( id: 1, name: "首页", uri: "/home", children: [ PermissionItem(id: 2, name: "订单", uri: "/orders") ] ) ] ), scenic: [] ) ]) XCTAssertTrue(permissionContext.canAccess("/home")) XCTAssertTrue(permissionContext.canAccess("/orders")) XCTAssertFalse(permissionContext.canAccess("/settings")) } }