100 lines
4.1 KiB
Swift
100 lines
4.1 KiB
Swift
//
|
|
// MessageCenterAPITests.swift
|
|
// suixinkanTests
|
|
//
|
|
|
|
import XCTest
|
|
@testable import suixinkan
|
|
|
|
/// 消息中心 API 路径、参数与模型解码测试。
|
|
@MainActor
|
|
final class MessageCenterAPITests: XCTestCase {
|
|
func testListBuildsAndroidQueryAndDecodesMessagePayload() async throws {
|
|
let payload = """
|
|
{
|
|
"has_more": true,
|
|
"last_id": 18,
|
|
"is_refresh": false,
|
|
"items": [{
|
|
"id": 21,
|
|
"receiver_id": 9,
|
|
"receiver_type": "staff",
|
|
"type": 2,
|
|
"type_name": "退款成功通知",
|
|
"title": "unused",
|
|
"content": "退款已完成",
|
|
"push_at": "2026-07-09 10:00:00",
|
|
"is_read": false,
|
|
"read_at": "",
|
|
"push_channel": 1,
|
|
"push_channel_name": "站内信",
|
|
"extra_data": {"order_no":"NO123","amount":12.5},
|
|
"created_at": "2026-07-09 10:00:00",
|
|
"updated_at": "2026-07-09 10:01:00"
|
|
}]
|
|
}
|
|
"""
|
|
let session = MockURLSession(responses: [envelopeJSON(payload)])
|
|
let api = MessageCenterAPI(client: APIClient(environment: .testing, session: session))
|
|
|
|
let response = try await api.list(lastId: 7, limit: 20, unread: 0)
|
|
|
|
let request = try XCTUnwrap(session.requests.first)
|
|
XCTAssertEqual(request.httpMethod, "GET")
|
|
XCTAssertEqual(request.url?.path, "/api/app/msg/list")
|
|
let query = URLComponents(url: try XCTUnwrap(request.url), resolvingAgainstBaseURL: false)?.queryItems
|
|
XCTAssertEqual(query?.first { $0.name == "last_id" }?.value, "7")
|
|
XCTAssertEqual(query?.first { $0.name == "limit" }?.value, "20")
|
|
XCTAssertEqual(query?.first { $0.name == "unread" }?.value, "0")
|
|
XCTAssertTrue(response.hasMore)
|
|
XCTAssertEqual(response.lastId, 18)
|
|
XCTAssertEqual(response.items.first?.id, 21)
|
|
XCTAssertEqual(response.items.first?.isRead, false)
|
|
XCTAssertEqual(response.items.first?.extraData?["order_no"], .string("NO123"))
|
|
}
|
|
|
|
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))
|
|
|
|
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(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(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)
|
|
}
|
|
|
|
private func envelopeJSON(_ dataJSON: String) -> Data {
|
|
"""
|
|
{"code":100000,"msg":"success","data":\(dataJSON)}
|
|
""".data(using: .utf8)!
|
|
}
|
|
|
|
private func bodyJSON(_ request: URLRequest) throws -> [String: Any] {
|
|
try XCTUnwrap(JSONSerialization.jsonObject(with: try XCTUnwrap(request.httpBody)) as? [String: Any])
|
|
}
|
|
}
|