feat: 接入消息未读数、全部已读与首页红点角标同步。

固定消息中心为首页入口,并在推送到达、已读后刷新桌面角标。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-07-21 18:02:43 +08:00
parent e7f1d777dd
commit caeeb9a1cf
18 changed files with 748 additions and 37 deletions

View File

@ -53,21 +53,37 @@ final class MessageCenterAPITests: XCTestCase {
XCTAssertEqual(response.items.first?.extraData?["order_no"], .string("NO123"))
}
func testReadAndDeleteUseAndroidPathsAndBody() async throws {
let session = MockURLSession(responses: [envelopeJSON("{}"), envelopeJSON("{}")])
func testUnreadCountReadAllReadAndDeleteUseExpectedContracts() async throws {
let session = MockURLSession(responses: [
envelopeJSON(#"{"unread_count":"12"}"#),
envelopeJSON(#"{"unread_count":11}"#),
envelopeJSON(#"{"updated_count":11,"unread_count":0}"#),
envelopeJSON("{}"),
])
let api = MessageCenterAPI(client: APIClient(environment: .testing, session: session))
try await api.markAsRead(messageId: 21)
let unread = try await api.unreadCount()
let read = try await api.markAsRead(messageId: 21)
let readAll = try await api.markAllAsRead()
try await api.delete(messageId: 21)
XCTAssertEqual(session.requests[0].httpMethod, "POST")
XCTAssertEqual(session.requests[0].url?.path, "/api/app/msg/read")
let readQuery = URLComponents(url: try XCTUnwrap(session.requests[0].url), resolvingAgainstBaseURL: false)?.queryItems
XCTAssertEqual(unread.unreadCount, 12)
XCTAssertEqual(session.requests[0].httpMethod, "GET")
XCTAssertEqual(session.requests[0].url?.path, "/api/app/msg/unread-count")
XCTAssertEqual(read.unreadCount, 11)
XCTAssertEqual(session.requests[1].httpMethod, "POST")
XCTAssertEqual(session.requests[1].url?.path, "/api/app/msg/read")
let readQuery = URLComponents(url: try XCTUnwrap(session.requests[1].url), resolvingAgainstBaseURL: false)?.queryItems
XCTAssertEqual(readQuery?.first { $0.name == "id" }?.value, "21")
XCTAssertEqual(session.requests[1].httpMethod, "POST")
XCTAssertEqual(session.requests[1].url?.path, "/api/app/msg/delete")
let deleteBody = try bodyJSON(session.requests[1])
XCTAssertEqual(readAll, MessageReadAllResponse(updatedCount: 11, unreadCount: 0))
XCTAssertEqual(session.requests[2].httpMethod, "POST")
XCTAssertEqual(session.requests[2].url?.path, "/api/app/msg/read-all")
XCTAssertEqual(session.requests[3].httpMethod, "POST")
XCTAssertEqual(session.requests[3].url?.path, "/api/app/msg/delete")
let deleteBody = try bodyJSON(session.requests[3])
XCTAssertEqual(deleteBody["id"] as? Int, 21)
}