Skip to content

Commit 0af4bb0

Browse files
committed
test: add unit tests
1 parent 949ed1f commit 0af4bb0

File tree

8 files changed

+389
-10
lines changed

8 files changed

+389
-10
lines changed

OSInAppBrowserLib.xcodeproj/project.pbxproj

Lines changed: 54 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,10 @@
4040
75EF1AFB2C13069E005D7164 /* OSIABViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75EF1AFA2C13069E005D7164 /* OSIABViewModelTests.swift */; };
4141
75EF1AFD2C1306B1005D7164 /* OSIABCacheManagerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75EF1AFC2C1306B1005D7164 /* OSIABCacheManagerTests.swift */; };
4242
75EF1B012C134878005D7164 /* OSIABWebViewStub.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75EF1B002C134878005D7164 /* OSIABWebViewStub.swift */; };
43+
887287832E717E8F00D9E41B /* ViewInspector in Frameworks */ = {isa = PBXBuildFile; productRef = 887287822E717E8F00D9E41B /* ViewInspector */; };
44+
8872878B2E71806200D9E41B /* OSIABWebView_ViewInspectorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8872878A2E71806200D9E41B /* OSIABWebView_ViewInspectorTests.swift */; };
45+
8872878F2E7192C200D9E41B /* OSIABWebViewRepresentableTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8872878E2E7192C200D9E41B /* OSIABWebViewRepresentableTests.swift */; };
46+
887287912E7194D800D9E41B /* OSIABApplicationRouterAdapterTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 887287902E7194D800D9E41B /* OSIABApplicationRouterAdapterTests.swift */; };
4347
/* End PBXBuildFile section */
4448

4549
/* Begin PBXContainerItemProxy section */
@@ -87,6 +91,9 @@
8791
75EF1AFA2C13069E005D7164 /* OSIABViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OSIABViewModelTests.swift; sourceTree = "<group>"; };
8892
75EF1AFC2C1306B1005D7164 /* OSIABCacheManagerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OSIABCacheManagerTests.swift; sourceTree = "<group>"; };
8993
75EF1B002C134878005D7164 /* OSIABWebViewStub.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OSIABWebViewStub.swift; sourceTree = "<group>"; };
94+
8872878A2E71806200D9E41B /* OSIABWebView_ViewInspectorTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OSIABWebView_ViewInspectorTests.swift; sourceTree = "<group>"; };
95+
8872878E2E7192C200D9E41B /* OSIABWebViewRepresentableTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OSIABWebViewRepresentableTests.swift; sourceTree = "<group>"; };
96+
887287902E7194D800D9E41B /* OSIABApplicationRouterAdapterTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OSIABApplicationRouterAdapterTests.swift; sourceTree = "<group>"; };
9097
/* End PBXFileReference section */
9198

