Initial commit: suixinkan_ios UIKit rewrite project.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
119
suixinkan_iosTests/ScenicSelectionViewModelTests.swift
Normal file
119
suixinkan_iosTests/ScenicSelectionViewModelTests.swift
Normal file
@ -0,0 +1,119 @@
|
||||
//
|
||||
// ScenicSelectionViewModelTests.swift
|
||||
// suixinkanTests
|
||||
//
|
||||
// Created by Codex on 2026/6/23.
|
||||
//
|
||||
|
||||
import XCTest
|
||||
@testable import suixinkan_ios
|
||||
|
||||
@MainActor
|
||||
/// 景区选择 ViewModel 测试,覆盖搜索、定位和切换持久化。
|
||||
final class ScenicSelectionViewModelTests: XCTestCase {
|
||||
/// 测试当前景区会优先展示并标记选中。
|
||||
func testCurrentScenicMovesToFirstItem() {
|
||||
let context = AccountContext()
|
||||
context.replaceScopes(
|
||||
scenic: [
|
||||
BusinessScope(id: 1, name: "西湖景区", kind: .scenic),
|
||||
BusinessScope(id: 2, name: "东湖景区", kind: .scenic)
|
||||
],
|
||||
stores: [],
|
||||
currentScenicId: 2
|
||||
)
|
||||
let viewModel = ScenicSelectionViewModel()
|
||||
|
||||
viewModel.reload(from: context)
|
||||
|
||||
XCTAssertEqual(viewModel.items.map(\.id), [2, 1])
|
||||
XCTAssertTrue(viewModel.items[0].isClosest)
|
||||
}
|
||||
|
||||
/// 测试搜索会按景区名称和地址过滤。
|
||||
func testSearchFiltersByNameAndAddress() {
|
||||
let viewModel = ScenicSelectionViewModel()
|
||||
let context = AccountContext()
|
||||
context.replaceScopes(
|
||||
scenic: [
|
||||
BusinessScope(id: 1, name: "西湖景区", kind: .scenic, address: "杭州"),
|
||||
BusinessScope(id: 2, name: "东湖景区", kind: .scenic, address: "武汉")
|
||||
],
|
||||
stores: []
|
||||
)
|
||||
viewModel.reload(from: context)
|
||||
|
||||
viewModel.searchQuery = "武汉"
|
||||
|
||||
XCTAssertEqual(viewModel.filteredItems.map(\.id), [2])
|
||||
}
|
||||
|
||||
/// 测试定位成功后会计算距离并标记最近景区。
|
||||
func testLocationSuccessMarksClosestScenic() {
|
||||
let context = AccountContext()
|
||||
context.replaceScopes(
|
||||
scenic: [
|
||||
BusinessScope(id: 1, name: "远景区", kind: .scenic, address: "远处", latitude: 31.0, longitude: 121.0),
|
||||
BusinessScope(id: 2, name: "近景区", kind: .scenic, address: "附近", latitude: 30.0001, longitude: 120.0001)
|
||||
],
|
||||
stores: []
|
||||
)
|
||||
let viewModel = ScenicSelectionViewModel()
|
||||
viewModel.reload(from: context)
|
||||
|
||||
viewModel.applyCurrentLocation(latitude: 30.0, longitude: 120.0)
|
||||
|
||||
XCTAssertEqual(viewModel.items.first(where: \.isClosest)?.id, 2)
|
||||
XCTAssertEqual(viewModel.currentLocationText, "附近")
|
||||
XCTAssertNotNil(viewModel.items.first(where: { $0.id == 2 })?.distanceMeters)
|
||||
}
|
||||
|
||||
/// 测试定位失败时保留列表并展示提示。
|
||||
func testLocationFailureKeepsItemsAndWarning() {
|
||||
let context = AccountContext()
|
||||
context.replaceScopes(scenic: [BusinessScope(id: 1, name: "西湖景区", kind: .scenic, address: "杭州")], stores: [])
|
||||
let viewModel = ScenicSelectionViewModel()
|
||||
viewModel.reload(from: context)
|
||||
|
||||
viewModel.applyLocationFailure("定位权限未开启")
|
||||
|
||||
XCTAssertEqual(viewModel.items.map(\.id), [1])
|
||||
XCTAssertEqual(viewModel.locationWarning, "定位权限未开启")
|
||||
}
|
||||
|
||||
/// 测试切换景区会联动门店并保存账号快照。
|
||||
func testSelectScenicUpdatesStoreAndPersistsSnapshot() {
|
||||
let suiteName = "ScenicSelectionViewModelTests.\(UUID().uuidString)"
|
||||
let defaults = UserDefaults(suiteName: suiteName)!
|
||||
defer { defaults.removePersistentDomain(forName: suiteName) }
|
||||
let snapshotStore = AccountSnapshotStore(defaults: defaults)
|
||||
let accountContext = AccountContext()
|
||||
let permissionContext = PermissionContext()
|
||||
accountContext.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
|
||||
)
|
||||
permissionContext.replaceRolePermissions([RolePermissionResponse(role: RoleInfo(id: 7, name: "运营"), scenic: [])])
|
||||
|
||||
ScenicSelectionViewModel().select(
|
||||
scenicId: 2,
|
||||
accountContext: accountContext,
|
||||
permissionContext: permissionContext,
|
||||
snapshotStore: snapshotStore
|
||||
)
|
||||
|
||||
XCTAssertEqual(accountContext.currentScenic?.id, 2)
|
||||
XCTAssertEqual(accountContext.currentStore?.id, 20)
|
||||
XCTAssertEqual(snapshotStore.load()?.currentScenicId, 2)
|
||||
XCTAssertEqual(snapshotStore.load()?.currentStoreId, 20)
|
||||
XCTAssertEqual(snapshotStore.load()?.currentRoleId, 7)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user