feat: 更新素材管理和举报风险地图

This commit is contained in:
2026-07-09 12:20:02 +08:00
parent 9b92d81902
commit 42aca73588
42 changed files with 6164 additions and 1369 deletions

View File

@ -0,0 +1,126 @@
//
// MaterialManagementAPITests.swift
// suixinkanTests
//
import XCTest
@testable import suixinkan
/// API
@MainActor
final class MaterialManagementAPITests: XCTestCase {
func testListBuildsAndroidQueryWithMaterialType() async throws {
let session = MockURLSession(responses: [envelopeJSON(#"{"total":0,"list":[],"order":null}"#)])
let api = MaterialManagementAPI(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, "1")
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 = MaterialManagementAPI(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 testDetailOperationDeleteAndTagUseAndroidPaths() async throws {
let detail = envelopeJSON(#"{"id":8,"status":1,"listing_status":1}"#)
let empty = envelopeJSON("{}")
let tag = envelopeJSON("23")
let session = MockURLSession(responses: [detail, empty, empty, tag])
let api = MaterialManagementAPI(client: APIClient(environment: .testing, session: session))
_ = try await api.detail(id: 8)
try await api.setListingStatus(id: 8, listingStatus: 0)
try await api.delete(id: 8)
let tagId = try await api.addTag(name: "snow-tag")
XCTAssertEqual(tagId, 23)
XCTAssertEqual(session.requests[0].url?.path, "/api/app/media-album/detail")
XCTAssertEqual(session.requests[1].url?.path, "/api/app/media-album/operation")
XCTAssertEqual(session.requests[2].url?.path, "/api/app/media-album/delete")
XCTAssertEqual(session.requests[3].url?.path, "/api/app/media-album/add-tag")
XCTAssertTrue(session.requests.prefix(3).allSatisfy { request in
URLComponents(url: request.url!, resolvingAgainstBaseURL: false)?
.queryItems?
.first { $0.name == "type" }?
.value == "1"
})
}
func testUploadAndEditEncodeAndroidBodyKeys() async throws {
let session = MockURLSession(responses: [envelopeJSON("{}"), envelopeJSON("{}")])
let api = MaterialManagementAPI(client: APIClient(environment: .testing, session: session))
let request = MaterialUploadRequest(
name: "素材A",
mediaType: .image,
mediaList: [
MaterialUploadMediaItem(
originalName: "a.jpg",
ossUrl: "https://cdn/a.jpg",
size: 1024,
fileWidthSize: MaterialUploadFileSize(width: 1920, height: 1080)
),
],
coverUrl: "https://cdn/c.jpg",
coverSize: "512",
scenicSpotId: 9,
materialTag: "1,2"
)
try await api.upload(request)
try await api.edit(MaterialUploadRequest(
id: 7,
name: "素材B",
mediaType: .video,
mediaList: request.mediaList,
coverUrl: request.coverUrl,
coverSize: request.coverSize,
scenicSpotId: request.scenicSpotId,
materialTag: "3"
))
let uploadBody = try bodyJSON(session.requests[0])
XCTAssertEqual(session.requests[0].url?.path, "/api/app/media-album/upload")
XCTAssertEqual(uploadBody["name"] as? String, "素材A")
XCTAssertEqual(uploadBody["type"] as? String, "1")
XCTAssertEqual(uploadBody["media_type"] as? String, "1")
XCTAssertNil(uploadBody["project_id"])
XCTAssertEqual(uploadBody["material_tag"] as? String, "1,2")
let media = (uploadBody["media_list"] as? [[String: Any]])?.first
XCTAssertEqual(media?["original_name"] as? String, "a.jpg")
XCTAssertEqual(media?["oss_url"] as? String, "https://cdn/a.jpg")
let editBody = try bodyJSON(session.requests[1])
XCTAssertEqual(session.requests[1].url?.path, "/api/app/media-album/edit")
XCTAssertEqual(editBody["id"] as? Int, 7)
XCTAssertEqual(editBody["type"] as? String, "1")
XCTAssertEqual(editBody["media_type"] as? String, "2")
XCTAssertNil(editBody["project_id"])
}
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])
}
}