
- 在Package.swift中注释掉旧的swift-composable-architecture依赖,并添加swift-case-paths依赖。 - 在Podfile中将iOS平台版本更新至16.0,并移除QCloudCOSXML/Transfer依赖,改为使用QCloudCOSXML。 - 更新Podfile.lock以反映依赖变更,确保项目依赖的准确性。 - 新增架构分析需求文档,明确项目架构评估和改进建议。 - 在多个文件中实现async/await语法,提升异步操作的可读性和性能。 - 更新日志输出方法,确保在调试模式下提供一致的调试信息。 - 优化多个视图组件,提升用户体验和代码可维护性。
176 lines
8.4 KiB
Swift
176 lines
8.4 KiB
Swift
//
|
||
// yanaAPITests.swift
|
||
// yanaAPITests
|
||
//
|
||
// Created by P on 2025/5/27.
|
||
//
|
||
|
||
import XCTest
|
||
@testable import yana
|
||
|
||
final class yanaAPITests: XCTestCase {
|
||
|
||
override func setUpWithError() throws {
|
||
// Put setup code here. This method is called before the invocation of each test method in the class.
|
||
}
|
||
|
||
override func tearDownWithError() throws {
|
||
// Put teardown code here. This method is called after the invocation of each test method in the class.
|
||
}
|
||
|
||
func testExample() throws {
|
||
// This is an example of a functional test case.
|
||
// Use XCTAssert and related functions to verify your tests produce the correct results.
|
||
// Any test you write for XCTest can be annotated as throws and async.
|
||
// Mark your test throws to produce an unexpected failure when your test encounters an uncaught error.
|
||
// Mark your test async to allow awaiting for asynchronous code to complete. Check the results with assertions afterwards.
|
||
}
|
||
|
||
func testPerformanceExample() throws {
|
||
// This is an example of a performance test case.
|
||
measure {
|
||
// Put the code you want to measure the time of here.
|
||
}
|
||
}
|
||
|
||
func testIDLoginRequest_Creation() {
|
||
// 测试ID登录请求的创建
|
||
let userID = "399113"
|
||
let password = "a123456"
|
||
|
||
let request = LoginHelper.createIDLoginRequest(userID: userID, password: password)
|
||
XCTAssertNotNil(request, "登录请求应该创建成功")
|
||
XCTAssertEqual(request?.endpoint, "/oauth/token", "端点应该正确")
|
||
XCTAssertEqual(request?.method, .POST, "请求方法应该是POST")
|
||
}
|
||
|
||
func testIDLoginResponse_Success() {
|
||
// 测试登录响应的成功解析
|
||
let successResponse = IDLoginResponse(
|
||
status: "success",
|
||
message: "登录成功",
|
||
code: 200,
|
||
data: IDLoginData(
|
||
accessToken: "test_token",
|
||
refreshToken: "refresh_token",
|
||
tokenType: "Bearer",
|
||
expiresIn: 3600,
|
||
scope: "read write",
|
||
userInfo: UserInfo(
|
||
userId: "123",
|
||
username: "testuser",
|
||
nickname: "Test User",
|
||
avatar: nil,
|
||
email: "test@example.com",
|
||
phone: "399113",
|
||
status: "active",
|
||
createTime: "2024-01-01",
|
||
updateTime: "2024-01-01"
|
||
)
|
||
)
|
||
)
|
||
|
||
XCTAssertTrue(successResponse.isSuccess, "响应应该标记为成功")
|
||
XCTAssertEqual(successResponse.data?.accessToken, "test_token", "访问令牌应该正确")
|
||
}
|
||
|
||
func testAccountModelFlow() {
|
||
// 测试完整的 AccountModel 流程
|
||
|
||
// 1. 模拟 oauth/token 响应(基于用户提供的真实数据)
|
||
let loginData = IDLoginData(
|
||
accessToken: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.test",
|
||
refreshToken: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.refresh",
|
||
tokenType: "bearer",
|
||
expiresIn: 2591999,
|
||
scope: "read write",
|
||
userInfo: nil, // 真实API没有返回user_info
|
||
uid: 3184,
|
||
netEaseToken: "6fba51065b5e32ad18a935438517a1a9",
|
||
jti: "d3a82ddb-ea6f-4d2f-8dc7-7bdb3d6b9e87"
|
||
)
|
||
|
||
// 2. 从 IDLoginData 创建 AccountModel
|
||
let accountModel = AccountModel.from(loginData: loginData)
|
||
|
||
XCTAssertNotNil(accountModel, "应该能从IDLoginData创建AccountModel")
|
||
XCTAssertEqual(accountModel?.uid, "3184", "UID应该正确转换为字符串")
|
||
XCTAssertEqual(accountModel?.accessToken, "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.test", "Access Token应该正确")
|
||
XCTAssertEqual(accountModel?.tokenType, "bearer", "Token类型应该正确")
|
||
XCTAssertEqual(accountModel?.netEaseToken, "6fba51065b5e32ad18a935438517a1a9", "网易云Token应该正确")
|
||
XCTAssertNil(accountModel?.ticket, "初始ticket应该为空")
|
||
|
||
// 3. 检查认证状态
|
||
XCTAssertTrue(accountModel?.hasValidAuthentication ?? false, "应该有有效的认证")
|
||
XCTAssertFalse(accountModel?.hasValidSession ?? true, "没有ticket时不应该有有效会话")
|
||
|
||
// 4. 模拟获取ticket后更新AccountModel
|
||
let ticketString = "eyJhbGciOiJIUzI1NiJ9.ticket"
|
||
let updatedAccountModel = accountModel?.withTicket(ticketString)
|
||
|
||
XCTAssertNotNil(updatedAccountModel, "应该能更新ticket")
|
||
XCTAssertEqual(updatedAccountModel?.ticket, ticketString, "Ticket应该正确设置")
|
||
XCTAssertTrue(updatedAccountModel?.hasValidSession ?? false, "有ticket时应该有有效会话")
|
||
|
||
// 5. 测试持久化和加载
|
||
if let finalAccountModel = updatedAccountModel {
|
||
UserInfoManager.saveAccountModel(finalAccountModel)
|
||
|
||
let loadedAccountModel = UserInfoManager.getAccountModel()
|
||
XCTAssertNotNil(loadedAccountModel, "应该能加载保存的AccountModel")
|
||
XCTAssertEqual(loadedAccountModel?.uid, "3184", "加载的UID应该正确")
|
||
XCTAssertEqual(loadedAccountModel?.accessToken, finalAccountModel.accessToken, "加载的Access Token应该正确")
|
||
XCTAssertEqual(loadedAccountModel?.ticket, ticketString, "加载的Ticket应该正确")
|
||
|
||
// 6. 测试向后兼容性
|
||
let userId = UserInfoManager.getCurrentUserId()
|
||
let accessToken = UserInfoManager.getAccessToken()
|
||
let ticket = UserInfoManager.getCurrentUserTicket()
|
||
|
||
XCTAssertEqual(userId, "3184", "向后兼容的用户ID应该正确")
|
||
XCTAssertEqual(accessToken, finalAccountModel.accessToken, "向后兼容的Access Token应该正确")
|
||
XCTAssertEqual(ticket, ticketString, "向后兼容的Ticket应该正确")
|
||
}
|
||
|
||
// 7. 清理
|
||
UserInfoManager.clearAllAuthenticationData()
|
||
XCTAssertNil(UserInfoManager.getAccountModel(), "清理后AccountModel应该为空")
|
||
XCTAssertNil(UserInfoManager.getCurrentUserId(), "清理后用户ID应该为空")
|
||
}
|
||
|
||
func testAccountModelWithRealAPIData() {
|
||
// 使用用户提供的真实API返回数据进行测试
|
||
let realAPIResponseData: [String: Any] = [
|
||
"uid": 3184,
|
||
"jti": "d3a82ddb-ea6f-4d2f-8dc7-7bdb3d6b9e87",
|
||
"token_type": "bearer",
|
||
"scope": "read write",
|
||
"refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX25hbWUiOiIyMzU2ODE0Iiwic2NvcGUiOlsicmVhZCIsIndyaXRlIl0sImF0aSI6ImQzYTgyZGRiLWVhNmYtNGQyZi04ZGM3LTdiZGIzZDZiOWU4NyIsImV4cCI6MTc1NTI0MjY5MiwiYXV0aG9yaXRpZXMiOlsiUk9MRV9hY2NvdW50IiwiUk9MRV9NT0JJTEUiLCJST0xFX1VOSVRZIl0sImp0aSI6ImFiZjhjN2ZjLTllOWEtNDE2Yy04NTk2LTBkMWYxZWQyODU2MiIsImNsaWVudF9pZCI6ImVyYmFuLWNsaWVudCJ9.6i_9FnZvviuWYIoXDv9of7EDRyjRVxNbkiHayNUFxNw",
|
||
"netEaseToken": "6fba51065b5e32ad18a935438517a1a9",
|
||
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3NTQ2Mzc4OTIsInVzZXJfbmFtZSI6IjIzNTY4MTQiLCJhdXRob3JpdGllcyI6WyJST0xFX2FjY291bnQiLCJST0xFX01PQklMRSIsIlJPTEVfVU5JVFkiXSwianRpIjoiZDNhODJkZGItZWE2Zi00ZDJmLThkYzctN2JkYjNkNmI5ZTg3IiwiY2xpZW50X2lkIjoiZXJiYW4tY2xpZW50Iiwic2NvcGUiOlsicmVhZCIsIndyaXRlIl19.ynUptBtAoPVXz4J1AO8LbaAhmFRF4UnF4C-Ggj6Izpc",
|
||
"expires_in": 2591999
|
||
]
|
||
|
||
// 模拟JSON解析
|
||
do {
|
||
let jsonData = try JSONSerialization.data(withJSONObject: realAPIResponseData)
|
||
let loginData = try JSONDecoder().decode(IDLoginData.self, from: jsonData)
|
||
|
||
// 创建AccountModel
|
||
let accountModel = AccountModel.from(loginData: loginData)
|
||
|
||
XCTAssertNotNil(accountModel, "应该能从真实API数据创建AccountModel")
|
||
XCTAssertEqual(accountModel?.uid, "3184", "真实API数据的UID应该正确")
|
||
XCTAssertTrue(accountModel?.hasValidAuthentication ?? false, "真实API数据应该有有效认证")
|
||
|
||
debugInfoSync("✅ 真实API数据测试通过")
|
||
debugInfoSync(" UID: \(accountModel?.uid ?? "nil")")
|
||
debugInfoSync(" Access Token存在: \(accountModel?.accessToken != nil)")
|
||
debugInfoSync(" Token类型: \(accountModel?.tokenType ?? "nil")")
|
||
|
||
} catch {
|
||
XCTFail("解析真实API数据失败: \(error)")
|
||
}
|
||
}
|
||
}
|