mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-03 16:10:20 +00:00
Configure the AuthenticationService later now that we have 2 flows on the start screen. (#3316)
* Don't query the homeserver until confirming it (or selecting a different one). * Setup the infrastructure to test AuthenticationService. Implement basic tests for configuration & password login. * Use the real AuthenticationService with a mock Client in all of the tests. * Add tests for the ServerConfirmationScreenViewModel. * Remove redundant view state and test for it.
This commit is contained in:
+3
-11
@@ -11,30 +11,22 @@ enum MockServerSelectionScreenState: CaseIterable {
|
||||
case matrix
|
||||
case emptyAddress
|
||||
case invalidAddress
|
||||
case nonModal
|
||||
|
||||
/// Generate the view struct for the screen state.
|
||||
@MainActor var viewModel: ServerSelectionScreenViewModel {
|
||||
switch self {
|
||||
case .matrix:
|
||||
return ServerSelectionScreenViewModel(homeserverAddress: "https://matrix.org",
|
||||
slidingSyncLearnMoreURL: ServiceLocator.shared.settings.slidingSyncLearnMoreURL,
|
||||
isModallyPresented: true)
|
||||
slidingSyncLearnMoreURL: ServiceLocator.shared.settings.slidingSyncLearnMoreURL)
|
||||
|
||||
case .emptyAddress:
|
||||
return ServerSelectionScreenViewModel(homeserverAddress: "",
|
||||
slidingSyncLearnMoreURL: ServiceLocator.shared.settings.slidingSyncLearnMoreURL,
|
||||
isModallyPresented: true)
|
||||
slidingSyncLearnMoreURL: ServiceLocator.shared.settings.slidingSyncLearnMoreURL)
|
||||
case .invalidAddress:
|
||||
let viewModel = ServerSelectionScreenViewModel(homeserverAddress: "thisisbad",
|
||||
slidingSyncLearnMoreURL: ServiceLocator.shared.settings.slidingSyncLearnMoreURL,
|
||||
isModallyPresented: true)
|
||||
slidingSyncLearnMoreURL: ServiceLocator.shared.settings.slidingSyncLearnMoreURL)
|
||||
viewModel.displayError(.footerMessage(L10n.errorUnknown))
|
||||
return viewModel
|
||||
case .nonModal:
|
||||
return ServerSelectionScreenViewModel(homeserverAddress: "https://matrix.org",
|
||||
slidingSyncLearnMoreURL: ServiceLocator.shared.settings.slidingSyncLearnMoreURL,
|
||||
isModallyPresented: false)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+6
-5
@@ -11,9 +11,9 @@ import SwiftUI
|
||||
struct ServerSelectionScreenCoordinatorParameters {
|
||||
/// The service used to authenticate the user.
|
||||
let authenticationService: AuthenticationServiceProtocol
|
||||
let authenticationFlow: AuthenticationFlow
|
||||
let slidingSyncLearnMoreURL: URL
|
||||
let userIndicatorController: UserIndicatorControllerProtocol
|
||||
/// Whether the screen is presented modally or within a navigation stack.
|
||||
let isModallyPresented: Bool
|
||||
}
|
||||
|
||||
enum ServerSelectionScreenCoordinatorAction {
|
||||
@@ -38,8 +38,7 @@ final class ServerSelectionScreenCoordinator: CoordinatorProtocol {
|
||||
init(parameters: ServerSelectionScreenCoordinatorParameters) {
|
||||
self.parameters = parameters
|
||||
viewModel = ServerSelectionScreenViewModel(homeserverAddress: parameters.authenticationService.homeserver.value.address,
|
||||
slidingSyncLearnMoreURL: ServiceLocator.shared.settings.slidingSyncLearnMoreURL,
|
||||
isModallyPresented: parameters.isModallyPresented)
|
||||
slidingSyncLearnMoreURL: parameters.slidingSyncLearnMoreURL)
|
||||
userIndicatorController = parameters.userIndicatorController
|
||||
}
|
||||
|
||||
@@ -85,7 +84,7 @@ final class ServerSelectionScreenCoordinator: CoordinatorProtocol {
|
||||
startLoading()
|
||||
|
||||
Task {
|
||||
switch await authenticationService.configure(for: homeserverAddress) {
|
||||
switch await authenticationService.configure(for: homeserverAddress, flow: parameters.authenticationFlow) {
|
||||
case .success:
|
||||
MXLog.info("Selected homeserver: \(homeserverAddress)")
|
||||
actionsSubject.send(.updated)
|
||||
@@ -107,6 +106,8 @@ final class ServerSelectionScreenCoordinator: CoordinatorProtocol {
|
||||
viewModel.displayError(.invalidWellKnownAlert(error))
|
||||
case .slidingSyncNotAvailable:
|
||||
viewModel.displayError(.slidingSyncAlert)
|
||||
case .registrationNotSupported:
|
||||
viewModel.displayError(.registrationAlert) // TODO: [DOUG] Test me!
|
||||
default:
|
||||
viewModel.displayError(.footerMessage(L10n.errorUnknown))
|
||||
}
|
||||
|
||||
+3
-9
@@ -22,19 +22,12 @@ struct ServerSelectionScreenViewState: BindableState {
|
||||
var bindings: ServerSelectionScreenBindings
|
||||
/// An error message to be shown in the text field footer.
|
||||
var footerErrorMessage: String?
|
||||
/// Whether the screen is presented modally or within a navigation stack.
|
||||
var isModallyPresented: Bool
|
||||
|
||||
/// The message to show in the text field footer.
|
||||
var footerMessage: AttributedString {
|
||||
footerErrorMessage.map(AttributedString.init) ?? regularFooterMessage
|
||||
}
|
||||
|
||||
/// The title shown on the confirm button.
|
||||
var buttonTitle: String {
|
||||
isModallyPresented ? L10n.actionContinue : L10n.actionNext
|
||||
}
|
||||
|
||||
/// The text field is showing an error.
|
||||
var isShowingFooterError: Bool {
|
||||
footerErrorMessage != nil
|
||||
@@ -45,10 +38,9 @@ struct ServerSelectionScreenViewState: BindableState {
|
||||
bindings.homeserverAddress.isEmpty || isShowingFooterError
|
||||
}
|
||||
|
||||
init(slidingSyncLearnMoreURL: URL, bindings: ServerSelectionScreenBindings, footerErrorMessage: String? = nil, isModallyPresented: Bool) {
|
||||
init(slidingSyncLearnMoreURL: URL, bindings: ServerSelectionScreenBindings, footerErrorMessage: String? = nil) {
|
||||
self.bindings = bindings
|
||||
self.footerErrorMessage = footerErrorMessage
|
||||
self.isModallyPresented = isModallyPresented
|
||||
|
||||
let linkPlaceholder = "{link}"
|
||||
var message = AttributedString(L10n.screenChangeServerFormNotice(linkPlaceholder))
|
||||
@@ -82,4 +74,6 @@ enum ServerSelectionScreenErrorType: Hashable {
|
||||
case invalidWellKnownAlert(String)
|
||||
/// An alert that allows the user to learn about sliding sync.
|
||||
case slidingSyncAlert
|
||||
/// An alert that informs the user that registration isn't supported.
|
||||
case registrationAlert
|
||||
}
|
||||
|
||||
+7
-4
@@ -19,13 +19,12 @@ class ServerSelectionScreenViewModel: ServerSelectionScreenViewModelType, Server
|
||||
actionsSubject.eraseToAnyPublisher()
|
||||
}
|
||||
|
||||
init(homeserverAddress: String, slidingSyncLearnMoreURL: URL, isModallyPresented: Bool) {
|
||||
init(homeserverAddress: String, slidingSyncLearnMoreURL: URL) {
|
||||
self.slidingSyncLearnMoreURL = slidingSyncLearnMoreURL
|
||||
let bindings = ServerSelectionScreenBindings(homeserverAddress: homeserverAddress)
|
||||
|
||||
super.init(initialViewState: ServerSelectionScreenViewState(slidingSyncLearnMoreURL: slidingSyncLearnMoreURL,
|
||||
bindings: bindings,
|
||||
isModallyPresented: isModallyPresented))
|
||||
bindings: bindings))
|
||||
}
|
||||
|
||||
override func process(viewAction: ServerSelectionScreenViewAction) {
|
||||
@@ -46,7 +45,7 @@ class ServerSelectionScreenViewModel: ServerSelectionScreenViewModelType, Server
|
||||
state.footerErrorMessage = message
|
||||
}
|
||||
case .invalidWellKnownAlert(let error):
|
||||
state.bindings.alertInfo = AlertInfo(id: .slidingSyncAlert,
|
||||
state.bindings.alertInfo = AlertInfo(id: .invalidWellKnownAlert(error),
|
||||
title: L10n.commonServerNotSupported,
|
||||
message: L10n.screenChangeServerErrorInvalidWellKnown(error))
|
||||
case .slidingSyncAlert:
|
||||
@@ -56,6 +55,10 @@ class ServerSelectionScreenViewModel: ServerSelectionScreenViewModelType, Server
|
||||
message: L10n.screenChangeServerErrorNoSlidingSyncMessage,
|
||||
primaryButton: .init(title: L10n.actionLearnMore, role: .cancel, action: openURL),
|
||||
secondaryButton: .init(title: L10n.actionCancel, action: nil))
|
||||
case .registrationAlert:
|
||||
state.bindings.alertInfo = AlertInfo(id: .registrationAlert,
|
||||
title: L10n.errorUnknown,
|
||||
message: L10n.errorAccountCreationNotPossible)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+4
-7
@@ -64,7 +64,7 @@ struct ServerSelectionScreen: View {
|
||||
.onSubmit(submit)
|
||||
|
||||
Button(action: submit) {
|
||||
Text(context.viewState.buttonTitle)
|
||||
Text(L10n.actionContinue)
|
||||
}
|
||||
.buttonStyle(.compound(.primary))
|
||||
.disabled(context.viewState.hasValidationError)
|
||||
@@ -72,15 +72,12 @@ struct ServerSelectionScreen: View {
|
||||
}
|
||||
}
|
||||
|
||||
@ToolbarContentBuilder
|
||||
var toolbar: some ToolbarContent {
|
||||
ToolbarItem(placement: .cancellationAction) {
|
||||
if context.viewState.isModallyPresented {
|
||||
Button { context.send(viewAction: .dismiss) } label: {
|
||||
Text(L10n.actionCancel)
|
||||
}
|
||||
.accessibilityIdentifier(A11yIdentifiers.changeServerScreen.dismiss)
|
||||
Button { context.send(viewAction: .dismiss) } label: {
|
||||
Text(L10n.actionCancel)
|
||||
}
|
||||
.accessibilityIdentifier(A11yIdentifiers.changeServerScreen.dismiss)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user