Integrate CYLTabBar center scan button and unify UIKit navigation.

Add CYLTabBarController with a global scan entry, promote MainTabBarController to the window root after login, replace RouterPath-based navigation with AppNavigator, and fix Profile diffable cell reconfiguration crashes.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-06-26 16:36:18 +08:00
parent 24a7339b68
commit a1c031c9b7
31 changed files with 838 additions and 517 deletions

View File

@ -0,0 +1,58 @@
//
// MainScanPlusButtonTests.swift
// suixinkanTests
//
import XCTest
@testable import suixinkan_ios
/// TabBar CYL PlusButton
@MainActor
final class MainScanPlusButtonTests: XCTestCase {
/// Tab
func testIndexOfPlusButtonInTabBarIsBetweenOrdersAndStatistics() {
XCTAssertEqual(MainScanPlusButton.indexOfPlusButtonInTabBar(), 2)
}
/// accessibility
func testPlusButtonAccessibilityIdentifier() {
guard let button = MainScanPlusButton.plusButton() as? UIButton else {
XCTFail("plusButton 应返回 UIButton 实例")
return
}
XCTAssertEqual(button.accessibilityIdentifier, "main.scan")
XCTAssertEqual(button.accessibilityLabel, "扫码核销")
}
/// Tab CYL Tab
func testMainTabBarControllerLoadsWithMatchingCYLAttributes() {
let services = AppServices(apiClient: APIClient(session: MainTabRecordingURLSession()))
let controller = MainTabBarController(services: services)
controller.loadViewIfNeeded()
for tab in AppTab.allCases {
XCTAssertNotNil(controller.navigationController(for: tab))
XCTAssertEqual(
controller.navigationController(for: tab)?.tabBarItem.accessibilityIdentifier,
"main.tab.\(tab.rawValue)"
)
}
}
}
/// 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)
}
}