Skip to content

Commit

Permalink
Fix unit tests crash
Browse files Browse the repository at this point in the history
  • Loading branch information
alessandroboron committed Nov 26, 2024
1 parent f40fb6c commit 2a77dee
Show file tree
Hide file tree
Showing 7 changed files with 51 additions and 20 deletions.
6 changes: 6 additions & 0 deletions DuckDuckGo.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -743,6 +743,8 @@
9F254AD92CF605310063B308 /* MockSSLErrorPageNavigationHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F254AD72CF605310063B308 /* MockSSLErrorPageNavigationHandler.swift */; };
9F254ADB2CF6120E0063B308 /* MockSpecialErrorPageNavigationDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F254ADA2CF6120E0063B308 /* MockSpecialErrorPageNavigationDelegate.swift */; };
9F254ADC2CF6120E0063B308 /* MockSpecialErrorPageNavigationDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F254ADA2CF6120E0063B308 /* MockSpecialErrorPageNavigationDelegate.swift */; };
9F254ADE2CF636CF0063B308 /* DummyWKNavigation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F254ADD2CF636CF0063B308 /* DummyWKNavigation.swift */; };
9F254ADF2CF636CF0063B308 /* DummyWKNavigation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F254ADD2CF636CF0063B308 /* DummyWKNavigation.swift */; };
9F46BEF82CD8D7490092E0EF /* OnboardingView+AddToDockContent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F46BEF72CD8D7490092E0EF /* OnboardingView+AddToDockContent.swift */; };
9F4CC5152C47AD08006A96EB /* ContextualOnboardingPresenterMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F4CC5142C47AD08006A96EB /* ContextualOnboardingPresenterMock.swift */; };
9F4CC5172C48B8D4006A96EB /* TabViewControllerDaxDialogTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F4CC5162C48B8D4006A96EB /* TabViewControllerDaxDialogTests.swift */; };
Expand Down Expand Up @@ -2572,6 +2574,7 @@
9F254AD42CF5E5B10063B308 /* DummyMaliciousSiteProtectionNavigationHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DummyMaliciousSiteProtectionNavigationHandler.swift; sourceTree = "<group>"; };
9F254AD72CF605310063B308 /* MockSSLErrorPageNavigationHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockSSLErrorPageNavigationHandler.swift; sourceTree = "<group>"; };
9F254ADA2CF6120E0063B308 /* MockSpecialErrorPageNavigationDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockSpecialErrorPageNavigationDelegate.swift; sourceTree = "<group>"; };
9F254ADD2CF636CF0063B308 /* DummyWKNavigation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DummyWKNavigation.swift; sourceTree = "<group>"; };
9F46BEF72CD8D7490092E0EF /* OnboardingView+AddToDockContent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "OnboardingView+AddToDockContent.swift"; sourceTree = "<group>"; };
9F4CC5142C47AD08006A96EB /* ContextualOnboardingPresenterMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContextualOnboardingPresenterMock.swift; sourceTree = "<group>"; };
9F4CC5162C48B8D4006A96EB /* TabViewControllerDaxDialogTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabViewControllerDaxDialogTests.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -4910,6 +4913,7 @@
9F254AD42CF5E5B10063B308 /* DummyMaliciousSiteProtectionNavigationHandler.swift */,
9F254AD72CF605310063B308 /* MockSSLErrorPageNavigationHandler.swift */,
9F254ADA2CF6120E0063B308 /* MockSpecialErrorPageNavigationDelegate.swift */,
9F254ADD2CF636CF0063B308 /* DummyWKNavigation.swift */,
);
path = TestDoubles;
sourceTree = "<group>";
Expand Down Expand Up @@ -8191,6 +8195,7 @@
85D2187224BF24F2004373D2 /* NotFoundCachingDownloaderTests.swift in Sources */,
C1935A242C89CC6D001AD72D /* AutofillHeaderViewFactoryTests.swift in Sources */,
C111B26927F579EF006558B1 /* BookmarkOrFolderTests.swift in Sources */,
9F254ADF2CF636CF0063B308 /* DummyWKNavigation.swift in Sources */,
6F7BACD42CEE084B00F561D8 /* OmniBarEqualityCheckTests.swift in Sources */,
6F7FB8E72C66197E00867DA7 /* NewTabPageSectionsSettingsModelTests.swift in Sources */,
851CD674244D7E6000331B98 /* UserDefaultsExtension.swift in Sources */,
Expand Down Expand Up @@ -8371,6 +8376,7 @@
9F254AD62CF5E5B10063B308 /* DummyMaliciousSiteProtectionNavigationHandler.swift in Sources */,
85F21DB0210F5E32002631A6 /* AtbIntegrationTests.swift in Sources */,
9F254AD22CF5D3A80063B308 /* MockSpecialErrorWebView.swift in Sources */,
9F254ADE2CF636CF0063B308 /* DummyWKNavigation.swift in Sources */,
8551912724746EDC0010FDD0 /* SnapshotHelper.swift in Sources */,
9F254ADB2CF6120E0063B308 /* MockSpecialErrorPageNavigationDelegate.swift in Sources */,
9F254ACC2CF5CDC60063B308 /* SpecialErrorPageNavigationHandlerTests.swift in Sources */,
Expand Down
8 changes: 8 additions & 0 deletions DuckDuckGo/SpecialErrorPage/SpecialErrorPageInterfaces.swift
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,14 @@ protocol SpecialErrorPageNavigationDelegate: AnyObject {
func closeSpecialErrorPageTab()
}

