Rename OIDC to OAuth. (#5525)

* Rename OIDC to OAuth.

* Update the enterprise submodule.
This commit is contained in:
Doug
2026-05-05 14:07:06 +01:00
committed by GitHub
parent 50f4022b7c
commit fe6c62b60f
57 changed files with 402 additions and 400 deletions

View File

@@ -21,22 +21,22 @@ struct AppRouteURLParserTests {
}
@Test
func oidcCallbackRoute() {
// Given an OIDC callback for this app.
let callbackURL = appSettings.oidcRedirectURL.appending(queryItems: [URLQueryItem(name: "state", value: "12345"),
URLQueryItem(name: "code", value: "67890")])
func oAuthCallbackRoute() {
// Given an OAuth callback for this app.
let callbackURL = appSettings.oAuthRedirectURL.appending(queryItems: [URLQueryItem(name: "state", value: "12345"),
URLQueryItem(name: "code", value: "67890")])
// When parsing that route.
let route = appRouteURLParser.route(from: callbackURL)
// Then it should be considered a valid OIDC callback.
#expect(route == .oidcCallback(url: callbackURL))
// Then it should be considered a valid OAuth callback.
#expect(route == .oAuthCallback(url: callbackURL))
}
@Test
func oidcCallbackAppVariantRoute() {
// Given an OIDC callback for a different app variant.
let callbackURL = appSettings.oidcRedirectURL
func oAuthCallbackAppVariantRoute() {
// Given an OAuth callback for a different app variant.
let callbackURL = appSettings.oAuthRedirectURL
.deletingLastPathComponent()
.appending(component: "io.element.elementz")
.appending(queryItems: [URLQueryItem(name: "state", value: "12345"),

View File

@@ -45,7 +45,7 @@ struct AuthenticationServiceTests {
}
@Test
mutating func configureLoginWithOIDC() async throws {
mutating func configureLoginWithOAuth() async throws {
try await setup()
try await service.configure(for: "matrix.org", flow: .login).get()
@@ -55,7 +55,7 @@ struct AuthenticationServiceTests {
}
@Test
mutating func configureRegisterWithOIDC() async throws {
mutating func configureRegisterWithOAuth() async throws {
try await setup()
try await service.configure(for: "matrix.org", flow: .register).get()

View File

@@ -64,15 +64,15 @@ final class AuthenticationStartScreenViewModelTests {
}
@Test
func provisionedOIDCState() async throws {
// Given a view model that has been provisioned with a server that supports OIDC.
func provisionedOAuthState() async throws {
// Given a view model that has been provisioned with a server that supports OAuth.
await setupViewModel(provisioningParameters: .init(accountProvider: "company.com", loginHint: "user@company.com"))
#expect(authenticationService.homeserver.value.loginMode == .unknown)
#expect(client.urlForOauthOauthConfigurationPromptLoginHintDeviceIdAdditionalScopesCallsCount == 0)
// When tapping the login button the authentication service should be used and the screen
// should request to continue the flow without any server selection needed.
let deferred = deferFulfillment(viewModel.actions) { $0.isLoginDirectlyWithOIDC }
let deferred = deferFulfillment(viewModel.actions) { $0.isLoginDirectlyWithOAuth }
context.send(viewAction: .login)
try await deferred.fulfill()
@@ -80,13 +80,13 @@ final class AuthenticationStartScreenViewModelTests {
#expect(client.urlForOauthOauthConfigurationPromptLoginHintDeviceIdAdditionalScopesCallsCount == 1)
#expect(client.urlForOauthOauthConfigurationPromptLoginHintDeviceIdAdditionalScopesReceivedArguments?.prompt == .consent)
#expect(client.urlForOauthOauthConfigurationPromptLoginHintDeviceIdAdditionalScopesReceivedArguments?.loginHint == "user@company.com")
#expect(authenticationService.homeserver.value.loginMode == .oidc(supportsCreatePrompt: false))
#expect(authenticationService.homeserver.value.loginMode == .oAuth(supportsCreatePrompt: false))
}
@Test
func provisionedPasswordState() async throws {
// Given a view model that has been provisioned with a server that does not support OIDC.
await setupViewModel(provisioningParameters: .init(accountProvider: "company.com", loginHint: "user@company.com"), supportsOIDC: false)
// Given a view model that has been provisioned with a server that does not support OAuth.
await setupViewModel(provisioningParameters: .init(accountProvider: "company.com", loginHint: "user@company.com"), supportsOAuth: false)
#expect(authenticationService.homeserver.value.loginMode == .unknown)
#expect(client.urlForOauthOauthConfigurationPromptLoginHintDeviceIdAdditionalScopesCallsCount == 0)
@@ -102,8 +102,8 @@ final class AuthenticationStartScreenViewModelTests {
}
@Test
func singleProviderOIDCState() async throws {
// Given a view model that for an app that only allows the use of a single provider that supports OIDC.
func singleProviderOAuthState() async throws {
// Given a view model that for an app that only allows the use of a single provider that supports OAuth.
setAllowedAccountProviders(["company.com"])
await setupViewModel()
#expect(authenticationService.homeserver.value.loginMode == .unknown)
@@ -111,7 +111,7 @@ final class AuthenticationStartScreenViewModelTests {
// When tapping the login button the authentication service should be used and the screen
// should request to continue the flow without any server selection needed.
let deferred = deferFulfillment(viewModel.actions) { $0.isLoginDirectlyWithOIDC }
let deferred = deferFulfillment(viewModel.actions) { $0.isLoginDirectlyWithOAuth }
context.send(viewAction: .login)
try await deferred.fulfill()
@@ -119,14 +119,14 @@ final class AuthenticationStartScreenViewModelTests {
#expect(client.urlForOauthOauthConfigurationPromptLoginHintDeviceIdAdditionalScopesCallsCount == 1)
#expect(client.urlForOauthOauthConfigurationPromptLoginHintDeviceIdAdditionalScopesReceivedArguments?.prompt == .consent)
#expect(client.urlForOauthOauthConfigurationPromptLoginHintDeviceIdAdditionalScopesReceivedArguments?.loginHint == nil)
#expect(authenticationService.homeserver.value.loginMode == .oidc(supportsCreatePrompt: false))
#expect(authenticationService.homeserver.value.loginMode == .oAuth(supportsCreatePrompt: false))
}
@Test
func singleProviderPasswordState() async throws {
// Given a view model that for an app that only allows the use of a single provider that does not support OIDC.
// Given a view model that for an app that only allows the use of a single provider that does not support OAuth.
setAllowedAccountProviders(["company.com"])
await setupViewModel(supportsOIDC: false)
await setupViewModel(supportsOAuth: false)
#expect(authenticationService.homeserver.value.loginMode == .unknown)
#expect(client.urlForOauthOauthConfigurationPromptLoginHintDeviceIdAdditionalScopesCallsCount == 0)
@@ -156,13 +156,13 @@ final class AuthenticationStartScreenViewModelTests {
// When continuing with the Classic app account the authentication service should be used and the screen
// should request to continue the flow without any server selection needed.
let deferred = deferFulfillment(viewModel.actions) { $0.isLoginDirectlyWithOIDC }
let deferred = deferFulfillment(viewModel.actions) { $0.isLoginDirectlyWithOAuth }
context.send(viewAction: .continueWithClassic(classicAppAccount))
try await deferred.fulfill()
#expect(clientFactory.makeClientHomeserverAddressSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksCallsCount == 1)
#expect(clientFactory.makeClientHomeserverAddressSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksReceivedArguments?.homeserverAddress == "company.com")
#expect(authenticationService.homeserver.value.loginMode == .oidc(supportsCreatePrompt: false))
#expect(authenticationService.homeserver.value.loginMode == .oAuth(supportsCreatePrompt: false))
#expect(client.urlForOauthOauthConfigurationPromptLoginHintDeviceIdAdditionalScopesReceivedArguments?.loginHint == "mxid:\(classicAppAccount.userID)")
}
@@ -180,21 +180,21 @@ final class AuthenticationStartScreenViewModelTests {
// When continuing with the Classic app account the authentication service should be used with the direct homeserver URL
// and the screen should request to continue the flow without any server selection needed.
let deferred = deferFulfillment(viewModel.actions) { $0.isLoginDirectlyWithOIDC }
let deferred = deferFulfillment(viewModel.actions) { $0.isLoginDirectlyWithOAuth }
context.send(viewAction: .continueWithClassic(classicAppAccount))
try await deferred.fulfill()
#expect(clientFactory.makeClientHomeserverAddressSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksCallsCount == 2)
#expect(clientFactory.makeClientHomeserverAddressSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksReceivedArguments?.homeserverAddress == "https://matrix.company.com")
#expect(authenticationService.homeserver.value.loginMode == .oidc(supportsCreatePrompt: false))
#expect(authenticationService.homeserver.value.loginMode == .oAuth(supportsCreatePrompt: false))
#expect(client.urlForOauthOauthConfigurationPromptLoginHintDeviceIdAdditionalScopesReceivedArguments?.loginHint == "mxid:\(classicAppAccount.userID)")
}
@Test
func classicAppAccountOnUnsupportedServer() async {
// Given a view model with a Classic app account whose server supports neither OIDC nor password login.
// Given a view model with a Classic app account whose server supports neither OAuth nor password login.
let classicAppAccount = makeClassicAppAccount()
await setupViewModel(classicAppAccount: classicAppAccount, supportsOIDC: false, supportsPasswordLogin: false)
await setupViewModel(classicAppAccount: classicAppAccount, supportsOAuth: false, supportsPasswordLogin: false)
guard case .welcomeBack(let account) = context.viewState.classicAppMode else {
Issue.record("Expected classicAppMode to be .welcomeBack")
return
@@ -271,7 +271,7 @@ final class AuthenticationStartScreenViewModelTests {
try await deferred.fulfill()
// When the user continues with the Classic account again.
let deferredAction = deferFulfillment(viewModel.actions) { $0.isLoginDirectlyWithOIDC }
let deferredAction = deferFulfillment(viewModel.actions) { $0.isLoginDirectlyWithOAuth }
context.send(viewAction: .continueWithClassic(classicAppAccount))
// Then the flow should continue the login process.
@@ -282,12 +282,12 @@ final class AuthenticationStartScreenViewModelTests {
private func setupViewModel(classicAppAccount: ClassicAppAccount? = nil,
provisioningParameters: AccountProvisioningParameters? = nil,
supportsOIDC: Bool = true,
supportsOAuth: Bool = true,
supportsPasswordLogin: Bool = true,
availableSecrets: ClassicAppAccount.AvailableSecrets = .complete) async {
// Manually create a configuration as the default homeserver address setting is immutable.
client = ClientSDKMock(configuration: .init(oidcLoginURL: supportsOIDC ? "https://account.company.com/authorize" : nil,
supportsOIDCCreatePrompt: false,
client = ClientSDKMock(configuration: .init(oAuthLoginURL: supportsOAuth ? "https://account.company.com/authorize" : nil,
supportsOAuthCreatePrompt: false,
supportsPasswordLogin: supportsPasswordLogin))
// Map both the server name and the homeserver URL so fallback lookups work.
let homeserverClients: [String: ClientSDKMock] = ["company.com": client,
@@ -321,7 +321,7 @@ final class AuthenticationStartScreenViewModelTests {
notificationCenter: notificationCenter,
userIndicatorController: UserIndicatorControllerMock())
// Add a fake window in order for the OIDC flow to continue
// Add a fake window in order for the OAuth flow to continue
viewModel.context.send(viewAction: .updateWindow(UIWindow()))
}
@@ -342,7 +342,7 @@ final class AuthenticationStartScreenViewModelTests {
allowOtherAccountProviders: false,
hideBrandChrome: false,
pushGatewayBaseURL: appSettings.pushGatewayBaseURL,
oidcRedirectURL: appSettings.oidcRedirectURL,
oAuthRedirectURL: appSettings.oAuthRedirectURL,
websiteURL: appSettings.websiteURL,
logoURL: appSettings.logoURL,
copyrightURL: appSettings.copyrightURL,
@@ -362,9 +362,9 @@ final class AuthenticationStartScreenViewModelTests {
}
extension AuthenticationStartScreenViewModelAction {
var isLoginDirectlyWithOIDC: Bool {
var isLoginDirectlyWithOAuth: Bool {
switch self {
case .loginDirectlyWithOIDC: true
case .loginDirectlyWithOAuth: true
default: false
}
}

View File

@@ -155,21 +155,21 @@ struct LoginScreenViewModelTests {
}
@Test
mutating func oidcServer() async throws {
mutating func oAuthServer() async throws {
// Given the screen configured for matrix.org
await setupViewModel()
// When entering a username for a user on a homeserver with OIDC.
// When entering a username for a user on a homeserver with OAuth.
let deferred = deferFulfillment(viewModel.actions) {
$0.isConfiguredForOIDC
$0.isConfiguredForOAuth
}
context.username = "@bob:company.com"
context.send(viewAction: .parseUsername)
try await deferred.fulfill()
// Then the view state should be updated with the homeserver and show the OIDC button.
#expect(context.viewState.loginMode.supportsOIDCFlow,
"The OIDC button should be shown.")
// Then the view state should be updated with the homeserver and show the OAuth button.
#expect(context.viewState.loginMode.supportsOAuthFlow,
"The OAuth button should be shown.")
}
@Test

View File

@@ -147,7 +147,7 @@ struct QRCodeLoginScreenViewModelTests {
try await deferred.fulfill()
var deferredAction = deferFulfillment(viewModel.actionsPublisher) { action in
guard case .requestOIDCAuthorisation = action else { return false }
guard case .requestOAuthAuthorisation = action else { return false }
return true
}
linkDesktopProgressSubject.send(.waitingForAuthorisation(verificationURL: .homeDirectory))
@@ -183,7 +183,7 @@ struct QRCodeLoginScreenViewModelTests {
try await deferredState.fulfill()
var deferredAction = deferFulfillment(viewModel.actionsPublisher) { action in
guard case .requestOIDCAuthorisation = action else { return false }
guard case .requestOAuthAuthorisation = action else { return false }
return true
}
linkMobileProgressSubject.send(.waitingForAuthorisation(verificationURL: .homeDirectory))

View File

@@ -21,7 +21,7 @@ struct ServerConfirmationScreenViewStateTests {
authenticationFlow: .login)
#expect(elementDotIoLogin.message == L10n.screenServerConfirmationMessageLoginElementDotIo, "element.io should have a custom message.")
let otherLogin = ServerConfirmationScreenViewState(mode: .confirmation(LoginHomeserver.mockOIDC.address),
let otherLogin = ServerConfirmationScreenViewState(mode: .confirmation(LoginHomeserver.mockOAuth.address),
authenticationFlow: .login)
#expect(otherLogin.message == "", "Other servers should not show a message.")
@@ -36,8 +36,8 @@ struct ServerConfirmationScreenViewStateTests {
authenticationFlow: .register)
#expect(matrixDotOrgRegister.message == L10n.screenServerConfirmationMessageRegister, "The registration message should always be the same.")
let oidcRegister = ServerConfirmationScreenViewState(mode: .confirmation(LoginHomeserver.mockOIDC.address),
authenticationFlow: .register)
#expect(oidcRegister.message == L10n.screenServerConfirmationMessageRegister, "The registration message should always be the same.")
let oAuthRegister = ServerConfirmationScreenViewState(mode: .confirmation(LoginHomeserver.mockOAuth.address),
authenticationFlow: .register)
#expect(oAuthRegister.message == L10n.screenServerConfirmationMessageRegister, "The registration message should always be the same.")
}
}

View File

@@ -46,7 +46,7 @@ final class ServerConfirmationScreenViewModelTests {
#expect(client.urlForOauthOauthConfigurationPromptLoginHintDeviceIdAdditionalScopesCallsCount == 0)
// When continuing from the confirmation screen.
let deferred = deferFulfillment(viewModel.actions) { $0.isContinueWithOIDC }
let deferred = deferFulfillment(viewModel.actions) { $0.isContinueWithOAuth }
context.send(viewAction: .confirm)
try await deferred.fulfill()
@@ -54,7 +54,7 @@ final class ServerConfirmationScreenViewModelTests {
#expect(clientFactory.makeClientHomeserverAddressSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksCallsCount == 1)
#expect(client.urlForOauthOauthConfigurationPromptLoginHintDeviceIdAdditionalScopesCallsCount == 1)
#expect(client.urlForOauthOauthConfigurationPromptLoginHintDeviceIdAdditionalScopesReceivedArguments?.prompt == .consent)
#expect(service.homeserver.value.loginMode == .oidc(supportsCreatePrompt: true))
#expect(service.homeserver.value.loginMode == .oAuth(supportsCreatePrompt: true))
}
@Test
@@ -65,13 +65,13 @@ final class ServerConfirmationScreenViewModelTests {
Issue.record("The configuration should succeed.")
return
}
#expect(service.homeserver.value.loginMode == .oidc(supportsCreatePrompt: true))
#expect(service.homeserver.value.loginMode == .oAuth(supportsCreatePrompt: true))
#expect(context.viewState.mode == .confirmation(service.homeserver.value.address))
#expect(clientFactory.makeClientHomeserverAddressSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksCallsCount == 1)
#expect(client.urlForOauthOauthConfigurationPromptLoginHintDeviceIdAdditionalScopesCallsCount == 0)
// When continuing from the confirmation screen.
let deferred = deferFulfillment(viewModel.actions) { $0.isContinueWithOIDC }
let deferred = deferFulfillment(viewModel.actions) { $0.isContinueWithOAuth }
context.send(viewAction: .confirm)
try await deferred.fulfill()
@@ -91,7 +91,7 @@ final class ServerConfirmationScreenViewModelTests {
#expect(client.urlForOauthOauthConfigurationPromptLoginHintDeviceIdAdditionalScopesCallsCount == 0)
// When continuing from the confirmation screen.
let deferred = deferFulfillment(viewModel.actions) { $0.isContinueWithOIDC }
let deferred = deferFulfillment(viewModel.actions) { $0.isContinueWithOAuth }
context.send(viewAction: .confirm)
try await deferred.fulfill()
@@ -100,7 +100,7 @@ final class ServerConfirmationScreenViewModelTests {
#expect(client.urlForOauthOauthConfigurationPromptLoginHintDeviceIdAdditionalScopesCallsCount == 1)
// The create prompt is broken: https://github.com/element-hq/matrix-authentication-service/issues/3429
// #expect(client.urlForOauthOauthConfigurationPromptReceivedArguments?.prompt == .create)
#expect(service.homeserver.value.loginMode == .oidc(supportsCreatePrompt: true))
#expect(service.homeserver.value.loginMode == .oAuth(supportsCreatePrompt: true))
}
@Test
@@ -111,13 +111,13 @@ final class ServerConfirmationScreenViewModelTests {
Issue.record("The configuration should succeed.")
return
}
#expect(service.homeserver.value.loginMode == .oidc(supportsCreatePrompt: true))
#expect(service.homeserver.value.loginMode == .oAuth(supportsCreatePrompt: true))
#expect(context.viewState.mode == .confirmation(service.homeserver.value.address))
#expect(clientFactory.makeClientHomeserverAddressSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksCallsCount == 1)
#expect(client.urlForOauthOauthConfigurationPromptLoginHintDeviceIdAdditionalScopesCallsCount == 0)
// When continuing from the confirmation screen.
let deferred = deferFulfillment(viewModel.actions) { $0.isContinueWithOIDC }
let deferred = deferFulfillment(viewModel.actions) { $0.isContinueWithOAuth }
context.send(viewAction: .confirm)
try await deferred.fulfill()
@@ -130,8 +130,8 @@ final class ServerConfirmationScreenViewModelTests {
@Test
func confirmPasswordLoginWithoutConfiguration() async throws {
// Given a view model for login using a service that hasn't been configured (against a server that doesn't support OIDC).
setupViewModel(authenticationFlow: .login, supportsOIDC: false)
// Given a view model for login using a service that hasn't been configured (against a server that doesn't support OAuth).
setupViewModel(authenticationFlow: .login, supportsOAuth: false)
#expect(service.homeserver.value.loginMode == .unknown)
#expect(context.viewState.mode == .confirmation(service.homeserver.value.address))
#expect(clientFactory.makeClientHomeserverAddressSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksCallsCount == 0)
@@ -142,7 +142,7 @@ final class ServerConfirmationScreenViewModelTests {
context.send(viewAction: .confirm)
try await deferred.fulfill()
// Then a call to configure service should be made, but not for the OIDC URL.
// Then a call to configure service should be made, but not for the OAuth URL.
#expect(clientFactory.makeClientHomeserverAddressSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksCallsCount == 1)
#expect(client.urlForOauthOauthConfigurationPromptLoginHintDeviceIdAdditionalScopesCallsCount == 0)
#expect(service.homeserver.value.loginMode == .password)
@@ -151,7 +151,7 @@ final class ServerConfirmationScreenViewModelTests {
@Test
func confirmPasswordLoginAfterConfiguration() async throws {
// Given a view model for login using a service that has already been configured (via the server selection screen).
setupViewModel(authenticationFlow: .login, supportsOIDC: false)
setupViewModel(authenticationFlow: .login, supportsOAuth: false)
guard case .success = await service.configure(for: viewModel.state.homeserverAddress, flow: .login) else {
Issue.record("The configuration should succeed.")
return
@@ -166,7 +166,7 @@ final class ServerConfirmationScreenViewModelTests {
context.send(viewAction: .confirm)
try await deferred.fulfill()
// Then the configured homeserver should be used and no additional client should be built, nor a call to get the OIDC URL.
// Then the configured homeserver should be used and no additional client should be built, nor a call to get the OAuth URL.
#expect(clientFactory.makeClientHomeserverAddressSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksCallsCount == 1)
#expect(client.urlForOauthOauthConfigurationPromptLoginHintDeviceIdAdditionalScopesCallsCount == 0)
}
@@ -175,7 +175,7 @@ final class ServerConfirmationScreenViewModelTests {
func registrationNotSupportedAlert() async throws {
// Given a view model for registration using a service that hasn't been configured and the default server doesn't support registration.
// Note: We don't currently take the create prompt into account when determining registration support.
setupViewModel(authenticationFlow: .register, supportsOIDC: false, supportsOIDCCreatePrompt: false)
setupViewModel(authenticationFlow: .register, supportsOAuth: false, supportsOAuthCreatePrompt: false)
#expect(service.homeserver.value.loginMode == .unknown)
#expect(clientFactory.makeClientHomeserverAddressSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksCallsCount == 0)
#expect(context.alertInfo == nil)
@@ -193,7 +193,7 @@ final class ServerConfirmationScreenViewModelTests {
@Test
func loginNotSupportedAlert() async throws {
// Given a view model for login using a service that hasn't been configured and the default server doesn't support login.
setupViewModel(authenticationFlow: .login, supportsOIDC: false, supportsOIDCCreatePrompt: false, supportsPasswordLogin: false)
setupViewModel(authenticationFlow: .login, supportsOAuth: false, supportsOAuthCreatePrompt: false, supportsPasswordLogin: false)
#expect(service.homeserver.value.loginMode == .unknown)
#expect(clientFactory.makeClientHomeserverAddressSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksCallsCount == 0)
#expect(context.alertInfo == nil)
@@ -211,7 +211,7 @@ final class ServerConfirmationScreenViewModelTests {
@Test
func elementProRequired() async throws {
// Given a view model for login using a service that hasn't been configured and the default server requires Element Pro.
setupViewModel(authenticationFlow: .login, supportsOIDC: false, supportsOIDCCreatePrompt: false, supportsPasswordLogin: false, requiresElementPro: true)
setupViewModel(authenticationFlow: .login, supportsOAuth: false, supportsOAuthCreatePrompt: false, supportsPasswordLogin: false, requiresElementPro: true)
#expect(service.homeserver.value.loginMode == .unknown)
#expect(clientFactory.makeClientHomeserverAddressSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksCallsCount == 0)
#expect(context.alertInfo == nil)
@@ -238,7 +238,7 @@ final class ServerConfirmationScreenViewModelTests {
#expect(client.urlForOauthOauthConfigurationPromptLoginHintDeviceIdAdditionalScopesCallsCount == 0)
// When continuing from the confirmation screen.
let deferred = deferFulfillment(viewModel.actions) { $0.isContinueWithOIDC }
let deferred = deferFulfillment(viewModel.actions) { $0.isContinueWithOAuth }
context.send(viewAction: .confirm)
try await deferred.fulfill()
@@ -246,7 +246,7 @@ final class ServerConfirmationScreenViewModelTests {
#expect(clientFactory.makeClientHomeserverAddressSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksCallsCount == 1)
#expect(client.urlForOauthOauthConfigurationPromptLoginHintDeviceIdAdditionalScopesCallsCount == 1)
#expect(client.urlForOauthOauthConfigurationPromptLoginHintDeviceIdAdditionalScopesReceivedArguments?.prompt == .consent)
#expect(service.homeserver.value.loginMode == .oidc(supportsCreatePrompt: true))
#expect(service.homeserver.value.loginMode == .oAuth(supportsCreatePrompt: true))
}
@Test
@@ -257,13 +257,13 @@ final class ServerConfirmationScreenViewModelTests {
Issue.record("The configuration should succeed.")
return
}
#expect(service.homeserver.value.loginMode == .oidc(supportsCreatePrompt: true))
#expect(service.homeserver.value.loginMode == .oAuth(supportsCreatePrompt: true))
#expect(context.viewState.mode == .picker(appSettings.accountProviders))
#expect(clientFactory.makeClientHomeserverAddressSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksCallsCount == 1)
#expect(client.urlForOauthOauthConfigurationPromptLoginHintDeviceIdAdditionalScopesCallsCount == 0)
// When continuing from the confirmation screen.
let deferred = deferFulfillment(viewModel.actions) { $0.isContinueWithOIDC }
let deferred = deferFulfillment(viewModel.actions) { $0.isContinueWithOAuth }
context.send(viewAction: .confirm)
try await deferred.fulfill()
@@ -275,8 +275,8 @@ final class ServerConfirmationScreenViewModelTests {
@Test
func pickerForPasswordLoginWithoutConfiguration() async throws {
// Given a view model for login using a service that hasn't been configured (against a server that doesn't support OIDC).
setupViewModel(authenticationFlow: .login, supportsOIDC: false, restrictedFlow: true)
// Given a view model for login using a service that hasn't been configured (against a server that doesn't support OAuth).
setupViewModel(authenticationFlow: .login, supportsOAuth: false, restrictedFlow: true)
#expect(service.homeserver.value.loginMode == .unknown)
#expect(context.viewState.mode == .picker(appSettings.accountProviders))
#expect(clientFactory.makeClientHomeserverAddressSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksCallsCount == 0)
@@ -287,7 +287,7 @@ final class ServerConfirmationScreenViewModelTests {
context.send(viewAction: .confirm)
try await deferred.fulfill()
// Then a call to configure service should be made, but not for the OIDC URL.
// Then a call to configure service should be made, but not for the OAuth URL.
#expect(clientFactory.makeClientHomeserverAddressSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksCallsCount == 1)
#expect(client.urlForOauthOauthConfigurationPromptLoginHintDeviceIdAdditionalScopesCallsCount == 0)
#expect(service.homeserver.value.loginMode == .password)
@@ -296,7 +296,7 @@ final class ServerConfirmationScreenViewModelTests {
@Test
func pickerForPasswordLoginAfterConfiguration() async throws {
// Given a view model for login using a service that has already been configured (via the server selection screen).
setupViewModel(authenticationFlow: .login, supportsOIDC: false, restrictedFlow: true)
setupViewModel(authenticationFlow: .login, supportsOAuth: false, restrictedFlow: true)
guard case .success = await service.configure(for: appSettings.accountProviders[0], flow: .login) else {
Issue.record("The configuration should succeed.")
return
@@ -311,7 +311,7 @@ final class ServerConfirmationScreenViewModelTests {
context.send(viewAction: .confirm)
try await deferred.fulfill()
// Then the configured homeserver should be used and no additional client should be built, nor a call to get the OIDC URL.
// Then the configured homeserver should be used and no additional client should be built, nor a call to get the OAuth URL.
#expect(clientFactory.makeClientHomeserverAddressSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksCallsCount == 1)
#expect(client.urlForOauthOauthConfigurationPromptLoginHintDeviceIdAdditionalScopesCallsCount == 0)
}
@@ -319,8 +319,8 @@ final class ServerConfirmationScreenViewModelTests {
// MARK: - Helpers
private func setupViewModel(authenticationFlow: AuthenticationFlow,
supportsOIDC: Bool = true,
supportsOIDCCreatePrompt: Bool = true,
supportsOAuth: Bool = true,
supportsOAuthCreatePrompt: Bool = true,
supportsPasswordLogin: Bool = true,
restrictedFlow: Bool = false,
requiresElementPro: Bool = false) {
@@ -330,7 +330,7 @@ final class ServerConfirmationScreenViewModelTests {
allowOtherAccountProviders: false,
hideBrandChrome: false,
pushGatewayBaseURL: appSettings.pushGatewayBaseURL,
oidcRedirectURL: appSettings.oidcRedirectURL,
oAuthRedirectURL: appSettings.oAuthRedirectURL,
websiteURL: appSettings.websiteURL,
logoURL: appSettings.logoURL,
copyrightURL: appSettings.copyrightURL,
@@ -350,8 +350,8 @@ final class ServerConfirmationScreenViewModelTests {
}
// Manually create a configuration as the default homeserver address setting is immutable.
client = ClientSDKMock(configuration: .init(oidcLoginURL: supportsOIDC ? "https://account.matrix.org/authorize" : nil,
supportsOIDCCreatePrompt: supportsOIDCCreatePrompt,
client = ClientSDKMock(configuration: .init(oAuthLoginURL: supportsOAuth ? "https://account.matrix.org/authorize" : nil,
supportsOAuthCreatePrompt: supportsOAuthCreatePrompt,
supportsPasswordLogin: supportsPasswordLogin,
elementWellKnown: requiresElementPro ? "{\"version\":1,\"enforce_element_pro\":true}" : nil))
let configuration = AuthenticationClientFactoryMock.Configuration(homeserverClients: ["matrix.org": client])
@@ -370,7 +370,7 @@ final class ServerConfirmationScreenViewModelTests {
appSettings: ServiceLocator.shared.settings,
userIndicatorController: UserIndicatorControllerMock())
// Add a fake window in order for the OIDC flow to continue
// Add a fake window in order for the OAuth flow to continue
viewModel.context.send(viewAction: .updateWindow(UIWindow()))
}
}
@@ -387,9 +387,9 @@ private extension ServerConfirmationScreenViewState {
}
private extension ServerConfirmationScreenViewModelAction {
var isContinueWithOIDC: Bool {
var isContinueWithOAuth: Bool {
switch self {
case .continueWithOIDC: true
case .continueWithOAuth: true
default: false
}
}

View File

@@ -45,7 +45,7 @@ struct SoftLogoutScreenViewModelTests {
}
@Test
func initialStateForOIDC() {
func initialStateForOAuth() {
let viewModel = SoftLogoutScreenViewModel(credentials: credentials,
homeserver: .mockMatrixDotOrg,
keyBackupNeeded: false)
@@ -54,7 +54,7 @@ struct SoftLogoutScreenViewModelTests {
// Given a view model where the user hasn't yet sent the verification email.
#expect(context.password.isEmpty, "The view model should start with an empty password.")
#expect(!context.viewState.canSubmit, "The view model should start with an invalid password.")
#expect(context.viewState.loginMode.supportsOIDCFlow, "The view model should show OIDC button for the given homeserver.")
#expect(context.viewState.loginMode.supportsOAuthFlow, "The view model should show OAuth button for the given homeserver.")
#expect(!context.viewState.showRecoverEncryptionKeysMessage, "The view model should not show recover encryption keys message.")
}