Files
suixinkan_uikit/suixinkanTests/CloudDriveViewModelTests.swift

140 lines
5.5 KiB
Swift

//
// CloudDriveViewModelTests.swift
// suixinkanTests
//
import XCTest
@testable import suixinkan
@MainActor
/// ViewModel
final class CloudDriveViewModelTests: XCTestCase {
func testLoadMoreSearchFilterSortAndFolderNavigation() async throws {
let api = MockCloudDriveAPI()
api.listResponses = [
CloudFileListResponse(total: 3, list: [file(id: 1), folder(id: 2)]),
CloudFileListResponse(total: 3, list: [file(id: 3)]),
CloudFileListResponse(total: 1, list: [file(id: 4)]),
CloudFileListResponse(total: 0, list: []),
]
let viewModel = CloudDriveListViewModel()
await viewModel.refresh(api: api)
await viewModel.loadMoreIfNeeded(lastVisibleIndex: 1, api: api)
viewModel.updateSearchText("")
await viewModel.chooseFilterType(.image, api: api)
_ = await viewModel.handleFileTap(folder(id: 9), api: api)
XCTAssertEqual(viewModel.files.map(\.id), [])
XCTAssertEqual(viewModel.pathStack.map(\.id), [0, 9])
XCTAssertEqual(api.listCalls.map(\.page), [1, 2, 1, 1])
XCTAssertEqual(api.listCalls[2].name, "")
XCTAssertEqual(api.listCalls[2].type, 2)
}
func testBackRestoresCachedRootAndGoHome() async {
let api = MockCloudDriveAPI()
api.listResponses = [
CloudFileListResponse(total: 1, list: [folder(id: 2)]),
CloudFileListResponse(total: 1, list: [file(id: 5)]),
]
let viewModel = CloudDriveListViewModel()
await viewModel.refresh(api: api)
_ = await viewModel.handleFileTap(folder(id: 2), api: api)
let handled = await viewModel.navigateBack(api: api)
XCTAssertTrue(handled)
XCTAssertEqual(viewModel.pathStack.map(\.id), [0])
XCTAssertEqual(viewModel.files.map(\.id), [2])
XCTAssertEqual(api.listCalls.count, 2)
}
func testCreateDeleteMoveAndRenameRefresh() async {
let api = MockCloudDriveAPI()
api.listResponses = Array(repeating: CloudFileListResponse(), count: 5)
let viewModel = CloudDriveListViewModel()
await viewModel.addFolder(name: " 新目录 ", api: api)
viewModel.setControlFile(file(id: 7, type: 2))
await viewModel.deleteCurrentFile(api: api)
await viewModel.moveCurrentFile(targetFolderId: 9, api: api)
await viewModel.saveCurrentFileName(" 新名.jpg ", api: api)
viewModel.setControlFile(folder(id: 8))
await viewModel.saveCurrentFileName(" 新目录名 ", api: api)
XCTAssertEqual(api.createFolderCalls.first?.name, "新目录")
XCTAssertEqual(api.deleteCalls.first?.list.first?.id, 7)
XCTAssertEqual(api.moveCalls.first?.targetFolderId, 9)
XCTAssertEqual(api.renameFileCalls.first?.fileName, "新名.jpg")
XCTAssertEqual(api.renameFolderCalls.first?.name, "新目录名")
}
func testUploadPermissionFailureShowsReason() async {
let api = MockCloudDriveAPI()
api.permission = CloudUploadPermissionResponse(canUpload: false, reason: "空间不足")
let viewModel = CloudDriveListViewModel()
var message: String?
viewModel.onShowMessage = { message = $0 }
let canUpload = await viewModel.checkCanUpload(api: api)
XCTAssertFalse(canUpload)
XCTAssertEqual(message, "空间不足")
}
private func file(id: Int, type: Int = 2) -> CloudFile {
CloudFile(id: id, fileUrl: "https://cdn/\(id).jpg", name: "文件\(id)", type: type)
}
private func folder(id: Int) -> CloudFile {
CloudFile(id: id, name: "目录\(id)", type: 99)
}
}
@MainActor
private final class MockCloudDriveAPI: CloudDriveServing {
var listResponses: [CloudFileListResponse] = []
var permission = CloudUploadPermissionResponse(canUpload: true, reason: "")
var listCalls: [(parentFolderId: Int, name: String, type: Int, orderBy: Int, page: Int, pageSize: Int)] = []
var createFolderCalls: [(parentFolderId: Int, name: String)] = []
var uploadCalls: [(parentFolderId: Int, fileUrl: String, fileName: String)] = []
var deleteCalls: [CloudFileDeleteRequest] = []
var moveCalls: [CloudFileMoveRequest] = []
var renameFolderCalls: [(fileId: Int, name: String)] = []
var renameFileCalls: [(fileId: Int, fileName: String)] = []
func cloudFileList(parentFolderId: Int, name: String, type: Int, orderBy: Int, page: Int, pageSize: Int) async throws -> CloudFileListResponse {
listCalls.append((parentFolderId, name, type, orderBy, page, pageSize))
return listResponses.isEmpty ? CloudFileListResponse() : listResponses.removeFirst()
}
func createCloudFolder(parentFolderId: Int, name: String) async throws {
createFolderCalls.append((parentFolderId, name))
}
func uploadCloudFile(parentFolderId: Int, fileUrl: String, fileName: String) async throws {
uploadCalls.append((parentFolderId, fileUrl, fileName))
}
func deleteCloudFiles(_ request: CloudFileDeleteRequest) async throws {
deleteCalls.append(request)
}
func moveCloudFiles(_ request: CloudFileMoveRequest) async throws {
moveCalls.append(request)
}
func checkUploadPermission() async throws -> CloudUploadPermissionResponse {
permission
}
func modifyCloudFolderName(fileId: Int, name: String) async throws {
renameFolderCalls.append((fileId, name))
}
func modifyCloudFileName(fileId: Int, fileName: String) async throws {
renameFileCalls.append((fileId, fileName))
}
}