Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions Example/HCaptcha_Tests/Core/HCaptchaWebViewManager__Tests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,27 @@ class HCaptchaWebViewManager__Tests: XCTestCase {
XCTAssertEqual(result2?.token, apiKey)
}

func test__Validate__Ignores_Late_Termination_After_Token() {
let exp = expectation(description: "load token")
var results = [HCaptchaResult]()

let manager = HCaptchaWebViewManager(messageBody: "{token: key}", apiKey: apiKey)
manager.validate(on: presenterView) { response in
results.append(response)
if results.count == 1 {
exp.fulfill()
}
}

waitForExpectations(timeout: TestTimeouts.standard)

manager.webViewWebContentProcessDidTerminate(manager.webView)

XCTAssertEqual(results.count, 1)
XCTAssertNil(results.first?.error)
XCTAssertEqual(results.first?.token, apiKey)
}


func test__Validate__Show_HCaptcha() {
let exp = expectation(description: "show hcaptcha")
Expand Down
43 changes: 29 additions & 14 deletions HCaptcha/Classes/HCaptchaWebViewManager+Private.swift
Original file line number Diff line number Diff line change
Expand Up @@ -37,17 +37,9 @@ extension HCaptchaWebViewManager {
func handle(result: HCaptchaDecoder.Result) {
Log.debug("WebViewManager.handleResult: \(result)")

guard !resultHandled else {
Log.debug("WebViewManager.handleResult skip as handled")
return
}

switch result {
case .token(let token):
completion?(HCaptchaResult(self, token: token))
case .error(let error):
handle(error: error)
onEvent?(.error, error)
case .token(let token): handleToken(token)
case .error(let error): handleDecoderError(error)
case .showHCaptcha: webView.isHidden = false
case .didLoad: didLoad()
case .onOpen: onEvent?(.open, nil)
Expand All @@ -58,6 +50,23 @@ extension HCaptchaWebViewManager {
}
}

private func handleToken(_ token: String) {
guard !resultHandled else {
Log.debug("WebViewManager.handleResult skip token as handled")
return
}
complete(HCaptchaResult(self, token: token))
}

private func handleDecoderError(_ error: HCaptchaError) {
guard !resultHandled else {
Log.debug("WebViewManager.handleResult skip error as handled")
return
}
handle(error: error)
onEvent?(.error, error)
}

private func handle(error: HCaptchaError) {
loadingTimer?.invalidate()
loadingTimer = nil
Expand All @@ -66,11 +75,11 @@ extension HCaptchaWebViewManager {
reset()
validate(on: view)
} else {
completion?(HCaptchaResult(self, error: error))
complete(HCaptchaResult(self, error: error))
}
} else {
if let completion = completion {
completion(HCaptchaResult(self, error: error))
if completion != nil {
complete(HCaptchaResult(self, error: error))
} else {
lastError = error
}
Expand Down Expand Up @@ -172,8 +181,8 @@ extension HCaptchaWebViewManager {
guard let self = self else { return }
Log.debug("WebViewManager complete with pendingError: \(error)")

self.completion?(HCaptchaResult(self, error: error))
self.lastError = nil
self.complete(HCaptchaResult(self, error: error))
}
if error == .networkError {
Log.debug("WebViewManager reloads html after \(error) error")
Expand All @@ -196,4 +205,10 @@ extension HCaptchaWebViewManager {
func executeJS(command: JSCommand) {
executeJS(command: command, didLoad: self.didFinishLoading)
}

func complete(_ result: HCaptchaResult) {
let completion = self.completion
self.completion = nil
completion?(result)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,13 @@ extension HCaptchaWebViewManager: WKNavigationDelegate, WKUIDelegate {
/// Tells the delegate that an error occurred during navigation.
func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error) {
Log.debug("WebViewManager.webViewDidFail with \(error)")
completion?(HCaptchaResult(self, error: .unexpected(error)))
complete(HCaptchaResult(self, error: .unexpected(error)))
}

/// Tells the delegate that an error occurred during the early navigation process.
func webView(_ webView: WKWebView, didFailProvisionalNavigation navigation: WKNavigation!, withError error: Error) {
Log.debug("WebViewManager.webViewDidFailProvisionalNavigation with \(error)")
completion?(HCaptchaResult(self, error: .unexpected(error)))
complete(HCaptchaResult(self, error: .unexpected(error)))
}

/// Tells the delegate that the web view’s content process was terminated.
Expand All @@ -49,7 +49,7 @@ extension HCaptchaWebViewManager: WKNavigationDelegate, WKUIDelegate {
userInfo: [
NSLocalizedDescriptionKey: "WebView web content process did terminate",
NSLocalizedRecoverySuggestionErrorKey: "Call HCaptcha.reset()"])
completion?(HCaptchaResult(self, error: .unexpected(error)))
didFinishLoading = false
complete(HCaptchaResult(self, error: .unexpected(error)))
}
}
3 changes: 2 additions & 1 deletion HCaptcha/Classes/HCaptchaWebViewManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ internal class HCaptchaWebViewManager: NSObject {

if !passiveApiKey {
guard let view = view else {
completion?(HCaptchaResult(self, error: .failedSetup))
complete(HCaptchaResult(self, error: .failedSetup))
return
}

Expand All @@ -171,6 +171,7 @@ internal class HCaptchaWebViewManager: NSObject {
func stop() {
Log.debug("WebViewManager.stop")
stopInitWebViewConfiguration = true
completion = nil
webView.stopLoading()
resultHandled = true
loadingTimer?.invalidate()
Expand Down
Loading