Files
suixinkan_ios_new/suixinkanTests/TravelAlbum/TravelAlbumAPITests.swift
汉秋 5e620623eb 对齐旅拍相册详情页 Android UI,并修复网格预览与布局问题。
重构相册详情为信息卡片、Tab 筛选、排序、批量删除与底部上传栏;修复网格重叠、禁用按钮蒙层,并支持点击预览大图。同步扩展素材列表 API 与 ViewModel 分页逻辑,并优化有线传图缩略图与传输性能。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-30 13:53:59 +08:00

128 lines
5.3 KiB
Swift
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//
// TravelAlbumAPITests.swift
// suixinkanTests
//
// Created by Codex on 2026/6/29.
//
import XCTest
@testable import suixinkan
@MainActor
/// API pathquery body
final class TravelAlbumAPITests: XCTestCase {
/// path
func testAlbumListAndCreateUseExpectedPaths() async throws {
let session = TravelAlbumRecordingURLSession(responses: [Self.listResponse, Self.createResponse])
let api = TravelAlbumAPI(client: APIClient(session: session))
let list = try await api.albumList(page: 1, pageSize: 20)
_ = try await api.createAlbum(
TravelAlbumCreateRequest(
name: "2026-06-29-001",
type: 1,
orderNumber: nil,
materialNum: 3,
materialPrice: 9.9,
materialPackagePrice: 99,
photoPrice: 0
)
)
XCTAssertEqual(session.requests.map { $0.url?.path }, [
"/api/yf-handset-app/photog/travel-album/list",
"/api/yf-handset-app/photog/travel-album/create"
])
XCTAssertEqual(list.total, 1)
XCTAssertEqual(list.list.first?.name, "2026-06-29-001")
let createBody = try bodyObject(from: session.requests[1])
XCTAssertEqual(createBody["name"] as? String, "2026-06-29-001")
XCTAssertEqual(createBody["type"] as? Int, 1)
}
/// body
func testUploadMaterialUsesExpectedBody() async throws {
let session = TravelAlbumRecordingURLSession(data: Self.uploadMaterialResponse)
let api = TravelAlbumAPI(client: APIClient(session: session))
_ = try await api.uploadMaterial(
TravelAlbumUploadMaterialRequest(
userEquityTravelId: 8,
fileName: "DSC_001.JPG",
fileURL: "https://cdn/a.jpg"
)
)
XCTAssertEqual(session.requests.first?.url?.path, "/api/yf-handset-app/photog/travel-album/upload-material")
let body = try bodyObject(from: try XCTUnwrap(session.requests.first))
XCTAssertEqual(body["user_equity_travel_id"] as? Int, 8)
XCTAssertEqual(body["file_name"] as? String, "DSC_001.JPG")
XCTAssertEqual(body["file_url"] as? String, "https://cdn/a.jpg")
}
/// order_by is_purchased
func testMaterialListUsesOrderByAndPurchasedQuery() async throws {
let session = TravelAlbumRecordingURLSession(data: Self.materialListResponse)
let api = TravelAlbumAPI(client: APIClient(session: session))
_ = try await api.materialList(
userEquityTravelId: 8,
page: 2,
pageSize: 30,
orderBy: 3,
isPurchased: 1
)
let components = try XCTUnwrap(URLComponents(url: try XCTUnwrap(session.requests.first?.url), resolvingAgainstBaseURL: false))
let query = Dictionary(uniqueKeysWithValues: (components.queryItems ?? []).map { ($0.name, $0.value) })
XCTAssertEqual(session.requests.first?.url?.path, "/api/yf-handset-app/photog/travel-album/material-list")
XCTAssertEqual(query["user_equity_travel_id"], "8")
XCTAssertEqual(query["page"], "2")
XCTAssertEqual(query["page_size"], "30")
XCTAssertEqual(query["order_by"], "3")
XCTAssertEqual(query["is_purchased"], "1")
}
fileprivate static let listResponse = Data(
#"{"code":100000,"msg":"success","data":{"total":"1","list":[{"id":"8","store_user_id":"1","name":"2026-06-29-001","type":"1","order_number":"","material_num":"3","material_price":"990","material_package_price":"9900","photo_price":"0","cover_url":"","user_id":"100","status":"1","created_at":"2026","updated_at":"2026","user":{"id":"200","phone":"13800138000"}}]}}"#.utf8
)
fileprivate static let createResponse = Data(
#"{"code":100000,"msg":"success","data":{"id":"9"}}"#.utf8
)
fileprivate static let uploadMaterialResponse = Data(
#"{"code":100000,"msg":"success","data":{"id":"11","user_equity_travel_id":"8","status":"1","order_number":"","user_id":"100","file_name":"DSC_001.JPG","file_type":"2","file_url":"https://cdn/a.jpg","file_size":"2048","cover_url":"","is_purchased":"0","created_at":"2026","updated_at":"2026"}}"#.utf8
)
fileprivate static let materialListResponse = Data(
#"{"code":100000,"msg":"success","data":{"total":"0","list":[]}}"#.utf8
)
}
private final class TravelAlbumRecordingURLSession: URLSessionProtocol {
private var responses: [Data]
private(set) var requests: [URLRequest] = []
init(data: Data) {
responses = [data]
}
init(responses: [Data]) {
self.responses = responses
}
func data(for request: URLRequest) async throws -> (Data, URLResponse) {
requests.append(request)
let data = responses.isEmpty ? TravelAlbumAPITests.listResponse : responses.removeFirst()
let response = HTTPURLResponse(url: request.url!, statusCode: 200, httpVersion: nil, headerFields: nil)!
return (data, response)
}
}
private func bodyObject(from request: URLRequest) throws -> [String: Any] {
let data = try XCTUnwrap(request.httpBody)
return try XCTUnwrap(JSONSerialization.jsonObject(with: data) as? [String: Any])
}