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
Original file line number Diff line number Diff line change
Expand Up @@ -204,10 +204,13 @@ struct CartView: View {
}

private func handleCheckoutLink(_ link: CheckoutLink) -> CheckoutLinkAction {
print("[CheckoutKitSwiftDemo] Checkout link clicked: \(link.url)")
switch windowOpenHandler {
case .default:
print("[CheckoutKitSwiftDemo] Checkout link delegated to Checkout Kit: \(link.url)")
return .open
case .externalApp:
print("[CheckoutKitSwiftDemo] Checkout link handled by sample: \(link.url)")
UIApplication.shared.open(link.url)
return .handled
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -860,11 +860,18 @@ extension CheckoutWebView: WKNavigationDelegate {
// - Deep links on offsite payment sites
//
if CheckoutURL(from: url).isDeepLink() {
Task { @MainActor [externalURLHandler] in
if await externalURLHandler.open(url) {
OSLogger.shared.debug("Deep link intercepted: \(LogSafeURL.string(url)) - opened externally")
} else {
OSLogger.shared.error("Deep link rejected: \(LogSafeURL.string(url)). No installed app can open this scheme.")
Task { @MainActor [externalURLHandler, linkActionProvider] in
switch linkActionProvider?(CheckoutLink(url: url)) ?? .open {
case .handled:
OSLogger.shared.debug("Raw navigation link handled by host")
case .cancel:
OSLogger.shared.debug("Raw navigation link canceled by host")
case .open:
if await externalURLHandler.open(url) {
OSLogger.shared.debug("Raw navigation link opened with SDK default handler")
} else {
OSLogger.shared.error("Raw navigation link rejected by SDK default handler")
}
}
decisionHandler(.cancel)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,43 @@ class CheckoutWebViewTests: XCTestCase {
XCTAssertEqual(handler.openedURL, link, "The deep link should be opened via the external URL handler exactly once")
}

func testDeepLinkHandledByLinkActionProviderIsNotOpenedExternally() throws {
let link = try XCTUnwrap(URL(string: "myapp://checkout"))
let handler = MockExternalURLHandler(didOpen: true)
view.externalURLHandler = handler
var handledLink: CheckoutLink?
view.linkActionProvider = { checkoutLink in
handledLink = checkoutLink
return .handled
}
let received = expectation(description: "policy decided")

view.webView(view, decidePolicyFor: MockExternalNavigationAction(url: link)) { policy in
XCTAssertEqual(policy, .cancel)
received.fulfill()
}

wait(for: [received], timeout: 2.0)
XCTAssertEqual(handledLink?.url, link)
XCTAssertNil(handler.openedURL)
}

func testDeepLinkCanceledByLinkActionProviderIsNotOpenedExternally() throws {
let link = try XCTUnwrap(URL(string: "myapp://checkout"))
let handler = MockExternalURLHandler(didOpen: true)
view.externalURLHandler = handler
view.linkActionProvider = { _ in .cancel }
let received = expectation(description: "policy decided")

view.webView(view, decidePolicyFor: MockExternalNavigationAction(url: link)) { policy in
XCTAssertEqual(policy, .cancel)
received.fulfill()
}

wait(for: [received], timeout: 2.0)
XCTAssertNil(handler.openedURL)
}

func testHTTPSubframeRequestIsAllowed() throws {
let link = try XCTUnwrap(URL(string: "https://shopify1.shopify.com/checkouts/cn/123"))
let received = expectation(description: "policy decided")
Expand Down
Loading