diff --git a/.github/workflows/sync-end-to-end.yml b/.github/workflows/sync-end-to-end.yml
new file mode 100644
index 0000000000..df2a04df7c
--- /dev/null
+++ b/.github/workflows/sync-end-to-end.yml
@@ -0,0 +1,63 @@
+name: Sync-End-to-End tests
+
+on:
+ schedule:
+ - cron: '0 5 * * *' # run at 5 AM UTC
+
+jobs:
+ sync-end-to-end-tests:
+ name: Sync End to end Tests
+ runs-on: macos-13
+
+ steps:
+ - name: Check out the code
+ uses: actions/checkout@v3
+ with:
+ submodules: recursive
+
+ - name: Set cache key hash
+ run: |
+ has_only_tags=$(jq '[ .object.pins[].state | has("version") ] | all' DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved)
+ if [[ "$has_only_tags" == "true" ]]; then
+ echo "cache_key_hash=${{ hashFiles('DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved') }}" >> $GITHUB_ENV
+ else
+ echo "Package.resolved contains dependencies specified by branch or commit, skipping cache."
+ fi
+
+ - name: Cache SPM
+ if: env.cache_key_hash
+ uses: actions/cache@v3
+ with:
+ path: DerivedData/SourcePackages
+ key: ${{ runner.os }}-spm-${{ env.cache_key_hash }}
+ restore-keys: |
+ ${{ runner.os }}-spm-
+
+ - name: Select Xcode
+ run: sudo xcode-select -s /Applications/Xcode_$(<.xcode-version).app/Contents/Developer
+
+ - name: Build for tests
+ run: |
+ set -o pipefail && xcodebuild \
+ -scheme "DuckDuckGo" \
+ -destination "platform=iOS Simulator,name=iPhone 14,OS=16.4" \
+ -derivedDataPath "DerivedData" \
+ | tee xcodebuild.log
+
+ - name: Create test account for Sync and return the recovery code
+ uses: duckduckgo/sync_crypto/action@main
+ id: sync-recovery-code
+ with:
+ debug: true
+
+ - name: Sync e2e tests
+ uses: mobile-dev-inc/action-maestro-cloud@v1.6.0
+ with:
+ api-key: ${{ secrets.MAESTRO_CLOUD_API_KEY }}
+ app-file: DerivedData/Build/Products/Debug-iphonesimulator/DuckDuckGo.app
+ workspace: .maestro
+ include-tags: sync
+ env: |
+ CODE=${{ steps.sync-recovery-code.outputs.recovery-code }}
+
+
diff --git a/.gitignore b/.gitignore
index d6fc1c4859..f723942232 100644
--- a/.gitignore
+++ b/.gitignore
@@ -70,9 +70,6 @@ fastlane/report.xml
fastlane/Preview.html
fastlane/test_output
-# Mestro
-.maestro/**/shared
-
# DuckDuckGo
Configuration/ExternalDeveloper.xcconfig
diff --git a/.maestro/shared/set_internal_user.yaml b/.maestro/shared/set_internal_user.yaml
new file mode 100644
index 0000000000..97d6e6c9c4
--- /dev/null
+++ b/.maestro/shared/set_internal_user.yaml
@@ -0,0 +1,10 @@
+appId: com.duckduckgo.mobile.ios
+---
+
+- scroll
+- scroll
+- scroll
+- assertVisible: Debug Menu
+- tapOn: Debug Menu
+- tapOn: Internal User State
+- tapOn: Settings
\ No newline at end of file
diff --git a/.maestro/shared/sync_create.yaml b/.maestro/shared/sync_create.yaml
new file mode 100644
index 0000000000..8164466ac3
--- /dev/null
+++ b/.maestro/shared/sync_create.yaml
@@ -0,0 +1,12 @@
+appId: com.duckduckgo.mobile.ios
+---
+
+- assertVisible: Sync
+- tapOn: Sync
+- assertVisible: Sync
+- tapOn: "0"
+- assertVisible: Turn on Sync?
+- tapOn: Turn on Sync
+- tapOn: Sync Another Device
+- tapOn: Show QR Code
+- assertVisible: "Go to Settings > Sync in the DuckDuckGo App on a different device and scan this QR code to sync."
\ No newline at end of file
diff --git a/.maestro/shared/sync_delete.yaml b/.maestro/shared/sync_delete.yaml
new file mode 100644
index 0000000000..a82919c953
--- /dev/null
+++ b/.maestro/shared/sync_delete.yaml
@@ -0,0 +1,9 @@
+appId: com.duckduckgo.mobile.ios
+---
+
+- assertVisible: Sync
+- scroll
+- tapOn:
+ point: 50%,91% # TODO: Revisit after new setup flow has been implemented.
+- assertVisible: Delete Server Data?
+- tapOn: Delete Server Data
\ No newline at end of file
diff --git a/.maestro/sync_tests/01_create_account.yaml b/.maestro/sync_tests/01_create_account.yaml
new file mode 100644
index 0000000000..6e39ee2fd4
--- /dev/null
+++ b/.maestro/sync_tests/01_create_account.yaml
@@ -0,0 +1,29 @@
+appId: com.duckduckgo.mobile.ios
+tags:
+ - sync
+
+---
+
+- clearState
+- launchApp
+- runFlow:
+ when:
+ visible:
+ text: "Let’s Do It!"
+ index: 0
+ file: ../shared/onboarding.yaml
+
+- tapOn: Settings
+- runFlow:
+ file: ../shared/set_internal_user.yaml
+- runFlow:
+ file: ../shared/sync_create.yaml
+
+
+# Clean up
+- tapOn: Back
+- tapOn: Cancel
+- tapOn: Not Now
+- assertVisible: Sync
+- runFlow:
+ file: ../shared/sync_delete.yaml
\ No newline at end of file
diff --git a/.maestro/sync_tests/02_login_account.yaml b/.maestro/sync_tests/02_login_account.yaml
new file mode 100644
index 0000000000..aef46f2912
--- /dev/null
+++ b/.maestro/sync_tests/02_login_account.yaml
@@ -0,0 +1,45 @@
+appId: com.duckduckgo.mobile.ios
+tags:
+ - sync
+
+---
+
+# Create an account
+- clearState
+- launchApp
+- runFlow:
+ when:
+ visible:
+ text: "Let’s Do It!"
+ index: 0
+ file: ../shared/onboarding.yaml
+
+- tapOn: Settings
+- runFlow:
+ file: ../shared/set_internal_user.yaml
+- runFlow:
+ file: ../shared/sync_create.yaml
+
+# Copy Sync Code and Log Out
+- tapOn: Back
+- tapOn: Cancel
+- assertVisible: Save Recovery Key
+- tapOn: Copy Key
+- tapOn: Not Now
+- tapOn: "1"
+- assertVisible: Turn Off Sync?
+- tapOn: Remove
+
+# Login
+- tapOn: "0"
+- tapOn: Recover Your Synced Data
+- tapOn: Manually Enter Code
+- tapOn: Paste
+- assertVisible: Device Synced!
+- tapOn: Next
+- tapOn: Not Now
+
+# Clean up
+- assertVisible: Sync
+- runFlow:
+ file: ../shared/sync_delete.yaml
\ No newline at end of file
diff --git a/.maestro/sync_tests/03_recover_account.yaml b/.maestro/sync_tests/03_recover_account.yaml
new file mode 100644
index 0000000000..265684b884
--- /dev/null
+++ b/.maestro/sync_tests/03_recover_account.yaml
@@ -0,0 +1,51 @@
+appId: com.duckduckgo.mobile.ios
+tags:
+ - sync
+
+---
+
+- clearState
+- launchApp
+- runFlow:
+ when:
+ visible:
+ text: "Let’s Do It!"
+ index: 0
+ file: ../shared/onboarding.yaml
+
+# This is a workaround to:
+# - Put the code in the clipboard on Maestro Cloud
+# - Prevent iOS from showing the Paste permission alert as Maestro can't handle it
+- tapOn:
+ id: searchEntry
+- inputText: ${CODE}
+- longPressOn:
+ id: searchEntry
+- tapOn: Select All
+- tapOn: Cut
+- tapOn:
+ id: searchEntry
+- longPressOn:
+ id: searchEntry
+- tapOn: Paste
+- tapOn: Cancel
+#
+
+# Recover Account test
+- tapOn: Settings
+- runFlow:
+ file: ../shared/set_internal_user.yaml
+- assertVisible: Sync
+- tapOn: Sync
+- assertVisible: Sync
+- tapOn: "0"
+- assertVisible: Turn on Sync?
+- tapOn: Recover Your Synced Data
+- assertVisible: Scan QR Code
+- tapOn: Manually Enter Code
+- tapOn: Paste
+- assertVisible: Device Synced!
+- tapOn: Next
+- tapOn: Not Now
+- tapOn: Settings
+- tapOn: Done
\ No newline at end of file
diff --git a/.maestro/sync_tests/04_sync_data.yaml b/.maestro/sync_tests/04_sync_data.yaml
new file mode 100644
index 0000000000..643cd1a431
--- /dev/null
+++ b/.maestro/sync_tests/04_sync_data.yaml
@@ -0,0 +1,162 @@
+appId: com.duckduckgo.mobile.ios
+tags:
+ - sync
+
+---
+
+- clearState
+- launchApp
+- runFlow:
+ when:
+ visible:
+ text: "Let’s Do It!"
+ index: 0
+ file: ../shared/onboarding.yaml
+
+# Add local favorite and bookmark
+- tapOn:
+ id: searchEntry
+- inputText: www.duckduckgo.com
+- pressKey: Enter
+- runFlow:
+ when:
+ visible:
+ text: "Got It"
+ commands:
+ - tapOn: Got It
+- tapOn: Browsing Menu
+- tapOn: Add Favorite
+- tapOn:
+ id: searchEntry
+- inputText: www.spreadprivacy.com
+- pressKey: Enter
+- tapOn: Browsing Menu
+- tapOn: Add Bookmark
+
+# Add local login
+- tapOn: Browsing Menu
+- tapOn: Settings
+- tapOn: Logins
+- tapOn: Add 24
+- tapOn: Title
+- inputText: My Personal Website
+- tapOn: username@example.com
+- inputText: me@mypersonalwebsite.com
+- tapOn: example.com
+- inputText: mypersonalwebsite.com
+- tapOn: Save
+- tapOn: Logins
+- tapOn: Settings
+- tapOn: Done
+
+# Sync data
+# This is a workaround to:
+# - Put the code in the clipboard on Maestro Cloud
+# - Prevent iOS from showing the Paste permission alert as Maestro can't handle it
+- tapOn:
+ id: searchEntry
+- inputText: ${CODE}
+- longPressOn:
+ id: searchEntry
+- runFlow:
+ when:
+ visible:
+ text: searchEntry
+ commands:
+ - tapOn: searchEntry
+- tapOn: Select All
+- tapOn: Cut
+- tapOn:
+ id: searchEntry
+- longPressOn:
+ id: searchEntry
+- tapOn: Paste
+- tapOn: Cancel
+
+- tapOn: Close Tabs and Clear Data
+- tapOn: Close Tabs and Clear Data
+- runFlow:
+ when:
+ visible:
+ text: "Cancel"
+ commands:
+ - tapOn: Cancel
+#
+
+- tapOn: Settings
+- runFlow:
+ file: ../shared/set_internal_user.yaml
+- assertVisible: Sync
+- tapOn: Sync
+- assertVisible: Sync
+- tapOn: "0"
+- assertVisible: Turn on Sync?
+- tapOn: Recover Your Synced Data
+- assertVisible: Scan QR Code
+- tapOn: Manually Enter Code
+- tapOn: Paste
+- assertVisible: Device Synced!
+- tapOn: Next
+- tapOn: Not Now
+- tapOn: Settings
+- tapOn: Done
+
+# Verify bookmarks and favorites have been merged
+- tapOn: Bookmarks
+
+- assertVisible: Spread Privacy
+- assertVisible: Stack Overflow - Where Developers Learn, Share, & Build Careers
+- assertVisible: DuckDuckGo — Privacy, simplified.
+- assertVisible: DuckDuckGo · GitHub
+- assertVisible: "Wolfram|Alpha: Computational Intelligence"
+- assertVisible: news
+- assertVisible: code
+- assertVisible: sports
+- tapOn: news
+- assertVisible: Breaking News, Latest News and Videos | CNN
+- assertVisible: News, sport and opinion from the Guardian's global edition | The Guardian
+- tapOn: Bookmarks
+- tapOn: code
+- assertVisible: "GitHub - duckduckgo/Android: DuckDuckGo Android App"
+- assertVisible: "GitHub - duckduckgo/iOS: DuckDuckGo iOS Application"
+- tapOn: Bookmarks
+- tapOn: sports
+- assertVisible: NFL.com | Official Site of the National Football League
+- assertVisible: AS.com - Diario online deportivo. Fútbol, motor y mucho más
+- tapOn: Bookmarks
+- tapOn: Favorites
+- assertVisible: DuckDuckGo — Privacy, simplified.
+- assertVisible: NFL.com | Official Site of the National Football League
+- assertVisible: DuckDuckGo · GitHub
+- assertVisible: Stack Overflow - Where Developers Learn, Share, & Build Careers
+- tapOn: Done
+
+# Verify logins
+- tapOn: Settings
+- tapOn: Logins
+- assertVisible: Unlock device to access saved Logins
+- tapOn: Passcode field
+- inputText: "0000"
+- pressKey: Enter
+- assertVisible: Dax Login
+- tapOn: Dax Login
+- assertVisible: daxthetest
+- assertVisible: duckduckgo.com
+- tapOn: Logins
+- assertVisible: Github
+- tapOn: Github
+- assertVisible: githubusername
+- assertVisible: github.com
+- tapOn: Logins
+- assertVisible: StackOverflow
+- tapOn: StackOverflow
+- assertVisible: stacker
+- assertVisible: stackoverflow.com
+- tapOn: Logins
+- assertVisible: My Personal Website
+- tapOn: My Personal Website
+- assertVisible: me@mypersonalwebsite.com
+- assertVisible: mypersonalwebsite.com
+- tapOn: Logins
+- tapOn: Settings
+- tapOn: Done
\ No newline at end of file
diff --git a/DuckDuckGo/AppDelegate.swift b/DuckDuckGo/AppDelegate.swift
index 7856e35272..9b3a32e512 100644
--- a/DuckDuckGo/AppDelegate.swift
+++ b/DuckDuckGo/AppDelegate.swift
@@ -62,7 +62,11 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
private lazy var privacyStore = PrivacyUserDefaults()
private var bookmarksDatabase: CoreDataDatabase = BookmarksDatabase.make()
+
+#if APP_TRACKING_PROTECTION
private var appTrackingProtectionDatabase: CoreDataDatabase = AppTrackingProtectionDatabase.make()
+#endif
+
private var autoClear: AutoClear?
private var showKeyboardIfSettingOn = true
private var lastBackgroundDate: Date?
@@ -200,6 +204,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
WidgetCenter.shared.reloadAllTimelines()
}
+#if APP_TRACKING_PROTECTION
appTrackingProtectionDatabase.loadStore { context, error in
guard context != nil else {
if let error = error {
@@ -216,6 +221,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
}
}
}
+#endif
Favicons.shared.migrateFavicons(to: Favicons.Constants.maxFaviconSize) {
WidgetCenter.shared.reloadAllTimelines()
@@ -258,12 +264,20 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
syncService.initializeIfNeeded()
self.syncService = syncService
+#if APP_TRACKING_PROTECTION
let main = MainViewController(bookmarksDatabase: bookmarksDatabase,
bookmarksDatabaseCleaner: syncDataProviders.bookmarksAdapter.databaseCleaner,
appTrackingProtectionDatabase: appTrackingProtectionDatabase,
syncService: syncService,
syncDataProviders: syncDataProviders,
appSettings: AppDependencyProvider.shared.appSettings)
+#else
+ let main = MainViewController(bookmarksDatabase: bookmarksDatabase,
+ bookmarksDatabaseCleaner: syncDataProviders.bookmarksAdapter.databaseCleaner,
+ syncService: syncService,
+ syncDataProviders: syncDataProviders,
+ appSettings: AppDependencyProvider.shared.appSettings)
+#endif
main.loadViewIfNeeded()
window = UIWindow(frame: UIScreen.main.bounds)
diff --git a/DuckDuckGo/BrokenSiteInfo.swift b/DuckDuckGo/BrokenSiteInfo.swift
index 063784c78f..9a1ed49e6e 100644
--- a/DuckDuckGo/BrokenSiteInfo.swift
+++ b/DuckDuckGo/BrokenSiteInfo.swift
@@ -24,11 +24,6 @@ public struct BrokenSiteInfo {
static let allowedQueryReservedCharacters = CharacterSet(charactersIn: ",")
- enum ProtectionsState: String {
- case enabled = "1"
- case disabled = "0"
- }
-
private struct Keys {
static let url = "siteUrl"
static let category = "category"
@@ -60,14 +55,14 @@ public struct BrokenSiteInfo {
private let manufacturer: String
private let systemVersion: String
private let gpc: Bool
- private let protectionsState: ProtectionsState
+ private let protectionsState: Bool
public init(url: URL?, httpsUpgrade: Bool,
blockedTrackerDomains: [String], installedSurrogates: [String],
isDesktop: Bool, tdsETag: String?,
ampUrl: String?,
urlParametersRemoved: Bool,
- protected: Bool,
+ protectionsState: Bool,
model: String = UIDevice.current.model,
manufacturer: String = "Apple",
systemVersion: String = UIDevice.current.systemVersion,
@@ -84,7 +79,7 @@ public struct BrokenSiteInfo {
self.model = model
self.manufacturer = manufacturer
self.systemVersion = systemVersion
- self.protectionsState = protected ? .enabled : .disabled
+ self.protectionsState = protectionsState
if let gpcParam = gpc {
self.gpc = gpcParam
@@ -111,7 +106,7 @@ public struct BrokenSiteInfo {
Keys.gpc: gpc ? "true" : "false",
Keys.ampUrl: ampUrl ?? "",
Keys.urlParametersRemoved: urlParametersRemoved ? "true" : "false",
- Keys.protectionsState: protectionsState.rawValue
+ Keys.protectionsState: protectionsState ? "true" : "false"
]
Pixel.fire(pixel: .brokenSiteReport,
diff --git a/DuckDuckGo/HomeViewController.swift b/DuckDuckGo/HomeViewController.swift
index f938dca3c1..4f97f8c46b 100644
--- a/DuckDuckGo/HomeViewController.swift
+++ b/DuckDuckGo/HomeViewController.swift
@@ -69,6 +69,7 @@ class HomeViewController: UIViewController {
private let appTPHomeViewModel: AppTPHomeViewModel
#endif
+#if APP_TRACKING_PROTECTION
static func loadFromStoryboard(model: Tab, favoritesViewModel: FavoritesListInteracting, appTPDatabase: CoreDataDatabase) -> HomeViewController {
let storyboard = UIStoryboard(name: "Home", bundle: nil)
let controller = storyboard.instantiateViewController(identifier: "HomeViewController", creator: { coder in
@@ -76,18 +77,33 @@ class HomeViewController: UIViewController {
})
return controller
}
-
+#else
+ static func loadFromStoryboard(model: Tab, favoritesViewModel: FavoritesListInteracting) -> HomeViewController {
+ let storyboard = UIStoryboard(name: "Home", bundle: nil)
+ let controller = storyboard.instantiateViewController(identifier: "HomeViewController", creator: { coder in
+ HomeViewController(coder: coder, tabModel: model, favoritesViewModel: favoritesViewModel)
+ })
+ return controller
+ }
+#endif
+
+#if APP_TRACKING_PROTECTION
required init?(coder: NSCoder, tabModel: Tab, favoritesViewModel: FavoritesListInteracting, appTPDatabase: CoreDataDatabase) {
self.tabModel = tabModel
self.favoritesViewModel = favoritesViewModel
-
-#if APP_TRACKING_PROTECTION
self.appTPHomeViewModel = AppTPHomeViewModel(appTrackingProtectionDatabase: appTPDatabase)
-#endif
super.init(coder: coder)
}
-
+#else
+ required init?(coder: NSCoder, tabModel: Tab, favoritesViewModel: FavoritesListInteracting) {
+ self.tabModel = tabModel
+ self.favoritesViewModel = favoritesViewModel
+
+ super.init(coder: coder)
+ }
+#endif
+
required init?(coder: NSCoder) {
fatalError("Not implemented")
}
diff --git a/DuckDuckGo/MainViewController+KeyCommands.swift b/DuckDuckGo/MainViewController+KeyCommands.swift
index e1229209d2..f7fffded92 100644
--- a/DuckDuckGo/MainViewController+KeyCommands.swift
+++ b/DuckDuckGo/MainViewController+KeyCommands.swift
@@ -110,7 +110,13 @@ extension MainViewController {
UIKeyCommand(title: "", action: #selector(keyboardEscape), input: UIKeyCommand.inputEscape, modifierFlags: [])
]
- return [alwaysAvailable, browsingCommands, findInPageCommands, arrowKeys, other].flatMap { $0 }
+ let commands = [alwaysAvailable, browsingCommands, findInPageCommands, arrowKeys, other].flatMap { $0 }
+ if #available(iOS 15, *) {
+ commands.forEach {
+ $0.wantsPriorityOverSystemBehavior = true
+ }
+ }
+ return commands
}
@objc func keyboardMoveSelectionUp() {
diff --git a/DuckDuckGo/MainViewController.swift b/DuckDuckGo/MainViewController.swift
index 8a84b48ed3..445153f922 100644
--- a/DuckDuckGo/MainViewController.swift
+++ b/DuckDuckGo/MainViewController.swift
@@ -79,8 +79,11 @@ class MainViewController: UIViewController {
let previewsSource = TabPreviewsSource()
let appSettings: AppSettings
private var launchTabObserver: LaunchTabNotification.Observer?
-
+
+#if APP_TRACKING_PROTECTION
private let appTrackingProtectionDatabase: CoreDataDatabase
+#endif
+
let bookmarksDatabase: CoreDataDatabase
private weak var bookmarksDatabaseCleaner: BookmarkDatabaseCleaner?
private var favoritesViewModel: FavoritesListInteracting
@@ -134,6 +137,7 @@ class MainViewController: UIViewController {
var viewCoordinator: MainViewCoordinator!
+#if APP_TRACKING_PROTECTION
init(
bookmarksDatabase: CoreDataDatabase,
bookmarksDatabaseCleaner: BookmarkDatabaseCleaner,
@@ -156,6 +160,27 @@ class MainViewController: UIViewController {
bindFavoritesDisplayMode()
bindSyncService()
}
+#else
+ init(
+ bookmarksDatabase: CoreDataDatabase,
+ bookmarksDatabaseCleaner: BookmarkDatabaseCleaner,
+ syncService: DDGSyncing,
+ syncDataProviders: SyncDataProviders,
+ appSettings: AppSettings
+ ) {
+ self.bookmarksDatabase = bookmarksDatabase
+ self.bookmarksDatabaseCleaner = bookmarksDatabaseCleaner
+ self.syncService = syncService
+ self.syncDataProviders = syncDataProviders
+ self.favoritesViewModel = FavoritesListViewModel(bookmarksDatabase: bookmarksDatabase)
+ self.bookmarksCachingSearch = BookmarksCachingSearch(bookmarksStore: CoreDataBookmarksSearchStore(bookmarksStore: bookmarksDatabase))
+ self.appSettings = appSettings
+
+ super.init(nibName: nil, bundle: nil)
+
+ bindSyncService()
+ }
+#endif
fileprivate var tabCountInfo: TabCountInfo?
@@ -616,10 +641,15 @@ class MainViewController: UIViewController {
AppDependencyProvider.shared.homePageConfiguration.refresh()
let tabModel = currentTab?.tabModel
+
+#if APP_TRACKING_PROTECTION
let controller = HomeViewController.loadFromStoryboard(model: tabModel!,
favoritesViewModel: favoritesViewModel,
appTPDatabase: appTrackingProtectionDatabase)
-
+#else
+ let controller = HomeViewController.loadFromStoryboard(model: tabModel!, favoritesViewModel: favoritesViewModel)
+#endif
+
homeController = controller
controller.chromeDelegate = self
@@ -756,8 +786,8 @@ class MainViewController: UIViewController {
allowContentUnderflow = false
request()
guard let tab = currentTab else { fatalError("no tab") }
- select(tab: tab)
dismissOmniBar()
+ select(tab: tab)
}
private func addTab(url: URL?, inheritedAttribution: AdClickAttributionLogic.State?) {
diff --git a/DuckDuckGo/TabViewController.swift b/DuckDuckGo/TabViewController.swift
index 89711c3924..2220dbebe6 100644
--- a/DuckDuckGo/TabViewController.swift
+++ b/DuckDuckGo/TabViewController.swift
@@ -870,7 +870,7 @@ class TabViewController: UIViewController {
let blockedTrackerDomains = privacyInfo?.trackerInfo.trackersBlocked.compactMap { $0.domain } ?? []
let configuration = ContentBlocking.shared.privacyConfigurationManager.privacyConfig
- let protected = configuration.isFeature(.contentBlocking, enabledForDomain: url?.host)
+ let protectionsState = configuration.isFeature(.contentBlocking, enabledForDomain: url?.host)
return BrokenSiteInfo(url: url,
httpsUpgrade: httpsForced,
@@ -880,7 +880,7 @@ class TabViewController: UIViewController {
tdsETag: ContentBlocking.shared.contentBlockingManager.currentMainRules?.etag ?? "",
ampUrl: linkProtection.lastAMPURLString,
urlParametersRemoved: linkProtection.urlParametersRemoved,
- protected: protected)
+ protectionsState: protectionsState)
}
public func print() {
diff --git a/DuckDuckGoTests/BrokenSiteReportingTests.swift b/DuckDuckGoTests/BrokenSiteReportingTests.swift
index 82b3d25c2a..e65fb7f268 100644
--- a/DuckDuckGoTests/BrokenSiteReportingTests.swift
+++ b/DuckDuckGoTests/BrokenSiteReportingTests.swift
@@ -75,7 +75,7 @@ final class BrokenSiteReportingTests: XCTestCase {
tdsETag: test.blocklistVersion,
ampUrl: nil,
urlParametersRemoved: false,
- protected: true,
+ protectionsState: true,
model: test.model ?? "",
manufacturer: test.manufacturer ?? "",
systemVersion: test.os ?? "",
diff --git a/IntegrationTests/ContentBlockingRulesTests.swift b/IntegrationTests/ContentBlockingRulesTests.swift
index a03e8bdcc6..723fa8bec8 100644
--- a/IntegrationTests/ContentBlockingRulesTests.swift
+++ b/IntegrationTests/ContentBlockingRulesTests.swift
@@ -33,10 +33,10 @@ class ContentBlockingRulesTests: XCTestCase {
andTemporaryUnprotectedDomains: [])
// Test tracker is set up to be blocked
- if let rule = rules.findExactFilter(filter: "^(https?)?(wss?)?://([a-z0-9-]+\\.)*googleadservices\\.com(:?[0-9]+)?/.*") {
+ if let rule = rules.findExactFilter(filter: "^(https?)?(wss?)?://([a-z0-9-]+\\.)*bad\\.third-party\\.site(:?[0-9]+)?/.*") {
XCTAssert(rule.action == .block())
} else {
- XCTFail("Missing google ad services rule")
+ XCTFail("Missing tracking rule")
}
// Test exceptiions are set to ignore previous rules