|
- // Copyright 2013 The Flutter Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
-
- import Flutter
- import XCTest
-
- @testable import url_launcher_ios
-
- // Tests whether NSURL parsing is strict. When linking against the iOS 17 SDK or later,
- // NSURL uses a more lenient parser which will not return nil.
- private func urlParsingIsStrict() -> Bool {
- return URL(string: "b a d U R L") == nil
- }
-
- final class URLLauncherTests: XCTestCase {
-
- private func createPlugin() -> URLLauncherPlugin {
- let launcher = FakeLauncher()
- return URLLauncherPlugin(launcher: launcher)
- }
-
- private func createPlugin(launcher: FakeLauncher) -> URLLauncherPlugin {
- return URLLauncherPlugin(launcher: launcher)
- }
-
- func testCanLaunchSuccess() {
- let result = createPlugin().canLaunchUrl(url: "good://url")
- XCTAssertEqual(result, .success)
- }
-
- func testCanLaunchFailure() {
- let result = createPlugin().canLaunchUrl(url: "bad://url")
- XCTAssertEqual(result, .failure)
- }
-
- func testCanLaunchFailureWithInvalidURL() {
- let result = createPlugin().canLaunchUrl(url: "urls can't have spaces")
-
- if urlParsingIsStrict() {
- XCTAssertEqual(result, .invalidUrl)
- } else {
- XCTAssertEqual(result, .failure)
- }
- }
-
- func testLaunchSuccess() {
- let expectation = XCTestExpectation(description: "completion called")
- createPlugin().launchUrl(url: "good://url", universalLinksOnly: false) { result in
- switch result {
- case .success(let details):
- XCTAssertEqual(details, .success)
- case .failure(let error):
- XCTFail("Unexpected error: \(error)")
- }
- expectation.fulfill()
- }
-
- wait(for: [expectation], timeout: 1)
- }
-
- func testLaunchFailure() {
- let expectation = XCTestExpectation(description: "completion called")
- createPlugin().launchUrl(url: "bad://url", universalLinksOnly: false) { result in
- switch result {
- case .success(let details):
- XCTAssertEqual(details, .failure)
- case .failure(let error):
- XCTFail("Unexpected error: \(error)")
- }
- expectation.fulfill()
- }
-
- wait(for: [expectation], timeout: 1)
- }
-
- func testLaunchFailureWithInvalidURL() {
- let expectation = XCTestExpectation(description: "completion called")
- createPlugin().launchUrl(url: "urls can't have spaces", universalLinksOnly: false) { result in
- switch result {
- case .success(let details):
- if urlParsingIsStrict() {
- XCTAssertEqual(details, .invalidUrl)
- } else {
- XCTAssertEqual(details, .failure)
- }
- case .failure(let error):
- XCTFail("Unexpected error: \(error)")
- }
- expectation.fulfill()
- }
-
- wait(for: [expectation], timeout: 1)
- }
-
- func testLaunchWithoutUniversalLinks() {
- let launcher = FakeLauncher()
- let plugin = createPlugin(launcher: launcher)
-
- let expectation = XCTestExpectation(description: "completion called")
- plugin.launchUrl(url: "good://url", universalLinksOnly: false) { result in
- switch result {
- case .success(let details):
- XCTAssertEqual(details, .success)
- case .failure(let error):
- XCTFail("Unexpected error: \(error)")
- }
- expectation.fulfill()
- }
-
- wait(for: [expectation], timeout: 1)
- XCTAssertEqual(launcher.passedOptions?[.universalLinksOnly] as? Bool, false)
- }
-
- func testLaunchWithUniversalLinks() {
- let launcher = FakeLauncher()
- let plugin = createPlugin(launcher: launcher)
-
- let expectation = XCTestExpectation(description: "completion called")
- plugin.launchUrl(url: "good://url", universalLinksOnly: true) { result in
- switch result {
- case .success(let details):
- XCTAssertEqual(details, .success)
- case .failure(let error):
- XCTFail("Unexpected error: \(error)")
- }
- expectation.fulfill()
- }
-
- wait(for: [expectation], timeout: 1)
- XCTAssertEqual(launcher.passedOptions?[.universalLinksOnly] as? Bool, true)
- }
-
- }
-
- final private class FakeLauncher: NSObject, Launcher {
- var passedOptions: [UIApplication.OpenExternalURLOptionsKey: Any]?
-
- func canOpenURL(_ url: URL) -> Bool {
- url.scheme == "good"
- }
-
- func open(
- _ url: URL,
- options: [UIApplication.OpenExternalURLOptionsKey: Any],
- completionHandler completion: ((Bool) -> Void)?
- ) {
- self.passedOptions = options
- completion?(url.scheme == "good")
- }
- }
|