9299
/* Begin PBXFrameworksBuildPhase section */
@@ -102,6 +109,7 @@
102109
buildActionMask = 2147483647;
103110
files = (
104111
7575CF6A2BFCEE6F008F3FD0 /* OSInAppBrowserLib.framework in Frameworks */,
112+
887287832E717E8F00D9E41B /* ViewInspector in Frameworks */,
105113
);
106114
runOnlyForDeploymentPostprocessing = 0;
107115
};
@@ -209,6 +217,8 @@
209217
7575CF6D2BFCEE6F008F3FD0 /* OSInAppBrowserLibTests */ = {
210218
isa = PBXGroup;
211219
children = (
220+
887287902E7194D800D9E41B /* OSIABApplicationRouterAdapterTests.swift */,
221+
8872877F2E717C4600D9E41B /* WebView */,
212222
7575CF7E2BFCEEEA008F3FD0 /* Helper Files */,
213223
75EF1AFC2C1306B1005D7164 /* OSIABCacheManagerTests.swift */,
214224
7575CF7D2BFCEEEA008F3FD0 /* OSIABEngineTests.swift */,
@@ -230,6 +240,23 @@
230240
path = "Helper Files";
231241
sourceTree = "<group>";
232242
};
243+
8872877E2E717C4600D9E41B /* Views */ = {
244+
isa = PBXGroup;
245+
children = (
246+
8872878A2E71806200D9E41B /* OSIABWebView_ViewInspectorTests.swift */,
247+
8872878E2E7192C200D9E41B /* OSIABWebViewRepresentableTests.swift */,
248+
);
249+
path = Views;
250+
sourceTree = "<group>";
251+
};
252+
8872877F2E717C4600D9E41B /* WebView */ = {
253+
isa = PBXGroup;
254+
children = (
255+
8872877E2E717C4600D9E41B /* Views */,
256+
);
257+
path = WebView;
258+
sourceTree = "<group>";
259+
};
233260
/* End PBXGroup section */
234261

235262
/* Begin PBXHeadersBuildPhase section */
@@ -309,6 +336,9 @@
309336
Base,
310337
);
311338
mainGroup = 7575CF572BFCEE6F008F3FD0;
339+
packageReferences = (
340+
887287812E717E8F00D9E41B /* XCRemoteSwiftPackageReference "ViewInspector" */,
341+
);
312342
productRefGroup = 7575CF622BFCEE6F008F3FD0 /* Products */;
313343
projectDirPath = "";
314344
projectRoot = "";
@@ -394,12 +424,15 @@
394424
buildActionMask = 2147483647;
395425
files = (
396426
756346482C00DD4700685AA3 /* OSIABSafariViewControllerRouterAdapterTests.swift in Sources */,
427+
8872878F2E7192C200D9E41B /* OSIABWebViewRepresentableTests.swift in Sources */,
428+
8872878B2E71806200D9E41B /* OSIABWebView_ViewInspectorTests.swift in Sources */,
397429
75EF1AFB2C13069E005D7164 /* OSIABViewModelTests.swift in Sources */,
398430
7575CF812BFCEEEA008F3FD0 /* OSIABRouterSpy.swift in Sources */,
399431
75094A072C121BD9006843E1 /* OSIABCacheManagerStub.swift in Sources */,
400432
75EF1AFD2C1306B1005D7164 /* OSIABCacheManagerTests.swift in Sources */,
401433
7575CF802BFCEEEA008F3FD0 /* OSIABEngineTests.swift in Sources */,
402434
75EF1B012C134878005D7164 /* OSIABWebViewStub.swift in Sources */,
435+
887287912E7194D800D9E41B /* OSIABApplicationRouterAdapterTests.swift in Sources */,
403436
75094A052C1213A3006843E1 /* OSIABWebViewRouterAdapterTests.swift in Sources */,
404437
);
405438
runOnlyForDeploymentPostprocessing = 0;
@@ -619,7 +652,7 @@
619652
CODE_SIGN_STYLE = Automatic;
620653
CURRENT_PROJECT_VERSION = 5;
621654
GENERATE_INFOPLIST_FILE = YES;
622-
IPHONEOS_DEPLOYMENT_TARGET = 17.0;
655+
IPHONEOS_DEPLOYMENT_TARGET = 15.6;
623656
MARKETING_VERSION = 2.2.0;
624657
PRODUCT_BUNDLE_IDENTIFIER = com.outsystems.rd.inappbrowser.OSInAppBrowserLibTests;
625658
PRODUCT_NAME = "$(TARGET_NAME)";
@@ -641,7 +674,7 @@
641674
CODE_SIGN_STYLE = Automatic;
642675
CURRENT_PROJECT_VERSION = 5;
643676
GENERATE_INFOPLIST_FILE = YES;
644-
IPHONEOS_DEPLOYMENT_TARGET = 17.0;
677+
IPHONEOS_DEPLOYMENT_TARGET = 15.6;
645678
MARKETING_VERSION = 2.2.0;
646679
PRODUCT_BUNDLE_IDENTIFIER = com.outsystems.rd.inappbrowser.OSInAppBrowserLibTests;
647680
PRODUCT_NAME = "$(TARGET_NAME)";
@@ -685,6 +718,25 @@
685718
defaultConfigurationName = Release;
686719
};
687720
/* End XCConfigurationList section */
721+
722+
/* Begin XCRemoteSwiftPackageReference section */
723+
887287812E717E8F00D9E41B /* XCRemoteSwiftPackageReference "ViewInspector" */ = {
724+
isa = XCRemoteSwiftPackageReference;
725+
repositoryURL = "https://github.com/nalexn/ViewInspector";
726+
requirement = {
727+
kind = upToNextMajorVersion;
728+
minimumVersion = 0.10.2;
729+
};
730+
};
731+
/* End XCRemoteSwiftPackageReference section */
732+
733+
/* Begin XCSwiftPackageProductDependency section */
734+
887287822E717E8F00D9E41B /* ViewInspector */ = {
735+
isa = XCSwiftPackageProductDependency;
736+
package = 887287812E717E8F00D9E41B /* XCRemoteSwiftPackageReference "ViewInspector" */;
737+
productName = ViewInspector;
738+
};
739+
/* End XCSwiftPackageProductDependency section */
688740
};
689741
rootObject = 7575CF582BFCEE6F008F3FD0 /* Project object */;
690742
}

