// // AllFunctionsViewModelTests.swift // suixinkanTests // import UIKit import XCTest @testable import suixinkan /// 全部功能 ViewModel 测试。 final class AllFunctionsViewModelTests: XCTestCase { private var defaults: UserDefaults! private var appStore: AppStore! private var menuStore: HomeCommonMenuStore! override func setUp() { defaults = UserDefaults(suiteName: "AllFunctionsViewModelTests")! defaults.removePersistentDomain(forName: "AllFunctionsViewModelTests") appStore = AppStore(defaults: defaults) menuStore = HomeCommonMenuStore(defaults: defaults) appStore.session.userId = "1001" appStore.session.accountType = .scenicUser appStore.session.roleCode = AppRoleCode.photographer.rawValue } override func tearDown() { defaults.removePersistentDomain(forName: "AllFunctionsViewModelTests") super.tearDown() } func testLoadFunctionsUsesDefaultFirstFourAndExcludesMessageCenter() { appStore.permissions.savePermissionItems([ HomePermissionItem(id: "1", name: "钱包", uri: "wallet"), HomePermissionItem(id: "2", name: "云盘", uri: "cloud_management"), HomePermissionItem(id: "3", name: "任务", uri: "task_management"), HomePermissionItem(id: "4", name: "设置", uri: "system_settings"), HomePermissionItem(id: "5", name: "消息", uri: "message_center"), ]) let viewModel = AllFunctionsViewModel(appStore: appStore, commonMenuStore: menuStore) viewModel.loadFunctions() XCTAssertEqual(viewModel.commonMenus.map(\.uri), [ "wallet", "cloud_management", "task_management", "system_settings", ]) XCTAssertTrue(viewModel.moreMenus.isEmpty) XCTAssertEqual( menuStore.savedCommonURIs( accountScope: appStore.session.accountCachePrefix, roleCode: appStore.session.roleCode ), ["wallet", "cloud_management", "task_management", "system_settings"] ) } func testLoadFunctionsUsesSavedURIsOverDefault() { appStore.permissions.savePermissionItems([ HomePermissionItem(id: "1", name: "钱包", uri: "wallet"), HomePermissionItem(id: "2", name: "云盘", uri: "cloud_management"), HomePermissionItem(id: "3", name: "任务", uri: "task_management"), ]) menuStore.saveCommonURIs( ["cloud_management"], accountScope: appStore.session.accountCachePrefix, roleCode: appStore.session.roleCode ) let viewModel = AllFunctionsViewModel(appStore: appStore, commonMenuStore: menuStore) viewModel.loadFunctions() XCTAssertEqual(viewModel.commonMenus.map(\.uri), ["cloud_management"]) XCTAssertEqual(Set(viewModel.moreMenus.map(\.uri)), Set(["wallet", "task_management"])) } func testAddToCommonMovesMenuAndPersists() { appStore.permissions.savePermissionItems([ HomePermissionItem(id: "1", name: "钱包", uri: "wallet"), HomePermissionItem(id: "2", name: "云盘", uri: "cloud_management"), ]) menuStore.saveCommonURIs( ["wallet"], accountScope: appStore.session.accountCachePrefix, roleCode: appStore.session.roleCode ) let viewModel = AllFunctionsViewModel(appStore: appStore, commonMenuStore: menuStore) viewModel.loadFunctions() let cloudMenu = viewModel.moreMenus.first { $0.uri == "cloud_management" }! viewModel.addToCommon(cloudMenu) XCTAssertEqual(viewModel.commonMenus.map(\.uri), ["wallet", "cloud_management"]) XCTAssertTrue(viewModel.moreMenus.isEmpty) XCTAssertTrue(viewModel.didCustomize) XCTAssertEqual( menuStore.savedCommonURIs( accountScope: appStore.session.accountCachePrefix, roleCode: appStore.session.roleCode ), ["wallet", "cloud_management"] ) } func testRemoveFromCommonMovesMenuAndPersists() { appStore.permissions.savePermissionItems([ HomePermissionItem(id: "1", name: "钱包", uri: "wallet"), HomePermissionItem(id: "2", name: "云盘", uri: "cloud_management"), ]) menuStore.saveCommonURIs( ["wallet", "cloud_management"], accountScope: appStore.session.accountCachePrefix, roleCode: appStore.session.roleCode ) let viewModel = AllFunctionsViewModel(appStore: appStore, commonMenuStore: menuStore) viewModel.loadFunctions() let walletMenu = viewModel.commonMenus.first { $0.uri == "wallet" }! viewModel.removeFromCommon(walletMenu) XCTAssertEqual(viewModel.commonMenus.map(\.uri), ["cloud_management"]) XCTAssertEqual(viewModel.moreMenus.map(\.uri), ["wallet"]) XCTAssertTrue(viewModel.didCustomize) } func testPhotographerReportMenuVisibleAndCanBeAddedToCommon() { appStore.permissions.savePermissionItems([ HomePermissionItem(id: "1", name: "位置上报", uri: "location_report"), HomePermissionItem(id: "2", name: "举报摄影师", uri: "report_photographer"), ]) menuStore.saveCommonURIs( ["location_report"], accountScope: appStore.session.accountCachePrefix, roleCode: appStore.session.roleCode ) let viewModel = AllFunctionsViewModel(appStore: appStore, commonMenuStore: menuStore) viewModel.loadFunctions() XCTAssertEqual(HomeMenuCatalog.item(for: "report_photographer")?.title, "举报摄影师") XCTAssertEqual(viewModel.moreMenus.map(\.uri), ["report_photographer"]) let menu = viewModel.moreMenus[0] viewModel.addToCommon(menu) XCTAssertEqual(viewModel.commonMenus.map(\.uri), ["location_report", "report_photographer"]) } } /// 全部功能菜单卡片交互语义测试。 @MainActor final class AllFunctionMenuCellTests: XCTestCase { func testAddStyleUsesWholeCellAsAccessibleActionWithoutNestedButton() { let cell = AllFunctionMenuCell(frame: CGRect(x: 0, y: 0, width: 100, height: 100)) let menu = HomeMenuItem(uri: "wallet", title: "钱包", iconName: "wallet.pass") cell.apply(menu: menu, actionStyle: .add) XCTAssertTrue(cell.isAccessibilityElement) XCTAssertEqual(cell.accessibilityLabel, "钱包") XCTAssertEqual(cell.accessibilityHint, "添加到常用应用") XCTAssertTrue(cell.accessibilityTraits.contains(.button)) XCTAssertFalse(containsButton(in: cell.contentView)) } func testRemoveStyleDescribesWholeCellRemoveAction() { let cell = AllFunctionMenuCell(frame: CGRect(x: 0, y: 0, width: 100, height: 100)) let menu = HomeMenuItem(uri: "wallet", title: "钱包", iconName: "wallet.pass") cell.apply(menu: menu, actionStyle: .remove) XCTAssertEqual(cell.accessibilityHint, "移出常用应用") XCTAssertTrue(cell.accessibilityTraits.contains(.button)) XCTAssertFalse(containsButton(in: cell.contentView)) } private func containsButton(in view: UIView) -> Bool { view is UIButton || view.subviews.contains(where: containsButton(in:)) } }