From 1273f544a96280aab8c0f97cf96cf20bbdb08734 Mon Sep 17 00:00:00 2001 From: Hernan Zalazar Date: Fri, 3 Feb 2017 17:00:22 -0300 Subject: [PATCH 1/3] Bring back commented out expect in tests --- .../Interactors/CDNLoaderInteractorSpec.swift | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/LockTests/Interactors/CDNLoaderInteractorSpec.swift b/LockTests/Interactors/CDNLoaderInteractorSpec.swift index 99c312332..a1381987f 100644 --- a/LockTests/Interactors/CDNLoaderInteractorSpec.swift +++ b/LockTests/Interactors/CDNLoaderInteractorSpec.swift @@ -104,7 +104,7 @@ class CDNLoaderInteractorSpec: QuickSpec { } } - context("remote connectin errors") { + context("remote connection errors") { it("should return invalid client error") { stub(condition: isCDN(forClientId: clientId)) { _ in OHHTTPStubsResponse(data: Data(), statusCode: 403, headers: [:]) } @@ -250,7 +250,7 @@ class CDNLoaderInteractorSpec: QuickSpec { stub(condition: isCDN(forClientId: clientId)) { _ in return Auth0Stubs.strategiesFromCDN([mockStrategy("facebook", connections: [mockOAuth2("facebook1"), mockOAuth2("facebook2")])]) } loader.load(callback) expect(connections?.oauth2).toEventuallyNot(beNil()) - //expect(connections?.oauth2.count).toEventually(be(2)) + expect(connections?.oauth2.count).toEventually(equal(2)) expect(connections?.oauth2[0].name) == "facebook1" expect(connections?.oauth2[1].name) == "facebook2" } @@ -277,7 +277,7 @@ class CDNLoaderInteractorSpec: QuickSpec { )]) } loader.load(callback) expect(connections?.enterprise).toEventuallyNot(beNil()) - //expect(connections?.enterprise.count).toEventually(be(2)) + expect(connections?.enterprise.count).toEventually(equal(2)) expect(connections?.enterprise[0].name) == "TestAD" expect(connections?.enterprise[1].name) == "fakeAD" } @@ -293,7 +293,7 @@ class CDNLoaderInteractorSpec: QuickSpec { expect(connections?.database?.name).toEventually(equal(databaseConnection)) expect(connections?.enterprise).toEventuallyNot(beNil()) - //expect(connections?.enterprise.count).toEventually(be(2)) + expect(connections?.enterprise.count).toEventually(equal(2)) expect(connections?.enterprise[0].name) == "TestAD" expect(connections?.enterprise[1].name) == "fakeAD" } @@ -309,12 +309,12 @@ class CDNLoaderInteractorSpec: QuickSpec { )]) } loader.load(callback) expect(connections?.oauth2).toEventuallyNot(beNil()) - //expect(connections?.oauth2.count).toEventually(be(2)) + expect(connections?.oauth2.count).toEventually(equal(2)) expect(connections?.oauth2[0].name) == "facebook1" expect(connections?.oauth2[1].name) == "facebook2" expect(connections?.enterprise).toEventuallyNot(beNil()) - //expect(connections?.enterprise.count).toEventually(be(2)) + expect(connections?.enterprise.count).toEventually(equal(2)) expect(connections?.enterprise[0].name) == "TestAD" expect(connections?.enterprise[1].name) == "fakeAD" } @@ -333,12 +333,12 @@ class CDNLoaderInteractorSpec: QuickSpec { expect(connections?.database?.name).toEventually(equal(databaseConnection)) expect(connections?.oauth2).toEventuallyNot(beNil()) - //expect(connections?.oauth2.count).toEventually(be(2)) + expect(connections?.oauth2.count).toEventually(equal(2)) expect(connections?.oauth2[0].name) == "facebook1" expect(connections?.oauth2[1].name) == "facebook2" expect(connections?.enterprise).toEventuallyNot(beNil()) - //expect(connections?.enterprise.count).toEventually(be(2)) + expect(connections?.enterprise.count).toEventually(equal(2)) expect(connections?.enterprise[0].name) == "TestAD" expect(connections?.enterprise[1].name) == "fakeAD" } From 4dc77839c3d7184b176a2831a7bd60a0bc4271cd Mon Sep 17 00:00:00 2001 From: Hernan Zalazar Date: Fri, 3 Feb 2017 17:09:02 -0300 Subject: [PATCH 2/3] Add a couple more tests for enterprise connections --- .../Interactors/CDNLoaderInteractorSpec.swift | 42 +++++++++++++++---- 1 file changed, 35 insertions(+), 7 deletions(-) diff --git a/LockTests/Interactors/CDNLoaderInteractorSpec.swift b/LockTests/Interactors/CDNLoaderInteractorSpec.swift index a1381987f..b8fb33d18 100644 --- a/LockTests/Interactors/CDNLoaderInteractorSpec.swift +++ b/LockTests/Interactors/CDNLoaderInteractorSpec.swift @@ -269,19 +269,47 @@ class CDNLoaderInteractorSpec: QuickSpec { // MARK: Enterprise - it("should load enterprise connections") { + it("should load single enterprise connections") { + stub(condition: isCDN(forClientId: clientId)) { _ in + return Auth0Stubs.strategiesFromCDN([ + mockStrategy("ad", connections: [ mockEntepriseConnection("TestAD", domain: ["test.com"]) ]) + ]) + } + loader.load(callback) + expect(connections?.enterprise).toEventually(haveCount(1)) + expect(connections?.enterprise.first?.name) == "TestAD" + expect(connections?.enterprise.first?.domains) == ["test.com"] + } + + it("should load multiple ad enterprise connections") { stub(condition: isCDN(forClientId: clientId)) { _ in return Auth0Stubs.strategiesFromCDN([ - mockStrategy("ad", connections: [ - mockEntepriseConnection("TestAD", domain: ["test.com"]), - mockEntepriseConnection("fakeAD", domain: ["fake.com"])] - )]) } + mockStrategy("ad", connections: [ + mockEntepriseConnection("TestAD", domain: ["test.com"]), + mockEntepriseConnection("fakeAD", domain: ["fake.com"])] + )]) } loader.load(callback) - expect(connections?.enterprise).toEventuallyNot(beNil()) - expect(connections?.enterprise.count).toEventually(equal(2)) + expect(connections?.enterprise).toEventually(haveCount(2)) expect(connections?.enterprise[0].name) == "TestAD" expect(connections?.enterprise[1].name) == "fakeAD" } + it("should load multiple enterprise connections") { + stub(condition: isCDN(forClientId: clientId)) { _ in + return Auth0Stubs.strategiesFromCDN([ + mockStrategy("ad", connections: [ + mockEntepriseConnection("fakeAD", domain: ["fake.com"])] + ), + mockStrategy("samlp", connections: [ + mockEntepriseConnection("fakeSAML", domain: ["false.com"])] + ) + ]) + } + loader.load(callback) + expect(connections?.enterprise).toEventually(haveCount(2)) + expect(connections?.enterprise[0].name) == "fakeAD" + expect(connections?.enterprise[1].name) == "fakeSAML" + } + it("should load database & enterprise connections") { stub(condition: isCDN(forClientId: clientId)) { _ in return Auth0Stubs.strategiesFromCDN([ mockStrategy("auth0", connections: [mockDatabaseConnection(name: databaseConnection)]), From bd2a51a6b44a4f67b2cd520fb4f0339284ea5325 Mon Sep 17 00:00:00 2001 From: Hernan Zalazar Date: Fri, 3 Feb 2017 18:04:43 -0300 Subject: [PATCH 3/3] Avoid crashing when when enterprise lacks domain --- App/ViewController.swift | 3 +- Lock/CDNLoaderInteractor.swift | 4 +- .../Interactors/CDNLoaderInteractorSpec.swift | 69 ++++++++++++------- 3 files changed, 46 insertions(+), 30 deletions(-) diff --git a/App/ViewController.swift b/App/ViewController.swift index 99948f570..848e993ba 100644 --- a/App/ViewController.swift +++ b/App/ViewController.swift @@ -40,7 +40,7 @@ class ViewController: UIViewController { header.leftAnchor.constraint(equalTo: view.leftAnchor), header.topAnchor.constraint(equalTo: view.topAnchor), header.rightAnchor.constraint(equalTo: view.rightAnchor), - header.heightAnchor.constraint(equalToConstant: 154), + header.heightAnchor.constraint(equalToConstant: 154) ]) header.translatesAutoresizingMaskIntoConstraints = false @@ -48,7 +48,6 @@ class ViewController: UIViewController { actionButton(withTitle: "LOGIN WITH CDN") { return Lock .classic() - .allowedConnections(["contoso-ad", "fake-saml", "facebook", "google-oauth2"]) .withOptions { applyDefaultOptions(&$0) $0.loginAfterSignup = false diff --git a/Lock/CDNLoaderInteractor.swift b/Lock/CDNLoaderInteractor.swift index 68bacdc20..37dd8f0c5 100644 --- a/Lock/CDNLoaderInteractor.swift +++ b/Lock/CDNLoaderInteractor.swift @@ -87,9 +87,9 @@ struct CDNLoaderInteractor: RemoteConnectionLoader, Loggable { } info.enterprise.forEach { strategy in strategy.connections.forEach { connection in - let domains = connection.json["domain_aliases"] as! [String] + let domains = connection.json["domain_aliases"] as? [String] ?? [] let template = AuthStyle.style(forStrategy: strategy.name, connectionName: connection.name) - let style = AuthStyle(name: domains.first!, color: template.normalColor, withImage: template.image) + let style = AuthStyle(name: domains.first ?? strategy.name, color: template.normalColor, withImage: template.image) connections.enterprise(name: connection.name, domains: domains, style: style) } } diff --git a/LockTests/Interactors/CDNLoaderInteractorSpec.swift b/LockTests/Interactors/CDNLoaderInteractorSpec.swift index b8fb33d18..847d5e104 100644 --- a/LockTests/Interactors/CDNLoaderInteractorSpec.swift +++ b/LockTests/Interactors/CDNLoaderInteractorSpec.swift @@ -161,7 +161,7 @@ class CDNLoaderInteractorSpec: QuickSpec { } it("should load single database connection") { - stub(condition: isCDN(forClientId: clientId)) { _ in return Auth0Stubs.strategiesFromCDN([mockStrategy("auth0", connections: [mockDatabaseConnection(name: databaseConnection)])]) } + stub(condition: isCDN(forClientId: clientId)) { _ in return Auth0Stubs.strategiesFromCDN([mockStrategy("auth0", connections: [mockDatabase(name: databaseConnection)])]) } loader.load(callback) expect(connections?.database).toEventuallyNot(beNil()) expect(connections?.database?.name).toEventually(equal(databaseConnection)) @@ -169,27 +169,27 @@ class CDNLoaderInteractorSpec: QuickSpec { } it("should load single database connection with no pwd policy") { - stub(condition: isCDN(forClientId: clientId)) { _ in return Auth0Stubs.strategiesFromCDN([mockStrategy("auth0", connections: [mockDatabaseConnection(name: databaseConnection)])]) } + stub(condition: isCDN(forClientId: clientId)) { _ in return Auth0Stubs.strategiesFromCDN([mockStrategy("auth0", connections: [mockDatabase(name: databaseConnection)])]) } loader.load(callback) expect(connections?.database?.passwordValidator.policy.name).toEventually(equal("none")) } it("should load single database connection with unknown pwd policy") { - stub(condition: isCDN(forClientId: clientId)) { _ in return Auth0Stubs.strategiesFromCDN([mockStrategy("auth0", connections: [mockDatabaseConnection(name: databaseConnection, passwordPolicy: "random")])]) } + stub(condition: isCDN(forClientId: clientId)) { _ in return Auth0Stubs.strategiesFromCDN([mockStrategy("auth0", connections: [mockDatabase(name: databaseConnection, passwordPolicy: "random")])]) } loader.load(callback) expect(connections?.database?.passwordValidator.policy.name).toEventually(equal("none")) } ["none", "low", "fair", "good", "excellent"].forEach { name in it("should load single database connection with policy \(name))") { - stub(condition: isCDN(forClientId: clientId)) { _ in return Auth0Stubs.strategiesFromCDN([mockStrategy("auth0", connections: [mockDatabaseConnection(name: databaseConnection, passwordPolicy: name)])]) } + stub(condition: isCDN(forClientId: clientId)) { _ in return Auth0Stubs.strategiesFromCDN([mockStrategy("auth0", connections: [mockDatabase(name: databaseConnection, passwordPolicy: name)])]) } loader.load(callback) expect(connections?.database?.passwordValidator.policy.name).toEventually(equal(name)) } } it("should load single database connection with custom username validation") { - stub(condition: isCDN(forClientId: clientId)) { _ in return Auth0Stubs.strategiesFromCDN([mockStrategy("auth0", connections: [mockDatabaseConnection(name: databaseConnection, validation: (["username": ["min": 10, "max": 200]] as Any) as! JSONObject )])]) } + stub(condition: isCDN(forClientId: clientId)) { _ in return Auth0Stubs.strategiesFromCDN([mockStrategy("auth0", connections: [mockDatabase(name: databaseConnection, validation: (["username": ["min": 10, "max": 200]] as Any) as! JSONObject )])]) } loader.load(callback) expect(connections?.database).toEventuallyNot(beNil()) expect(connections?.database?.name).toEventually(equal(databaseConnection)) @@ -200,7 +200,7 @@ class CDNLoaderInteractorSpec: QuickSpec { } it("should load single database connection with custom username validation with strings") { - stub(condition: isCDN(forClientId: clientId)) { _ in return Auth0Stubs.strategiesFromCDN([mockStrategy("auth0", connections: [mockDatabaseConnection(name: databaseConnection, validation: (["username": ["min": "9", "max": "100"]] as Any) as! JSONObject)])]) } + stub(condition: isCDN(forClientId: clientId)) { _ in return Auth0Stubs.strategiesFromCDN([mockStrategy("auth0", connections: [mockDatabase(name: databaseConnection, validation: (["username": ["min": "9", "max": "100"]] as Any) as! JSONObject)])]) } loader.load(callback) expect(connections?.database).toEventuallyNot(beNil()) expect(connections?.database?.name).toEventually(equal(databaseConnection)) @@ -211,14 +211,14 @@ class CDNLoaderInteractorSpec: QuickSpec { } it("should load multiple database connections but pick the first") { - stub(condition: isCDN(forClientId: clientId)) { _ in return Auth0Stubs.strategiesFromCDN([mockStrategy("auth0", connections: [mockDatabaseConnection(name: databaseConnection), mockDatabaseConnection(name: "another one")])]) } + stub(condition: isCDN(forClientId: clientId)) { _ in return Auth0Stubs.strategiesFromCDN([mockStrategy("auth0", connections: [mockDatabase(name: databaseConnection), mockDatabase(name: "another one")])]) } loader.load(callback) expect(connections?.database).toEventuallyNot(beNil()) expect(connections?.database?.name).toEventually(equal(databaseConnection)) } it("should load single database connection with requires_username") { - stub(condition: isCDN(forClientId: clientId)) { _ in return Auth0Stubs.strategiesFromCDN([mockStrategy("auth0", connections: [mockDatabaseConnection(name: databaseConnection, requiresUsername: true)])]) } + stub(condition: isCDN(forClientId: clientId)) { _ in return Auth0Stubs.strategiesFromCDN([mockStrategy("auth0", connections: [mockDatabase(name: databaseConnection, requiresUsername: true)])]) } loader.load(callback) expect(connections?.database).toEventuallyNot(beNil()) expect(connections?.database?.name).toEventually(equal(databaseConnection)) @@ -258,7 +258,7 @@ class CDNLoaderInteractorSpec: QuickSpec { it("should load database & oauth2 connection") { stub(condition: isCDN(forClientId: clientId)) { _ in return Auth0Stubs.strategiesFromCDN([ - mockStrategy("auth0", connections: [mockDatabaseConnection(name: databaseConnection)]), + mockStrategy("auth0", connections: [mockDatabase(name: databaseConnection)]), mockStrategy("facebook", connections: [mockOAuth2("facebook")]) ]) } @@ -269,23 +269,37 @@ class CDNLoaderInteractorSpec: QuickSpec { // MARK: Enterprise - it("should load single enterprise connections") { + it("should load single enterprise connection") { stub(condition: isCDN(forClientId: clientId)) { _ in return Auth0Stubs.strategiesFromCDN([ - mockStrategy("ad", connections: [ mockEntepriseConnection("TestAD", domain: ["test.com"]) ]) + mockStrategy("ad", connections: [mockEnterprise(name: "TestAD", domains: ["test.com"]) ]) ]) } loader.load(callback) expect(connections?.enterprise).toEventually(haveCount(1)) expect(connections?.enterprise.first?.name) == "TestAD" expect(connections?.enterprise.first?.domains) == ["test.com"] + expect(connections?.enterprise.first?.style.name) == "test.com" + } + + it("should load single enterprise connection with no domain") { + stub(condition: isCDN(forClientId: clientId)) { _ in + return Auth0Stubs.strategiesFromCDN([ + mockStrategy("ad", connections: [mockEnterprise(name: "TestAD", domains: []) ]) + ]) + } + loader.load(callback) + expect(connections?.enterprise).toEventually(haveCount(1)) + expect(connections?.enterprise.first?.name) == "TestAD" + expect(connections?.enterprise.first?.domains).toEventually(beEmpty()) + expect(connections?.enterprise.first?.style.name) == "ad" } it("should load multiple ad enterprise connections") { stub(condition: isCDN(forClientId: clientId)) { _ in return Auth0Stubs.strategiesFromCDN([ mockStrategy("ad", connections: [ - mockEntepriseConnection("TestAD", domain: ["test.com"]), - mockEntepriseConnection("fakeAD", domain: ["fake.com"])] + mockEnterprise(name: "TestAD", domains: ["test.com"]), + mockEnterprise(name: "fakeAD", domains: ["fake.com"])] )]) } loader.load(callback) expect(connections?.enterprise).toEventually(haveCount(2)) @@ -297,10 +311,10 @@ class CDNLoaderInteractorSpec: QuickSpec { stub(condition: isCDN(forClientId: clientId)) { _ in return Auth0Stubs.strategiesFromCDN([ mockStrategy("ad", connections: [ - mockEntepriseConnection("fakeAD", domain: ["fake.com"])] + mockEnterprise(name: "fakeAD", domains: ["fake.com"])] ), mockStrategy("samlp", connections: [ - mockEntepriseConnection("fakeSAML", domain: ["false.com"])] + mockEnterprise(name: "fakeSAML", domains: ["false.com"])] ) ]) } @@ -312,10 +326,10 @@ class CDNLoaderInteractorSpec: QuickSpec { it("should load database & enterprise connections") { stub(condition: isCDN(forClientId: clientId)) { _ in return Auth0Stubs.strategiesFromCDN([ - mockStrategy("auth0", connections: [mockDatabaseConnection(name: databaseConnection)]), + mockStrategy("auth0", connections: [mockDatabase(name: databaseConnection)]), mockStrategy("ad", connections: [ - mockEntepriseConnection("TestAD", domain: ["test.com"]), - mockEntepriseConnection("fakeAD", domain: ["fake.com"])] + mockEnterprise(name: "TestAD", domains: ["test.com"]), + mockEnterprise(name: "fakeAD", domains: ["fake.com"])] )]) } loader.load(callback) expect(connections?.database?.name).toEventually(equal(databaseConnection)) @@ -332,8 +346,8 @@ class CDNLoaderInteractorSpec: QuickSpec { mockOAuth2("facebook1"), mockOAuth2("facebook2")]), mockStrategy("ad", connections: [ - mockEntepriseConnection("TestAD", domain: ["test.com"]), - mockEntepriseConnection("fakeAD", domain: ["fake.com"])] + mockEnterprise(name: "TestAD", domains: ["test.com"]), + mockEnterprise(name: "fakeAD", domains: ["fake.com"])] )]) } loader.load(callback) expect(connections?.oauth2).toEventuallyNot(beNil()) @@ -349,13 +363,13 @@ class CDNLoaderInteractorSpec: QuickSpec { it("should load enterprise, database & social connections") { stub(condition: isCDN(forClientId: clientId)) { _ in return Auth0Stubs.strategiesFromCDN([ - mockStrategy("auth0", connections: [mockDatabaseConnection(name: databaseConnection)]), + mockStrategy("auth0", connections: [mockDatabase(name: databaseConnection)]), mockStrategy("facebook", connections: [ mockOAuth2("facebook1"), mockOAuth2("facebook2")]), mockStrategy("ad", connections: [ - mockEntepriseConnection("TestAD", domain: ["test.com"]), - mockEntepriseConnection("fakeAD", domain: ["fake.com"])] + mockEnterprise(name: "TestAD", domains: ["test.com"]), + mockEnterprise(name: "fakeAD", domains: ["fake.com"])] )]) } loader.load(callback) expect(connections?.database?.name).toEventually(equal(databaseConnection)) @@ -386,7 +400,7 @@ private func mockOAuth2(_ name: String) -> JSONObject { return json } -private func mockDatabaseConnection(name: String, requiresUsername: Bool? = nil, validation: JSONObject = [:], passwordPolicy: String? = nil) -> JSONObject { +private func mockDatabase(name: String, requiresUsername: Bool? = nil, validation: JSONObject = [:], passwordPolicy: String? = nil) -> JSONObject { var json: JSONObject = ["name": name ] if let requiresUsername = requiresUsername { json["requires_username"] = requiresUsername @@ -398,7 +412,10 @@ private func mockDatabaseConnection(name: String, requiresUsername: Bool? = nil, return json } -private func mockEntepriseConnection(_ name: String, domain: [String] ) -> JSONObject { - let json: JSONObject = ["name" : name as Any, "domain" : domain.first! as Any, "domain_aliases" : domain as Any] +private func mockEnterprise(name: String, domains: [String] ) -> JSONObject { + var json: JSONObject = ["name": name, "domain_aliases": domains] + if let domain = domains.first { + json["domain"] = domain + } return json }