修复合作获客扫码绑定崩溃与 Toast 层级,并接入分成比例修改。
将扫码页提升到列表层弹出并补齐 AppDelegate.window,避免扫码时 UIKit 取主窗口崩溃;Toast 改用独立 UIWindow 显示在 sheet 之上;合作获客员支持短信验证修改分成比例,同时优化冷启动根视图创建时机并补充相关测试。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
133
suixinkanTests/BindAcquirerViewModelTests.swift
Normal file
133
suixinkanTests/BindAcquirerViewModelTests.swift
Normal file
@ -0,0 +1,133 @@
|
||||
//
|
||||
// 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")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user