// // ScenicSelectionViewModelTests.swift // suixinkanTests // import XCTest @testable import suixinkan /// 景区选择 ViewModel 测试。 final class ScenicSelectionViewModelTests: XCTestCase { private var appStore: AppStore! private var defaults: UserDefaults! override func setUp() { defaults = UserDefaults(suiteName: "ScenicSelectionViewModelTests")! defaults.removePersistentDomain(forName: "ScenicSelectionViewModelTests") appStore = AppStore(defaults: defaults) appStore.session.configureTestAccount() } override func tearDown() { appStore.logout() super.tearDown() } func testSearchFiltersByNameAndAddress() { appStore.permissions.saveRoleScenicList([ ScenicInfo(id: 1, name: "西湖景区", status: 1, location: ScenicLocationInfo(lng: 120.1, lat: 30.2, address: "杭州西湖"), coverImg: nil), ScenicInfo(id: 2, name: "灵隐寺", status: 1, location: ScenicLocationInfo(lng: 120.2, lat: 30.3, address: "杭州灵隐"), coverImg: nil), ]) let viewModel = ScenicSelectionViewModel(appStore: appStore) viewModel.loadFromLocal() XCTAssertEqual(viewModel.spots.count, 2) viewModel.onSearchQueryChange("西湖") XCTAssertEqual(viewModel.spots.count, 1) XCTAssertEqual(viewModel.spots.first?.name, "西湖景区") viewModel.onSearchQueryChange("灵隐") XCTAssertEqual(viewModel.spots.count, 1) XCTAssertEqual(viewModel.spots.first?.name, "灵隐寺") } func testNearestTagWhenLocationProvided() { appStore.permissions.saveRoleScenicList([ ScenicInfo(id: 1, name: "近", status: 1, location: ScenicLocationInfo(lng: 116.40, lat: 39.91, address: "A"), coverImg: nil), ScenicInfo(id: 2, name: "远", status: 1, location: ScenicLocationInfo(lng: 116.50, lat: 39.95, address: "B"), coverImg: nil), ]) let items = ScenicSpotDisplayMapper.buildItems( scenicList: appStore.permissions.roleScenicList(), searchQuery: "", currentLat: 39.9087, currentLng: 116.3975, selectedScenicId: 0 ) XCTAssertEqual(items.first?.openStatus, .nearest) } func testClosedStatusTag() { appStore.permissions.saveRoleScenicList([ ScenicInfo(id: 1, name: "停业", status: 2, location: nil, coverImg: nil), ]) let viewModel = ScenicSelectionViewModel(appStore: appStore) viewModel.loadFromLocal() XCTAssertEqual(viewModel.spots.first?.openStatus, .closed) XCTAssertEqual(viewModel.spots.first?.statusLabel, "暂未营业") } func testSelectSpotWritesAppStore() { appStore.permissions.saveRoleScenicList([ ScenicInfo(id: 5, name: "测试景区", status: 1), ]) let viewModel = ScenicSelectionViewModel(appStore: appStore) var completed = false viewModel.onSelectionComplete = { completed = true } viewModel.loadFromLocal() viewModel.selectSpot(viewModel.spots[0]) XCTAssertEqual(appStore.session.currentScenicId, 5) XCTAssertEqual(appStore.session.currentScenicName, "测试景区") XCTAssertTrue(completed) XCTAssertTrue(viewModel.spots.first?.isSelected == true) } func testOnApplyNowRoutesToStatusWhenPendingReviewing() async throws { let pendingJSON = """ {"code":100000,"msg":"success","data":[{"code":"AP001","role_id":1,"role_name":"摄影师","scenic_list":[],"status":1,"status_label":"审核中","created_at":"","audit_note":"","audited_at":null,"audited_by":null}]} """.data(using: .utf8)! let api = await MainActor.run { HomeAPI(client: APIClient(environment: .testing, session: MockURLSession(responses: [pendingJSON]))) } let viewModel = ScenicSelectionViewModel(appStore: appStore) var statusCode: String? viewModel.onNavigateApplyStatus = { statusCode = $0 } await viewModel.onApplyNow(api: api) XCTAssertEqual(statusCode, "AP001") } }