// // CooperationAcquirerViewModelTests.swift // suixinkanTests // import XCTest @testable import suixinkan @MainActor final class CooperationAcquirerViewModelTests: XCTestCase { private var appStore: AppStore! private var defaults: UserDefaults! override func setUp() { defaults = UserDefaults(suiteName: "CooperationAcquirerViewModelTests")! defaults.removePersistentDomain(forName: "CooperationAcquirerViewModelTests") appStore = AppStore(defaults: defaults) appStore.session.currentStoreId = 5 } func testSaveRemarkWithValidLengthCallsAPI() async throws { let json = """ {"code":100000,"msg":"success","data":{}} """.data(using: .utf8)! let viewModel = CooperationAcquirerViewModel(appStore: appStore) var message: String? viewModel.onShowMessage = { message = $0 } viewModel.startEditRemark(CooperativeSalerEntity(saleUserId: 1)) viewModel.updateRemarkDraft("备注A") await viewModel.saveRemark(api: makeAPI(responses: [json])) XCTAssertEqual(message, "备注已保存") } func testSaveCommissionRateRequiresSmsCode() async { let viewModel = CooperationAcquirerViewModel(appStore: appStore) var message: String? viewModel.onShowMessage = { message = $0 } viewModel.startEditCommissionRate(CooperativeSalerEntity(saleUserId: 1, salerPhone: "13800138000")) viewModel.updateCommissionRateDraft("20") await viewModel.saveCommissionRate(api: makeAPI(responses: [])) XCTAssertEqual(message, "请输入验证码") } func testCommissionRateDraftFiltersDigitsAndLimitsLength() { let viewModel = CooperationAcquirerViewModel(appStore: appStore) viewModel.updateCommissionRateDraft("a12b345") XCTAssertEqual(viewModel.commissionRateDraft, "123") } func testCommissionSmsCodeDraftFiltersDigitsAndLimitsLength() { let viewModel = CooperationAcquirerViewModel(appStore: appStore) viewModel.updateCommissionSmsCodeDraft("1a2b345678") XCTAssertEqual(viewModel.commissionSmsCodeDraft, "123456") } func testRequestCommissionSmsCodeShowsCountdownMessageWhenTimerActive() async { let json = """ {"code":100000,"msg":"success","data":{}} """.data(using: .utf8)! let viewModel = CooperationAcquirerViewModel(appStore: appStore) var message: String? viewModel.onShowMessage = { message = $0 } viewModel.startEditCommissionRate(CooperativeSalerEntity(saleUserId: 1, salerPhone: "13800138000")) await viewModel.requestCommissionSmsCode(api: makeAPI(responses: [json])) await Task.yield() await viewModel.requestCommissionSmsCode(api: makeAPI(responses: [])) XCTAssertEqual(message, "请在倒计时结束后重新获取") viewModel.dismissCommissionRateDialog() } func testProcessScanResultNavigatesWithValidQR() { let viewModel = CooperationAcquirerViewModel(appStore: appStore) var navigatedId: Int? viewModel.onNavigateBindAcquirer = { navigatedId = $0 } viewModel.processScanResult(#"{"method":"sale_user_bind","sale_user_id":88}"#) XCTAssertEqual(navigatedId, 88) } func testProcessScanResultShowsErrorForInvalidQR() { let viewModel = CooperationAcquirerViewModel(appStore: appStore) var message: String? viewModel.onNavigateBindAcquirer = { _ in XCTFail("Should not navigate") } viewModel.onShowMessage = { message = $0 } viewModel.processScanResult("invalid") XCTAssertEqual(message, "请扫描正确的获客员二维码") } func testLoadAcquirersUsesStoreId() async throws { let json = """ {"code":100000,"msg":"success","data":{"total":1,"list":[{"sale_user_id":3,"name":"获客员A"}]}} """.data(using: .utf8)! let session = MockURLSession(responses: [json]) let api = OrderAPI(client: APIClient(environment: .testing, session: session)) let viewModel = CooperationAcquirerViewModel(appStore: appStore) await viewModel.loadAcquirers(api: api) XCTAssertEqual(viewModel.acquirers.count, 1) let url = try XCTUnwrap(session.requests.first?.url?.absoluteString) XCTAssertTrue(url.contains("store_id=5")) } private func makeAPI(responses: [Data]) -> OrderAPI { OrderAPI(client: APIClient(environment: .testing, session: MockURLSession(responses: responses))) } }