Skip to content

Commit

Permalink
Refactored ObserverStore dismissLock management
Browse files Browse the repository at this point in the history
Updated Tests
  • Loading branch information
cocojoe committed Jan 16, 2017
1 parent 5a4228c commit 267103a
Show file tree
Hide file tree
Showing 12 changed files with 58 additions and 33 deletions.
2 changes: 1 addition & 1 deletion Lock.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,7 @@
5BCDE1341DDDF12100AA2A6C /* EnterpriseActiveAuthPresenterSpec.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EnterpriseActiveAuthPresenterSpec.swift; sourceTree = "<group>"; };
5BCED4C51DD1FCF200E2CE8A /* EnterpriseDomainPresenterSpec.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EnterpriseDomainPresenterSpec.swift; sourceTree = "<group>"; };
5F0FCF8F1E20117E00E3D53B /* ObserverStore.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ObserverStore.swift; sourceTree = "<group>"; };
5F0FCF911E201CF300E3D53B /* ObserverStoreSpec.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ObserverStoreSpec.swift; sourceTree = "<group>"; };
5F0FCF911E201CF300E3D53B /* ObserverStoreSpec.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = ObserverStoreSpec.swift; sourceTree = "<group>"; 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; };
Expand Down
2 changes: 1 addition & 1 deletion Lock/Auth0OAuth2Interactor.swift
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ struct Auth0OAuth2Interactor: OAuth2Authenticatable {
.start { result in
switch result {
case .success(let credentials):
self.dispatcher.dispatch(result: .auth(credentials), dismissLock: true)
self.dispatcher.dispatch(result: .auth(credentials))
callback(nil)
case .failure(WebAuthError.userCancelled):
callback(.cancelled)
Expand Down
4 changes: 2 additions & 2 deletions Lock/DatabaseInteractor.swift
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ struct DatabaseInteractor: DatabaseAuthenticatable, DatabaseUserCreator, Loggabl
"verified": user.verified
]
extra["username"] = user.username
self.dispatcher.dispatch(result: .signUp(user.email, extra), dismissLock: !self.options.allow.contains(.Login) && self.options.autoClose.contains(.Signup))
self.dispatcher.dispatch(result: .signUp(user.email, extra))
callback(nil, nil)
}
case .failure(let cause as AuthenticationError) where cause.isPasswordNotStrongEnough:
Expand Down Expand Up @@ -204,7 +204,7 @@ struct DatabaseInteractor: DatabaseAuthenticatable, DatabaseUserCreator, Loggabl
case .success(let credentials):
self.logger.info("Authenticated user <\(self.identifier)>")
callback(nil)
self.dispatcher.dispatch(result: .auth(credentials), dismissLock: true)
self.dispatcher.dispatch(result: .auth(credentials))
}
}
}
2 changes: 1 addition & 1 deletion Lock/DatabasePasswordInteractor.swift
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ struct DatabasePasswordInteractor: PasswordRecoverable {
.resetPassword(email: email, connection: connection)
.start {
guard case .success = $0 else { return callback(.emailNotSent) }
self.dispatcher.dispatch(result: .forgotPassword(email), dismissLock: !self.options.allow.contains(.Login) && self.options.autoClose.contains(.ResetPassword))
self.dispatcher.dispatch(result: .forgotPassword(email))
callback(nil)
}
}
Expand Down
2 changes: 1 addition & 1 deletion Lock/EnterpriseActiveAuthInteractor.swift
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ struct EnterpriseActiveAuthInteractor: DatabaseAuthenticatable, Loggable {
case .success(let credentials):
self.logger.info("Authenticated user <\(self.identifier)>")
callback(nil)
self.dispatcher.dispatch(result: .auth(credentials), dismissLock: true)
self.dispatcher.dispatch(result: .auth(credentials))
}
}

Expand Down
3 changes: 2 additions & 1 deletion Lock/Lock.swift
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ public class Lock: NSObject {
var optionsBuilder: OptionBuildable = LockOptions()
var options: Options { return self.optionsBuilder }

var observerStore = ObserverStore()
var observerStore = ObserverStore(options: LockOptions())

var style: Style = Style()

Expand Down Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion Lock/LockViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ public class LockViewController: UIViewController {

header.showClose = self.router.lock.options.closable
header.onClosePressed = { [weak self] in
self?.router.lock.observerStore.dispatch(result: .cancel, dismissLock: true)
self?.router.lock.observerStore.dispatch(result: .cancel)
}
header.apply(style: style)

Expand Down
2 changes: 1 addition & 1 deletion Lock/MultifactorInteractor.swift
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ struct MultifactorInteractor: MultifactorAuthenticatable {
callback(.couldNotLogin)
case .success(let credentials):
callback(nil)
self.dispatcher.dispatch(result: .auth(credentials), dismissLock: true)
self.dispatcher.dispatch(result: .auth(credentials))
}
}
}
Expand Down
19 changes: 15 additions & 4 deletions Lock/ObserverStore.swift
Original file line number Diff line number Diff line change
Expand Up @@ -28,23 +28,34 @@ struct ObserverStore: Dispatcher {
var onFailure: (Error) -> () = { _ in }
var onCancel: () -> () = { }
var onSignUp: (String, [String: Any]) -> () = { _ in }
var onForgetPassword: (String) -> () = { _ in }
var onForgotPassword: (String) -> () = { _ in }
var options: Options

weak var controller: UIViewController?

func dispatch(result: Result, dismissLock: Bool) {
init(options: Options = LockOptions()) {
self.options = options
}

func dispatch(result: Result) {
let dismissLock: Bool
let closure: () -> ()
switch result {
case .auth(let credentials):
dismissLock = true
closure = { self.onAuth(credentials) }
case .error(let error):
dismissLock = false
closure = { self.onFailure(error) }
case .cancel:
dismissLock = true
closure = { self.onCancel() }
case .signUp(let email, let attributes):
dismissLock = !self.options.allow.contains(.Login) && self.options.autoClose.contains(.Signup)
closure = { self.onSignUp(email, attributes) }
case .forgotPassword(let email):
closure = { self.onForgetPassword(email) }
dismissLock = !self.options.allow.contains(.Login) && self.options.autoClose.contains(.ResetPassword)
closure = { self.onForgotPassword(email) }
}

Queue.main.async(dismissLock ? dismiss(from: controller?.presentingViewController, completion: closure) : closure)
Expand All @@ -65,5 +76,5 @@ enum Result {
}

protocol Dispatcher {
func dispatch(result: Result, dismissLock: Bool)
func dispatch(result: Result)
}
17 changes: 13 additions & 4 deletions LockTests/Interactors/DatabaseInteractorSpec.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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") {
Expand Down Expand Up @@ -561,7 +568,7 @@ class DatabaseInteractorSpec: QuickSpec {
}

// TODO: Check why it fails only in travis
describe("login dispatch") {
pending("login dispatch") {

var options: LockOptions!
var auth: Credentials?
Expand Down Expand Up @@ -1119,6 +1126,7 @@ class DatabaseInteractorSpec: QuickSpec {

it("should dispatch signup event and dimiss Lock") {
options.allow = .Signup
dispatcher.options = options
database = DatabaseInteractor(connection: db, authentication: authentication, user: user, options: options, dispatcher: dispatcher)
try! database.update(.email, value: email)
try! database.update(.username, value: username)
Expand All @@ -1130,6 +1138,7 @@ class DatabaseInteractorSpec: QuickSpec {

it("should dispatch signup event and dimiss Lock") {
options.allow = [.Signup, .ResetPassword]
dispatcher.options = options
database = DatabaseInteractor(connection: db, authentication: authentication, user: user, options: options, dispatcher: dispatcher)
try! database.update(.email, value: email)
try! database.update(.username, value: username)
Expand Down
8 changes: 6 additions & 2 deletions LockTests/Interactors/DatabasePasswordInteractorSpec.swift
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,7 @@ class DatabasePasswordInteractorSpec: QuickSpec {
var dispatcher: ObserverStore!

beforeEach {
options = LockOptions()
dispatcher = ObserverStore()
presenter = MockController()
controller = MockLockController(lock: Lock())
Expand All @@ -164,8 +165,7 @@ class DatabasePasswordInteractorSpec: QuickSpec {
dispatcher.controller = controller

userEmail = nil
options = LockOptions()
dispatcher.onForgetPassword = { email in
dispatcher.onForgotPassword = { email in
userEmail = email
}
forgot = DatabasePasswordInteractor(connections: connections, authentication: authentication, user: user, options: options, dispatcher: dispatcher)
Expand All @@ -183,6 +183,7 @@ class DatabasePasswordInteractorSpec: QuickSpec {

it("should dispatch forgotPassword event and dismiss lock") {
options.allow = .ResetPassword
dispatcher.options = options
forgot = DatabasePasswordInteractor(connections: connections, authentication: authentication, user: user, options: options, dispatcher: dispatcher)

try! forgot.updateEmail(email)
Expand All @@ -193,6 +194,7 @@ class DatabasePasswordInteractorSpec: QuickSpec {

it("should dispatch forgotPassword event and dismiss lock") {
options.allow = [.ResetPassword, .Signup]
dispatcher.options = options
forgot = DatabasePasswordInteractor(connections: connections, authentication: authentication, user: user, options: options, dispatcher: dispatcher)

try! forgot.updateEmail(email)
Expand All @@ -205,6 +207,7 @@ class DatabasePasswordInteractorSpec: QuickSpec {

it("should dispatch forgotPassword and stay on screen") {
options.autoClose = []
dispatcher.options = options
forgot = DatabasePasswordInteractor(connections: connections, authentication: authentication, user: user, options: options, dispatcher: dispatcher)

try! forgot.updateEmail(email)
Expand All @@ -216,6 +219,7 @@ class DatabasePasswordInteractorSpec: QuickSpec {
it("should dispatch forgotPassword event and stay on screen") {
options.allow = [.ResetPassword]
options.autoClose = []
dispatcher.options = options
forgot = DatabasePasswordInteractor(connections: connections, authentication: authentication, user: user, options: options, dispatcher: dispatcher)

try! forgot.updateEmail(email)
Expand Down
28 changes: 14 additions & 14 deletions LockTests/Models/ObserverStoreSpec.swift
Original file line number Diff line number Diff line change
Expand Up @@ -49,34 +49,34 @@ class ObserverStoreSpec: QuickSpec {
store.onAuth = { credentials = $0 }
store.onCancel = { closed = true }
store.onSignUp = { newEmail = $0; newAttributes = $1 }
store.onForgetPassword = { newEmail = $0 }
store.onForgotPassword = { newEmail = $0 }
dispatcher = store
}

it("should dispatch errors") {
dispatcher.dispatch(result: .error(UnrecoverableError.invalidClientOrDomain), dismissLock: false)
dispatcher.dispatch(result: .error(UnrecoverableError.invalidClientOrDomain))
expect(error).toEventuallyNot(beNil())
}

it("should dispatch credentials") {
let value = mockCredentials()
dispatcher.dispatch(result: .auth(value), dismissLock: false)
dispatcher.dispatch(result: .auth(value))
expect(credentials).toEventually(equal(value))
}

it("should dispatch when lock is dismissed") {
dispatcher.dispatch(result: .cancel, dismissLock: false)
dispatcher.dispatch(result: .cancel)
expect(closed).toEventually(beTrue())
}

it("should disptach when user signs up") {
dispatcher.dispatch(result: .signUp(email, ["username": username]), dismissLock: false)
dispatcher.dispatch(result: .signUp(email, ["username": username]))
expect(newEmail).toEventually(equal(email))
expect(newAttributes?["username"] as? String).toEventually(equal(username))
}

it("should disptach when user requests password") {
dispatcher.dispatch(result: .forgotPassword(email), dismissLock: false)
dispatcher.dispatch(result: .forgotPassword(email))
expect(newEmail).toEventually(equal(email))
}

Expand All @@ -96,24 +96,24 @@ class ObserverStoreSpec: QuickSpec {

it("should dismiss onAuth") {
let value = mockCredentials()
dispatcher.dispatch(result: .auth(value), dismissLock: true)
dispatcher.dispatch(result: .auth(value))
expect(presenter.presented).toEventually(beNil(), timeout: 2)
}

it("should dismiss onCancel") {
dispatcher.dispatch(result: .cancel, dismissLock: true)
dispatcher.dispatch(result: .cancel)
expect(presenter.presented).toEventually(beNil(), timeout: 2)
}

it("should dismiss onSignUp") {
dispatcher.dispatch(result: .signUp(email, ["username": username]), dismissLock: true)
it("should not dismiss onSignUp") {
dispatcher.dispatch(result: .signUp(email, ["username": username]))
expect(newEmail).toEventually(equal(email))
expect(presenter.presented).toEventually(beNil(), timeout: 2)
expect(presenter.presented).toEventuallyNot(beNil(), timeout: 2)
}

it("should dismiss forgotPassword") {
dispatcher.dispatch(result: .forgotPassword(email), dismissLock: true)
expect(presenter.presented).toEventually(beNil(), timeout: 2)
it("should not dismiss forgotPassword") {
dispatcher.dispatch(result: .forgotPassword(email))
expect(presenter.presented).toEventuallyNot(beNil(), timeout: 2)
}
}
}
Expand Down

0 comments on commit 267103a

Please sign in to comment.