mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-10-31 16:24:11 +00:00
e5bfc3a26d
Expose OpenID tokens and homeserver credentials from the client proxy, and add fork-only services for the HealthChat member directory backend (api.healthchat.ch) plus a service that reads MSC4133 extended profile fields directly from the homeserver. Groundwork for the members tab and the profile screens. Claude-Session: https://claude.ai/code/session_013qdTbAWsZj2quQzEkagXaS
87 lines
3.6 KiB
Swift
87 lines
3.6 KiB
Swift
//
|
|
// Copyright 2026 Element Creations Ltd.
|
|
//
|
|
// SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
|
|
// Please see LICENSE files in the repository root for full details.
|
|
//
|
|
|
|
@testable import ElementX
|
|
import Foundation
|
|
import Testing
|
|
|
|
final class HealthChatOpenIDTokenProviderTests {
|
|
private let clientProxy = ClientProxyMock(.init())
|
|
|
|
@Test
|
|
func fetchesTokenOnFirstCall() async {
|
|
clientProxy.requestOpenIDTokenReturnValue = .success(.init(accessToken: "tokenA",
|
|
matrixServerName: "healthchat.ch",
|
|
expiresIn: 3600))
|
|
let provider = HealthChatOpenIDTokenProvider(clientProxy: clientProxy)
|
|
|
|
let result = await provider.validToken()
|
|
|
|
#expect(result == .success("tokenA"))
|
|
#expect(clientProxy.requestOpenIDTokenCallsCount == 1)
|
|
}
|
|
|
|
@Test
|
|
func cachesTokenUntilExpiry() async {
|
|
clientProxy.requestOpenIDTokenReturnValue = .success(.init(accessToken: "tokenA",
|
|
matrixServerName: "healthchat.ch",
|
|
expiresIn: 3600))
|
|
let provider = HealthChatOpenIDTokenProvider(clientProxy: clientProxy)
|
|
|
|
_ = await provider.validToken()
|
|
let result = await provider.validToken()
|
|
|
|
#expect(result == .success("tokenA"))
|
|
#expect(clientProxy.requestOpenIDTokenCallsCount == 1)
|
|
}
|
|
|
|
@Test
|
|
func refreshesTokenWithinExpiryBuffer() async {
|
|
clientProxy.requestOpenIDTokenReturnValue = .success(.init(accessToken: "tokenA",
|
|
matrixServerName: "healthchat.ch",
|
|
expiresIn: 120))
|
|
var now = Date(timeIntervalSince1970: 1_000_000)
|
|
let provider = HealthChatOpenIDTokenProvider(clientProxy: clientProxy) { now }
|
|
|
|
_ = await provider.validToken()
|
|
|
|
// 59s of validity left is inside the 60s buffer and must trigger a refresh.
|
|
now = now.addingTimeInterval(61)
|
|
clientProxy.requestOpenIDTokenReturnValue = .success(.init(accessToken: "tokenB",
|
|
matrixServerName: "healthchat.ch",
|
|
expiresIn: 120))
|
|
let result = await provider.validToken()
|
|
|
|
#expect(result == .success("tokenB"))
|
|
#expect(clientProxy.requestOpenIDTokenCallsCount == 2)
|
|
}
|
|
|
|
@Test
|
|
func invalidateForcesRefetch() async {
|
|
clientProxy.requestOpenIDTokenReturnValue = .success(.init(accessToken: "tokenA",
|
|
matrixServerName: "healthchat.ch",
|
|
expiresIn: 3600))
|
|
let provider = HealthChatOpenIDTokenProvider(clientProxy: clientProxy)
|
|
|
|
_ = await provider.validToken()
|
|
provider.invalidateToken()
|
|
_ = await provider.validToken()
|
|
|
|
#expect(clientProxy.requestOpenIDTokenCallsCount == 2)
|
|
}
|
|
|
|
@Test
|
|
func failedRequestReturnsTokenAcquisitionFailure() async {
|
|
clientProxy.requestOpenIDTokenReturnValue = .failure(.sdkError(ClientProxyMockError.generic))
|
|
let provider = HealthChatOpenIDTokenProvider(clientProxy: clientProxy)
|
|
|
|
let result = await provider.validToken()
|
|
|
|
#expect(result == .failure(.tokenAcquisitionFailed))
|
|
}
|
|
}
|