// // NavigationRouterTests.swift // suixinkanTests // // Created by Codex on 2026/6/22. // import XCTest @testable import suixinkan_ios /// 主导航路由测试,覆盖 AppRoute 的跨页面导航策略。 @MainActor final class NavigationRouterTests: XCTestCase { /// 测试通过 NavigationStack push 的子页面默认隐藏底部 TabBar。 func testPushedRoutesHideTabBarByDefault() { XCTAssertTrue(AppRoute.placeholder(title: "详情").hidesTabBarWhenPushed) XCTAssertTrue(AppRoute.home(.moreFunctions).hidesTabBarWhenPushed) XCTAssertTrue(AppRoute.home(.paymentCollection).hidesTabBarWhenPushed) XCTAssertTrue(AppRoute.home(.wallet).hidesTabBarWhenPushed) XCTAssertTrue(AppRoute.orders(.storeDetail(try! Self.firstOrder())).hidesTabBarWhenPushed) XCTAssertTrue(AppRoute.orders(.writeOffDetail(try! Self.firstWriteOffOrder())).hidesTabBarWhenPushed) XCTAssertTrue(AppRoute.orders(.multiTravelTaskUpload(orderNumber: "MT001")).hidesTabBarWhenPushed) XCTAssertTrue(AppRoute.orders(.orderTrailer(orderNumber: "MT001", title: "尾片上传")).hidesTabBarWhenPushed) } /// 测试切换订单 Tab 时会保存订单内部子入口。 func testSelectOrdersUpdatesTabAndEntry() { let router = AppRouter() router.selectOrders(entry: .verificationOrders) XCTAssertEqual(router.selectedTab, .orders) XCTAssertEqual(router.selectedOrdersEntry, .verificationOrders) } /// 测试全局扫码核销路由会切到订单核销入口并保存扫码结果。 func testRouteToOrderVerificationStoresPendingScanCode() { let router = AppRouter() router.routeToOrderVerification(scannedCode: "order_number=VERIFY001") XCTAssertEqual(router.selectedTab, .orders) XCTAssertEqual(router.selectedOrdersEntry, .verificationOrders) XCTAssertEqual(router.pendingOrderScanCode, "order_number=VERIFY001") } /// 测试全局扫码结果只能被消费一次。 func testConsumePendingOrderScanCodeClearsValueAfterFirstRead() { let router = AppRouter() router.routeToOrderVerification(scannedCode: "VERIFY001") XCTAssertEqual(router.consumePendingOrderScanCode(), "VERIFY001") XCTAssertNil(router.consumePendingOrderScanCode()) } /// 测试重置主路由时会清理未消费的扫码结果。 func testResetClearsPendingOrderScanCode() { let router = AppRouter() router.routeToOrderVerification(scannedCode: "VERIFY001") router.reset() XCTAssertEqual(router.selectedTab, .home) XCTAssertEqual(router.selectedOrdersEntry, .storeOrders) XCTAssertNil(router.pendingOrderScanCode) } /// 测试订单模块真实路由可被压入导航栈。 func testOrderRoutesCanBePushedIntoRouterPath() throws { let router = RouterPath() let order = try Self.firstOrder() let writeOff = try Self.firstWriteOffOrder() router.navigate(to: .orders(.storeDetail(order))) router.navigate(to: .orders(.writeOffDetail(writeOff))) router.navigate(to: .orders(.multiTravelTaskUpload(orderNumber: "MT001"))) router.navigate(to: .orders(.orderTrailer(orderNumber: "MT001", title: "视频预告"))) XCTAssertEqual(router.path.count, 4) XCTAssertEqual(router.path[0], .orders(.storeDetail(order))) XCTAssertEqual(router.path[1], .orders(.writeOffDetail(writeOff))) XCTAssertEqual(router.path[2], .orders(.multiTravelTaskUpload(orderNumber: "MT001"))) XCTAssertEqual(router.path[3], .orders(.orderTrailer(orderNumber: "MT001", title: "视频预告"))) } /// 返回测试用订单管理列表项。 private static func firstOrder() throws -> OrderEntity { let payload = try TestFixture.payload(ListPayload.self, named: "order_v2_success") return try XCTUnwrap(payload.list.first) } /// 返回测试用核销订单列表项。 private static func firstWriteOffOrder() throws -> WriteOffOrderItem { let payload = try TestFixture.payload(ListPayload.self, named: "writeoff_list_success") return try XCTUnwrap(payload.list.first) } }