feat: add travel album module

This commit is contained in:
2026-07-07 17:23:31 +08:00
parent a80c181bd7
commit 00bda390e8
16 changed files with 3115 additions and 0 deletions

View File

@ -0,0 +1,92 @@
//
// TravelAlbumModelsTests.swift
// suixinkanTests
//
import XCTest
@testable import suixinkan
///
final class TravelAlbumModelsTests: XCTestCase {
func testTravelAlbumDecodesSnakeCaseFields() throws {
let json = """
{
"id": 7,
"store_user_id": 2,
"name": "",
"type": 1,
"order_number": "NO001",
"material_num": 3,
"material_price": 1200,
"material_package_price": 5000,
"photo_price": 0,
"cover_url": "https://cdn/cover.jpg",
"user_id": 9,
"status": 1,
"created_at": "2026-07-07 10:00:00",
"updated_at": "2026-07-07 10:10:00",
"user": {"id": 4, "phone": "13800138000"}
}
""".data(using: .utf8)!
let album = try JSONDecoder().decode(TravelAlbum.self, from: json)
XCTAssertEqual(album.id, 7)
XCTAssertEqual(album.storeUserId, 2)
XCTAssertEqual(album.orderNumber, "NO001")
XCTAssertEqual(album.displayPhone, "13800138000")
}
func testTravelAlbumMaterialDecodesSnakeCaseFields() throws {
let json = """
{
"id": 11,
"user_equity_travel_id": 7,
"status": 1,
"order_number": "",
"user_id": 9,
"file_name": "IMG_0001.JPG",
"file_type": 2,
"file_url": "https://cdn/a.jpg",
"file_size": 2048,
"cover_url": "",
"is_purchased": false,
"created_at": "",
"updated_at": ""
}
""".data(using: .utf8)!
let material = try JSONDecoder().decode(TravelAlbumMaterial.self, from: json)
XCTAssertEqual(material.userEquityTravelId, 7)
XCTAssertEqual(material.fileName, "IMG_0001.JPG")
XCTAssertFalse(material.isPurchased)
}
func testDisplayFormatters() {
XCTAssertEqual(TravelAlbumDisplayFormatter.maskPhone("13800138000"), "138****8000")
XCTAssertEqual(TravelAlbumDisplayFormatter.maskPhone(""), "--")
XCTAssertEqual(TravelAlbumDisplayFormatter.fileSizeText(2048), "2.0KB")
XCTAssertEqual(TravelAlbumDisplayFormatter.fileSizeText(2 * 1024 * 1024), "2.0MB")
}
@MainActor
func testBuildTodayAlbumNameUsesExistingSameDayCount() {
let date = Calendar(identifier: .gregorian).date(from: DateComponents(year: 2026, month: 7, day: 7))!
let viewModel = TravelAlbumEntryViewModel(currentScenicIdProvider: { 1 }, dateProvider: { date })
viewModel.onStateChange = {}
let api = TravelAlbumMockAPI()
api.listResponse = TravelAlbumListResponse(
total: 2,
list: [
TravelAlbum(id: 1, createdAt: "2026-07-07 09:00:00"),
TravelAlbum(id: 2, createdAt: "2026-07-06 09:00:00"),
]
)
let exp = expectation(description: "load")
Task {
await viewModel.loadAlbums(api: api)
XCTAssertEqual(viewModel.buildTodayAlbumName(), "2026-07-07-002")
exp.fulfill()
}
wait(for: [exp], timeout: 1)
}
}