-
Notifications
You must be signed in to change notification settings - Fork 10
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Tespach/phishing detection tests (#3222)
Task/Issue URL: https://app.asana.com/0/0/1208196336229421/f Tech Design URL: CC: **Description**: Implement test cases for phishing detection error page, tab extension, and privacy dashboard. **Steps to test this PR**: 1. Run the UnitTests + IntegrationTests 2. Visit https://privacy-test-pages.site/security/badware/phishing.html 3. Ensure warning is thrown 4. Click through warning <!-- Tagging instructions If this PR isn't ready to be merged for whatever reason it should be marked with the `DO NOT MERGE` label (particularly if it's a draft) If it's pending Product Review/PFR, please add the `Pending Product Review` label. If at any point it isn't actively being worked on/ready for review/otherwise moving forward (besides the above PR/PFR exception) strongly consider closing it (or not opening it in the first place). If you decide not to close it, make sure it's labelled to make it clear the PRs state and comment with more information. --> **Definition of Done**: * [ ] Does this PR satisfy our [Definition of Done](https://app.asana.com/0/1202500774821704/1207634633537039/f)? --- ###### Internal references: [Pull Request Review Checklist](https://app.asana.com/0/1202500774821704/1203764234894239/f) [Software Engineering Expectations](https://app.asana.com/0/59792373528535/199064865822552) [Technical Design Template](https://app.asana.com/0/59792373528535/184709971311943) [Pull Request Documentation](https://app.asana.com/0/1202500774821704/1204012835277482/f)
- Loading branch information
1 parent
b939d61
commit 1c75030
Showing
9 changed files
with
505 additions
and
16 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
181 changes: 181 additions & 0 deletions
181
IntegrationTests/PhishingDetection/PhishingDetectionIntegrationTests.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,181 @@ | ||
// | ||
// PhishingDetectionIntegrationTests.swift | ||
// | ||
// 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 Combine | ||
import Common | ||
import XCTest | ||
import BrowserServicesKit | ||
import PhishingDetection | ||
|
||
@testable import DuckDuckGo_Privacy_Browser | ||
|
||
@available(macOS 12.0, *) | ||
class PhishingDetectionIntegrationTests: XCTestCase { | ||
|
||
var window: NSWindow! | ||
var cancellables: Set<AnyCancellable>! | ||
var phishingDetector: PhishingSiteDetecting! | ||
var tab: Tab! | ||
var tabViewModel: TabViewModel! | ||
|
||
@MainActor | ||
override func setUp() { | ||
super.setUp() | ||
WebTrackingProtectionPreferences.shared.isGPCEnabled = false | ||
PhishingDetectionPreferences.shared.isEnabled = true | ||
let featureFlagger = MockFeatureFlagger() | ||
phishingDetector = PhishingDetection(featureFlagger: featureFlagger, configManager: MockPrivacyConfigurationManager()) | ||
tab = Tab(content: .none, phishingDetector: phishingDetector) | ||
tabViewModel = TabViewModel(tab: tab) | ||
window = WindowsManager.openNewWindow(with: tab)! | ||
cancellables = Set<AnyCancellable>() | ||
} | ||
|
||
@MainActor | ||
override func tearDown() async throws { | ||
window.close() | ||
window = nil | ||
cancellables = nil | ||
phishingDetector = nil | ||
tab = nil | ||
tabViewModel = nil | ||
WebTrackingProtectionPreferences.shared.isGPCEnabled = true | ||
try await super.tearDown() | ||
} | ||
|
||
// MARK: - Tests | ||
|
||
@MainActor | ||
func testPhishingNotDetected_tabIsNotMarkedPhishing() async throws { | ||
try await loadUrl("http://privacy-test-pages.site/") | ||
let tabErrorCode2 = tabViewModel.tab.error?.errorCode | ||
XCTAssertNil(tabErrorCode2) | ||
} | ||
|
||
@MainActor | ||
func testPhishingDetected_tabIsMarkedPhishing() async throws { | ||
try await loadUrl("http://privacy-test-pages.site/security/badware/phishing.html") | ||
let url = URL(string: "http://privacy-test-pages.site/security/badware/phishing.html")! | ||
try await waitForTabToFinishLoading() | ||
let tabErrorCode = tabViewModel.tab.error?.errorCode | ||
XCTAssertEqual(tabErrorCode, PhishingDetectionError.detected.errorCode) | ||
} | ||
|
||
@MainActor | ||
func testFeatureDisabledAndPhishingDetection_tabIsNotMarkedPhishing() async throws { | ||
PhishingDetectionPreferences.shared.isEnabled = false | ||
try await loadUrl("http://privacy-test-pages.site/security/badware/phishing.html") | ||
let url = URL(string: "http://privacy-test-pages.site/security/badware/phishing.html")! | ||
try await waitForTabToFinishLoading() | ||
let tabErrorCode = tabViewModel.tab.error?.errorCode | ||
XCTAssertNil(tabErrorCode) | ||
} | ||
|
||
@MainActor | ||
func testPhishingDetectedThenNotDetected_tabIsNotMarkedPhishing() async throws { | ||
try await loadUrl("http://privacy-test-pages.site/security/badware/phishing.html") | ||
try await waitForTabToFinishLoading() | ||
let tabErrorCode = tabViewModel.tab.error?.errorCode | ||
XCTAssertEqual(tabErrorCode, PhishingDetectionError.detected.errorCode) | ||
|
||
try await loadUrl("http://broken.third-party.site/") | ||
try await waitForTabToFinishLoading() | ||
let tabErrorCode2 = tabViewModel.tab.error?.errorCode | ||
XCTAssertNil(tabErrorCode2) | ||
} | ||
|
||
@MainActor | ||
func testPhishingDetectedThenDDGLoaded_tabIsNotMarkedPhishing() async throws { | ||
try await loadUrl("http://privacy-test-pages.site/security/badware/phishing.html") | ||
try await waitForTabToFinishLoading() | ||
let tabErrorCode = tabViewModel.tab.error?.errorCode | ||
XCTAssertEqual(tabErrorCode, PhishingDetectionError.detected.errorCode) | ||
|
||
try await loadUrl("http://duckduckgo.com/") | ||
try await waitForTabToFinishLoading() | ||
let tabErrorCode2 = tabViewModel.tab.error?.errorCode | ||
XCTAssertNil(tabErrorCode2) | ||
} | ||
|
||
@MainActor | ||
func testPhishingDetectedViaHTTPRedirectChain_tabIsMarkedPhishing() async throws { | ||
try await loadUrl("http://bad.third-party.site/security/badware/phishing-redirect/") | ||
try await waitForTabToFinishLoading() | ||
let tabErrorCode = tabViewModel.tab.error?.errorCode | ||
XCTAssertEqual(tabErrorCode, PhishingDetectionError.detected.errorCode) | ||
} | ||
|
||
@MainActor | ||
func testPhishingDetectedRepeatedClientRedirectChains_tabIsMarkedPhishing() async throws { | ||
let urls = [ | ||
"http://privacy-test-pages.site/security/badware/phishing-js-redirector-helper.html", | ||
"http://privacy-test-pages.site/security/badware/phishing-js-redirector.html", | ||
"http://privacy-test-pages.site/security/badware/phishing-meta-redirect.html", | ||
] | ||
|
||
for url in urls { | ||
try await loadUrl(url) | ||
try await waitForTabToFinishLoading() | ||
let tabErrorCode = tabViewModel.tab.error?.errorCode | ||
XCTAssertEqual(tabErrorCode, PhishingDetectionError.detected.errorCode) | ||
} | ||
} | ||
|
||
@MainActor | ||
func testPhishingDetectedRepeatedServerRedirectChains_tabIsMarkedPhishing() async throws { | ||
let urls = [ | ||
"http://privacy-test-pages.site/security/badware/phishing-redirect/302", | ||
"http://privacy-test-pages.site/security/badware/phishing-redirect/js", | ||
"http://privacy-test-pages.site/security/badware/phishing-redirect/meta", | ||
"http://privacy-test-pages.site/security/badware/phishing-redirect/meta2" | ||
] | ||
|
||
for url in urls { | ||
try await loadUrl(url) | ||
try await waitForTabToFinishLoading() | ||
let tabErrorCode = tabViewModel.tab.error?.errorCode | ||
XCTAssertEqual(tabErrorCode, PhishingDetectionError.detected.errorCode) | ||
} | ||
} | ||
|
||
// MARK: - Helper Methods | ||
|
||
@MainActor | ||
private func loadUrl(_ urlString: String) async throws { | ||
guard let url = URL(string: urlString) else { return } | ||
_ = await tabViewModel.tab.setUrl(url, source: .link)?.result | ||
} | ||
|
||
@MainActor | ||
func waitForTabToFinishLoading() async throws { | ||
let loadingExpectation = expectation(description: "Tab finished loading") | ||
Task { | ||
while tabViewModel.tab.isLoading { | ||
await Task.yield() | ||
} | ||
loadingExpectation.fulfill() | ||
} | ||
await fulfillment(of: [loadingExpectation], timeout: 5) | ||
} | ||
} | ||
|
||
class MockFeatureFlagger: FeatureFlagger { | ||
func isFeatureOn<F>(forProvider: F) -> Bool where F: BrowserServicesKit.FeatureFlagSourceProviding { | ||
return true | ||
} | ||
} |
Oops, something went wrong.