Replace CYLTabBarController with native UITabBarController for main tabs.
Use a system scan tab slot with MainScanTabItem interception so scanner presentation no longer depends on CYL PlusButton, and remove the CYLTabBarController pod dependency. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
115
suixinkan_iosTests/MainScanTabItemTests.swift
Normal file
115
suixinkan_iosTests/MainScanTabItemTests.swift
Normal file
@ -0,0 +1,115 @@
|
||||
//
|
||||
// MainScanTabItemTests.swift
|
||||
// suixinkanTests
|
||||
//
|
||||
|
||||
import XCTest
|
||||
@testable import suixinkan_ios
|
||||
|
||||
/// 主 TabBar 中间扫码入口测试,覆盖系统 TabBar 槽位配置。
|
||||
@MainActor
|
||||
final class MainScanTabItemTests: XCTestCase {
|
||||
|
||||
/// 测试主 Tab 容器加载后包含四个业务 Tab 和中间扫码入口。
|
||||
func testMainTabBarControllerLoadsFiveSystemTabItems() {
|
||||
let services = AppServices(apiClient: APIClient(session: MainTabRecordingURLSession()))
|
||||
let controller = MainTabBarController(services: services)
|
||||
|
||||
controller.loadViewIfNeeded()
|
||||
|
||||
XCTAssertEqual(controller.viewControllers?.count, 5)
|
||||
for tab in AppTab.allCases {
|
||||
XCTAssertNotNil(controller.navigationController(for: tab))
|
||||
XCTAssertEqual(
|
||||
controller.navigationController(for: tab)?.tabBarItem.accessibilityIdentifier,
|
||||
"main.tab.\(tab.rawValue)"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/// 测试扫码入口位于订单与数据之间,并保留指定无障碍标识。
|
||||
func testScanTabItemIsCenteredBetweenOrdersAndStatistics() throws {
|
||||
let services = AppServices(apiClient: APIClient(session: MainTabRecordingURLSession()))
|
||||
let controller = MainTabBarController(services: services)
|
||||
|
||||
controller.loadViewIfNeeded()
|
||||
|
||||
let scanItem = try XCTUnwrap(controller.viewControllers?[2].tabBarItem)
|
||||
XCTAssertEqual(scanItem.title, "扫码")
|
||||
XCTAssertEqual(scanItem.accessibilityIdentifier, "main.scan")
|
||||
XCTAssertEqual(scanItem.accessibilityLabel, "扫码核销")
|
||||
XCTAssertNotNil(scanItem.image)
|
||||
XCTAssertNotNil(scanItem.selectedImage)
|
||||
}
|
||||
|
||||
/// 测试点击扫码槽位会被拦截且不改变当前选中页面。
|
||||
func testSelectingScanTabPresentsScannerWithoutSelectingPlaceholder() throws {
|
||||
let services = AppServices(apiClient: APIClient(session: MainTabRecordingURLSession()))
|
||||
let controller = MainTabBarController(services: services)
|
||||
var scanTapCount = 0
|
||||
controller.onScanTabSelected = {
|
||||
scanTapCount += 1
|
||||
}
|
||||
|
||||
controller.loadViewIfNeeded()
|
||||
controller.selectedIndex = 1
|
||||
|
||||
let scanController = try XCTUnwrap(controller.viewControllers?[2])
|
||||
XCTAssertFalse(controller.tabBarController(controller, shouldSelect: scanController))
|
||||
XCTAssertEqual(scanTapCount, 1)
|
||||
XCTAssertEqual(controller.selectedIndex, 1)
|
||||
}
|
||||
|
||||
/// 测试业务 Tab 仍允许系统 TabBar 正常选中。
|
||||
func testSelectingBusinessTabIsAllowed() throws {
|
||||
let services = AppServices(apiClient: APIClient(session: MainTabRecordingURLSession()))
|
||||
let controller = MainTabBarController(services: services)
|
||||
|
||||
controller.loadViewIfNeeded()
|
||||
|
||||
let ordersController = try XCTUnwrap(controller.viewControllers?[1])
|
||||
XCTAssertTrue(controller.tabBarController(controller, shouldSelect: ordersController))
|
||||
}
|
||||
|
||||
/// 测试各 Tab 的图标资源可被加载并挂载到 tabBarItem。
|
||||
func testMainTabBarControllerTabBarItemsHaveImages() {
|
||||
let services = AppServices(apiClient: APIClient(session: MainTabRecordingURLSession()))
|
||||
let controller = MainTabBarController(services: services)
|
||||
controller.loadViewIfNeeded()
|
||||
|
||||
for tab in AppTab.allCases {
|
||||
let item = controller.navigationController(for: tab)?.tabBarItem
|
||||
XCTAssertNotNil(item?.image, "tab \(tab.rawValue) image should not be nil")
|
||||
XCTAssertNotNil(item?.selectedImage, "tab \(tab.rawValue) selectedImage should not be nil")
|
||||
XCTAssertGreaterThan(item?.image?.size.width ?? 0, 0)
|
||||
XCTAssertGreaterThan(item?.selectedImage?.size.width ?? 0, 0)
|
||||
}
|
||||
}
|
||||
|
||||
/// 测试订单角标仍挂载在订单业务导航控制器的系统 TabBarItem 上。
|
||||
func testOrderBadgeUsesOrdersNavigationTabBarItem() throws {
|
||||
let services = AppServices(apiClient: APIClient(session: MainTabRecordingURLSession()))
|
||||
let controller = MainTabBarController(services: services)
|
||||
|
||||
controller.loadViewIfNeeded()
|
||||
|
||||
let ordersNavigationController = try XCTUnwrap(controller.navigationController(for: .orders))
|
||||
ordersNavigationController.tabBarItem.badgeValue = "3"
|
||||
|
||||
XCTAssertEqual(controller.viewControllers?[1].tabBarItem.badgeValue, "3")
|
||||
}
|
||||
}
|
||||
|
||||
/// 主 Tab 测试使用的空网络会话,确保容器加载不触发真实请求。
|
||||
private final class MainTabRecordingURLSession: URLSessionProtocol {
|
||||
/// 返回空成功响应。
|
||||
func data(for request: URLRequest) async throws -> (Data, URLResponse) {
|
||||
let response = HTTPURLResponse(
|
||||
url: request.url ?? URL(string: "https://example.com")!,
|
||||
statusCode: 200,
|
||||
httpVersion: nil,
|
||||
headerFields: nil
|
||||
)!
|
||||
return (Data(), response)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user