diff --git a/Lock.xcodeproj/project.pbxproj b/Lock.xcodeproj/project.pbxproj index 172b4bdce..5dd74572d 100644 --- a/Lock.xcodeproj/project.pbxproj +++ b/Lock.xcodeproj/project.pbxproj @@ -225,7 +225,7 @@ 5BCDE1341DDDF12100AA2A6C /* EnterpriseActiveAuthPresenterSpec.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EnterpriseActiveAuthPresenterSpec.swift; sourceTree = ""; }; 5BCED4C51DD1FCF200E2CE8A /* EnterpriseDomainPresenterSpec.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EnterpriseDomainPresenterSpec.swift; sourceTree = ""; }; 5F0FCF8F1E20117E00E3D53B /* ObserverStore.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ObserverStore.swift; sourceTree = ""; }; - 5F0FCF911E201CF300E3D53B /* ObserverStoreSpec.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ObserverStoreSpec.swift; sourceTree = ""; }; + 5F0FCF911E201CF300E3D53B /* ObserverStoreSpec.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = ObserverStoreSpec.swift; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.swift; }; 5F1456591D5130E80085DF9C /* Colors.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Colors.swift; path = Lock/Colors.swift; sourceTree = SOURCE_ROOT; }; 5F1C498D1D8360AA005B74FC /* Style.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Style.swift; path = Lock/Style.swift; sourceTree = SOURCE_ROOT; }; 5F1C498F1D8360BF005B74FC /* ConnectionLoadingPresenter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = ConnectionLoadingPresenter.swift; path = Lock/ConnectionLoadingPresenter.swift; sourceTree = SOURCE_ROOT; }; diff --git a/Lock/DatabaseForgotPasswordPresenter.swift b/Lock/DatabaseForgotPasswordPresenter.swift index 77ad96544..bd85708eb 100644 --- a/Lock/DatabaseForgotPasswordPresenter.swift +++ b/Lock/DatabaseForgotPasswordPresenter.swift @@ -72,7 +72,9 @@ class DatabaseForgotPasswordPresenter: Presentable, Loggable { self.logger.error("Failed with error \(error)") } else { let message = "We've just sent you an email to reset your password".i18n(key: "com.auth0.lock.database.forgot.success.message", comment: "forgot password email sent") - self.messagePresenter?.showSuccess(message) + if self.options.allow.contains(.Login) || !self.options.autoClose { + self.messagePresenter?.showSuccess(message) + } guard self.options.allow.contains(.Login) else { return } self.navigator.navigate(.root) } diff --git a/Lock/DatabasePasswordInteractor.swift b/Lock/DatabasePasswordInteractor.swift index 3b6755ac3..8c20d3e3c 100644 --- a/Lock/DatabasePasswordInteractor.swift +++ b/Lock/DatabasePasswordInteractor.swift @@ -26,6 +26,7 @@ import Auth0 struct DatabasePasswordInteractor: PasswordRecoverable { private var user: DatabaseUser + private let dispatcher: Dispatcher var email: String? { return self.user.email } var validEmail: Bool { return self.user.validEmail } @@ -34,10 +35,11 @@ struct DatabasePasswordInteractor: PasswordRecoverable { let connections: Connections let emailValidator: InputValidator = EmailValidator() - init(connections: Connections, authentication: Authentication, user: DatabaseUser) { + init(connections: Connections, authentication: Authentication, user: DatabaseUser, dispatcher: Dispatcher) { self.authentication = authentication self.connections = connections self.user = user + self.dispatcher = dispatcher } mutating func updateEmail(_ value: String?) throws { @@ -55,6 +57,7 @@ struct DatabasePasswordInteractor: PasswordRecoverable { .resetPassword(email: email, connection: connection) .start { guard case .success = $0 else { return callback(.emailNotSent) } + self.dispatcher.dispatch(result: .forgotPassword(email)) callback(nil) } } diff --git a/Lock/DatabasePresenter.swift b/Lock/DatabasePresenter.swift index 701cf8601..01f7115f0 100644 --- a/Lock/DatabasePresenter.swift +++ b/Lock/DatabasePresenter.swift @@ -102,6 +102,10 @@ class DatabasePresenter: Presentable, Loggable { button.inProgress = false guard let error = error else { self.logger.debug("Logged in!") + let message = "You have logged in successfully.".i18n(key: "com.auth0.lock.database.login.success.message", comment: "User logged in") + if !self.options.autoClose { + self.messagePresenter?.showSuccess(message) + } return } if case DatabaseAuthenticatableError.multifactorRequired = error { @@ -162,7 +166,9 @@ class DatabasePresenter: Presentable, Loggable { if let databaseView = self.databaseView, self.options.allow.contains(.Login) { self.showLogin(inView: databaseView, identifier: self.creator.identifier) } - self.messagePresenter?.showSuccess(message) + if self.options.allow.contains(.Login) || !self.options.autoClose { + self.messagePresenter?.showSuccess(message) + } } return } diff --git a/Lock/Lock.swift b/Lock/Lock.swift index 7f0412908..f7ee3f1ff 100644 --- a/Lock/Lock.swift +++ b/Lock/Lock.swift @@ -147,6 +147,7 @@ public class Lock: NSObject { var builder: OptionBuildable = self.optionsBuilder closure(&builder) self.optionsBuilder = builder + self.observerStore.options = self.options _ = self.authentication.logging(enabled: self.options.logHttpRequest) _ = self.webAuth.logging(enabled: self.options.logHttpRequest) return self diff --git a/Lock/LockOptions.swift b/Lock/LockOptions.swift index cb707ff27..04230e356 100644 --- a/Lock/LockOptions.swift +++ b/Lock/LockOptions.swift @@ -33,6 +33,7 @@ struct LockOptions: OptionBuildable { var scope: String = "openid" var parameters: [String : Any] = [:] var allow: DatabaseMode = [.Login, .Signup, .ResetPassword] + var autoClose: Bool = true var initialScreen: DatabaseScreen = .login var usernameStyle: DatabaseIdentifierStyle = [.Username, .Email] var customSignupFields: [CustomTextField] = [] diff --git a/Lock/ObserverStore.swift b/Lock/ObserverStore.swift index ac3e7fcba..7ba0f862d 100644 --- a/Lock/ObserverStore.swift +++ b/Lock/ObserverStore.swift @@ -28,6 +28,8 @@ struct ObserverStore: Dispatcher { var onFailure: (Error) -> () = { _ in } var onCancel: () -> () = { } var onSignUp: (String, [String: Any]) -> () = { _ in } + var onForgotPassword: (String) -> () = { _ in } + var options: Options = LockOptions() weak var controller: UIViewController? @@ -35,16 +37,29 @@ struct ObserverStore: Dispatcher { let closure: () -> () switch result { case .auth(let credentials): - closure = dismiss(from: controller?.presentingViewController, completion: { self.onAuth(credentials) }) + if self.options.autoClose { + closure = dismiss(from: controller?.presentingViewController, completion: { self.onAuth(credentials) }) + } else { + closure = { self.onAuth(credentials) } + } case .error(let error): closure = { self.onFailure(error) } case .cancel: closure = dismiss(from: controller?.presentingViewController, completion: { self.onCancel() }) case .signUp(let email, let attributes): - closure = { self.onSignUp(email, attributes) } - default: - closure = {} + if !self.options.allow.contains(.Login) && self.options.autoClose { + closure = dismiss(from: controller?.presentingViewController, completion: { self.onSignUp(email, attributes) }) + } else { + closure = { self.onSignUp(email, attributes) } + } + case .forgotPassword(let email): + if !self.options.allow.contains(.Login) && self.options.autoClose { + closure = dismiss(from: controller?.presentingViewController, completion: { self.onForgotPassword(email) }) + } else { + closure = { self.onForgotPassword(email) } + } } + Queue.main.async(closure) } diff --git a/Lock/OptionBuildable.swift b/Lock/OptionBuildable.swift index 00e53799c..1a1fc90b0 100644 --- a/Lock/OptionBuildable.swift +++ b/Lock/OptionBuildable.swift @@ -54,6 +54,9 @@ public protocol OptionBuildable: Options { /// What database modes are allowed and must be at least one. By default all modes are allowed. var allow: DatabaseMode { get set } + /// Should Lock close if only mode available. By default is true + var autoClose: Bool { get set } + /// Initial screen displayed by Lock when a database connection is available. By default is Login var initialScreen: DatabaseScreen { get set } @@ -87,6 +90,7 @@ internal extension OptionBuildable { func validate() -> UnrecoverableError? { guard !self.allow.isEmpty else { return UnrecoverableError.invalidOptions(cause: "Must allow at least one database mode") } guard !self.usernameStyle.isEmpty else { return UnrecoverableError.invalidOptions(cause: "Must specify at least one username style") } + guard self.allow.contains(.Login) || self.closable || self.autoClose else { return UnrecoverableError.invalidOptions(cause: "Must enable autoclose or enable closable") } return nil } } diff --git a/Lock/Options.swift b/Lock/Options.swift index 39a821ac2..a1f8b333f 100644 --- a/Lock/Options.swift +++ b/Lock/Options.swift @@ -35,6 +35,7 @@ public protocol Options { var scope: String { get } var parameters: [String: Any] { get } var allow: DatabaseMode { get } + var autoClose: Bool { get } var initialScreen: DatabaseScreen { get } var usernameStyle: DatabaseIdentifierStyle { get } var customSignupFields: [CustomTextField] { get } diff --git a/Lock/Router.swift b/Lock/Router.swift index 437620538..7779256a1 100644 --- a/Lock/Router.swift +++ b/Lock/Router.swift @@ -97,7 +97,7 @@ struct Router: Navigable { exit(withError: UnrecoverableError.clientWithNoConnections) return nil } - let interactor = DatabasePasswordInteractor(connections: connections, authentication: self.lock.authentication, user: self.user) + let interactor = DatabasePasswordInteractor(connections: connections, authentication: self.lock.authentication, user: self.user, dispatcher: lock.observerStore) let presenter = DatabaseForgotPasswordPresenter(interactor: interactor, connections: connections, navigator: self, options: self.lock.options) presenter.customLogger = self.lock.logger return presenter diff --git a/LockTests/Interactors/DatabaseInteractorSpec.swift b/LockTests/Interactors/DatabaseInteractorSpec.swift index cc503619f..c96314c17 100644 --- a/LockTests/Interactors/DatabaseInteractorSpec.swift +++ b/LockTests/Interactors/DatabaseInteractorSpec.swift @@ -38,13 +38,16 @@ class DatabaseInteractorSpec: QuickSpec { describe("init") { + let options = LockOptions() + let dispatcher = ObserverStore() + it("should build with authentication") { - let database = DatabaseInteractor(connection: DatabaseConnection(name: "db", requiresUsername: true), authentication: authentication, user: User(), options: LockOptions(), dispatcher: ObserverStore()) + let database = DatabaseInteractor(connection: DatabaseConnection(name: "db", requiresUsername: true), authentication: authentication, user: User(), options: options, dispatcher: dispatcher) expect(database).toNot(beNil()) } it("should have authentication object") { - let database = DatabaseInteractor(connection: DatabaseConnection(name: "db", requiresUsername: true), authentication: authentication, user: User(), options: LockOptions(), dispatcher: ObserverStore()) + let database = DatabaseInteractor(connection: DatabaseConnection(name: "db", requiresUsername: true), authentication: authentication, user: User(), options: options, dispatcher: dispatcher) expect(database.credentialAuth.authentication.clientId) == "CLIENT_ID" expect(database.credentialAuth.authentication.url.host) == "samples.auth0.com" expect(database.credentialAuth.oidc) == false @@ -56,12 +59,16 @@ class DatabaseInteractorSpec: QuickSpec { var database: DatabaseInteractor! var user: User! var options: OptionBuildable! + var dispatcher: ObserverStore! beforeEach { + options = LockOptions() + dispatcher = ObserverStore() + Auth0Stubs.failUnknown() user = User() let db = DatabaseConnection(name: connection, requiresUsername: true, usernameValidator: UsernameValidator(withLength: 1...15, characterSet: UsernameValidator.auth0), passwordValidator: PasswordPolicyValidator(policy: .good)) - database = DatabaseInteractor(connection: db, authentication: authentication, user: user, options: LockOptions(), dispatcher: ObserverStore()) + database = DatabaseInteractor(connection: db, authentication: authentication, user: user, options: options, dispatcher: dispatcher) } describe("updateAttribute") { @@ -559,7 +566,6 @@ class DatabaseInteractorSpec: QuickSpec { } } } - } describe("login OIDC Conformant") { @@ -733,7 +739,6 @@ class DatabaseInteractorSpec: QuickSpec { } } } - } // MARK: - Signup @@ -796,7 +801,7 @@ class DatabaseInteractorSpec: QuickSpec { } } - context("Auto log in after sign up") { + context("auto log in after sign up") { var options = LockOptions() @@ -1020,48 +1025,6 @@ class DatabaseInteractorSpec: QuickSpec { } } - context("auto login disabled") { - - var options: LockOptions! - var newUserEmail: String? - - beforeEach { - newUserEmail = nil - options = LockOptions() - options.loginAfterSignup = false - var dispatcher = ObserverStore() - dispatcher.onSignUp = { email, _ in - newUserEmail = email - } - let db = DatabaseConnection(name: connection, requiresUsername: true, usernameValidator: UsernameValidator(withLength: 1...15, characterSet: UsernameValidator.auth0), passwordValidator: PasswordPolicyValidator(policy: .good)) - database = DatabaseInteractor(connection: db, authentication: authentication, user: user, options: options, dispatcher: dispatcher) - stub(condition: databaseLogin(identifier: email, password: password, connection: connection)) { _ in return Auth0Stubs.failure() } - stub(condition: databaseSignUp(email: email, username: username, password: password, connection: connection)) { _ in return Auth0Stubs.createdUser(email) } - } - - it("should only signup user") { - try! database.update(.email, value: email) - try! database.update(.username, value: username) - try! database.update(.password(enforcePolicy: false), value: password) - waitUntil(timeout: 2) { done in - database.create { create, login in - expect(create).to(beNil()) - expect(login).to(beNil()) - done() - } - } - } - - it("should dispatch signup event") { - try! database.update(.email, value: email) - try! database.update(.username, value: username) - try! database.update(.password(enforcePolicy: false), value: password) - database.create { _ in } - expect(newUserEmail).toEventually(equal(email)) - } - - } - describe("signup OIDC Conformnant") { beforeEach { @@ -1253,7 +1216,7 @@ class DatabaseInteractorSpec: QuickSpec { } } } - + it("should send parameters on login") { let state = UUID().uuidString var options = LockOptions() @@ -1272,7 +1235,7 @@ class DatabaseInteractorSpec: QuickSpec { } } } - + } } diff --git a/LockTests/Interactors/DatabasePasswordInteractorSpec.swift b/LockTests/Interactors/DatabasePasswordInteractorSpec.swift index 76b546ea5..c8c31d1b5 100644 --- a/LockTests/Interactors/DatabasePasswordInteractorSpec.swift +++ b/LockTests/Interactors/DatabasePasswordInteractorSpec.swift @@ -39,7 +39,7 @@ class DatabasePasswordInteractorSpec: QuickSpec { } describe("init") { - let database = DatabasePasswordInteractor(connections: OfflineConnections(), authentication: authentication, user: User()) + let database = DatabasePasswordInteractor(connections: OfflineConnections(), authentication: authentication, user: User(), dispatcher: ObserverStore()) it("should build with authentication") { expect(database).toNot(beNil()) @@ -54,12 +54,14 @@ class DatabasePasswordInteractorSpec: QuickSpec { var user: User! var connections: OfflineConnections! var forgot: DatabasePasswordInteractor! + var dispatcher: Dispatcher! beforeEach { + dispatcher = ObserverStore() connections = OfflineConnections() connections.database(name: connection, requiresUsername: true) user = User() - forgot = DatabasePasswordInteractor(connections: connections, authentication: authentication, user: user) + forgot = DatabasePasswordInteractor(connections: connections, authentication: authentication, user: user, dispatcher: dispatcher) } describe("updateEmail") { @@ -102,7 +104,7 @@ class DatabasePasswordInteractorSpec: QuickSpec { describe("request email") { it("should fail if no db connection is found") { - forgot = DatabasePasswordInteractor(connections: OfflineConnections(), authentication: authentication, user: user) + forgot = DatabasePasswordInteractor(connections: OfflineConnections(), authentication: authentication, user: user, dispatcher: dispatcher) try! forgot.updateEmail(email) waitUntil(timeout: 2) { done in forgot.requestEmail { error in @@ -142,8 +144,7 @@ class DatabasePasswordInteractorSpec: QuickSpec { } } } - } } - + } diff --git a/LockTests/Models/ObserverStoreSpec.swift b/LockTests/Models/ObserverStoreSpec.swift index 8c661c6ef..df440f932 100644 --- a/LockTests/Models/ObserverStoreSpec.swift +++ b/LockTests/Models/ObserverStoreSpec.swift @@ -49,6 +49,7 @@ class ObserverStoreSpec: QuickSpec { store.onAuth = { credentials = $0 } store.onCancel = { closed = true } store.onSignUp = { newEmail = $0; newAttributes = $1 } + store.onForgotPassword = { newEmail = $0 } dispatcher = store } @@ -74,9 +75,14 @@ class ObserverStoreSpec: QuickSpec { expect(newAttributes?["username"] as? String).toEventually(equal(username)) } + it("should disptach when user requests password") { + dispatcher.dispatch(result: .forgotPassword(email)) + expect(newEmail).toEventually(equal(email)) + } + + // TODO: Check why it fails only in travis pending("controller displayed") { - // TODO: Check why it fails only in travis var controller: MockLockController! var presenter: MockController! @@ -94,11 +100,69 @@ class ObserverStoreSpec: QuickSpec { expect(presenter.presented).toEventually(beNil(), timeout: 2) } + it("should not dismiss onAuth when autoclose disabled") { + let value = mockCredentials() + var options = LockOptions() + options.autoClose = false + dispatcher.options = options + dispatcher.dispatch(result: .auth(value)) + expect(presenter.presented).toEventuallyNot(beNil(), timeout: 2) + } + it("should dismiss onCancel") { dispatcher.dispatch(result: .cancel) expect(presenter.presented).toEventually(beNil(), timeout: 2) } + it("should not dismiss onSignUp") { + dispatcher.dispatch(result: .signUp(email, ["username": username])) + expect(newEmail).toEventually(equal(email)) + expect(presenter.presented).toEventuallyNot(beNil(), timeout: 2) + } + + it("should dismiss onSignUp when single screen") { + var options = LockOptions() + options.allow = [.Signup] + dispatcher.options = options + dispatcher.dispatch(result: .signUp(email, ["username": username])) + expect(newEmail).toEventually(equal(email)) + expect(presenter.presented).toEventually(beNil(), timeout: 2) + } + + it("should not dismiss onSignUp when single screen but autoclose disabled") { + var options = LockOptions() + options.allow = [.Signup] + options.autoClose = false + dispatcher.options = options + dispatcher.dispatch(result: .signUp(email, ["username": username])) + expect(newEmail).toEventually(equal(email)) + expect(presenter.presented).toEventuallyNot(beNil(), timeout: 2) + } + + it("should not dismiss forgotPassword") { + dispatcher.dispatch(result: .forgotPassword(email)) + expect(presenter.presented).toEventuallyNot(beNil(), timeout: 2) + } + + it("should dismiss forgotPassword when single screen") { + var options = LockOptions() + options.allow = [.ResetPassword] + dispatcher.options = options + dispatcher.dispatch(result: .forgotPassword(email)) + expect(newEmail).toEventually(equal(email)) + expect(presenter.presented).toEventually(beNil(), timeout: 2) + } + + it("should not dismiss forgotPassword when single screen but autoclose disabled") { + var options = LockOptions() + options.allow = [.ResetPassword] + options.autoClose = false + dispatcher.options = options + dispatcher.dispatch(result: .forgotPassword(email)) + expect(newEmail).toEventually(equal(email)) + expect(presenter.presented).toEventuallyNot(beNil(), timeout: 2) + } + } } } diff --git a/LockTests/OptionsSpec.swift b/LockTests/OptionsSpec.swift index 94caec5ab..30d3f174a 100644 --- a/LockTests/OptionsSpec.swift +++ b/LockTests/OptionsSpec.swift @@ -88,6 +88,10 @@ class OptionsSpec: QuickSpec { it("should have no audience") { expect(options.audience).to(beNil()) } + + it("should be auto closeable") { + expect(options.autoClose) == true + } } describe("validation") { @@ -124,6 +128,30 @@ class OptionsSpec: QuickSpec { expect(options.validate()).toNot(beNil()) } + context("auto close") { + + it("should fail when autoclose is empty and no .Login allowed") { + options.autoClose = false + options.allow = [.Signup, .ResetPassword] + expect(options.validate()).toNot(beNil()) + } + + it("should fail autoclose disabled and single screen") { + options.autoClose = false + options.allow = [.ResetPassword] + expect(options.validate()).toNot(beNil()) + } + + it("should pass when autoclose empty, no login, but closeable set") { + options.closable = true + options.autoClose = false + options.allow = [.Signup, .ResetPassword] + expect(options.validate()).to(beNil()) + } + + } + + } describe("builder") { diff --git a/LockTests/Presenters/DatabaseForgotPasswordPresenterSpec.swift b/LockTests/Presenters/DatabaseForgotPasswordPresenterSpec.swift index a60e8bf50..3364017bf 100644 --- a/LockTests/Presenters/DatabaseForgotPasswordPresenterSpec.swift +++ b/LockTests/Presenters/DatabaseForgotPasswordPresenterSpec.swift @@ -194,6 +194,40 @@ class DatabaseForgotPasswordPresenterSpec: QuickSpec { expect(button.inProgress).toEventually(beFalse()) } + context("no login screen") { + + beforeEach { + options.allow = .ResetPassword + presenter = DatabaseForgotPasswordPresenter(interactor: interactor, connections: connections, navigator: navigator, options: options) + presenter.messagePresenter = messagePresenter + view = presenter.view as! DatabaseForgotPasswordView + } + + it("should not show global success message") { + interactor.onRequest = { + return nil + } + view.primaryButton?.onPress(view.primaryButton!) + expect(messagePresenter.message).toEventually(beNil()) + } + + it("should show global success message") { + options.allow = .ResetPassword + options.autoClose = false + presenter = DatabaseForgotPasswordPresenter(interactor: interactor, connections: connections, navigator: navigator, options: options) + presenter.messagePresenter = messagePresenter + view = presenter.view as! DatabaseForgotPasswordView + + interactor.onRequest = { + return nil + } + view.primaryButton?.onPress(view.primaryButton!) + expect(messagePresenter.message).toEventuallyNot(beNil()) + } + + } + + } describe("navigation on success") { diff --git a/LockTests/Presenters/DatabasePresenterSpec.swift b/LockTests/Presenters/DatabasePresenterSpec.swift index fd5871903..ac90902fa 100644 --- a/LockTests/Presenters/DatabasePresenterSpec.swift +++ b/LockTests/Presenters/DatabasePresenterSpec.swift @@ -307,7 +307,16 @@ class DatabasePresenterSpec: QuickSpec { view.primaryButton?.onPress(view.primaryButton!) expect(messagePresenter.error).toEventually(beError(error: DatabaseAuthenticatableError.couldNotLogin)) } - + + it("should show no success message") { + interactor.onLogin = { + return nil + } + view.primaryButton?.onPress(view.primaryButton!) + expect(messagePresenter.error).toEventually(beNil()) + expect(messagePresenter.message).toEventually(beNil()) + } + it("should navigate to multifactor required screen") { interactor.onLogin = { return .multifactorRequired @@ -349,6 +358,20 @@ class DatabasePresenterSpec: QuickSpec { button.onPress(button) expect(navigator.route).toEventually(equal(Route.forgotPassword)) } + + it("should always show terms button in signup") { + var options = LockOptions() + options.autoClose = false + presenter = DatabasePresenter(authenticator: interactor, creator: interactor, connection: DatabaseConnection(name: connection, requiresUsername: true), navigator: navigator, options: options) + presenter.messagePresenter = messagePresenter + view = presenter.view as! DatabaseOnlyView + interactor.onLogin = { + return nil + } + view.primaryButton?.onPress(view.primaryButton!) + expect(messagePresenter.error).toEventually(beNil()) + expect(messagePresenter.message).toEventuallyNot(beNil()) + } } } @@ -471,6 +494,14 @@ class DatabasePresenterSpec: QuickSpec { expect(messagePresenter.error).toEventually(beNil()) expect(messagePresenter.message).toEventually(beNil()) } + + it("should show no success message") { + interactor.onSignUp = { + return nil + } + view.primaryButton?.onPress(view.primaryButton!) + expect(messagePresenter.message).toEventually(beNil()) + } it("should show global error message") { interactor.onSignUp = { @@ -555,7 +586,26 @@ class DatabasePresenterSpec: QuickSpec { expect(button.title).toEventually(contain("Sign up")) } + context("no auto login or auto close") { + beforeEach { + options.loginAfterSignup = false + options.allow = [.Signup] + options.autoClose = false + presenter = DatabasePresenter(authenticator: interactor, creator: interactor, connection: DatabaseConnection(name: connection, requiresUsername: true), navigator: navigator, options: options) + presenter.messagePresenter = messagePresenter + view = presenter.view as! DatabaseOnlyView + } + + it("should show no success message") { + interactor.onSignUp = { + return nil + } + view.primaryButton?.onPress(view.primaryButton!) + expect(messagePresenter.error).toEventually(beNil()) + expect(messagePresenter.message).toEventuallyNot(beNil()) + } + } } }