fix: 推送点击仅按 type 路由到收款页或消息中心。

对齐后端消息类型约定,去掉 route/uri 等兼容字段,并补充联调日志与单测。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-07-22 18:20:36 +08:00
parent caeeb9a1cf
commit 1b2637f0ee
6 changed files with 544 additions and 133 deletions

View File

@ -27,22 +27,40 @@ final class PushNotificationTests: XCTestCase {
super.tearDown()
}
func testPayloadRoutesTopLevelAndKnownDestinations() {
XCTAssertEqual(PushPayload(userInfo: ["type": "1"]).destination, .payment)
XCTAssertEqual(PushPayload(userInfo: ["route": "photographer_orders"]).destination, .orders)
XCTAssertEqual(PushPayload(userInfo: ["route": "verification_order"]).destination, .verificationOrders)
XCTAssertEqual(PushPayload(userInfo: ["action": "task_management"]).destination, .task)
XCTAssertEqual(PushPayload(userInfo: ["uri": "/scenic-queue"]).destination, .queue)
XCTAssertEqual(PushPayload(userInfo: ["route": "message_center"]).destination, .messageCenter)
func testPayloadRoutesPaymentTypesToTheirPages() {
XCTAssertEqual(
PushPayload(userInfo: ["type": 1, "route": "message_center"]).destination,
.paymentRecord
)
XCTAssertEqual(
PushPayload(userInfo: ["type": "6", "action": "task_management"]).destination,
.paymentDetails
)
}
func testPayloadRoutesNestedJSONStringAndUnknownFallsBackToMessageCenter() {
func testPayloadIgnoresNonTypeRoutingFieldsAndOtherTypesFallBackToMessageCenter() {
let conflictingFields: [AnyHashable: Any] = [
"type": 2,
"route": "payment",
"uri": "/payment_qr",
"action": "收款",
]
[0, 2, 3, 4, 5, 7, 8, 9, 10, 11, 12, 100, 999].forEach { type in
XCTAssertEqual(PushPayload(userInfo: ["type": type]).destination, .messageCenter)
}
XCTAssertEqual(PushPayload(userInfo: conflictingFields).destination, .messageCenter)
XCTAssertEqual(PushPayload(userInfo: ["route": "payment"]).destination, .messageCenter)
XCTAssertEqual(PushPayload(userInfo: ["data": ["type": 6]]).destination, .messageCenter)
XCTAssertEqual(PushPayload(userInfo: ["type": 999]).destination, .messageCenter)
}
func testPayloadReadsTypeFromNestedJSONStringWithoutUsingOtherFields() {
let nested = PushPayload(userInfo: [
"extras": #"{"data":{"action":""}}"#,
"extras": #"{"type":6,"route":"message_center"}"#,
])
XCTAssertEqual(nested.destination, .queue)
XCTAssertEqual(PushPayload(userInfo: ["title": "未知消息"]).destination, .messageCenter)
XCTAssertEqual(nested.destination, .paymentDetails)
}
func testPushAPIUsesAndroidCompatibleEndpointAndQuery() async throws {
@ -152,10 +170,10 @@ final class PushNotificationTests: XCTestCase {
XCTAssertTrue(router.destinations.isEmpty)
manager.handleNotificationTap(
payload: PushPayload(userInfo: ["route": "task_management"]),
payload: PushPayload(userInfo: ["type": 1, "route": "task_management"]),
requestIdentifier: "request-1"
)
XCTAssertEqual(router.destinations, [.task])
XCTAssertEqual(router.destinations, [.paymentRecord])
}
func testRemoteNotificationNotifiesUnreadMessageStateChange() async {
@ -186,19 +204,18 @@ final class PushNotificationTests: XCTestCase {
window.rootViewController = UINavigationController(rootViewController: UIViewController())
coordinator.attach(window: window)
coordinator.handle(destination: .queue, requestIdentifier: "cold-request")
coordinator.handle(destination: .paymentDetails, requestIdentifier: "cold-request")
authenticate(userID: "100")
appStore.session.currentScenicId = 9
let mainTab = MainTabBarController()
mainTab.loadViewIfNeeded()
window.rootViewController = mainTab
coordinator.routePendingIfPossible()
let navigationController = mainTab.selectedViewController as? UINavigationController
XCTAssertTrue(navigationController?.topViewController is ScenicQueueViewController)
XCTAssertTrue(navigationController?.topViewController is PaymentCollectionDetailsViewController)
coordinator.handle(destination: .messageCenter, requestIdentifier: "cold-request")
XCTAssertTrue(navigationController?.topViewController is ScenicQueueViewController)
XCTAssertTrue(navigationController?.topViewController is PaymentCollectionDetailsViewController)
}
private func authenticate(userID: String) {