新增门店订单与核销管理列表,对齐 Android 订单能力并完善账号级缓存。
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@ -223,6 +223,93 @@ final class OrdersViewModelTests: XCTestCase {
|
||||
XCTAssertEqual(query["end_time"], "2026-05-31")
|
||||
}
|
||||
|
||||
/// 测试精修选择更新会同步本地列表状态。
|
||||
func testUpdateRefinedChoiceUpdatesLocalOrder() async throws {
|
||||
let api = MockOrderService()
|
||||
api.storeResponses = [try TestFixture.payload(ListPayload<OrderEntity>.self, named: "order_v2_success")]
|
||||
let viewModel = OrdersViewModel()
|
||||
try await viewModel.reloadStoreOrders(api: api, scenicId: 88, appRole: nil)
|
||||
|
||||
try await viewModel.updateRefinedChoice(api: api, orderNumber: "ORDV2001", isRefined: 0)
|
||||
|
||||
XCTAssertEqual(api.refinedUpdates.count, 1)
|
||||
XCTAssertEqual(api.refinedUpdates[0].0, "ORDV2001")
|
||||
XCTAssertEqual(api.refinedUpdates[0].1, 0)
|
||||
let order = try XCTUnwrap(viewModel.storeOrders.first { $0.orderNumber == "ORDV2001" })
|
||||
XCTAssertEqual(order.isRefined, 0)
|
||||
}
|
||||
|
||||
/// 测试取消订单会调用接口并刷新列表。
|
||||
func testCancelOrderRefreshesStoreOrders() async throws {
|
||||
let api = MockOrderService()
|
||||
api.storeResponses = [
|
||||
try TestFixture.payload(ListPayload<OrderEntity>.self, named: "order_v2_success"),
|
||||
try TestFixture.payload(ListPayload<OrderEntity>.self, named: "order_v2_success")
|
||||
]
|
||||
let viewModel = OrdersViewModel()
|
||||
try await viewModel.reloadStoreOrders(api: api, scenicId: 88, appRole: nil)
|
||||
|
||||
try await viewModel.cancelOrder(api: api, scenicId: 88, appRole: nil, orderNumber: "ORDV2001")
|
||||
|
||||
XCTAssertEqual(api.cancelledOrders, ["ORDV2001"])
|
||||
XCTAssertEqual(api.orderListCalls.count, 2)
|
||||
}
|
||||
|
||||
/// 测试赠送弹窗上下文与提交流程。
|
||||
func testSendGiftFlowPreparesAndSubmits() async throws {
|
||||
let api = MockOrderService()
|
||||
api.storeResponses = [
|
||||
try TestFixture.payload(ListPayload<OrderEntity>.self, named: "order_v2_success"),
|
||||
try TestFixture.payload(ListPayload<OrderEntity>.self, named: "order_v2_success")
|
||||
]
|
||||
let viewModel = OrdersViewModel()
|
||||
try await viewModel.reloadStoreOrders(api: api, scenicId: 88, appRole: nil)
|
||||
let order = try XCTUnwrap(viewModel.storeOrders.first)
|
||||
|
||||
viewModel.prepareSendGift(for: order)
|
||||
XCTAssertEqual(viewModel.sendGiftContext?.orderNumber, order.orderNumber)
|
||||
XCTAssertEqual(viewModel.sendGiftContext?.sendPhotoNum, 2)
|
||||
|
||||
try await viewModel.submitSendGift(api: api, scenicId: 88, appRole: nil, photoNum: 3, videoNum: 1)
|
||||
|
||||
XCTAssertEqual(api.sendGiftCalls.count, 1)
|
||||
XCTAssertEqual(api.sendGiftCalls[0].0, order.orderNumber)
|
||||
XCTAssertEqual(api.sendGiftCalls[0].1, 3)
|
||||
XCTAssertEqual(api.sendGiftCalls[0].2, 1)
|
||||
XCTAssertNil(viewModel.sendGiftContext)
|
||||
XCTAssertEqual(api.orderListCalls.count, 2)
|
||||
}
|
||||
|
||||
/// 测试退款按钮展示条件。
|
||||
func testShouldShowRefundButtonConditions() async throws {
|
||||
let api = MockOrderService()
|
||||
api.storeResponses = [try TestFixture.payload(ListPayload<OrderEntity>.self, named: "order_v2_success")]
|
||||
let viewModel = OrdersViewModel()
|
||||
try await viewModel.reloadStoreOrders(api: api, scenicId: 88, appRole: nil)
|
||||
|
||||
let multiTravel = try XCTUnwrap(viewModel.storeOrders.first { $0.orderType == 19 })
|
||||
let deposit = try XCTUnwrap(viewModel.storeOrders.first { $0.orderType == 4 })
|
||||
|
||||
XCTAssertFalse(viewModel.shouldShowRefundButton(order: multiTravel, appRole: nil))
|
||||
XCTAssertTrue(viewModel.shouldShowRefundButton(order: deposit, appRole: nil))
|
||||
XCTAssertFalse(viewModel.shouldShowRefundButton(order: deposit, appRole: .scenicAdmin))
|
||||
}
|
||||
|
||||
/// 测试核销按钮展示条件。
|
||||
func testShouldShowVerifyButtonConditions() async throws {
|
||||
let api = MockOrderService()
|
||||
api.storeResponses = [try TestFixture.payload(ListPayload<OrderEntity>.self, named: "order_v2_success")]
|
||||
let viewModel = OrdersViewModel()
|
||||
try await viewModel.reloadStoreOrders(api: api, scenicId: 88, appRole: nil)
|
||||
|
||||
let multiTravel = try XCTUnwrap(viewModel.storeOrders.first { $0.orderType == 19 })
|
||||
let deposit = try XCTUnwrap(viewModel.storeOrders.first { $0.orderType == 4 })
|
||||
|
||||
XCTAssertTrue(viewModel.shouldShowVerifyButton(order: multiTravel, appRole: nil))
|
||||
XCTAssertFalse(viewModel.shouldShowVerifyButton(order: deposit, appRole: nil))
|
||||
XCTAssertFalse(viewModel.shouldShowVerifyButton(order: multiTravel, appRole: .scenicAdmin))
|
||||
}
|
||||
|
||||
private static func date(_ text: String) -> Date {
|
||||
let formatter = DateFormatter()
|
||||
formatter.locale = Locale(identifier: "en_US_POSIX")
|
||||
@ -261,6 +348,9 @@ private final class MockOrderService: OrderServing {
|
||||
private(set) var writeOffListCalls: [WriteOffListCall] = []
|
||||
private(set) var detailCalls: [(storeId: Int, orderNumber: String)] = []
|
||||
private(set) var verifiedOrderNumbers: [String] = []
|
||||
private(set) var refinedUpdates: [(String, Int)] = []
|
||||
private(set) var cancelledOrders: [String] = []
|
||||
private(set) var sendGiftCalls: [(String, Int, Int)] = []
|
||||
|
||||
/// 返回测试订单管理列表。
|
||||
func orderList(
|
||||
@ -291,11 +381,50 @@ private final class MockOrderService: OrderServing {
|
||||
}
|
||||
|
||||
/// 返回测试核销订单列表。
|
||||
func writeOffList(scenicId: Int, storeId: Int?, page: Int, pageSize: Int) async throws -> ListPayload<WriteOffOrderItem> {
|
||||
func writeOffList(
|
||||
scenicId: Int,
|
||||
storeId: Int?,
|
||||
page: Int,
|
||||
pageSize: Int,
|
||||
orderStatus: Int?,
|
||||
orderVerifyStatus: Int?,
|
||||
startTime: String?,
|
||||
endTime: String?,
|
||||
userPhone: String?
|
||||
) async throws -> ListPayload<WriteOffOrderItem> {
|
||||
writeOffListCalls.append(WriteOffListCall(scenicId: scenicId, storeId: storeId, page: page, pageSize: pageSize))
|
||||
return writeOffResponses.isEmpty ? ListPayload(total: 0, list: []) : writeOffResponses.removeFirst()
|
||||
}
|
||||
|
||||
func updateRefinedChoice(orderNumber: String, isRefined: Int) async throws {
|
||||
refinedUpdates.append((orderNumber, isRefined))
|
||||
}
|
||||
func cancelOrder(orderNumber: String) async throws {
|
||||
cancelledOrders.append(orderNumber)
|
||||
}
|
||||
func sendGift(orderNumber: String, photoNum: Int, videoNum: Int) async throws {
|
||||
sendGiftCalls.append((orderNumber, photoNum, videoNum))
|
||||
}
|
||||
func storeOrderList(
|
||||
storeId: Int?,
|
||||
page: Int,
|
||||
pageSize: Int,
|
||||
userPhone: String?,
|
||||
orderStatus: Int?,
|
||||
orderType: Int?,
|
||||
startTime: String?,
|
||||
endTime: String?
|
||||
) async throws -> ListPayload<StoreOrderListItem> {
|
||||
ListPayload(total: 0, list: [])
|
||||
}
|
||||
func storeOrderRefund(
|
||||
storeId: Int,
|
||||
orderNumber: String,
|
||||
refundType: OrderRefundMode,
|
||||
refundAmount: String,
|
||||
refundReason: String
|
||||
) async throws {}
|
||||
|
||||
/// 记录测试核销订单号。
|
||||
func writeOff(orderNumber: String) async throws {
|
||||
verifiedOrderNumbers.append(orderNumber)
|
||||
|
||||
Reference in New Issue
Block a user