添加提交任务流程并抽取资料编辑页
This commit is contained in:
96
suixinkanTests/ProfileEditViewModelTests.swift
Normal file
96
suixinkanTests/ProfileEditViewModelTests.swift
Normal file
@ -0,0 +1,96 @@
|
||||
//
|
||||
// ProfileEditViewModelTests.swift
|
||||
// suixinkanTests
|
||||
//
|
||||
|
||||
import XCTest
|
||||
@testable import suixinkan
|
||||
|
||||
@MainActor
|
||||
/// 资料编辑页 ViewModel 测试。
|
||||
final class ProfileEditViewModelTests: XCTestCase {
|
||||
|
||||
func testInitPrefillsNicknameWhenSet() {
|
||||
let viewModel = ProfileEditViewModel(nickname: "测试昵称", avatarURL: "https://example.com/a.jpg")
|
||||
XCTAssertEqual(viewModel.editingNickname, "测试昵称")
|
||||
}
|
||||
|
||||
func testInitClearsPlaceholderNickname() {
|
||||
let viewModel = ProfileEditViewModel(nickname: "未设置昵称", avatarURL: "")
|
||||
XCTAssertEqual(viewModel.editingNickname, "")
|
||||
}
|
||||
|
||||
func testSaveProfileRejectsEmptyNickname() async {
|
||||
let viewModel = ProfileEditViewModel(nickname: "未设置昵称", avatarURL: "")
|
||||
let session = MockURLSession(responses: [])
|
||||
let api = ProfileAPI(client: APIClient(environment: .testing, session: session))
|
||||
|
||||
do {
|
||||
try await viewModel.saveProfile(
|
||||
api: api,
|
||||
uploader: MockOSSUploadService(),
|
||||
scenicId: 1
|
||||
)
|
||||
XCTFail("空昵称应抛出校验错误")
|
||||
} catch {
|
||||
guard let validationError = error as? ProfileValidationError else {
|
||||
return XCTFail("期望 ProfileValidationError,实际为 \(error)")
|
||||
}
|
||||
XCTAssertEqual(validationError, .emptyNickname)
|
||||
}
|
||||
}
|
||||
|
||||
func testSaveProfilePostsNotificationAndUpdatesAppStore() async throws {
|
||||
let viewModel = ProfileEditViewModel(nickname: "旧昵称", avatarURL: "")
|
||||
viewModel.updateEditingNickname("新昵称")
|
||||
|
||||
let expectation = expectation(forNotification: NotificationName.userProfileDidUpdate, object: nil)
|
||||
|
||||
let responseData = try TestJSON.envelope(data: EmptyPayload())
|
||||
let session = MockURLSession(responses: [responseData])
|
||||
let api = ProfileAPI(client: APIClient(environment: .testing, session: session))
|
||||
|
||||
try await viewModel.saveProfile(
|
||||
api: api,
|
||||
uploader: MockOSSUploadService(),
|
||||
scenicId: 1
|
||||
)
|
||||
|
||||
await fulfillment(of: [expectation], timeout: 1)
|
||||
XCTAssertEqual(AppStore.shared.userName, "新昵称")
|
||||
}
|
||||
}
|
||||
|
||||
/// 测试用 OSS 上传替身,直接返回固定 URL。
|
||||
@MainActor
|
||||
private struct MockOSSUploadService: OSSUploadServing {
|
||||
func uploadUserAvatar(
|
||||
data: Data,
|
||||
fileName: String,
|
||||
scenicId: Int,
|
||||
onProgress: @escaping (Int) -> Void
|
||||
) async throws -> String {
|
||||
onProgress(100)
|
||||
return "https://cdn.example.com/avatar.jpg"
|
||||
}
|
||||
|
||||
func uploadRealNameImage(
|
||||
data: Data,
|
||||
fileName: String,
|
||||
scenicId: Int,
|
||||
onProgress: @escaping (Int) -> Void
|
||||
) async throws -> String {
|
||||
onProgress(100)
|
||||
return "https://cdn.example.com/realname.jpg"
|
||||
}
|
||||
|
||||
func uploadBankCardImage(
|
||||
data: Data,
|
||||
fileName: String,
|
||||
scenicId: Int,
|
||||
onProgress: @escaping (Int) -> Void
|
||||
) async throws -> String {
|
||||
onProgress(100)
|
||||
return "https://cdn.example.com/bank.jpg"
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user