Files
suixinkan_uikit/suixinkanTests/CloudStoragePickForTaskViewModelTests.swift
汉秋 3c4ca7eefb Add submit-task flow aligned with Android and extract profile edit page.
Implement task creation with cloud/local media, order linking, and OSS upload; wire home entry and move profile nickname/avatar editing to ProfileEditViewController.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-07 10:12:20 +08:00

109 lines
3.7 KiB
Swift

//
// CloudStoragePickForTaskViewModelTests.swift
// suixinkanTests
//
import XCTest
@testable import suixinkan
@MainActor
/// ViewModel
final class CloudStoragePickForTaskViewModelTests: XCTestCase {
func testHandleItemTapTogglesMediaSelection() async throws {
let listJSON = try makeListJSON(files: [
makeFileJSON(id: 5, name: "图片", type: 2),
])
let api = makeAPI(responses: [listJSON, listJSON])
let viewModel = CloudStoragePickForTaskViewModel()
await viewModel.refresh(api: api)
let file = try XCTUnwrap(viewModel.files.first)
await viewModel.handleItemTap(file, api: api)
XCTAssertTrue(viewModel.isSelected(5))
await viewModel.handleItemTap(file, api: api)
XCTAssertFalse(viewModel.isSelected(5))
}
func testHandleItemTapShowsImportedMessage() async throws {
let listJSON = try makeListJSON(files: [
makeFileJSON(id: 5, name: "图片", type: 2),
])
let api = makeAPI(responses: [listJSON])
let viewModel = CloudStoragePickForTaskViewModel(importedFileIDs: [5])
var message: String?
viewModel.onShowMessage = { message = $0 }
await viewModel.refresh(api: api)
let file = try XCTUnwrap(viewModel.files.first)
await viewModel.handleItemTap(file, api: api)
XCTAssertEqual(message, "已选择")
XCTAssertFalse(viewModel.isSelected(5))
}
func testNavigateToFolderUpdatesPathStack() async throws {
let rootJSON = try makeListJSON(files: [
makeFileJSON(id: 8, name: "文件夹", type: 99),
])
let childJSON = try makeListJSON(files: [])
let api = makeAPI(responses: [rootJSON, childJSON])
let viewModel = CloudStoragePickForTaskViewModel()
await viewModel.refresh(api: api)
let folder = try XCTUnwrap(viewModel.files.first)
await viewModel.handleItemTap(folder, api: api)
XCTAssertEqual(viewModel.pathStack.map(\.id), [0, 8])
}
func testSelectedFileListReturnsAllChosenFiles() async throws {
let listJSON = try makeListJSON(files: [
makeFileJSON(id: 1, name: "A", type: 2),
makeFileJSON(id: 2, name: "B", type: 2),
])
let api = makeAPI(responses: [listJSON, listJSON, listJSON])
let viewModel = CloudStoragePickForTaskViewModel()
await viewModel.refresh(api: api)
await viewModel.handleItemTap(viewModel.files[0], api: api)
await viewModel.handleItemTap(viewModel.files[1], api: api)
XCTAssertEqual(Set(viewModel.selectedFileList.map(\.id)), Set([1, 2]))
}
private func makeAPI(responses: [Data]) -> TaskAPI {
TaskAPI(client: APIClient(environment: .testing, session: MockURLSession(responses: responses)))
}
private func makeListJSON(files: [[String: Any]]) throws -> Data {
let listData = try JSONSerialization.data(withJSONObject: files)
let listObject = try JSONSerialization.jsonObject(with: listData)
let envelope: [String: Any] = [
"code": 100000,
"msg": "success",
"data": [
"total": files.count,
"list": listObject,
],
]
return try JSONSerialization.data(withJSONObject: envelope)
}
private func makeFileJSON(id: Int, name: String, type: Int) -> [String: Any] {
[
"id": id,
"parent_folder_id": 0,
"file_url": "https://cdn/\(id).jpg",
"cover_url": "",
"updated_at": "",
"name": name,
"created_at": "",
"child_num": 0,
"type": type,
"file_size": 100,
]
}
}