OSInAppBrowserLib.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved

Lines changed: 15 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<Scheme
3+
LastUpgradeVersion = "1640"
4+
version = "1.7">
5+
<BuildAction
6+
parallelizeBuildables = "YES"
7+
buildImplicitDependencies = "YES"
8+
buildArchitectures = "Automatic">
9+
</BuildAction>
10+
<TestAction
11+
buildConfiguration = "Debug"
12+
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
13+
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
14+
shouldUseLaunchSchemeArgsEnv = "YES"
15+
shouldAutocreateTestPlan = "YES">
16+
<Testables>
17+
<TestableReference
18+
skipped = "NO"
19+
parallelizable = "YES">
20+
<BuildableReference
21+
BuildableIdentifier = "primary"
22+
BlueprintIdentifier = "7575CF682BFCEE6F008F3FD0"
23+
BuildableName = "OSInAppBrowserLibTests.xctest"
24+
BlueprintName = "OSInAppBrowserLibTests"
25+
ReferencedContainer = "container:OSInAppBrowserLib.xcodeproj">
26+
</BuildableReference>
27+
</TestableReference>
28+
</Testables>
29+
</TestAction>
30+
<LaunchAction
31+
buildConfiguration = "Debug"
32+
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
33+
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
34+
launchStyle = "0"
35+
useCustomWorkingDirectory = "NO"
36+
ignoresPersistentStateOnLaunch = "NO"
37+
debugDocumentVersioning = "YES"
38+
debugServiceExtension = "internal"
39+
allowLocationSimulation = "YES">
40+
</LaunchAction>
41+
<ProfileAction
42+
buildConfiguration = "Release"
43+
shouldUseLaunchSchemeArgsEnv = "YES"
44+
savedToolIdentifier = ""
45+
useCustomWorkingDirectory = "NO"
46+
debugDocumentVersioning = "YES">
47+
</ProfileAction>
48+
<AnalyzeAction
49+
buildConfiguration = "Debug">
50+
</AnalyzeAction>
51+
<ArchiveAction
52+
buildConfiguration = "Release"
53+
revealArchiveInOrganizer = "YES">
54+
</ArchiveAction>
55+
</Scheme>
Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,35 @@
11
import UIKit
22

