Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tespach/phishing detection tests #3222

Merged
Show file tree
Hide file tree
Changes from 28 commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
06d77ff
Add tests
not-a-rootkit Sep 5, 2024
4036618
Cleanup tests
not-a-rootkit Sep 5, 2024
350b28d
Make integration tests more robust.
not-a-rootkit Sep 6, 2024
e036f34
Remove sleeps from tests.
not-a-rootkit Sep 6, 2024
0faf308
Fix redirect chains breaking error page navigation flows.
not-a-rootkit Sep 6, 2024
d90bf24
Simplify - remove what should be in UI tests
not-a-rootkit Sep 6, 2024
f3b6954
Add feature disabled test case
not-a-rootkit Sep 6, 2024
8d7f520
Swiftlint fix
not-a-rootkit Sep 6, 2024
e97623a
Replace .none reload with .redirect
not-a-rootkit Sep 6, 2024
ec85c3f
Add ErrorPageTabExtension tests for phishing
not-a-rootkit Sep 6, 2024
3923cf5
Add DuckURLSchemeHandler tests
not-a-rootkit Sep 6, 2024
b5e74f6
Simplify testDidNotLoadAndStartDataActivities_IfFeatureDisabled
not-a-rootkit Sep 6, 2024
fa52d22
Remove duplicate tests
not-a-rootkit Sep 6, 2024
e103d7e
Add privacyDashboardIntegrationTest for phishingInfo
not-a-rootkit Sep 6, 2024
bf578d9
Remove duplicate PhishingDetection initialization
not-a-rootkit Sep 6, 2024
25d4559
Test disable integration tests
not-a-rootkit Sep 6, 2024
03b77e7
Revert .load and return .none instead of .redirect
not-a-rootkit Sep 6, 2024
ee06b77
Rewrite integration tests to look at tab.error instead of url
not-a-rootkit Sep 6, 2024
132192d
Refactor UnitTests to fix handling .load instead of .redirect.
not-a-rootkit Sep 6, 2024
ae0a792
Add extra checks to determine remote test failure.
not-a-rootkit Sep 9, 2024
717b052
Merge branch 'tespach/phishing-detection-integration' into tespach/ph…
not-a-rootkit Sep 9, 2024
c49e0bb
Update featureFlagger references.
not-a-rootkit Sep 9, 2024
7558e35
Inject always-true feature flagger into PhishingDetection
not-a-rootkit Sep 9, 2024
9fe5de9
Inject PrivacyConfigManager
not-a-rootkit Sep 9, 2024
494c11c
Split redirect chain tests into two separate test cases
not-a-rootkit Sep 9, 2024
7a07edc
Remove flaky tests- repeatedRedirectChains
not-a-rootkit Sep 9, 2024
ee19078
Replace HTTP redirect chain test.
not-a-rootkit Sep 9, 2024
fdef653
Use privacy-test-pages.site as test origin.
not-a-rootkit Sep 9, 2024
0b89b22
Add feature disabled test
not-a-rootkit Sep 9, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 20 additions & 2 deletions DuckDuckGo.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -2703,6 +2703,10 @@
CD34F0C12C886482006826BE /* PhishingDetectionMocks.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD34F0BF2C886482006826BE /* PhishingDetectionMocks.swift */; };
CD34F0C22C886482006826BE /* PhishingDetectionMocks.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD34F0BF2C886482006826BE /* PhishingDetectionMocks.swift */; };
CD34F0C42C8869FF006826BE /* PhishingDetection in Frameworks */ = {isa = PBXBuildFile; productRef = CD34F0C32C8869FF006826BE /* PhishingDetection */; };
CD89DD612C89E08D0080F9AF /* PhishingDetectionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD89DD5D2C89E08D0080F9AF /* PhishingDetectionTests.swift */; };
CD89DD622C89E08D0080F9AF /* PhishingDetectionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD89DD5D2C89E08D0080F9AF /* PhishingDetectionTests.swift */; };
CD89DD652C89E0BB0080F9AF /* PhishingDetectionIntegrationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD89DD632C89E0BB0080F9AF /* PhishingDetectionIntegrationTests.swift */; };
CD89DD662C89E0BB0080F9AF /* PhishingDetectionIntegrationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD89DD632C89E0BB0080F9AF /* PhishingDetectionIntegrationTests.swift */; };
D64A5FF82AEA5C2B00B6D6E7 /* HomeButtonMenuFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = D64A5FF72AEA5C2B00B6D6E7 /* HomeButtonMenuFactory.swift */; };
D64A5FF92AEA5C2B00B6D6E7 /* HomeButtonMenuFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = D64A5FF72AEA5C2B00B6D6E7 /* HomeButtonMenuFactory.swift */; };
D6BC8AC62C5A95AA0025375B /* DuckPlayer in Frameworks */ = {isa = PBXBuildFile; productRef = D6BC8AC52C5A95AA0025375B /* DuckPlayer */; };
Expand Down Expand Up @@ -4408,6 +4412,8 @@
CD33012B2C89B588009AA127 /* ErrorPageHTMLFactory.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ErrorPageHTMLFactory.swift; sourceTree = "<group>"; };
CD33012F2C89B602009AA127 /* ErrorPageHTMLFactoryTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ErrorPageHTMLFactoryTests.swift; sourceTree = "<group>"; };
CD34F0BF2C886482006826BE /* PhishingDetectionMocks.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PhishingDetectionMocks.swift; sourceTree = "<group>"; };
CD89DD5D2C89E08D0080F9AF /* PhishingDetectionTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PhishingDetectionTests.swift; sourceTree = "<group>"; };
CD89DD632C89E0BB0080F9AF /* PhishingDetectionIntegrationTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PhishingDetectionIntegrationTests.swift; sourceTree = "<group>"; };
CDE248A32C821FFE00F9399D /* hashPrefixes.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = hashPrefixes.json; sourceTree = "<group>"; };
CDE248A42C821FFE00F9399D /* PhishingDetection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PhishingDetection.swift; sourceTree = "<group>"; };
CDE248A52C821FFE00F9399D /* PhishingDetectionPreferences.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PhishingDetectionPreferences.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -4717,7 +4723,6 @@
EE7295E32A545B9A008C0991 /* NetworkProtection in Frameworks */,
9807F645278CA16F00E1547B /* BrowserServicesKit in Frameworks */,
D6BC8AC62C5A95AA0025375B /* DuckPlayer in Frameworks */,
CDE248A02C821DF400F9399D /* PhishingDetection in Frameworks */,
987799ED299998B1005D8EB6 /* Bookmarks in Frameworks */,
1E950E3F2912A10D0051A99B /* ContentBlocking in Frameworks */,
31A3A4E32B0C115F0021063C /* DataBrokerProtection in Frameworks */,
Expand Down Expand Up @@ -5280,7 +5285,6 @@
isa = PBXGroup;
children = (
9D9DE5712C63A96400D20B15 /* AppKitExtensions */,
CDE2489E2C821DE800F9399D /* BrowserServicesKit */,
7B9167A82C09E88800322310 /* AppLauncher */,
378E279D2970217400FCADA2 /* BuildToolPlugins */,
3192A2702A4C4E330084EA89 /* DataBrokerProtection */,
Expand Down Expand Up @@ -5485,6 +5489,7 @@
B62A233E29C41D2D00D22475 /* History */,
B603973229BEF84900902A34 /* HTTPSUpgrade */,
B62A233A29C322A000D22475 /* NavigationProtection */,
CD89DD642C89E0BB0080F9AF /* PhishingDetection */,
B603973629BF0E9400902A34 /* PrivacyDashboard */,
B644B43C29D56811003FA9AB /* Tab */,
4B1AD91625FC46FB00261379 /* CoreDataEncryptionTests.swift */,
Expand Down Expand Up @@ -8783,6 +8788,7 @@
isa = PBXGroup;
children = (
CD34F0C02C886482006826BE /* Mocks */,
CD89DD5D2C89E08D0080F9AF /* PhishingDetectionTests.swift */,
);
path = PhishingDetection;
sourceTree = "<group>";
Expand All @@ -8795,6 +8801,14 @@
path = Mocks;
sourceTree = "<group>";
};
CD89DD642C89E0BB0080F9AF /* PhishingDetection */ = {
isa = PBXGroup;
children = (
CD89DD632C89E0BB0080F9AF /* PhishingDetectionIntegrationTests.swift */,
);
path = PhishingDetection;
sourceTree = "<group>";
};
CDE248A22C821FD500F9399D /* PhishingDetection */ = {
isa = PBXGroup;
children = (
Expand Down Expand Up @@ -11337,6 +11351,7 @@
3706FE75293F661700E42796 /* WebsiteBreakageReportTests.swift in Sources */,
56D145EF29E6DAD900E3488A /* DataImportProviderTests.swift in Sources */,
569277C529DEE09D00B633EF /* ContinueSetUpModelTests.swift in Sources */,
CD89DD622C89E08D0080F9AF /* PhishingDetectionTests.swift in Sources */,
3706FE76293F661700E42796 /* MockSecureVault.swift in Sources */,
F1AFDBD92C23221700710F2C /* SubscriptionAppStoreRestorerTests.swift in Sources */,
C1E961F32B87B273001760E1 /* MockAutofillActionExecutor.swift in Sources */,
Expand Down Expand Up @@ -11407,6 +11422,7 @@
3706FEA5293F662100E42796 /* CoreDataEncryptionTesting.xcdatamodeld in Sources */,
B603973D29BF1D7D00902A34 /* AutoconsentIntegrationTests.swift in Sources */,
B60C6F8729B1CAB2007BFAA8 /* TestRunHelper.swift in Sources */,
CD89DD662C89E0BB0080F9AF /* PhishingDetectionIntegrationTests.swift in Sources */,
B64CE01F2B8622D700126CA5 /* AddressBarTests.swift in Sources */,
B603972D29BEDF2100902A34 /* ExpectedNavigationExtension.swift in Sources */,
3706FEA6293F662100E42796 /* EncryptionKeyStoreTests.swift in Sources */,
Expand Down Expand Up @@ -11451,6 +11467,7 @@
B644B43D29D56829003FA9AB /* SearchNonexistentDomainTests.swift in Sources */,
B603973C29BF1D7D00902A34 /* AutoconsentIntegrationTests.swift in Sources */,
B60C6F8629B1CAB0007BFAA8 /* TestRunHelper.swift in Sources */,
CD89DD652C89E0BB0080F9AF /* PhishingDetectionIntegrationTests.swift in Sources */,
B64CE01E2B8622D700126CA5 /* AddressBarTests.swift in Sources */,
B603972C29BEDF2100902A34 /* ExpectedNavigationExtension.swift in Sources */,
4B1AD8D525FC38DD00261379 /* EncryptionKeyStoreTests.swift in Sources */,
Expand Down Expand Up @@ -12743,6 +12760,7 @@
857E5AFA2A7961FF00FC0FB4 /* PixelExperimentTests.swift in Sources */,
AAC9C01524CAFBCE00AD1325 /* TabTests.swift in Sources */,
B69B504C2726CA2900758A2B /* MockVariantManager.swift in Sources */,
CD89DD612C89E08D0080F9AF /* PhishingDetectionTests.swift in Sources */,
310E79BF294A19A8007C49E8 /* FireproofingReferenceTests.swift in Sources */,
B6BBF1722744CE36004F850E /* FireproofDomainsStoreMock.swift in Sources */,
4BA1A6D9258C0CB300F6F690 /* DataEncryptionTests.swift in Sources */,
Expand Down
34 changes: 26 additions & 8 deletions DuckDuckGo/PhishingDetection/PhishingDetection.swift
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ public class PhishingDetection: PhishingSiteDetecting {
private var detectionPreferences: PhishingDetectionPreferences
private var dataStore: PhishingDetectionDataSaving
private var featureFlagger: FeatureFlagger
private var config: PrivacyConfiguration
private var configManager: PrivacyConfigurationManaging
private var cancellable: AnyCancellable?
private let revision: Int
private let filterSetURL: URL
Expand All @@ -59,14 +59,16 @@ public class PhishingDetection: PhishingSiteDetecting {
updateManager: PhishingDetectionUpdateManaging? = nil,
dataActivities: PhishingDetectionDataActivityHandling? = nil,
detectionPreferences: PhishingDetectionPreferences = PhishingDetectionPreferences.shared,
featureFlagger: FeatureFlagger? = nil
featureFlagger: FeatureFlagger? = nil,
configManager: PrivacyConfigurationManaging? = nil
) {
self.revision = revision
self.filterSetURL = filterSetURL
self.filterSetDataSHA = filterSetDataSHA
self.hashPrefixURL = hashPrefixURL
self.hashPrefixDataSHA = hashPrefixDataSHA
self.featureFlagger = featureFlagger ?? NSApp.delegateTyped.featureFlagger
self.configManager = configManager ?? AppPrivacyFeatures.shared.contentBlocking.privacyConfigurationManager

let resolvedDependencies = PhishingDetection.resolveDependencies(
revision: revision,
Expand All @@ -87,7 +89,6 @@ public class PhishingDetection: PhishingSiteDetecting {
self.updateManager = resolvedDependencies.updateManager
self.dataActivities = resolvedDependencies.dataActivities
self.detectionPreferences = detectionPreferences
self.config = AppPrivacyFeatures.shared.contentBlocking.privacyConfigurationManager.privacyConfig

self.startUpdateTasksIfEnabled()
self.setupBindings()
Expand All @@ -96,12 +97,28 @@ public class PhishingDetection: PhishingSiteDetecting {
convenience init(
dataActivities: PhishingDetectionDataActivityHandling,
dataStore: PhishingDetectionDataSaving,
detector: PhishingDetecting
detector: PhishingDetecting,
configManager: PrivacyConfigurationManaging = AppPrivacyFeatures.shared.contentBlocking.privacyConfigurationManager
) {
self.init(
dataStore: dataStore,
detector: detector,
dataActivities: dataActivities
dataStore: dataStore, detector: detector, dataActivities: dataActivities,
detectionPreferences: PhishingDetectionPreferences.shared,
featureFlagger: NSApp.delegateTyped.featureFlagger,
configManager: configManager
)
}

convenience init(featureFlagger: FeatureFlagger, configManager: PrivacyConfigurationManaging) {
self.init(
detectionClient: PhishingDetectionAPIClient(),
dataProvider: nil,
dataStore: nil,
detector: nil,
updateManager: nil,
dataActivities: nil,
detectionPreferences: PhishingDetectionPreferences.shared,
featureFlagger: featureFlagger,
configManager: configManager
)
}

Expand Down Expand Up @@ -131,6 +148,7 @@ public class PhishingDetection: PhishingSiteDetecting {
let resolvedDetector = detector ?? PhishingDetector(apiClient: detectionClient, dataStore: resolvedDataStore)
let resolvedUpdateManager = updateManager ?? PhishingDetectionUpdateManager(client: detectionClient, dataStore: resolvedDataStore)
let resolvedDataActivities = dataActivities ?? PhishingDetectionDataActivities(phishingDetectionDataProvider: resolvedDataProvider, updateManager: resolvedUpdateManager)

return (resolvedDataStore, resolvedDetector, resolvedUpdateManager, resolvedDataActivities)
}

Expand All @@ -148,7 +166,7 @@ public class PhishingDetection: PhishingSiteDetecting {
}

public func checkIsMaliciousIfEnabled(url: URL) async -> Bool {
if config.isFeature(.phishingDetection, enabledForDomain: url.host),
if configManager.privacyConfig.isFeature(.phishingDetection, enabledForDomain: url.host),
detectionPreferences.isEnabled {
return await detector.isMalicious(url: url)
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ extension SpecialErrorPageTabExtension: NavigationResponder {
errorData = SpecialErrorData(kind: .phishing, domain: domain, eTldPlus1: tld.eTLDplus1(failingURL?.host))
if let errorURL = generateErrorPageURL(url) {
_ = webView?.load(URLRequest(url: errorURL))
return .cancel
return .none
}
} else {
return handleMaliciousIframe(navigationAction: navigationAction)
Expand All @@ -152,7 +152,7 @@ extension SpecialErrorPageTabExtension: NavigationResponder {

if let errorURL = generateErrorPageURL(iframeTopUrl) {
_ = webView?.load(URLRequest(url: errorURL))
return .cancel
return .none
}

return .next
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
//
// 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
not-a-rootkit marked this conversation as resolved.
Show resolved Hide resolved
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 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
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -86,4 +86,25 @@ class PrivacyDashboardIntegrationTests: XCTestCase {
XCTAssertEqual(trackersCount2, 0)
}

@MainActor
func testWhenPhishingDetected_phishingInfoUpdated() async throws {
let tabViewModel = self.tabViewModel
let tab = tabViewModel.tab

let isPhishingPromise = tab.privacyInfoPublisher
.compactMap {
$0?.$isPhishing
}
.map { _ in true }
.timeout(10)
.first()
.promise()
// Load the test page
let url = URL(string: "http://privacy-test-pages.site/security/badware/phishing.html")!
_ = await tab.setUrl(url, source: .link)?.result

let isPhishing = try await isPhishingPromise.value
XCTAssertTrue(isPhishing)
}

}
Loading
Loading