对齐 Android 样片模块布局与加载状态,补充共享 UI 组件与图片资源,并增强列表解析容错与单元测试覆盖。 Co-authored-by: Cursor <cursoragent@cursor.com>
173 lines
8.4 KiB
Swift
173 lines
8.4 KiB
Swift
//
|
|
// SampleManagementAPITests.swift
|
|
// suixinkanTests
|
|
//
|
|
|
|
import XCTest
|
|
@testable import suixinkan
|
|
|
|
/// 样片管理 API 测试。
|
|
@MainActor
|
|
final class SampleManagementAPITests: XCTestCase {
|
|
func testListBuildsAndroidQuery() async throws {
|
|
let session = MockURLSession(responses: [envelopeJSON(#"{"total":0,"list":[],"order":null}"#)])
|
|
let api = SampleManagementAPI(client: APIClient(environment: .testing, session: session))
|
|
|
|
_ = try await api.list(status: 4, keyword: "雪山", page: 2, pageSize: 10)
|
|
|
|
let request = try XCTUnwrap(session.requests.first)
|
|
XCTAssertEqual(request.httpMethod, "GET")
|
|
XCTAssertEqual(request.url?.path, "/api/app/media-album/list")
|
|
let query = URLComponents(url: try XCTUnwrap(request.url), resolvingAgainstBaseURL: false)?.queryItems
|
|
XCTAssertEqual(query?.first { $0.name == "status" }?.value, "4")
|
|
XCTAssertEqual(query?.first { $0.name == "keyword" }?.value, "雪山")
|
|
XCTAssertEqual(query?.first { $0.name == "type" }?.value, "2")
|
|
XCTAssertEqual(query?.first { $0.name == "page" }?.value, "2")
|
|
XCTAssertEqual(query?.first { $0.name == "page_size" }?.value, "10")
|
|
}
|
|
|
|
func testListDecodesNullableOrderAmounts() async throws {
|
|
let session = MockURLSession(responses: [envelopeJSON(#"{"total":0,"list":[],"order":{"avg_change":-1025,"avg_order_amount":null,"refund_total":null,"total_num":0}}"#)])
|
|
let api = SampleManagementAPI(client: APIClient(environment: .testing, session: session))
|
|
|
|
let response = try await api.list(status: 4, keyword: nil, page: 1, pageSize: 10)
|
|
|
|
XCTAssertEqual(response.order?.avgOrderAmount, "0")
|
|
XCTAssertEqual(response.order?.refundTotal, "0")
|
|
XCTAssertEqual(response.order?.avgChange, -1025)
|
|
XCTAssertEqual(response.order?.totalNum, 0)
|
|
}
|
|
|
|
func testDetailAndOperationUseSampleType() async throws {
|
|
let detail = envelopeJSON(#"{"id":8,"status":1,"listing_status":1}"#)
|
|
let empty = envelopeJSON("{}")
|
|
let session = MockURLSession(responses: [detail, empty])
|
|
let api = SampleManagementAPI(client: APIClient(environment: .testing, session: session))
|
|
|
|
_ = try await api.detail(id: 8)
|
|
try await api.setListingStatus(id: 8, listingStatus: 0)
|
|
|
|
XCTAssertEqual(session.requests[0].url?.path, "/api/app/media-album/detail")
|
|
let detailQuery = URLComponents(url: session.requests[0].url!, resolvingAgainstBaseURL: false)?.queryItems
|
|
XCTAssertEqual(detailQuery?.first { $0.name == "id" }?.value, "8")
|
|
XCTAssertEqual(detailQuery?.first { $0.name == "type" }?.value, "2")
|
|
|
|
XCTAssertEqual(session.requests[1].httpMethod, "POST")
|
|
XCTAssertEqual(session.requests[1].url?.path, "/api/app/media-album/operation")
|
|
let operationQuery = URLComponents(url: session.requests[1].url!, resolvingAgainstBaseURL: false)?.queryItems
|
|
XCTAssertEqual(operationQuery?.first { $0.name == "id" }?.value, "8")
|
|
XCTAssertEqual(operationQuery?.first { $0.name == "listing_status" }?.value, "0")
|
|
XCTAssertEqual(operationQuery?.first { $0.name == "type" }?.value, "2")
|
|
}
|
|
|
|
func testDetailMediaTypeZeroFallsBackToAlbumType() async throws {
|
|
let detail = envelopeJSON(#"{"id":8,"type":2,"status":1,"listing_status":1,"media_list":[{"id":1,"type":0,"oss_url":"https://cdn/video.mp4"}]}"#)
|
|
let session = MockURLSession(responses: [detail])
|
|
let api = SampleManagementAPI(client: APIClient(environment: .testing, session: session))
|
|
|
|
let response = try await api.detail(id: 8)
|
|
|
|
XCTAssertEqual(response.mediaList?.first?.resolvedType(fallback: response.type ?? 1), 2)
|
|
}
|
|
|
|
func testUploadEncodesAndroidBodyKeys() async throws {
|
|
let session = MockURLSession(responses: [envelopeJSON("{}")])
|
|
let api = SampleManagementAPI(client: APIClient(environment: .testing, session: session))
|
|
let request = SampleUploadMaterialRequest(
|
|
name: "样片A",
|
|
mediaType: .image,
|
|
mediaList: [
|
|
SampleUploadMediaItem(
|
|
originalName: "a.jpg",
|
|
ossUrl: "https://cdn/a.jpg",
|
|
size: 1024,
|
|
fileWidthSize: SampleUploadFileSize(width: 1920, height: 1080)
|
|
),
|
|
],
|
|
coverUrl: "https://cdn/c.jpg",
|
|
coverSize: "512",
|
|
scenicSpotId: 9,
|
|
projectId: 7
|
|
)
|
|
|
|
try await api.upload(request)
|
|
|
|
let urlRequest = try XCTUnwrap(session.requests.first)
|
|
XCTAssertEqual(urlRequest.httpMethod, "POST")
|
|
XCTAssertEqual(urlRequest.url?.path, "/api/app/media-album/upload")
|
|
let body = try JSONSerialization.jsonObject(with: try XCTUnwrap(urlRequest.httpBody)) as? [String: Any]
|
|
XCTAssertEqual(body?["name"] as? String, "样片A")
|
|
XCTAssertEqual(body?["type"] as? String, "2")
|
|
XCTAssertEqual(body?["media_type"] as? String, "1")
|
|
XCTAssertEqual(body?["cover_url"] as? String, "https://cdn/c.jpg")
|
|
XCTAssertEqual(body?["cover_size"] as? String, "512")
|
|
XCTAssertEqual(body?["scenic_spot_id"] as? Int, 9)
|
|
XCTAssertEqual(body?["material_tag"] as? String, "")
|
|
XCTAssertEqual(body?["project_id"] as? Int, 7)
|
|
let media = (body?["media_list"] as? [[String: Any]])?.first
|
|
XCTAssertEqual(media?["original_name"] as? String, "a.jpg")
|
|
XCTAssertEqual(media?["oss_url"] as? String, "https://cdn/a.jpg")
|
|
XCTAssertEqual(media?["size"] as? Int, 1024)
|
|
let fileSize = media?["file_width_size"] as? [String: Any]
|
|
XCTAssertEqual(fileSize?["width"] as? Int, 1920)
|
|
XCTAssertEqual(fileSize?["height"] as? Int, 1080)
|
|
}
|
|
|
|
func testUploadEncodesVideoMetadata() async throws {
|
|
let session = MockURLSession(responses: [envelopeJSON("{}")])
|
|
let api = SampleManagementAPI(client: APIClient(environment: .testing, session: session))
|
|
let request = SampleUploadMaterialRequest(
|
|
name: "视频样片",
|
|
mediaType: .video,
|
|
mediaList: [
|
|
SampleUploadMediaItem(
|
|
originalName: "rotated.mp4",
|
|
ossUrl: "https://cdn/rotated.mp4",
|
|
size: 4_096,
|
|
fileWidthSize: SampleUploadFileSize(width: 1080, height: 1920)
|
|
),
|
|
],
|
|
coverUrl: "https://cdn/cover.jpg",
|
|
coverSize: "512",
|
|
scenicSpotId: 9,
|
|
projectId: 7
|
|
)
|
|
|
|
try await api.upload(request)
|
|
|
|
let body = try JSONSerialization.jsonObject(with: try XCTUnwrap(session.requests.first?.httpBody)) as? [String: Any]
|
|
XCTAssertEqual(body?["type"] as? String, "2")
|
|
XCTAssertEqual(body?["media_type"] as? String, "2")
|
|
let media = (body?["media_list"] as? [[String: Any]])?.first
|
|
XCTAssertEqual(media?["original_name"] as? String, "rotated.mp4")
|
|
XCTAssertEqual(media?["size"] as? Int, 4_096)
|
|
let fileSize = media?["file_width_size"] as? [String: Any]
|
|
XCTAssertEqual(fileSize?["width"] as? Int, 1080)
|
|
XCTAssertEqual(fileSize?["height"] as? Int, 1920)
|
|
}
|
|
|
|
func testProjectAndScenicSpotPaths() async throws {
|
|
let spots = envelopeJSON(#"{"total":1,"list":[]}"#)
|
|
let projects = envelopeJSON(#"{"total":1,"list":[]}"#)
|
|
let session = MockURLSession(responses: [spots, projects])
|
|
let api = SampleManagementAPI(client: APIClient(environment: .testing, session: session))
|
|
|
|
_ = try await api.scenicSpotListAll(scenicId: "12")
|
|
_ = try await api.projectList(scenicId: "12", name: nil, page: 3, pageSize: 10)
|
|
|
|
XCTAssertEqual(session.requests[0].url?.path, "/api/yf-handset-app/photog/scenic-spot/list-all")
|
|
XCTAssertEqual(URLComponents(url: session.requests[0].url!, resolvingAgainstBaseURL: false)?.queryItems?.first { $0.name == "scenic_id" }?.value, "12")
|
|
XCTAssertEqual(session.requests[1].url?.path, "/api/yf-handset-app/photog/project/list")
|
|
let query = URLComponents(url: session.requests[1].url!, resolvingAgainstBaseURL: false)?.queryItems
|
|
XCTAssertEqual(query?.first { $0.name == "scenic_id" }?.value, "12")
|
|
XCTAssertEqual(query?.first { $0.name == "page" }?.value, "3")
|
|
XCTAssertEqual(query?.first { $0.name == "page_size" }?.value, "10")
|
|
}
|
|
|
|
private func envelopeJSON(_ dataJSON: String) -> Data {
|
|
"""
|
|
{"code":100000,"msg":"success","data":\(dataJSON)}
|
|
""".data(using: .utf8)!
|
|
}
|
|
}
|