// MARK: - WebViewNavigation

/// For testing purposes.
protocol WebViewNavigation {}

// Used in tests. WKNavigation() crashes on deinit when initialising it manually.
// As workaround we used to Swizzle the implementation of deinit in tests.
// The problem with that approach is that when running different test suites it is possible that unrelated tests re-set the original implementation of deinit while other tests are running.
// This cause the app to crash as the original implementation is executed.
// Defining a protocol for WKNavigation and using mocks such as DummyWKNavigation in tests resolves the problem.
extension WKNavigation: WebViewNavigation {}
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ extension SpecialErrorPageNavigationHandler: WebViewNavigationHandling {
sslErrorPageNavigationHandler.handleServerTrustChallenge(challenge, completionHandler: completionHandler)
}

func handleWebView(_ webView: WKWebView, didFailProvisionalNavigation navigation: WKNavigation!, withError error: NSError) {
func handleWebView(_ webView: WKWebView, didFailProvisionalNavigation navigation: WebViewNavigation, withError error: NSError) {
guard let (url, sslErrorType, specialErrorData) = sslErrorPageNavigationHandler.makeNewRequestURLAndSpecialErrorDataIfEnabled(error: error) else { return }
failedURL = url
sslErrorPageNavigationHandler.errorPageVisited(errorType: sslErrorType)
Expand All @@ -90,7 +90,7 @@ extension SpecialErrorPageNavigationHandler: WebViewNavigationHandling {
loadSpecialErrorPage(url: url)
}

func handleWebView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
func handleWebView(_ webView: WKWebView, didFinish navigation: WebViewNavigation) {
userScript?.isEnabled = webView.url == failedURL
if webView.url != failedURL {
isSpecialErrorPageVisible = false
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,10 @@ final class SSLSpecialErrorPageTests: XCTestCase {
let featureFlagger = MockFeatureFlagger()
featureFlagger.enabledFeatureFlags = [.sslCertificatesBypass]
sut = SSLErrorPageNavigationHandler(urlCredentialCreator: MockCredentialCreator(), featureFlagger: featureFlagger)
WKNavigation.swizzleDealloc()
}

override func tearDown() async throws {
try await super.tearDown()
await WKNavigation.restoreDealloc()
sut = nil
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,12 @@ final class SpecialErrorPageNavigationHandlerIntegrationTests {
sslErrorPageNavigationHandler: sslErrorPageNavigationHandler,
maliciousSiteProtectionNavigationHandler: DummyMaliciousSiteProtectionNavigationHandler()
)
WKNavigation.swizzleDealloc()
}

deinit {
sslErrorPageNavigationHandler = nil
sut = nil
webView = nil
WKNavigation.restoreDealloc()
}

@MainActor
Expand All @@ -68,7 +66,7 @@ final class SpecialErrorPageNavigationHandlerIntegrationTests {
}

// WHEN
sut.handleWebView(webView, didFailProvisionalNavigation: WKNavigation(), withError: error)
sut.handleWebView(webView, didFailProvisionalNavigation: DummyWKNavigation(), withError: error)

// THEN
let html = try #require(expectedHTML)
Expand Down Expand Up @@ -102,7 +100,7 @@ final class SpecialErrorPageNavigationHandlerIntegrationTests {
}

// WHEN
sut.handleWebView(webView, didFailProvisionalNavigation: WKNavigation(), withError: error)
sut.handleWebView(webView, didFailProvisionalNavigation: DummyWKNavigation(), withError: error)

// THEN
let html = try #require(expectedHTML)
Expand Down Expand Up @@ -136,7 +134,7 @@ final class SpecialErrorPageNavigationHandlerIntegrationTests {
}

// WHEN
sut.handleWebView(webView, didFailProvisionalNavigation: WKNavigation(), withError: error)
sut.handleWebView(webView, didFailProvisionalNavigation: DummyWKNavigation(), withError: error)

// THEN
let html = try #require(expectedHTML)
Expand Down Expand Up @@ -170,7 +168,7 @@ final class SpecialErrorPageNavigationHandlerIntegrationTests {
}

// WHEN
sut.handleWebView(webView, didFailProvisionalNavigation: WKNavigation(), withError: error)
sut.handleWebView(webView, didFailProvisionalNavigation: DummyWKNavigation(), withError: error)

// THEN
let html = try #require(expectedHTML)
Expand All @@ -195,7 +193,7 @@ final class SpecialErrorPageNavigationHandlerIntegrationTests {
#expect(script.isEnabled == false)

// WHEN
sut.handleWebView(webView, didFinish: WKNavigation())
sut.handleWebView(webView, didFinish: DummyWKNavigation())

// THEN
#expect(script.isEnabled == false)
Expand All @@ -215,11 +213,11 @@ final class SpecialErrorPageNavigationHandlerIntegrationTests {
sut.setUserScript(script)
sut.attachWebView(webView)
// Fail the request with a different URL.
sut.handleWebView(webView, didFailProvisionalNavigation: WKNavigation(), withError: error)
sut.handleWebView(webView, didFailProvisionalNavigation: DummyWKNavigation(), withError: error)
#expect(script.isEnabled == false)

// WHEN
sut.handleWebView(webView, didFinish: WKNavigation())
sut.handleWebView(webView, didFinish: DummyWKNavigation())

// THEN
#expect(script.isEnabled == false)
Expand All @@ -234,7 +232,7 @@ final class SpecialErrorPageNavigationHandlerIntegrationTests {
let script = SpecialErrorPageUserScript(localeStrings: "", languageCode: "")
sut.setUserScript(script)
sut.attachWebView(webView)
let navigation = WKNavigation()
let navigation = DummyWKNavigation()
let error = NSError(
domain: "test",
code: NSURLErrorServerCertificateUntrusted,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,12 @@ final class SpecialErrorPageNavigationHandlerTests {
sslErrorPageNavigationHandler: sslErrorPageNavigationHandler,
maliciousSiteProtectionNavigationHandler: DummyMaliciousSiteProtectionNavigationHandler()
)
WKNavigation.swizzleDealloc()
}

deinit {
sslErrorPageNavigationHandler = nil
sut = nil
webView = nil
WKNavigation.restoreDealloc()
}

@Test("Receive Challenge forward event to SSL Error Page Navigation Handler")
Expand All @@ -65,7 +63,7 @@ final class SpecialErrorPageNavigationHandlerTests {
@Test("Leave Site forward event to SSL Error Page Navigation Handler")
func whenLeaveSite_AndSSLError_ThenCallLeaveSiteOnSSLErrorPageNavigationHandler() {
// GIVEN
sut.handleWebView(webView, didFailProvisionalNavigation: WKNavigation(), withError: .genericSSL)
sut.handleWebView(webView, didFailProvisionalNavigation: DummyWKNavigation(), withError: .genericSSL)
#expect(!sslErrorPageNavigationHandler.didCallLeaveSite)

// WHEN
Expand Down Expand Up @@ -115,7 +113,7 @@ final class SpecialErrorPageNavigationHandlerTests {
@Test("Visit Site forward event to SSL Error Page Navigation Handler")
func whenVisitSite_AndSSLError_ThenCallVisitSiteOnSSLErrorPageNavigationHandler() {
// GIVEN
sut.handleWebView(webView, didFailProvisionalNavigation: WKNavigation(), withError: .genericSSL)
sut.handleWebView(webView, didFailProvisionalNavigation: DummyWKNavigation(), withError: .genericSSL)
#expect(!sslErrorPageNavigationHandler.didCallVisitSite)

// WHEN
Expand All @@ -135,7 +133,7 @@ final class SpecialErrorPageNavigationHandlerTests {
func whenVisitSite_ThenSetIsSpecialErrorPageVisibleToFalseAndReloadPage() {
// GIVEN
sut.attachWebView(webView)
sut.handleWebView(webView, didFailProvisionalNavigation: WKNavigation(), withError: .genericSSL)
sut.handleWebView(webView, didFailProvisionalNavigation: DummyWKNavigation(), withError: .genericSSL)
#expect(sut.isSpecialErrorPageVisible)
#expect(!webView.didCallReload)

Expand All @@ -150,7 +148,7 @@ final class SpecialErrorPageNavigationHandlerTests {
@Test("Advanced Info Presented forward event to SSL Error Page Navigation Handler")
func whenAdvancedInfoPresented_AndSSLError_ThenCallAdvancedInfoPresentedOnSSLErrorPageNavigationHandler() {
// GIVEN
sut.handleWebView(webView, didFailProvisionalNavigation: WKNavigation(), withError: .genericSSL)
sut.handleWebView(webView, didFailProvisionalNavigation: DummyWKNavigation(), withError: .genericSSL)
#expect(!sslErrorPageNavigationHandler.didCalladvancedInfoPresented)

// WHEN
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
//

Check failure on line 1 in DuckDuckGoTests/SpecialErrorPage/TestDoubles/DummyWKNavigation.swift

View workflow job for this annotation

GitHub Actions / SwiftLint

Header comments should be consistent with project patterns (file_header)
// MockWKNavigation.swift
// DuckDuckGo
//
// Copyright © 2024 DuckDuckGo. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

import Foundation
@testable import DuckDuckGo

final class DummyWKNavigation: WebViewNavigation {}

0 comments on commit 2a77dee

Please sign in to comment.