From 6905867262629d12863101ca6494180d5dc9843c Mon Sep 17 00:00:00 2001 From: Hassaan El-Garem Date: Mon, 29 Nov 2021 18:01:39 +0200 Subject: [PATCH 1/3] Add enableOnePassword flag --- .../WordPressAuthenticatorConfiguration.swift | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/WordPressAuthenticator/Authenticator/WordPressAuthenticatorConfiguration.swift b/WordPressAuthenticator/Authenticator/WordPressAuthenticatorConfiguration.swift index c57ad7c5b..5e4c0deb1 100644 --- a/WordPressAuthenticator/Authenticator/WordPressAuthenticatorConfiguration.swift +++ b/WordPressAuthenticator/Authenticator/WordPressAuthenticatorConfiguration.swift @@ -88,6 +88,17 @@ public struct WordPressAuthenticatorConfiguration { /// If enabled, the "Enter your existing site address" button in the login prologue is shown first. /// Default value is disabled let continueWithSiteAddressFirst: Bool + + + /// Flag for 1Password extension integration. + /// If disabled, 1Password buttons are not added to email and username textfields, + /// instead we depend on the key icon in the keyboard to initiate a password manager. + /// If enabled, we add 1Password buttons normally. + /// Default value is enabled + /// Before disabling the flag, make sure to setup the app's associated domains according to this: + /// https://href.li/?https://developer.apple.com/documentation/xcode/supporting-associated-domains + /// + let enableOnePassword: Bool /// Designated Initializer /// @@ -108,7 +119,8 @@ public struct WordPressAuthenticatorConfiguration { enableUnifiedAuth: Bool = false, enableUnifiedCarousel: Bool = false, displayHintButtons: Bool = true, - continueWithSiteAddressFirst: Bool = false) { + continueWithSiteAddressFirst: Bool = false, + enableOnePassword: Bool = true) { self.wpcomClientId = wpcomClientId self.wpcomSecret = wpcomSecret @@ -128,5 +140,6 @@ public struct WordPressAuthenticatorConfiguration { self.displayHintButtons = displayHintButtons self.enableSignupWithGoogle = enableSignupWithGoogle self.continueWithSiteAddressFirst = continueWithSiteAddressFirst + self.enableOnePassword = enableOnePassword } } From ca27fbfe2db5274b8a58a1966cc948f342b53fcf Mon Sep 17 00:00:00 2001 From: Hassaan El-Garem Date: Mon, 29 Nov 2021 18:02:05 +0200 Subject: [PATCH 2/3] Control 1Password enabling using flag --- .../project.pbxproj | 12 ++++ .../WordPressAuthenticatorConfiguration.swift | 3 +- .../Extensions/WPStyleGuide+Login.swift | 4 +- .../Services/OnePasswordFacade.swift | 29 +++++++--- .../Services/OnePasswordService.swift | 19 +++++++ .../Mocks/MockOnePasswordService.swift | 38 +++++++++++++ .../WordpressAuthenticatorProvider.swift | 5 +- .../Services/OnePasswordFacadeTests.swift | 56 +++++++++++++++++++ 8 files changed, 153 insertions(+), 13 deletions(-) create mode 100644 WordPressAuthenticator/Services/OnePasswordService.swift create mode 100644 WordPressAuthenticatorTests/Mocks/MockOnePasswordService.swift create mode 100644 WordPressAuthenticatorTests/Services/OnePasswordFacadeTests.swift diff --git a/WordPressAuthenticator.xcodeproj/project.pbxproj b/WordPressAuthenticator.xcodeproj/project.pbxproj index 517a1ac56..d8d802d78 100644 --- a/WordPressAuthenticator.xcodeproj/project.pbxproj +++ b/WordPressAuthenticator.xcodeproj/project.pbxproj @@ -17,6 +17,9 @@ 3FFF2FC123D7ED7C00D38C77 /* EmailClients.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3FFF2FC023D7ED7C00D38C77 /* EmailClients.plist */; }; 3FFF2FC323D7F53200D38C77 /* AppSelector.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3FFF2FC223D7F53200D38C77 /* AppSelector.swift */; }; 7A7A9B9CD2D81959F9AB9AF6 /* Pods_WordPressAuthenticator.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C736FF243DE333FCAB1C2614 /* Pods_WordPressAuthenticator.framework */; }; + 80CE9B162754763900871C00 /* OnePasswordFacadeTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 80CE9B152754763900871C00 /* OnePasswordFacadeTests.swift */; }; + 80CE9B18275493F700871C00 /* OnePasswordService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 80CE9B17275493F700871C00 /* OnePasswordService.swift */; }; + 80CE9B1A2754952D00871C00 /* MockOnePasswordService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 80CE9B192754952C00871C00 /* MockOnePasswordService.swift */; }; 982C8E7923021C20003F1BA0 /* LoginPrologueLoginMethodViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 982C8E7823021C20003F1BA0 /* LoginPrologueLoginMethodViewController.swift */; }; 984D508224D4B21A00251A63 /* PasswordViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 984D508124D4B21A00251A63 /* PasswordViewController.swift */; }; 984D508424D4B24500251A63 /* Password.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 984D508324D4B24500251A63 /* Password.storyboard */; }; @@ -223,6 +226,9 @@ 3FFF2FC023D7ED7C00D38C77 /* EmailClients.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = EmailClients.plist; sourceTree = ""; }; 3FFF2FC223D7F53200D38C77 /* AppSelector.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppSelector.swift; sourceTree = ""; }; 5A441EC80D2B8D2209C2E228 /* Pods_WordPressAuthenticatorTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_WordPressAuthenticatorTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 80CE9B152754763900871C00 /* OnePasswordFacadeTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnePasswordFacadeTests.swift; sourceTree = ""; }; + 80CE9B17275493F700871C00 /* OnePasswordService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnePasswordService.swift; sourceTree = ""; }; + 80CE9B192754952C00871C00 /* MockOnePasswordService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockOnePasswordService.swift; sourceTree = ""; }; 8F7217C3F7A6285D9C6CF786 /* Pods-WordPressAuthenticator.release-internal.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-WordPressAuthenticator.release-internal.xcconfig"; path = "Pods/Target Support Files/Pods-WordPressAuthenticator/Pods-WordPressAuthenticator.release-internal.xcconfig"; sourceTree = ""; }; 982C8E7823021C20003F1BA0 /* LoginPrologueLoginMethodViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LoginPrologueLoginMethodViewController.swift; sourceTree = ""; }; 984D508124D4B21A00251A63 /* PasswordViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PasswordViewController.swift; sourceTree = ""; }; @@ -549,6 +555,7 @@ isa = PBXGroup; children = ( B501C040208FC52500D1E58F /* LoginFacadeTests.m */, + 80CE9B152754763900871C00 /* OnePasswordFacadeTests.swift */, ); path = Services; sourceTree = ""; @@ -678,6 +685,7 @@ 1A21EE9722832BC200C940C6 /* WordPressComOAuthClientFacade+Swift.swift */, B5609106208A54F800399AE4 /* WordPressXMLRPCAPIFacade.h */, B5609102208A54F800399AE4 /* WordPressXMLRPCAPIFacade.m */, + 80CE9B17275493F700871C00 /* OnePasswordService.swift */, ); path = Services; sourceTree = ""; @@ -825,6 +833,7 @@ BA53D64C24DFE4E6001F1ABF /* ModalViewControllerPresentingSpy.swift */, BA53D64A24DFE07D001F1ABF /* WordpressAuthenticatorProvider.swift */, D85C36EB256E10EA00D56E34 /* MockNavigationController.swift */, + 80CE9B192754952C00871C00 /* MockOnePasswordService.swift */, ); path = Mocks; sourceTree = ""; @@ -1224,6 +1233,7 @@ B5609116208A555600399AE4 /* LoginTextField.swift in Sources */, D85C3653256DEDA900D56E34 /* WordPressAuthenticatorResult.swift in Sources */, F1C96669250BF53400EB529D /* UIViewController+Dismissal.swift in Sources */, + 80CE9B18275493F700871C00 /* OnePasswordService.swift in Sources */, CE811D6724EDC0FB00F4CCD6 /* LoginMagicLinkViewController.swift in Sources */, F11448EC258B827B0048203D /* URL+JetpackConnect.swift in Sources */, B56090E2208A4F9D00399AE4 /* WPNUXSecondaryButton.m in Sources */, @@ -1330,6 +1340,8 @@ 3108613125AFA4830022F75E /* PasteboardTests.swift in Sources */, D85C36F0256E118D00D56E34 /* NavigationToEnterAccountTests.swift in Sources */, D85C36E6256E0DDE00D56E34 /* NavigationToEnterSiteTests.swift in Sources */, + 80CE9B1A2754952D00871C00 /* MockOnePasswordService.swift in Sources */, + 80CE9B162754763900871C00 /* OnePasswordFacadeTests.swift in Sources */, D85C3882256E3FEC00D56E34 /* WordPressComSiteInfoTests.swift in Sources */, D8611A672576236800A5DF27 /* NavigateBackTests.swift in Sources */, F12F9FB824D8A7FC00771BCE /* AnalyticsTrackerTests.swift in Sources */, diff --git a/WordPressAuthenticator/Authenticator/WordPressAuthenticatorConfiguration.swift b/WordPressAuthenticator/Authenticator/WordPressAuthenticatorConfiguration.swift index 5e4c0deb1..4ea971574 100644 --- a/WordPressAuthenticator/Authenticator/WordPressAuthenticatorConfiguration.swift +++ b/WordPressAuthenticator/Authenticator/WordPressAuthenticatorConfiguration.swift @@ -89,14 +89,13 @@ public struct WordPressAuthenticatorConfiguration { /// Default value is disabled let continueWithSiteAddressFirst: Bool - /// Flag for 1Password extension integration. /// If disabled, 1Password buttons are not added to email and username textfields, /// instead we depend on the key icon in the keyboard to initiate a password manager. /// If enabled, we add 1Password buttons normally. /// Default value is enabled /// Before disabling the flag, make sure to setup the app's associated domains according to this: - /// https://href.li/?https://developer.apple.com/documentation/xcode/supporting-associated-domains + /// https://developer.apple.com/documentation/xcode/supporting-associated-domains /// let enableOnePassword: Bool diff --git a/WordPressAuthenticator/Extensions/WPStyleGuide+Login.swift b/WordPressAuthenticator/Extensions/WPStyleGuide+Login.swift index 9f046418e..43a45abb0 100644 --- a/WordPressAuthenticator/Extensions/WPStyleGuide+Login.swift +++ b/WordPressAuthenticator/Extensions/WPStyleGuide+Login.swift @@ -44,7 +44,7 @@ extension WPStyleGuide { /// - Note: this is for the old UI. /// class func configureOnePasswordButtonForTextfield(_ textField: WPWalkthroughTextField, target: NSObject, selector: Selector) { - guard OnePasswordFacade.isOnePasswordEnabled else { + guard OnePasswordFacade().isOnePasswordEnabled else { return } @@ -66,7 +66,7 @@ extension WPStyleGuide { /// - Note: this is for the old UI. /// class func configureOnePasswordButtonForStackView(_ stack: UIStackView, target: NSObject, selector: Selector) { - guard OnePasswordFacade.isOnePasswordEnabled else { + guard OnePasswordFacade().isOnePasswordEnabled else { return } diff --git a/WordPressAuthenticator/Services/OnePasswordFacade.swift b/WordPressAuthenticator/Services/OnePasswordFacade.swift index de9c6282a..2e21ed7fe 100644 --- a/WordPressAuthenticator/Services/OnePasswordFacade.swift +++ b/WordPressAuthenticator/Services/OnePasswordFacade.swift @@ -2,10 +2,24 @@ import Foundation import UIKit import OnePasswordExtension -// MARK: - This protocol is a Facade that hides some of the implementation details for interacting with 1Password. -// -class OnePasswordFacade { +extension OnePasswordExtension: OnePasswordService {} +/// A facade that hides some of the implementation details for interacting with 1Password. +/// +class OnePasswordFacade { + + // MARK: - Private Properties + // + private let onePasswordService: OnePasswordService + + // MARK: - Initializer + // + init(onePasswordService: OnePasswordService = OnePasswordExtension.shared()) { + self.onePasswordService = onePasswordService + } + + // MARK: - Public Functions + /// This method will pull up the 1Password extension and display any logins for the passed in `loginUrl`. /// /// - Parameters: @@ -20,7 +34,7 @@ class OnePasswordFacade { sender: Any, success: @escaping (_ username: String, _ password: String, _ otp: String?) -> Void, failure: @escaping (OnePasswordError) -> Void) { - OnePasswordExtension.shared().findLogin(forURLString: url, for: viewController, sender: sender) { (dictionary, error) in + onePasswordService.findLogin(forURLString: url, for: viewController, sender: sender) { (dictionary, error) in if let error = error as NSError? { failure(OnePasswordError(error: error)) return @@ -76,7 +90,7 @@ class OnePasswordFacade { AppExtensionGeneratedPasswordMaxLengthKey: maximumLength ] - OnePasswordExtension.shared().storeLogin(forURLString: url, loginDetails: loginDetails, passwordGenerationOptions: options, for: viewController, sender: sender) { (loginDict, error) in + onePasswordService.storeLogin(forURLString: url, loginDetails: loginDetails, passwordGenerationOptions: options, for: viewController, sender: sender) { (loginDict, error) in if let error = error as NSError? { failure(OnePasswordError(error: error)) return @@ -95,8 +109,9 @@ class OnePasswordFacade { /// Indicates if the 1P Extension is enabled, or not. /// - static var isOnePasswordEnabled: Bool { - return OnePasswordExtension.shared().isAppExtensionAvailable() + var isOnePasswordEnabled: Bool { + return WordPressAuthenticator.shared.configuration.enableOnePassword && + onePasswordService.isAppExtensionAvailable() } } diff --git a/WordPressAuthenticator/Services/OnePasswordService.swift b/WordPressAuthenticator/Services/OnePasswordService.swift new file mode 100644 index 000000000..1c081c724 --- /dev/null +++ b/WordPressAuthenticator/Services/OnePasswordService.swift @@ -0,0 +1,19 @@ +// +// OnePasswordService.swift +// WordPressAuthenticator +// +// Created by Hassaan El-Garem on 11/29/21. +// Copyright © 2021 Automattic. All rights reserved. +// + +import Foundation + +/// Protocol that acts as a wrapper around OnePasswordExtension +protocol OnePasswordService { + + typealias OnePasswordServiceLoginDictionaryCompletionBlock = ([AnyHashable : Any]?, Error?) -> Void + + func findLogin(forURLString URLString: String, for viewController: UIViewController, sender: Any?, completion: @escaping OnePasswordServiceLoginDictionaryCompletionBlock) + func storeLogin(forURLString URLString: String, loginDetails loginDetailsDictionary: [AnyHashable : Any]?, passwordGenerationOptions: [AnyHashable : Any]?, for viewController: UIViewController, sender: Any?, completion: @escaping OnePasswordServiceLoginDictionaryCompletionBlock) + func isAppExtensionAvailable() -> Bool +} diff --git a/WordPressAuthenticatorTests/Mocks/MockOnePasswordService.swift b/WordPressAuthenticatorTests/Mocks/MockOnePasswordService.swift new file mode 100644 index 000000000..6747c88ad --- /dev/null +++ b/WordPressAuthenticatorTests/Mocks/MockOnePasswordService.swift @@ -0,0 +1,38 @@ +// +// MockOnePasswordService.swift +// WordPressAuthenticatorTests +// +// Created by Hassaan El-Garem on 11/29/21. +// Copyright © 2021 Automattic. All rights reserved. +// + +import Foundation +@testable import WordPressAuthenticator + + +class MockOnePasswordService: OnePasswordService { + + // MARK: - Private Properties + // + var onePasswordAvailable: Bool + + // MARK: - Initializer + // + init(onePasswordAvailable: Bool) { + self.onePasswordAvailable = onePasswordAvailable + } + + // MARK: - OnePasswordService + // + func findLogin(forURLString URLString: String, for viewController: UIViewController, sender: Any?, completion: @escaping OnePasswordServiceLoginDictionaryCompletionBlock) { + // Do nothing + } + + func storeLogin(forURLString URLString: String, loginDetails loginDetailsDictionary: [AnyHashable : Any]?, passwordGenerationOptions: [AnyHashable : Any]?, for viewController: UIViewController, sender: Any?, completion: @escaping OnePasswordServiceLoginDictionaryCompletionBlock) { + // Do nothing + } + + func isAppExtensionAvailable() -> Bool { + return onePasswordAvailable + } +} diff --git a/WordPressAuthenticatorTests/Mocks/WordpressAuthenticatorProvider.swift b/WordPressAuthenticatorTests/Mocks/WordpressAuthenticatorProvider.swift index ae894db5e..6ecf0e18a 100644 --- a/WordPressAuthenticatorTests/Mocks/WordpressAuthenticatorProvider.swift +++ b/WordPressAuthenticatorTests/Mocks/WordpressAuthenticatorProvider.swift @@ -2,7 +2,7 @@ @objc public class WordpressAuthenticatorProvider: NSObject { - static func wordPressAuthenticatorConfiguration() -> WordPressAuthenticatorConfiguration { + static func wordPressAuthenticatorConfiguration(enableOnePassword: Bool = true) -> WordPressAuthenticatorConfiguration { return WordPressAuthenticatorConfiguration(wpcomClientId: "23456", wpcomSecret: "arfv35dj57l3g2323", wpcomScheme: "https", @@ -10,7 +10,8 @@ public class WordpressAuthenticatorProvider: NSObject { googleLoginClientId: "", googleLoginServerClientId: "", googleLoginScheme: "com.googleuserconsent.apps", - userAgent: "") + userAgent: "", + enableOnePassword: enableOnePassword) } static func wordPressAuthenticatorStyle(_ style: AuthenticatorStyleType) -> WordPressAuthenticatorStyle { diff --git a/WordPressAuthenticatorTests/Services/OnePasswordFacadeTests.swift b/WordPressAuthenticatorTests/Services/OnePasswordFacadeTests.swift new file mode 100644 index 000000000..8de5e9acd --- /dev/null +++ b/WordPressAuthenticatorTests/Services/OnePasswordFacadeTests.swift @@ -0,0 +1,56 @@ +// +// OnePasswordFacadeTests.swift +// WordPressAuthenticatorTests +// +// Created by Hassaan El-Garem on 11/29/21. +// Copyright © 2021 Automattic. All rights reserved. +// + +import XCTest +@testable import WordPressAuthenticator + +class OnePasswordFacadeTests: XCTestCase { + + func testOnePasswordEnabled() { + // Given + WordPressAuthenticator.initialize( + configuration: WordpressAuthenticatorProvider.wordPressAuthenticatorConfiguration(enableOnePassword: true), + style: WordpressAuthenticatorProvider.wordPressAuthenticatorStyle(.random), + unifiedStyle: WordpressAuthenticatorProvider.wordPressAuthenticatorUnifiedStyle(.random) + ) + let mockOnePasswordService = MockOnePasswordService(onePasswordAvailable: true) + let onePasswordFacade = OnePasswordFacade(onePasswordService: mockOnePasswordService) + + // When & Then + XCTAssertTrue(onePasswordFacade.isOnePasswordEnabled) + } + + func testOnePasswordDisabledIfUnAvailable() { + // Given + WordPressAuthenticator.initialize( + configuration: WordpressAuthenticatorProvider.wordPressAuthenticatorConfiguration(enableOnePassword: true), + style: WordpressAuthenticatorProvider.wordPressAuthenticatorStyle(.random), + unifiedStyle: WordpressAuthenticatorProvider.wordPressAuthenticatorUnifiedStyle(.random) + ) + let mockOnePasswordService = MockOnePasswordService(onePasswordAvailable: false) + let onePasswordFacade = OnePasswordFacade(onePasswordService: mockOnePasswordService) + + // When & Then + XCTAssertFalse(onePasswordFacade.isOnePasswordEnabled) + } + + func testOnePasswordDisabledFromConfiguration() { + // Given + WordPressAuthenticator.initialize( + configuration: WordpressAuthenticatorProvider.wordPressAuthenticatorConfiguration(enableOnePassword: false), + style: WordpressAuthenticatorProvider.wordPressAuthenticatorStyle(.random), + unifiedStyle: WordpressAuthenticatorProvider.wordPressAuthenticatorUnifiedStyle(.random) + ) + let mockOnePasswordService = MockOnePasswordService(onePasswordAvailable: true) + let onePasswordFacade = OnePasswordFacade(onePasswordService: mockOnePasswordService) + + // When & Then + XCTAssertFalse(onePasswordFacade.isOnePasswordEnabled) + } + +} From 9eff9ed286436ad1b169c231cbcb5ceae45084f3 Mon Sep 17 00:00:00 2001 From: Hassaan El-Garem Date: Tue, 30 Nov 2021 04:48:43 +0200 Subject: [PATCH 3/3] Apply linting rules --- .../WordPressAuthenticatorConfiguration.swift | 2 +- .../Services/OnePasswordFacade.swift | 8 ++++---- .../Services/OnePasswordService.swift | 8 ++++---- .../Mocks/MockOnePasswordService.swift | 13 ++++++------- .../Services/OnePasswordFacadeTests.swift | 12 ++++++------ 5 files changed, 21 insertions(+), 22 deletions(-) diff --git a/WordPressAuthenticator/Authenticator/WordPressAuthenticatorConfiguration.swift b/WordPressAuthenticator/Authenticator/WordPressAuthenticatorConfiguration.swift index 4ea971574..2f539cf01 100644 --- a/WordPressAuthenticator/Authenticator/WordPressAuthenticatorConfiguration.swift +++ b/WordPressAuthenticator/Authenticator/WordPressAuthenticatorConfiguration.swift @@ -88,7 +88,7 @@ public struct WordPressAuthenticatorConfiguration { /// If enabled, the "Enter your existing site address" button in the login prologue is shown first. /// Default value is disabled let continueWithSiteAddressFirst: Bool - + /// Flag for 1Password extension integration. /// If disabled, 1Password buttons are not added to email and username textfields, /// instead we depend on the key icon in the keyboard to initiate a password manager. diff --git a/WordPressAuthenticator/Services/OnePasswordFacade.swift b/WordPressAuthenticator/Services/OnePasswordFacade.swift index 2e21ed7fe..f5c2a52eb 100644 --- a/WordPressAuthenticator/Services/OnePasswordFacade.swift +++ b/WordPressAuthenticator/Services/OnePasswordFacade.swift @@ -7,19 +7,19 @@ extension OnePasswordExtension: OnePasswordService {} /// A facade that hides some of the implementation details for interacting with 1Password. /// class OnePasswordFacade { - + // MARK: - Private Properties // private let onePasswordService: OnePasswordService - + // MARK: - Initializer // init(onePasswordService: OnePasswordService = OnePasswordExtension.shared()) { self.onePasswordService = onePasswordService } - + // MARK: - Public Functions - + /// This method will pull up the 1Password extension and display any logins for the passed in `loginUrl`. /// /// - Parameters: diff --git a/WordPressAuthenticator/Services/OnePasswordService.swift b/WordPressAuthenticator/Services/OnePasswordService.swift index 1c081c724..dd6922c3c 100644 --- a/WordPressAuthenticator/Services/OnePasswordService.swift +++ b/WordPressAuthenticator/Services/OnePasswordService.swift @@ -10,10 +10,10 @@ import Foundation /// Protocol that acts as a wrapper around OnePasswordExtension protocol OnePasswordService { - - typealias OnePasswordServiceLoginDictionaryCompletionBlock = ([AnyHashable : Any]?, Error?) -> Void - + + typealias OnePasswordServiceLoginDictionaryCompletionBlock = ([AnyHashable: Any]?, Error?) -> Void + func findLogin(forURLString URLString: String, for viewController: UIViewController, sender: Any?, completion: @escaping OnePasswordServiceLoginDictionaryCompletionBlock) - func storeLogin(forURLString URLString: String, loginDetails loginDetailsDictionary: [AnyHashable : Any]?, passwordGenerationOptions: [AnyHashable : Any]?, for viewController: UIViewController, sender: Any?, completion: @escaping OnePasswordServiceLoginDictionaryCompletionBlock) + func storeLogin(forURLString URLString: String, loginDetails loginDetailsDictionary: [AnyHashable: Any]?, passwordGenerationOptions: [AnyHashable: Any]?, for viewController: UIViewController, sender: Any?, completion: @escaping OnePasswordServiceLoginDictionaryCompletionBlock) func isAppExtensionAvailable() -> Bool } diff --git a/WordPressAuthenticatorTests/Mocks/MockOnePasswordService.swift b/WordPressAuthenticatorTests/Mocks/MockOnePasswordService.swift index 6747c88ad..b74dcc0d7 100644 --- a/WordPressAuthenticatorTests/Mocks/MockOnePasswordService.swift +++ b/WordPressAuthenticatorTests/Mocks/MockOnePasswordService.swift @@ -9,29 +9,28 @@ import Foundation @testable import WordPressAuthenticator - class MockOnePasswordService: OnePasswordService { - + // MARK: - Private Properties // var onePasswordAvailable: Bool - + // MARK: - Initializer // init(onePasswordAvailable: Bool) { self.onePasswordAvailable = onePasswordAvailable } - + // MARK: - OnePasswordService // func findLogin(forURLString URLString: String, for viewController: UIViewController, sender: Any?, completion: @escaping OnePasswordServiceLoginDictionaryCompletionBlock) { // Do nothing } - - func storeLogin(forURLString URLString: String, loginDetails loginDetailsDictionary: [AnyHashable : Any]?, passwordGenerationOptions: [AnyHashable : Any]?, for viewController: UIViewController, sender: Any?, completion: @escaping OnePasswordServiceLoginDictionaryCompletionBlock) { + + func storeLogin(forURLString URLString: String, loginDetails loginDetailsDictionary: [AnyHashable: Any]?, passwordGenerationOptions: [AnyHashable: Any]?, for viewController: UIViewController, sender: Any?, completion: @escaping OnePasswordServiceLoginDictionaryCompletionBlock) { // Do nothing } - + func isAppExtensionAvailable() -> Bool { return onePasswordAvailable } diff --git a/WordPressAuthenticatorTests/Services/OnePasswordFacadeTests.swift b/WordPressAuthenticatorTests/Services/OnePasswordFacadeTests.swift index 8de5e9acd..2943b0e13 100644 --- a/WordPressAuthenticatorTests/Services/OnePasswordFacadeTests.swift +++ b/WordPressAuthenticatorTests/Services/OnePasswordFacadeTests.swift @@ -10,7 +10,7 @@ import XCTest @testable import WordPressAuthenticator class OnePasswordFacadeTests: XCTestCase { - + func testOnePasswordEnabled() { // Given WordPressAuthenticator.initialize( @@ -20,11 +20,11 @@ class OnePasswordFacadeTests: XCTestCase { ) let mockOnePasswordService = MockOnePasswordService(onePasswordAvailable: true) let onePasswordFacade = OnePasswordFacade(onePasswordService: mockOnePasswordService) - + // When & Then XCTAssertTrue(onePasswordFacade.isOnePasswordEnabled) } - + func testOnePasswordDisabledIfUnAvailable() { // Given WordPressAuthenticator.initialize( @@ -34,11 +34,11 @@ class OnePasswordFacadeTests: XCTestCase { ) let mockOnePasswordService = MockOnePasswordService(onePasswordAvailable: false) let onePasswordFacade = OnePasswordFacade(onePasswordService: mockOnePasswordService) - + // When & Then XCTAssertFalse(onePasswordFacade.isOnePasswordEnabled) } - + func testOnePasswordDisabledFromConfiguration() { // Given WordPressAuthenticator.initialize( @@ -48,7 +48,7 @@ class OnePasswordFacadeTests: XCTestCase { ) let mockOnePasswordService = MockOnePasswordService(onePasswordAvailable: true) let onePasswordFacade = OnePasswordFacade(onePasswordService: mockOnePasswordService) - + // When & Then XCTAssertFalse(onePasswordFacade.isOnePasswordEnabled) }