将扫码页提升到列表层弹出并补齐 AppDelegate.window,避免扫码时 UIKit 取主窗口崩溃;Toast 改用独立 UIWindow 显示在 sheet 之上;合作获客员支持短信验证修改分成比例,同时优化冷启动根视图创建时机并补充相关测试。 Co-authored-by: Cursor <cursoragent@cursor.com>
134 lines
4.7 KiB
Swift
134 lines
4.7 KiB
Swift
//
|
|
// BindAcquirerViewModelTests.swift
|
|
// suixinkanTests
|
|
//
|
|
// Created by Codex on 2026/7/3.
|
|
//
|
|
|
|
import XCTest
|
|
@testable import suixinkan
|
|
|
|
/// 绑定获客员 ViewModel 分账比例校验测试。
|
|
@MainActor
|
|
final class BindAcquirerViewModelTests: XCTestCase {
|
|
/// 测试分账比例输入只保留数字且最多 3 位。
|
|
func testUpdateCommissionRateDraftFiltersInput() {
|
|
let viewModel = BindAcquirerViewModel()
|
|
viewModel.updateCommissionRateDraft("12a3.4")
|
|
XCTAssertEqual(viewModel.commissionRateDraft, "123")
|
|
viewModel.updateCommissionRateDraft("1234")
|
|
XCTAssertEqual(viewModel.commissionRateDraft, "123")
|
|
}
|
|
|
|
/// 测试未填写分账比例时提交失败。
|
|
func testAcceptBindRequiresCommissionRate() async {
|
|
let viewModel = BindAcquirerViewModel()
|
|
let api = BindAcquirerMockAPI()
|
|
await viewModel.load(api: api, saleUserId: 101)
|
|
|
|
do {
|
|
try await viewModel.acceptBind(api: api)
|
|
XCTFail("Expected validation error")
|
|
} catch let error as CooperationOrderCommissionRateValidationError {
|
|
XCTAssertEqual(error.message, "请输入分账比例")
|
|
} catch {
|
|
XCTFail("Unexpected error: \(error)")
|
|
}
|
|
XCTAssertEqual(api.acceptBindCalls.count, 0)
|
|
}
|
|
|
|
/// 测试分账比例超出范围时提交失败。
|
|
func testAcceptBindRejectsOutOfRangeCommissionRate() async {
|
|
let viewModel = BindAcquirerViewModel()
|
|
let api = BindAcquirerMockAPI()
|
|
await viewModel.load(api: api, saleUserId: 101)
|
|
viewModel.updateCommissionRateDraft("101")
|
|
|
|
do {
|
|
try await viewModel.acceptBind(api: api)
|
|
XCTFail("Expected validation error")
|
|
} catch let error as CooperationOrderCommissionRateValidationError {
|
|
XCTAssertEqual(error.message, "分账比例需在0到100之间")
|
|
} catch {
|
|
XCTFail("Unexpected error: \(error)")
|
|
}
|
|
XCTAssertEqual(api.acceptBindCalls.count, 0)
|
|
}
|
|
|
|
/// 测试合法分账比例时调用 accept-bind 接口。
|
|
func testAcceptBindPassesCommissionRateToAPI() async throws {
|
|
let viewModel = BindAcquirerViewModel()
|
|
let api = BindAcquirerMockAPI()
|
|
await viewModel.load(api: api, saleUserId: 101)
|
|
viewModel.updateCommissionRateDraft("20")
|
|
|
|
try await viewModel.acceptBind(api: api)
|
|
|
|
XCTAssertEqual(api.acceptBindCalls.count, 1)
|
|
XCTAssertEqual(api.acceptBindCalls.first?.saleUserId, 101)
|
|
XCTAssertEqual(api.acceptBindCalls.first?.commissionRate, 20)
|
|
}
|
|
}
|
|
|
|
@MainActor
|
|
private final class BindAcquirerMockAPI: CooperationOrderServing {
|
|
struct AcceptBindCall {
|
|
let saleUserId: Int
|
|
let commissionRate: Int
|
|
}
|
|
|
|
var acceptBindCalls: [AcceptBindCall] = []
|
|
|
|
func cooperativeSalers(storeId: Int?, page: Int, pageSize: Int) async throws -> CooperativeSalerListPayload {
|
|
fatalError("Not used in BindAcquirerViewModelTests")
|
|
}
|
|
|
|
func saleUserInviteInfo(saleUserId: Int) async throws -> SaleUserInviteInfo {
|
|
SaleUserInviteInfo(
|
|
saleUserId: saleUserId,
|
|
salerName: "测试获客员",
|
|
salerPhone: "13800138000"
|
|
)
|
|
}
|
|
|
|
func saleUserAcceptBind(saleUserId: Int, commissionRate: Int) async throws {
|
|
acceptBindCalls.append(AcceptBindCall(saleUserId: saleUserId, commissionRate: commissionRate))
|
|
}
|
|
|
|
func saleUserReferralLeads(page: Int, pageSize: Int) async throws -> ListPayload<ReferralLead> {
|
|
fatalError("Not used in BindAcquirerViewModelTests")
|
|
}
|
|
|
|
func saleUserAcquisitionOrders(keyword: String?, page: Int, pageSize: Int) async throws -> ListPayload<AcquisitionOrder> {
|
|
fatalError("Not used in BindAcquirerViewModelTests")
|
|
}
|
|
|
|
func saleUserReferralOrders(saleUserId: Int, page: Int, pageSize: Int) async throws -> ReferralOrderListPayload {
|
|
fatalError("Not used in BindAcquirerViewModelTests")
|
|
}
|
|
|
|
func saleUserBindReferralOrder(orderNumber: String, referralOrderNo: String) async throws {
|
|
fatalError("Not used in BindAcquirerViewModelTests")
|
|
}
|
|
|
|
func saleUserUpdateReferralOrderStatus(id: Int, status: Int) async throws {
|
|
fatalError("Not used in BindAcquirerViewModelTests")
|
|
}
|
|
|
|
func saleUserUpdateRemark(saleUserId: Int, photogRemarkName: String) async throws {
|
|
fatalError("Not used in BindAcquirerViewModelTests")
|
|
}
|
|
|
|
func saleUserCommissionRateSendSmsCode(phone: String) async throws {
|
|
fatalError("Not used in BindAcquirerViewModelTests")
|
|
}
|
|
|
|
func saleUserUpdateCommissionRate(
|
|
saleUserId: Int,
|
|
commissionRate: Int,
|
|
smsCode: String
|
|
) async throws -> CooperativeSaler {
|
|
fatalError("Not used in BindAcquirerViewModelTests")
|
|
}
|
|
}
|