3-
/// Adapter that makes the required calls so that can perform the External Browser routing.
4-
public class OSIABApplicationRouterAdapter: OSIABRouter {
5-
public typealias ReturnType = Bool
6-
7-
/// Constructor method.
3+
public protocol URLOpener {
4+
func canOpenURL(_ url: URL) -> Bool
5+
func open(_ url: URL, completionHandler: ((Bool) -> Void)?)
6+
}
7+
8+
public class DefaultURLOpener: URLOpener {
89
public init() {}
910

11+
public func canOpenURL(_ url: URL) -> Bool {
12+
UIApplication.shared.canOpenURL(url)
13+
}
14+
15+
public func open(_ url: URL, completionHandler: ((Bool) -> Void)?) {
16+
UIApplication.shared.open(url, completionHandler: completionHandler ?? { _ in })
17+
}
18+
}
19+
20+
public class OSIABApplicationRouterAdapter: OSIABRouter {
21+
public typealias ReturnType = Bool
22+
23+
private let urlOpener: URLOpener
24+
25+
public init(urlOpener: URLOpener = DefaultURLOpener()) {
26+
self.urlOpener = urlOpener
27+
}
28+
1029
public func handleOpen(_ url: URL, _ completionHandler: @escaping (ReturnType) -> Void) {
11-
guard UIApplication.shared.canOpenURL(url) else { return completionHandler(false) }
12-
UIApplication.shared.open(url, completionHandler: completionHandler)
30+
guard urlOpener.canOpenURL(url) else {
31+
return completionHandler(false)
32+
}
33+
urlOpener.open(url, completionHandler: completionHandler)
1334
}
1435
}

Sources/OSInAppBrowserLib/WebView/OSIABWebViewModel.swift

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,14 @@ class OSIABWebViewModel: NSObject, ObservableObject {
3838
@Published private(set) var addressLabel: String = ""
3939

4040
private var cancellables = Set<AnyCancellable>()
41-
41+
42+
#if DEBUG
43+
/// Test-only method to set error for unit tests
44+
func setErrorForTesting(_ error: Error?) {
45+
self.error = error
46+
}
47+
#endif
48+
4249
/// Constructor method.
4350
/// - Parameters:
4451
/// - url: The current URL being displayed
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
import XCTest
2+
@testable import OSInAppBrowserLib
3+
4+
class MockURLOpener: URLOpener {
5+
var canOpenURLCalled = false
6+
var openCalled = false
7+
8+
var canOpenURLResult = true
9+
var lastOpenedURL: URL?
10+
var completionResult = true
11+
12+
func canOpenURL(_ url: URL) -> Bool {
13+
canOpenURLCalled = true
14+
return canOpenURLResult
15+
}
16+
17+
func open(_ url: URL, completionHandler: ((Bool) -> Void)?) {
18+
openCalled = true
19+
lastOpenedURL = url
20+
completionHandler?(completionResult)
21+
}
22+
}
23+
24+
final class OSIABApplicationRouterAdapterTests: XCTestCase {
25+
26+
func test_handleOpen_whenCanOpenURLIsFalse_shouldCallCompletionWithFalse() {
27+
let mock = MockURLOpener()
28+
mock.canOpenURLResult = false
29+
let sut = OSIABApplicationRouterAdapter(urlOpener: mock)
30+
31+
let expectation = XCTestExpectation(description: "Completion called")
32+
33+
sut.handleOpen(URL(string: "https://example.com")!) { success in
34+
XCTAssertFalse(success)
35+
XCTAssertTrue(mock.canOpenURLCalled)
36+
XCTAssertFalse(mock.openCalled)
37+
expectation.fulfill()
38+
}
39+
40+
wait(for: [expectation], timeout: 1)
41+
}
42+
43+
func test_handleOpen_whenCanOpenURLIsTrue_shouldOpenURL() {
44+
let mock = MockURLOpener()
45+
mock.canOpenURLResult = true
46+
mock.completionResult = true
47+
let sut = OSIABApplicationRouterAdapter(urlOpener: mock)
48+
49+
let url = URL(string: "https://example.com")!
50+
let expectation = XCTestExpectation(description: "Completion called")
51+
52+
sut.handleOpen(url) { success in
53+
XCTAssertTrue(success)
54+
XCTAssertTrue(mock.canOpenURLCalled)
55+
XCTAssertTrue(mock.openCalled)
56+
XCTAssertEqual(mock.lastOpenedURL, url)
57+
expectation.fulfill()
58+
}
59+
60+
wait(for: [expectation], timeout: 1)
61+
}
62+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import XCTest
2+
import WebKit
3+
@testable import OSInAppBrowserLib
4+
5+
final class OSIABWebViewRepresentableTests: XCTestCase {
6+
7+
func testInitializerStoresInjectedWebView() {
8+
let webView = WKWebView()
9+
let representable = OSIABWebViewRepresentable(webView)
10+
XCTAssertNotNil(representable)
11+
}
12+
}

0 commit comments

Comments
 (0)