同步相册云盘界面并完善相关交互
This commit is contained in:
@ -9,12 +9,47 @@ import XCTest
|
||||
@MainActor
|
||||
/// 相册云盘 ViewModel 测试。
|
||||
final class CloudDriveViewModelTests: XCTestCase {
|
||||
func testDisplayModeToggleSwitchesBetweenGridAndListAndNotifiesUI() {
|
||||
let viewModel = CloudDriveListViewModel()
|
||||
var notificationCount = 0
|
||||
viewModel.onStateChange = { notificationCount += 1 }
|
||||
|
||||
viewModel.toggleDisplayMode()
|
||||
XCTAssertEqual(viewModel.displayMode, .list)
|
||||
|
||||
viewModel.toggleDisplayMode()
|
||||
XCTAssertEqual(viewModel.displayMode, .grid)
|
||||
XCTAssertEqual(notificationCount, 2)
|
||||
}
|
||||
|
||||
func testListFileDescriptionMatchesAndroidDateSizeAndFolderCount() {
|
||||
let image = CloudFile(
|
||||
id: 1,
|
||||
name: "海边.jpg",
|
||||
createdAt: "2026-07-10 18:32:15",
|
||||
type: 2,
|
||||
fileSize: 2_048
|
||||
)
|
||||
let folder = CloudFile(
|
||||
id: 2,
|
||||
name: "旅行",
|
||||
createdAt: "2026-07-09 09:08:07",
|
||||
childNum: 3,
|
||||
type: 99
|
||||
)
|
||||
|
||||
XCTAssertEqual(CloudDriveFormatter.fileDescription(image), "2026-07-10 | 2.00 KB")
|
||||
XCTAssertEqual(CloudDriveFormatter.fileDescription(folder), "2026-07-09 | 3个项目")
|
||||
XCTAssertEqual(CloudDriveFormatter.fileSize(0), "0 B")
|
||||
}
|
||||
|
||||
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: 1, list: [file(id: 5)]),
|
||||
CloudFileListResponse(total: 0, list: []),
|
||||
]
|
||||
let viewModel = CloudDriveListViewModel()
|
||||
@ -23,13 +58,16 @@ final class CloudDriveViewModelTests: XCTestCase {
|
||||
await viewModel.loadMoreIfNeeded(lastVisibleIndex: 1, api: api)
|
||||
viewModel.updateSearchText("图")
|
||||
await viewModel.chooseFilterType(.image, api: api)
|
||||
await viewModel.chooseSortType(.createdAscending, 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.map(\.page), [1, 2, 1, 1, 1])
|
||||
XCTAssertEqual(api.listCalls[2].name, "图")
|
||||
XCTAssertEqual(api.listCalls[2].type, 2)
|
||||
XCTAssertEqual(api.listCalls[3].orderBy, 1)
|
||||
XCTAssertEqual(api.listCalls[4].name, "")
|
||||
}
|
||||
|
||||
func testBackRestoresCachedRootAndGoHome() async {
|
||||
@ -50,6 +88,58 @@ final class CloudDriveViewModelTests: XCTestCase {
|
||||
XCTAssertEqual(api.listCalls.count, 2)
|
||||
}
|
||||
|
||||
func testRootBackReturnsFalseWithoutRequest() async {
|
||||
let api = MockCloudDriveAPI()
|
||||
let viewModel = CloudDriveListViewModel()
|
||||
|
||||
let handled = await viewModel.navigateBack(api: api)
|
||||
|
||||
XCTAssertFalse(handled)
|
||||
XCTAssertEqual(viewModel.pathStack.map(\.id), [0])
|
||||
XCTAssertTrue(api.listCalls.isEmpty)
|
||||
}
|
||||
|
||||
func testBreadcrumbAndGoHomeRestoreFolderCaches() async {
|
||||
let api = MockCloudDriveAPI()
|
||||
api.listResponses = [
|
||||
CloudFileListResponse(total: 1, list: [folder(id: 2)]),
|
||||
CloudFileListResponse(total: 1, list: [folder(id: 3)]),
|
||||
CloudFileListResponse(total: 1, list: [file(id: 9)]),
|
||||
]
|
||||
let viewModel = CloudDriveListViewModel()
|
||||
|
||||
await viewModel.refresh(api: api)
|
||||
_ = await viewModel.handleFileTap(folder(id: 2), api: api)
|
||||
_ = await viewModel.handleFileTap(folder(id: 3), api: api)
|
||||
await viewModel.navigateToPathIndex(1, api: api)
|
||||
|
||||
XCTAssertEqual(viewModel.pathStack.map(\.id), [0, 2])
|
||||
XCTAssertEqual(viewModel.files.map(\.id), [3])
|
||||
XCTAssertEqual(api.listCalls.count, 3)
|
||||
|
||||
await viewModel.goHome(api: api)
|
||||
|
||||
XCTAssertEqual(viewModel.pathStack.map(\.id), [0])
|
||||
XCTAssertEqual(viewModel.files.map(\.id), [2])
|
||||
XCTAssertEqual(api.listCalls.count, 3)
|
||||
}
|
||||
|
||||
func testFolderDepthLimitPreventsSixthLevel() async {
|
||||
let api = MockCloudDriveAPI()
|
||||
let viewModel = CloudDriveListViewModel()
|
||||
var message: String?
|
||||
viewModel.onShowMessage = { message = $0 }
|
||||
|
||||
for id in 1 ... 4 {
|
||||
_ = await viewModel.handleFileTap(folder(id: id), api: api)
|
||||
}
|
||||
await viewModel.addFolder(name: "第六层", api: api)
|
||||
|
||||
XCTAssertEqual(viewModel.pathStack.count, 5)
|
||||
XCTAssertEqual(message, "不能创建更深的文件夹")
|
||||
XCTAssertTrue(api.createFolderCalls.isEmpty)
|
||||
}
|
||||
|
||||
func testCreateDeleteMoveAndRenameRefresh() async {
|
||||
let api = MockCloudDriveAPI()
|
||||
api.listResponses = Array(repeating: CloudFileListResponse(), count: 5)
|
||||
@ -83,6 +173,38 @@ final class CloudDriveViewModelTests: XCTestCase {
|
||||
XCTAssertEqual(message, "空间不足")
|
||||
}
|
||||
|
||||
func testEmptyFolderAndRenameNamesAreRejected() async {
|
||||
let api = MockCloudDriveAPI()
|
||||
let viewModel = CloudDriveListViewModel()
|
||||
var messages: [String] = []
|
||||
viewModel.onShowMessage = { messages.append($0) }
|
||||
|
||||
await viewModel.addFolder(name: " ", api: api)
|
||||
viewModel.setControlFile(file(id: 7))
|
||||
await viewModel.saveCurrentFileName("\n", api: api)
|
||||
|
||||
XCTAssertEqual(messages, ["名称不能为空", "名称不能为空"])
|
||||
XCTAssertTrue(api.createFolderCalls.isEmpty)
|
||||
XCTAssertTrue(api.renameFileCalls.isEmpty)
|
||||
}
|
||||
|
||||
func testUploadCompletionRefreshesOnlyCurrentFolder() async {
|
||||
let api = MockCloudDriveAPI()
|
||||
api.listResponses = [
|
||||
CloudFileListResponse(total: 1, list: [file(id: 1)]),
|
||||
CloudFileListResponse(total: 1, list: [file(id: 2)]),
|
||||
]
|
||||
let viewModel = CloudDriveListViewModel()
|
||||
|
||||
await viewModel.refresh(api: api)
|
||||
await viewModel.handleUploadCompleted(parentFolderId: 9, api: api)
|
||||
XCTAssertEqual(api.listCalls.count, 1)
|
||||
|
||||
await viewModel.handleUploadCompleted(parentFolderId: 0, api: api)
|
||||
XCTAssertEqual(api.listCalls.count, 2)
|
||||
XCTAssertEqual(viewModel.files.map(\.id), [2])
|
||||
}
|
||||
|
||||
private func file(id: Int, type: Int = 2) -> CloudFile {
|
||||
CloudFile(id: id, fileUrl: "https://cdn/\(id).jpg", name: "文件\(id)", type: type)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user