Implement profile tab with Android-aligned flows and OSS upload.

Add personal info page, account switch, real-name auth, withdrawal settings, session cache extensions, AlibabaCloudOSS SPM, and unit tests.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-07-06 16:01:05 +08:00
parent 02a80764ea
commit 005cac3f78
36 changed files with 4077 additions and 57 deletions

View File

@ -0,0 +1,52 @@
//
// ProfileViewModelTests.swift
// suixinkanTests
//
import XCTest
@testable import suixinkan
@MainActor
/// ViewModel
final class ProfileViewModelTests: XCTestCase {
func testDisplayNicknameUsesFallbackWhenEmpty() {
let viewModel = ProfileViewModel()
XCTAssertEqual(viewModel.displayNickname, "未设置昵称")
}
func testShowPhotographerFieldsWhenRoleCodeIsPhotographer() {
AppStore.shared.roleCode = AppRoleCode.photographer.rawValue
let viewModel = ProfileViewModel()
XCTAssertTrue(viewModel.showPhotographerFields)
AppStore.shared.roleCode = ""
}
func testMaskCardNumberShowsLastFourDigits() {
XCTAssertEqual(
ProfileViewModel.maskCardNumber("6222021234567890"),
"**** **** **** 7890"
)
}
func testUpdatePasswordRejectsShortPassword() async {
let session = MockURLSession(responses: [])
let api = ProfileAPI(client: APIClient(environment: .testing, session: session))
let viewModel = ProfileViewModel()
do {
try await viewModel.updatePassword("12345", api: api)
XCTFail("短密码应抛出校验错误")
} catch {
guard let validationError = error as? ProfileValidationError else {
return XCTFail("期望 ProfileValidationError实际为 \(error)")
}
XCTAssertEqual(validationError, .shortPassword)
}
}
func testBeginEditingPrefillsNickname() {
let viewModel = ProfileViewModel()
viewModel.beginEditing()
XCTAssertTrue(viewModel.isEditingProfile)
}
}