Skip to content

Commit

Permalink
Fix: Better encapsulation with new achitecture
Browse files Browse the repository at this point in the history
  • Loading branch information
fjcaetano committed Mar 12, 2018
1 parent 8a91279 commit 8160d36
Show file tree
Hide file tree
Showing 8 changed files with 165 additions and 69 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
buildConfiguration = "Release"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
language = ""
Expand Down
17 changes: 17 additions & 0 deletions Example/ReCaptcha_Tests/Core/ReCaptchaWebViewManager__Tests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -309,4 +309,21 @@ class ReCaptchaWebViewManager__Tests: XCTestCase {
XCTAssertNil(result?.error)
XCTAssertEqual(result?.token, apiKey)
}

// MARK: Force Challenge Visible

func test__Force_Visible_Challenge() {
let manager = ReCaptchaWebViewManager()

// Initial value
XCTAssertFalse(manager.forceVisibleChallenge)

// Set True
manager.forceVisibleChallenge = true
XCTAssertEqual(manager.webView.customUserAgent, "Googlebot/2.1")

// Set False
manager.forceVisibleChallenge = false
XCTAssertNotEqual(manager.webView.customUserAgent?.isEmpty, false)
}
}
11 changes: 11 additions & 0 deletions Example/ReCaptcha_Tests/Core/ReCaptcha__Tests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,17 @@ class ReCaptcha__Tests: XCTestCase {
)
XCTAssertEqual(config2?.apiKey, key)
}

func test__Force_Visible_Challenge() {
let recaptcha = ReCaptcha(manager: ReCaptchaWebViewManager())

// Initial value
XCTAssertFalse(recaptcha.forceVisibleChallenge)

// Set true
recaptcha.forceVisibleChallenge = true
XCTAssertTrue(recaptcha.forceVisibleChallenge)
}
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

import Foundation
@testable import ReCaptcha

import WebKit

