Skip to content

Commit 6568825

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

File tree

5 files changed

+279
-3
lines changed

5 files changed

+279
-3
lines changed

OSInAppBrowserLib.xcodeproj/project.pbxproj

Lines changed: 46 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@
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 */; };
4345
/* End PBXBuildFile section */
4446

4547
/* Begin PBXContainerItemProxy section */
@@ -87,6 +89,7 @@
8789
75EF1AFA2C13069E005D7164 /* OSIABViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OSIABViewModelTests.swift; sourceTree = "<group>"; };
8890
75EF1AFC2C1306B1005D7164 /* OSIABCacheManagerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OSIABCacheManagerTests.swift; sourceTree = "<group>"; };
8991
75EF1B002C134878005D7164 /* OSIABWebViewStub.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OSIABWebViewStub.swift; sourceTree = "<group>"; };
92+
8872878A2E71806200D9E41B /* OSIABWebView_ViewInspectorTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OSIABWebView_ViewInspectorTests.swift; sourceTree = "<group>"; };
9093
/* End PBXFileReference section */
9194

9295
/* Begin PBXFrameworksBuildPhase section */
@@ -102,6 +105,7 @@
102105
buildActionMask = 2147483647;
103106
files = (
104107
7575CF6A2BFCEE6F008F3FD0 /* OSInAppBrowserLib.framework in Frameworks */,
108+
887287832E717E8F00D9E41B /* ViewInspector in Frameworks */,
105109
);
106110
runOnlyForDeploymentPostprocessing = 0;
107111
};
@@ -209,6 +213,7 @@
209213
7575CF6D2BFCEE6F008F3FD0 /* OSInAppBrowserLibTests */ = {
210214
isa = PBXGroup;
211215
children = (
216+
8872877F2E717C4600D9E41B /* WebView */,
212217
7575CF7E2BFCEEEA008F3FD0 /* Helper Files */,
213218
75EF1AFC2C1306B1005D7164 /* OSIABCacheManagerTests.swift */,
214219
7575CF7D2BFCEEEA008F3FD0 /* OSIABEngineTests.swift */,
@@ -230,6 +235,22 @@
230235
path = "Helper Files";
231236
sourceTree = "<group>";
232237
};
238+
8872877E2E717C4600D9E41B /* Views */ = {
239+
isa = PBXGroup;
240+
children = (
241+
8872878A2E71806200D9E41B /* OSIABWebView_ViewInspectorTests.swift */,
242+
);
243+
path = Views;
244+
sourceTree = "<group>";
245+
};
246+
8872877F2E717C4600D9E41B /* WebView */ = {
247+
isa = PBXGroup;
248+
children = (
249+
8872877E2E717C4600D9E41B /* Views */,
250+
);
251+
path = WebView;
252+
sourceTree = "<group>";
253+
};
233254
/* End PBXGroup section */
234255

235256
/* Begin PBXHeadersBuildPhase section */
@@ -309,6 +330,9 @@
309330
Base,
310331
);
311332
mainGroup = 7575CF572BFCEE6F008F3FD0;
333+
packageReferences = (
334+
887287812E717E8F00D9E41B /* XCRemoteSwiftPackageReference "ViewInspector" */,
335+
);
312336
productRefGroup = 7575CF622BFCEE6F008F3FD0 /* Products */;
313337
projectDirPath = "";
314338
projectRoot = "";
@@ -394,6 +418,7 @@
394418
buildActionMask = 2147483647;
395419
files = (
396420
756346482C00DD4700685AA3 /* OSIABSafariViewControllerRouterAdapterTests.swift in Sources */,
421+
8872878B2E71806200D9E41B /* OSIABWebView_ViewInspectorTests.swift in Sources */,
397422
75EF1AFB2C13069E005D7164 /* OSIABViewModelTests.swift in Sources */,
398423
7575CF812BFCEEEA008F3FD0 /* OSIABRouterSpy.swift in Sources */,
399424
75094A072C121BD9006843E1 /* OSIABCacheManagerStub.swift in Sources */,
@@ -619,7 +644,7 @@
619644
CODE_SIGN_STYLE = Automatic;
620645
CURRENT_PROJECT_VERSION = 5;
621646
GENERATE_INFOPLIST_FILE = YES;
622-
IPHONEOS_DEPLOYMENT_TARGET = 17.0;
647+
IPHONEOS_DEPLOYMENT_TARGET = 15.6;
623648
MARKETING_VERSION = 2.2.0;
624649
PRODUCT_BUNDLE_IDENTIFIER = com.outsystems.rd.inappbrowser.OSInAppBrowserLibTests;
625650
PRODUCT_NAME = "$(TARGET_NAME)";
@@ -641,7 +666,7 @@
641666
CODE_SIGN_STYLE = Automatic;
642667
CURRENT_PROJECT_VERSION = 5;
643668
GENERATE_INFOPLIST_FILE = YES;
644-
IPHONEOS_DEPLOYMENT_TARGET = 17.0;
669+
IPHONEOS_DEPLOYMENT_TARGET = 15.6;
645670
MARKETING_VERSION = 2.2.0;
646671
PRODUCT_BUNDLE_IDENTIFIER = com.outsystems.rd.inappbrowser.OSInAppBrowserLibTests;
647672
PRODUCT_NAME = "$(TARGET_NAME)";
@@ -685,6 +710,25 @@
685710
defaultConfigurationName = Release;
686711
};
687712
/* End XCConfigurationList section */
713+
714+
/* Begin XCRemoteSwiftPackageReference section */
715+
887287812E717E8F00D9E41B /* XCRemoteSwiftPackageReference "ViewInspector" */ = {
716+
isa = XCRemoteSwiftPackageReference;
717+
repositoryURL = "https://github.com/nalexn/ViewInspector";
718+
requirement = {
719+
kind = upToNextMajorVersion;
720+
minimumVersion = 0.10.2;
721+
};
722+
};
723+
/* End XCRemoteSwiftPackageReference section */
724+
725+
/* Begin XCSwiftPackageProductDependency section */
726+
887287822E717E8F00D9E41B /* ViewInspector */ = {
727+
isa = XCSwiftPackageProductDependency;
728+
package = 887287812E717E8F00D9E41B /* XCRemoteSwiftPackageReference "ViewInspector" */;
729+
productName = ViewInspector;
730+
};
731+
/* End XCSwiftPackageProductDependency section */
688732
};
689733
rootObject = 7575CF582BFCEE6F008F3FD0 /* Project object */;
690734
}

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>

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: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
import XCTest
2+
import ViewInspector
3+
@testable import OSInAppBrowserLib
4+
5+
final class OSIABWebViewViewInspectorTests: XCTestCase {
6+
func testToolbarAppearsAtTop() throws {
7+
let model = OSIABWebViewModel(
8+
url: URL(string: "https://test.com")!,
9+
webViewConfiguration: .init(),
10+
uiModel: .init(
11+
showURL: true,
12+
showToolbar: true,
13+
toolbarPosition: .top,
14+
showNavigationButtons: true,
15+
leftToRight: false,
16+
closeButtonText: "Close"
17+
),
18+
callbackHandler: .init(
19+
onDelegateURL: { _ in },
20+
onDelegateAlertController: { _ in },
21+
onBrowserPageLoad: {},
22+
onBrowserClosed: { _ in },
23+
onBrowserPageNavigationCompleted: { _ in }
24+
)
25+
)
26+
let view = OSIABWebView(model)
27+
let vStack = try view.inspect().vStack()
28+
// Toolbar should be the first element
29+
XCTAssertNoThrow(try vStack.hStack(0))
30+
}
31+
32+
func testToolbarAppearsAtBottom() throws {
33+
let model = OSIABWebViewModel(
34+
url: URL(string: "https://test.com")!,
35+
webViewConfiguration: .init(),
36+
uiModel: .init(
37+
showURL: true,
38+
showToolbar: true,
39+
toolbarPosition: .bottom,
40+
showNavigationButtons: true,
41+
leftToRight: false,
42+
closeButtonText: "Close"
43+
),
44+
callbackHandler: .init(
45+
onDelegateURL: { _ in },
46+
onDelegateAlertController: { _ in },
47+
onBrowserPageLoad: {},
48+
onBrowserClosed: { _ in },
49+
onBrowserPageNavigationCompleted: { _ in }
50+
)
51+
)
52+
let view = OSIABWebView(model)
53+
let vStack = try view.inspect().vStack()
54+
// Toolbar should be the last element
55+
XCTAssertNoThrow(try vStack.view(OSIABNavigationView.self, 2))
56+
}
57+
58+
func testErrorViewAppears() throws {
59+
let model = OSIABWebViewModel(
60+
url: URL(string: "https://test.com")!,
61+
webViewConfiguration: .init(),
62+
uiModel: .init(
63+
showURL: true,
64+
showToolbar: true,
65+
toolbarPosition: .top,
66+
showNavigationButtons: true,
67+
leftToRight: false,
68+
closeButtonText: "Close"
69+
),
70+
callbackHandler: .init(
71+
onDelegateURL: { _ in },
72+
onDelegateAlertController: { _ in },
73+
onBrowserPageLoad: {},
74+
onBrowserClosed: { _ in },
75+
onBrowserPageNavigationCompleted: { _ in }
76+
)
77+
)
78+
// Simulate error using test-only method
79+
model.setErrorForTesting(NSError(domain: "Test", code: 1, userInfo: nil))
80+
let view = OSIABWebView(model)
81+
let vStack = try view.inspect().vStack()
82+
// Error view should be present
83+
XCTAssertNoThrow(try vStack.view(OSIABErrorView.self, 1))
84+
}
85+
86+
func testCloseButtonAction() throws {
87+
var closed = false
88+
let model = OSIABWebViewModel(
89+
url: URL(string: "https://test.com")!,
90+
webViewConfiguration: .init(),
91+
uiModel: .init(
92+
showURL: true,
93+
showToolbar: true,
94+
toolbarPosition: .top,
95+
showNavigationButtons: true,
96+
leftToRight: false,
97+
closeButtonText: "Close"
98+
),
99+
callbackHandler: .init(
100+
onDelegateURL: { _ in },
101+
onDelegateAlertController: { _ in },
102+
onBrowserPageLoad: {},
103+
onBrowserClosed: { _ in closed = true },
104+
onBrowserPageNavigationCompleted: { _ in }
105+
)
106+
)
107+
let view = OSIABWebView(model)
108+
let vStack = try view.inspect().vStack()
109+
let hStack = try vStack.hStack(0)
110+
// Find the button with label "Close"
111+
var found = false
112+
for idx in 0..<hStack.count {
113+
if let label = try? hStack.button(idx).labelView().text().string(), label == "Close" {
114+
try hStack.button(idx).tap()
115+
found = true
116+
break
117+
}
118+
}
119+
XCTAssertTrue(found, "Close button not found")
120+
XCTAssertTrue(closed)
121+
}
122+
123+
func testLoadURLCalledOnAppear() throws {
124+
class TestModel: OSIABWebViewModel {
125+
var loadURLCalled = false
126+
override func loadURL() {
127+
super.loadURL()
128+
loadURLCalled = true
129+
}
130+
}
131+
let model = TestModel(
132+
url: URL(string: "https://test.com")!,
133+
webViewConfiguration: .init(),
134+
uiModel: .init(
135+
showURL: true,
136+
showToolbar: true,
137+
toolbarPosition: .top,
138+
showNavigationButtons: true,
139+
leftToRight: false,
140+
closeButtonText: "Close"
141+
),
142+
callbackHandler: .init(
143+
onDelegateURL: { _ in },
144+
onDelegateAlertController: { _ in },
145+
onBrowserPageLoad: {},
146+
onBrowserClosed: { _ in },
147+
onBrowserPageNavigationCompleted: { _ in }
148+
)
149+
)
150+
let view = OSIABWebView(model)
151+
let vStack = try view.inspect().vStack()
152+
_ = try vStack.callOnAppear()
153+
XCTAssertTrue(model.loadURLCalled)
154+
}
155+
}

0 commit comments

Comments
 (0)