Files
suixinkan_uikit/suixinkanTests/AllFunctionsViewModelTests.swift
汉秋 caeeb9a1cf feat: 接入消息未读数、全部已读与首页红点角标同步。
固定消息中心为首页入口,并在推送到达、已读后刷新桌面角标。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-21 18:02:43 +08:00

181 lines
7.2 KiB
Swift

//
// 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:))
}
}