extension ReCaptchaWebViewManager {
private static let unformattedHTML: String! = {
Expand All @@ -18,7 +18,7 @@ extension ReCaptchaWebViewManager {
}()

convenience init(
messageBody: String,
messageBody: String = "",
apiKey: String? = nil,
endpoint: String? = nil,
shouldFail: Bool = false
Expand All @@ -36,4 +36,15 @@ extension ReCaptchaWebViewManager {
endpoint: endpoint ?? localhost.absoluteString
)
}

func configureWebView(_ configure: @escaping (WKWebView) -> Void) {
configureWebView = configure
}

func validate(on view: UIView, resetOnError: Bool = true, completion: @escaping (ReCaptchaResult) -> Void) {
self.shouldResetOnError = resetOnError
self.completion = completion

validate(on: view)
}
}
49 changes: 29 additions & 20 deletions Example/ReCaptcha_Tests/RxSwift/ReCaptcha+Rx__Tests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -35,14 +35,14 @@ class ReCaptcha_Rx__Tests: XCTestCase {


func test__Validate__Token() {
let manager = ReCaptchaWebViewManager(messageBody: "{token: key}", apiKey: apiKey)
manager.configureWebView { _ in
let recaptcha = ReCaptcha(manager: ReCaptchaWebViewManager(messageBody: "{token: key}", apiKey: apiKey))
recaptcha.configureWebView { _ in
XCTFail("should not ask to configure the webview")
}

do {
// Validate
let result = try manager.rx.validate(on: presenterView)
let result = try recaptcha.rx.validate(on: presenterView)
.toBlocking()
.single()

Expand All @@ -56,16 +56,19 @@ class ReCaptcha_Rx__Tests: XCTestCase {


func test__Validate__Show_ReCaptcha() {
let manager = ReCaptchaWebViewManager(messageBody: "{action: \"showReCaptcha\"}", apiKey: apiKey)
let recaptcha = ReCaptcha(
manager: ReCaptchaWebViewManager(messageBody: "{action: \"showReCaptcha\"}", apiKey: apiKey)
)

var didConfigureWebView = false

manager.configureWebView { _ in
recaptcha.configureWebView { _ in
didConfigureWebView = true
}

do {
// Validate
_ = try manager.rx.validate(on: presenterView)
_ = try recaptcha.rx.validate(on: presenterView)
.timeout(2, scheduler: MainScheduler.instance)
.toBlocking()
.single()
Expand All @@ -80,14 +83,14 @@ class ReCaptcha_Rx__Tests: XCTestCase {


func test__Validate__Error() {
let manager = ReCaptchaWebViewManager(messageBody: "\"foobar\"", apiKey: apiKey)
manager.configureWebView { _ in
let recaptcha = ReCaptcha(manager: ReCaptchaWebViewManager(messageBody: "\"foobar\"", apiKey: apiKey))
recaptcha.configureWebView { _ in
XCTFail("should not ask to configure the webview")
}

do {
// Validate
_ = try manager.rx.validate(on: presenterView, resetOnError: false)
_ = try recaptcha.rx.validate(on: presenterView, resetOnError: false)
.toBlocking()
.single()

Expand All @@ -104,12 +107,12 @@ class ReCaptcha_Rx__Tests: XCTestCase {
let exp = expectation(description: "stop loading")

// Stop
let manager = ReCaptchaWebViewManager(messageBody: "{action: \"showReCaptcha\"}")
manager.configureWebView { _ in
let recaptcha = ReCaptcha(manager: ReCaptchaWebViewManager(messageBody: "{action: \"showReCaptcha\"}"))
recaptcha.configureWebView { _ in
XCTFail("should not ask to configure the webview")
}

let disposable = manager.rx.validate(on: presenterView)
let disposable = recaptcha.rx.validate(on: presenterView)
.do(onDispose: exp.fulfill)
.subscribe { _ in
XCTFail("should not validate")
Expand All @@ -126,14 +129,17 @@ class ReCaptcha_Rx__Tests: XCTestCase {

func test__Reset() {
// Validate
let manager = ReCaptchaWebViewManager(messageBody: "{token: key}", apiKey: apiKey, shouldFail: true)
manager.configureWebView { _ in
let recaptcha = ReCaptcha(
manager: ReCaptchaWebViewManager(messageBody: "{token: key}", apiKey: apiKey, shouldFail: true)
)

recaptcha.configureWebView { _ in
XCTFail("should not ask to configure the webview")
}

do {
// Error
_ = try manager.rx.validate(on: presenterView, resetOnError: false)
_ = try recaptcha.rx.validate(on: presenterView, resetOnError: false)
.toBlocking()
.single()
}
Expand All @@ -142,12 +148,12 @@ class ReCaptcha_Rx__Tests: XCTestCase {

// Resets after failure
_ = Observable<Void>.just(())
.bind(to: manager.rx.reset)
.bind(to: recaptcha.rx.reset)
}

do {
// Resets and tries again
let result = try manager.rx.validate(on: presenterView, resetOnError: false)
let result = try recaptcha.rx.validate(on: presenterView, resetOnError: false)
.toBlocking()
.single()

Expand All @@ -160,14 +166,17 @@ class ReCaptcha_Rx__Tests: XCTestCase {

func test__Validate__Reset_On_Error() {
// Validate
let manager = ReCaptchaWebViewManager(messageBody: "{token: key}", apiKey: apiKey, shouldFail: true)
manager.configureWebView { _ in
let recaptcha = ReCaptcha(
manager: ReCaptchaWebViewManager(messageBody: "{token: key}", apiKey: apiKey, shouldFail: true)
)

recaptcha.configureWebView { _ in
XCTFail("should not ask to configure the webview")
}

do {
// Error
let result = try manager.rx.validate(on: presenterView, resetOnError: true)
let result = try recaptcha.rx.validate(on: presenterView, resetOnError: true)
.toBlocking()
.single()

Expand Down
77 changes: 73 additions & 4 deletions ReCaptcha/Classes/ReCaptcha.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ import Foundation
import WebKit


/** The public facade of ReCaptcha
/**
*/
open class ReCaptcha: ReCaptchaWebViewManager {
public class ReCaptcha {
fileprivate struct Constants {
struct InfoDictKeys {
static let APIKey = "ReCaptchaKey"
Expand Down Expand Up @@ -97,6 +97,9 @@ open class ReCaptcha: ReCaptchaWebViewManager {
}
}

/// The worker that handles webview events and communication
let manager: ReCaptchaWebViewManager

/**
- parameters:
- apiKey: The API key sent to the ReCaptcha init
Expand All @@ -118,15 +121,81 @@ open class ReCaptcha: ReCaptchaWebViewManager {
Info.plist.
- Throws: Rethrows any exceptions thrown by `String(contentsOfFile:)`
*/
public init(apiKey: String? = nil, baseURL: URL? = nil, endpoint: Endpoint = .default) throws {
public convenience init(apiKey: String? = nil, baseURL: URL? = nil, endpoint: Endpoint = .default) throws {
let infoDict = Bundle.main.infoDictionary

let plistApiKey = infoDict?[Constants.InfoDictKeys.APIKey] as? String
let plistDomain = (infoDict?[Constants.InfoDictKeys.Domain] as? String).flatMap(URL.init(string:))

let config = try Config(apiKey: apiKey, infoPlistKey: plistApiKey, baseURL: baseURL, infoPlistURL: plistDomain)
super.init(html: config.html, apiKey: config.apiKey, baseURL: config.baseURL, endpoint: endpoint.url)

self.init(manager: ReCaptchaWebViewManager(
html: config.html,
apiKey: config.apiKey,
baseURL: config.baseURL,
endpoint: endpoint.url
))
}

/**
- parameter manager: A ReCaptchaWebViewManager instance.
Initializes ReCaptcha with the given manager
*/
init(manager: ReCaptchaWebViewManager) {
self.manager = manager
}

/**
- parameters:
- view: The view that should present the webview.
- resetOnError: If ReCaptcha should be reset if it errors. Defaults to `true`.
- completion: A closure that receives a ReCaptchaResult which may contain a valid result token.
Starts the challenge validation
*/
public func validate(on view: UIView, resetOnError: Bool = true, completion: @escaping (ReCaptchaResult) -> Void) {
manager.shouldResetOnError = resetOnError
manager.completion = completion

manager.validate(on: view)
}


/// Stops the execution of the webview
public func stop() {
manager.stop()
}


/**
- parameter configure: A closure that receives an instance of `WKWebView` for configuration.
Provides a closure to configure the webview for presentation if necessary.
If presentation is required, the webview will already be a subview of `presenterView` if one is provided. Otherwise
it might need to be added in a view currently visible.
*/
public func configureWebView(_ configure: @escaping (WKWebView) -> Void) {
manager.configureWebView = configure
}

/**
Resets the ReCaptcha.
The reset is achieved by calling `grecaptcha.reset()` on the JS API.
*/
public func reset() {
manager.reset()
}

#if DEBUG
/// Forces the challenge to be explicitly displayed.
public var forceVisibleChallenge: Bool {
get { return manager.forceVisibleChallenge }
set { manager.forceVisibleChallenge = newValue }
}
#endif
}

// MARK: - Private Methods
Expand Down
Loading

0 comments on commit 8160d36

Please sign in to comment.