mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-10-31 16:24:11 +00:00
Add an AccountProvider type and use it within the authentication flow. (#6103)
* Add an AccountProvider type and use it within AppSettings. * Use the AccountProvider type within the Authentication flow too. * Fix unit test compilation with Swift 6.4 * Make sure defaultAccountProvider takes allowOtherAccountProviders into account. * Document a caveat on using AuthenticationService.homeserver.value.accountProvider.
This commit is contained in:
@@ -50,7 +50,7 @@ final class AuthenticationStartScreenViewModelTests {
|
||||
try await deferred.fulfill()
|
||||
|
||||
// Then the authentication service should not be used yet.
|
||||
#expect(clientFactory.makeAuthenticationClientHomeserverAddressSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksCallsCount == 0)
|
||||
#expect(clientFactory.makeAuthenticationClientServerNameOrBaseURLSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksCallsCount == 0)
|
||||
#expect(client.urlForOauthOauthConfigurationPromptLoginHintDeviceIdAdditionalScopesCallsCount == 0)
|
||||
#expect(authenticationService.homeserver.value.loginMode == .unknown)
|
||||
}
|
||||
@@ -69,7 +69,7 @@ final class AuthenticationStartScreenViewModelTests {
|
||||
context.send(viewAction: .login)
|
||||
try await deferred.fulfill()
|
||||
|
||||
#expect(clientFactory.makeAuthenticationClientHomeserverAddressSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksCallsCount == 1)
|
||||
#expect(clientFactory.makeAuthenticationClientServerNameOrBaseURLSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksCallsCount == 1)
|
||||
#expect(client.urlForOauthOauthConfigurationPromptLoginHintDeviceIdAdditionalScopesCallsCount == 1)
|
||||
#expect(client.urlForOauthOauthConfigurationPromptLoginHintDeviceIdAdditionalScopesReceivedArguments?.prompt == .consent)
|
||||
#expect(client.urlForOauthOauthConfigurationPromptLoginHintDeviceIdAdditionalScopesReceivedArguments?.loginHint == "user@company.com")
|
||||
@@ -90,14 +90,14 @@ final class AuthenticationStartScreenViewModelTests {
|
||||
try await deferred.fulfill()
|
||||
|
||||
// Then a call to configure service should be made.
|
||||
#expect(clientFactory.makeAuthenticationClientHomeserverAddressSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksCallsCount == 1)
|
||||
#expect(clientFactory.makeAuthenticationClientServerNameOrBaseURLSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksCallsCount == 1)
|
||||
#expect(authenticationService.homeserver.value.loginMode == .password)
|
||||
}
|
||||
|
||||
@Test
|
||||
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"])
|
||||
setAllowedAccountProviders([.generic("company.com")])
|
||||
await setupViewModel()
|
||||
#expect(authenticationService.homeserver.value.loginMode == .unknown)
|
||||
#expect(client.urlForOauthOauthConfigurationPromptLoginHintDeviceIdAdditionalScopesCallsCount == 0)
|
||||
@@ -108,7 +108,7 @@ final class AuthenticationStartScreenViewModelTests {
|
||||
context.send(viewAction: .login)
|
||||
try await deferred.fulfill()
|
||||
|
||||
#expect(clientFactory.makeAuthenticationClientHomeserverAddressSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksCallsCount == 1)
|
||||
#expect(clientFactory.makeAuthenticationClientServerNameOrBaseURLSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksCallsCount == 1)
|
||||
#expect(client.urlForOauthOauthConfigurationPromptLoginHintDeviceIdAdditionalScopesCallsCount == 1)
|
||||
#expect(client.urlForOauthOauthConfigurationPromptLoginHintDeviceIdAdditionalScopesReceivedArguments?.prompt == .consent)
|
||||
#expect(client.urlForOauthOauthConfigurationPromptLoginHintDeviceIdAdditionalScopesReceivedArguments?.loginHint == nil)
|
||||
@@ -118,7 +118,7 @@ final class AuthenticationStartScreenViewModelTests {
|
||||
@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 OAuth.
|
||||
setAllowedAccountProviders(["company.com"])
|
||||
setAllowedAccountProviders([.generic("company.com")])
|
||||
await setupViewModel(supportsOAuth: false)
|
||||
#expect(authenticationService.homeserver.value.loginMode == .unknown)
|
||||
#expect(client.urlForOauthOauthConfigurationPromptLoginHintDeviceIdAdditionalScopesCallsCount == 0)
|
||||
@@ -130,7 +130,7 @@ final class AuthenticationStartScreenViewModelTests {
|
||||
try await deferred.fulfill()
|
||||
|
||||
// Then a call to configure service should be made.
|
||||
#expect(clientFactory.makeAuthenticationClientHomeserverAddressSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksCallsCount == 1)
|
||||
#expect(clientFactory.makeAuthenticationClientServerNameOrBaseURLSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksCallsCount == 1)
|
||||
#expect(authenticationService.homeserver.value.loginMode == .password)
|
||||
}
|
||||
|
||||
@@ -153,8 +153,8 @@ final class AuthenticationStartScreenViewModelTests {
|
||||
context.send(viewAction: .continueWithClassic(classicAppAccount))
|
||||
try await deferred.fulfill()
|
||||
|
||||
#expect(clientFactory.makeAuthenticationClientHomeserverAddressSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksCallsCount == 1)
|
||||
#expect(clientFactory.makeAuthenticationClientHomeserverAddressSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksReceivedArguments?.homeserverAddress == "company.com")
|
||||
#expect(clientFactory.makeAuthenticationClientServerNameOrBaseURLSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksCallsCount == 1)
|
||||
#expect(clientFactory.makeAuthenticationClientServerNameOrBaseURLSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksReceivedArguments?.serverNameOrBaseURL == "company.com")
|
||||
#expect(authenticationService.homeserver.value.loginMode == .oAuth(supportsCreatePrompt: false))
|
||||
#expect(client.urlForOauthOauthConfigurationPromptLoginHintDeviceIdAdditionalScopesReceivedArguments?.loginHint == "mxid:\(classicAppAccount.userID)")
|
||||
}
|
||||
@@ -177,8 +177,8 @@ final class AuthenticationStartScreenViewModelTests {
|
||||
context.send(viewAction: .continueWithClassic(classicAppAccount))
|
||||
try await deferred.fulfill()
|
||||
|
||||
#expect(clientFactory.makeAuthenticationClientHomeserverAddressSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksCallsCount == 2)
|
||||
#expect(clientFactory.makeAuthenticationClientHomeserverAddressSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksReceivedArguments?.homeserverAddress == "https://matrix.company.com")
|
||||
#expect(clientFactory.makeAuthenticationClientServerNameOrBaseURLSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksCallsCount == 2)
|
||||
#expect(clientFactory.makeAuthenticationClientServerNameOrBaseURLSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksReceivedArguments?.serverNameOrBaseURL == "https://matrix.company.com")
|
||||
#expect(authenticationService.homeserver.value.loginMode == .oAuth(supportsCreatePrompt: false))
|
||||
#expect(client.urlForOauthOauthConfigurationPromptLoginHintDeviceIdAdditionalScopesReceivedArguments?.loginHint == "mxid:\(classicAppAccount.userID)")
|
||||
}
|
||||
@@ -214,7 +214,7 @@ final class AuthenticationStartScreenViewModelTests {
|
||||
// Given a view model for an app that only allows a single provider that matches the Classic account's server.
|
||||
let classicAppAccount = makeClassicAppAccount(serverName: "company.com",
|
||||
homeserverURL: "https://matrix.company.com")
|
||||
setAllowedAccountProviders(["company.com"])
|
||||
setAllowedAccountProviders([.generic("company.com")])
|
||||
await setupViewModel(classicAppAccount: classicAppAccount)
|
||||
|
||||
// Then the Classic app account should be shown as a welcome-back option.
|
||||
@@ -230,7 +230,7 @@ final class AuthenticationStartScreenViewModelTests {
|
||||
// Given a view model for an app that only allows a single provider that does NOT match the Classic account's server.
|
||||
let classicAppAccount = makeClassicAppAccount(serverName: "other-server.org",
|
||||
homeserverURL: "https://matrix.other-server.org")
|
||||
setAllowedAccountProviders(["company.com"])
|
||||
setAllowedAccountProviders([.generic("company.com")])
|
||||
await setupViewModel(classicAppAccount: classicAppAccount)
|
||||
|
||||
// Then the Classic app account should not be shown since the server is not in the allowed providers.
|
||||
@@ -278,7 +278,7 @@ final class AuthenticationStartScreenViewModelTests {
|
||||
supportsOAuth: Bool = true,
|
||||
supportsPasswordLogin: Bool = true,
|
||||
availableSecrets: ClassicAppAccount.AvailableSecrets = .complete) async {
|
||||
// Manually create a configuration as the default homeserver address setting is immutable.
|
||||
// Manually create a configuration as the default account provider setting is immutable.
|
||||
client = ClientSDKMock(.init(oAuthLoginURL: supportsOAuth ? "https://account.company.com/authorize" : nil,
|
||||
supportsOAuthCreatePrompt: false,
|
||||
supportsPasswordLogin: supportsPasswordLogin))
|
||||
@@ -330,7 +330,7 @@ final class AuthenticationStartScreenViewModelTests {
|
||||
accessToken: "accessToken")
|
||||
}
|
||||
|
||||
private func setAllowedAccountProviders(_ providers: [String]) {
|
||||
private func setAllowedAccountProviders(_ providers: [AccountProvider]) {
|
||||
appSettings.override(accountProviders: providers,
|
||||
allowOtherAccountProviders: false,
|
||||
hideBrandChrome: false,
|
||||
|
||||
Reference in New Issue
Block a user