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>
This commit is contained in:
108
suixinkanTests/CloudStoragePickForTaskViewModelTests.swift
Normal file
108
suixinkanTests/CloudStoragePickForTaskViewModelTests.swift
Normal file
@ -0,0 +1,108 @@
|
||||
//
|
||||
// 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,
|
||||
]
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user