Files
e-party-iOS/yanaAPITests/yanaAPITests.swift
edwinQQQ 0fe3b6cb7a feat: 新增用户信息获取功能及相关模型
- 在APIEndpoints.swift中新增getUserInfo端点以支持获取用户信息。
- 在APIModels.swift中实现获取用户信息请求和响应模型,处理用户信息的请求与解析。
- 在UserInfoManager中新增方法以从服务器获取用户信息,并在登录成功后自动获取用户信息。
- 在SettingFeature中新增用户信息刷新状态管理,支持用户信息的刷新操作。
- 在SettingView中集成用户信息刷新按钮,提升用户体验。
- 在SplashFeature中实现自动获取用户信息的逻辑,优化用户登录流程。
- 在yanaAPITests中添加用户信息相关的单元测试,确保功能的正确性。
2025-07-23 11:46:46 +08:00

241 lines
11 KiB
Swift
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//
// 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, // APIuser_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. ticketAccountModel
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)")
}
}
}
// MARK: - User Info API Tests
extension yanaAPITests {
func testGetUserInfoRequest() {
//
let uid = "12345"
let request = UserInfoHelper.createGetUserInfoRequest(uid: uid)
XCTAssertEqual(request.endpoint, "/user/get", "端点应该正确")
XCTAssertEqual(request.method, .GET, "请求方法应该是GET")
XCTAssertEqual(request.queryParameters?["uid"], uid, "UID参数应该正确")
XCTAssertFalse(request.shouldShowLoading, "不应该显示loading")
XCTAssertFalse(request.shouldShowError, "不应该显示错误")
}
func testGetUserInfoResponse() {
//
let responseData: [String: Any] = [
"code": 200,
"message": "success",
"timestamp": 1640995200000,
"data": [
"user_id": "12345",
"username": "testuser",
"nickname": "测试用户",
"avatar": "https://example.com/avatar.jpg",
"email": "test@example.com",
"phone": "13800138000",
"status": "active",
"create_time": "2024-01-01 00:00:00",
"update_time": "2024-01-01 00:00:00"
]
]
do {
let jsonData = try JSONSerialization.data(withJSONObject: responseData)
let response = try JSONDecoder().decode(GetUserInfoResponse.self, from: jsonData)
XCTAssertTrue(response.isSuccess, "响应应该成功")
XCTAssertEqual(response.code, 200, "状态码应该正确")
XCTAssertNotNil(response.data, "用户信息数据应该存在")
if let userInfo = response.data {
XCTAssertEqual(userInfo.userId, "12345", "用户ID应该正确")
XCTAssertEqual(userInfo.username, "testuser", "用户名应该正确")
XCTAssertEqual(userInfo.nickname, "测试用户", "昵称应该正确")
}
debugInfoSync("✅ 用户信息响应解析测试通过")
} catch {
XCTFail("解析用户信息响应失败: \(error)")
}
}
func testUserInfoHelper() {
// UserInfoHelper
let uid = "67890"
UserInfoHelper.debugGetUserInfoRequest(uid: uid)
let request = UserInfoHelper.createGetUserInfoRequest(uid: uid)
XCTAssertEqual(request.queryParameters?["uid"], uid, "Helper创建的请求应该正确")
}
}