From ca9356c060d5055040d15a95ea9facc7e6f55f49 Mon Sep 17 00:00:00 2001 From: Fernando Bunn Date: Tue, 13 Aug 2024 17:36:22 +0100 Subject: [PATCH 1/6] Change behavior of feature flag turned off (#3097) Task/Issue URL: https://app.asana.com/0/72649045549333/1208037869675970/f **Description**: If the feature flag for autoplay is turned off, we should send autoplay disabled to C-S-S --- DuckDuckGo/YoutubePlayer/DuckPlayer.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/DuckDuckGo/YoutubePlayer/DuckPlayer.swift b/DuckDuckGo/YoutubePlayer/DuckPlayer.swift index d1cd1602f3..7b1386d988 100644 --- a/DuckDuckGo/YoutubePlayer/DuckPlayer.swift +++ b/DuckDuckGo/YoutubePlayer/DuckPlayer.swift @@ -248,10 +248,10 @@ final class DuckPlayer { var isAutoplayEnabled = DuckPlayerPreferences.shared.duckPlayerAutoplay - /// If the feature flag is disabled, we want to turn autoPlay to true since this was the default + /// If the feature flag is disabled, we want to turn autoPlay to false /// https://app.asana.com/0/1204167627774280/1207906550241281/f if !isAutoplayFeatureEnabled { - isAutoplayEnabled = true + isAutoplayEnabled = false } // Disable WebView PiP if if the subFeature is off From 878252b62358fe901772d2b3d0a035cc12f5cbab Mon Sep 17 00:00:00 2001 From: Dax Mobile <44842493+daxmobile@users.noreply.github.com> Date: Tue, 13 Aug 2024 13:04:03 -0400 Subject: [PATCH 2/6] Update BSK with autofill 13.0.0 (#3088) Task/Issue URL: https://app.asana.com/0/1208019517385800/1208019517385800 Autofill Release: https://github.com/duckduckgo/duckduckgo-autofill/releases/tag/13.0.0 BSK PR: https://github.com/duckduckgo/BrowserServicesKit/pull/938 ## Description Updates Autofill to version [13.0.0](https://github.com/duckduckgo/duckduckgo-autofill/releases/tag/13.0.0). --- DuckDuckGo.xcodeproj/project.pbxproj | 2 +- .../xcshareddata/swiftpm/Package.resolved | 8 ++++---- LocalPackages/DataBrokerProtection/Package.swift | 2 +- LocalPackages/NetworkProtectionMac/Package.swift | 2 +- LocalPackages/SubscriptionUI/Package.swift | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/DuckDuckGo.xcodeproj/project.pbxproj b/DuckDuckGo.xcodeproj/project.pbxproj index 9c20a38a1c..0a3f086eae 100644 --- a/DuckDuckGo.xcodeproj/project.pbxproj +++ b/DuckDuckGo.xcodeproj/project.pbxproj @@ -13465,7 +13465,7 @@ repositoryURL = "https://github.com/duckduckgo/BrowserServicesKit"; requirement = { kind = exactVersion; - version = 183.0.0; + version = 183.0.1; }; }; 9FF521422BAA8FF300B9819B /* XCRemoteSwiftPackageReference "lottie-spm" */ = { diff --git a/DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index b73f4a2edd..f252c26951 100644 --- a/DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -32,8 +32,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/duckduckgo/BrowserServicesKit", "state" : { - "revision" : "c3ae1865ba36ebbcb5451a836424213ea875d135", - "version" : "183.0.0" + "revision" : "f0220c164618c7ca1cbf276db644d71711b0c76a", + "version" : "183.0.1" } }, { @@ -50,8 +50,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/duckduckgo/duckduckgo-autofill.git", "state" : { - "revision" : "9fea1c6762db726328b14bb9ebfd6508849eae28", - "version" : "12.1.0" + "revision" : "1f12b78d9bac4a1d9b6bad18dc2ef0593bed34a3", + "version" : "13.0.0" } }, { diff --git a/LocalPackages/DataBrokerProtection/Package.swift b/LocalPackages/DataBrokerProtection/Package.swift index 523146a87a..fa17f1c540 100644 --- a/LocalPackages/DataBrokerProtection/Package.swift +++ b/LocalPackages/DataBrokerProtection/Package.swift @@ -29,7 +29,7 @@ let package = Package( targets: ["DataBrokerProtection"]) ], dependencies: [ - .package(url: "https://github.com/duckduckgo/BrowserServicesKit", exact: "183.0.0"), + .package(url: "https://github.com/duckduckgo/BrowserServicesKit", exact: "183.0.1"), .package(path: "../SwiftUIExtensions"), .package(path: "../XPCHelper"), ], diff --git a/LocalPackages/NetworkProtectionMac/Package.swift b/LocalPackages/NetworkProtectionMac/Package.swift index f16de1d04a..4b72f71fe9 100644 --- a/LocalPackages/NetworkProtectionMac/Package.swift +++ b/LocalPackages/NetworkProtectionMac/Package.swift @@ -32,7 +32,7 @@ let package = Package( .library(name: "VPNAppLauncher", targets: ["VPNAppLauncher"]), ], dependencies: [ - .package(url: "https://github.com/duckduckgo/BrowserServicesKit", exact: "183.0.0"), + .package(url: "https://github.com/duckduckgo/BrowserServicesKit", exact: "183.0.1"), .package(url: "https://github.com/airbnb/lottie-spm", exact: "4.4.3"), .package(path: "../AppLauncher"), .package(path: "../UDSHelper"), diff --git a/LocalPackages/SubscriptionUI/Package.swift b/LocalPackages/SubscriptionUI/Package.swift index 7ebc01f10d..31b26c3215 100644 --- a/LocalPackages/SubscriptionUI/Package.swift +++ b/LocalPackages/SubscriptionUI/Package.swift @@ -12,7 +12,7 @@ let package = Package( targets: ["SubscriptionUI"]), ], dependencies: [ - .package(url: "https://github.com/duckduckgo/BrowserServicesKit", exact: "183.0.0"), + .package(url: "https://github.com/duckduckgo/BrowserServicesKit", exact: "183.0.1"), .package(path: "../SwiftUIExtensions") ], targets: [ From 6001f2574d538eec7e7debae9b5be078c169788e Mon Sep 17 00:00:00 2001 From: Pete Smith Date: Tue, 13 Aug 2024 20:40:22 +0200 Subject: [PATCH 3/6] Add and Throw Explicit Errors for DB Migration Failure Points (#3096) Task/Issue URL: https://app.asana.com/0/1206488453854252/1207802624568506/f **Description**: The PIR v3 migration can fail at three points: 1. Orphaned Record Cleanup 2. Table Recreation 3. Final Foreign Key Violation Check Currently, we throw an explicit error for #3, which is observable via Pixels. We should also throw explicit errors for #1 and #2. This PR adds these new errors. --- ...ProtectionDatabaseMigrationsProvider.swift | 40 +++++++++++++------ ...DataBrokerProtectionDatabaseProvider.swift | 1 - 2 files changed, 27 insertions(+), 14 deletions(-) diff --git a/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Storage/DataBrokerProtectionDatabaseMigrationsProvider.swift b/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Storage/DataBrokerProtectionDatabaseMigrationsProvider.swift index 486eed4811..628268ed37 100644 --- a/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Storage/DataBrokerProtectionDatabaseMigrationsProvider.swift +++ b/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Storage/DataBrokerProtectionDatabaseMigrationsProvider.swift @@ -20,6 +20,12 @@ import Foundation import GRDB import Common +enum DataBrokerProtectionDatabaseMigrationErrors: Error { + case deleteOrphanedRecordFailed + case recreateTablesFailed + case foreignKeyViolation +} + /// Conforming types provide migrations for the PIR database. Mostly utilized for testing. protocol DataBrokerProtectionDatabaseMigrationsProvider { static var v2Migrations: (inout DatabaseMigrator) throws -> Void { get } @@ -238,7 +244,7 @@ final class DefaultDataBrokerProtectionDatabaseMigrationsProvider: DataBrokerPro // Throws an error if a foreign key violation exists in the database. try database.checkForeignKeys() } catch { - throw DataBrokerProtectionDatabaseErrors.migrationFailureIntegrityCheck + throw DataBrokerProtectionDatabaseMigrationErrors.foreignKeyViolation } } @@ -279,8 +285,12 @@ final class DefaultDataBrokerProtectionDatabaseMigrationsProvider: DataBrokerPro deleteStatements.append(sqlOrphanedCleanupFromProfile(of: AddressDB.databaseTableName)) deleteStatements.append(sqlOrphanedCleanupFromProfile(of: PhoneDB.databaseTableName)) - for sql in deleteStatements { - try database.execute(sql: sql) + do { + for sql in deleteStatements { + try database.execute(sql: sql) + } + } catch { + throw DataBrokerProtectionDatabaseMigrationErrors.deleteOrphanedRecordFailed } // As a precaution, explicitly check for any foreign key violations which were missed @@ -356,16 +366,20 @@ final class DefaultDataBrokerProtectionDatabaseMigrationsProvider: DataBrokerPro } private static func recreateTablesV3(database: Database) throws { - try recreateNameTable(database: database) - try recreateAddressTable(database: database) - try recreatePhoneTable(database: database) - try recreateProfileQueryTable(database: database) - try recreateScanTable(database: database) - try recreateScanHistoryTable(database: database) - try recreateExtractedProfileTable(database: database) - try recreateOptOutTable(database: database) - try recreateOptOutHistoryTable(database: database) - try recreateOptOutAttemptTable(database: database) + do { + try recreateNameTable(database: database) + try recreateAddressTable(database: database) + try recreatePhoneTable(database: database) + try recreateProfileQueryTable(database: database) + try recreateScanTable(database: database) + try recreateScanHistoryTable(database: database) + try recreateExtractedProfileTable(database: database) + try recreateOptOutTable(database: database) + try recreateOptOutHistoryTable(database: database) + try recreateOptOutAttemptTable(database: database) + } catch { + throw DataBrokerProtectionDatabaseMigrationErrors.recreateTablesFailed + } } private static func recreateNameTable(database: Database) throws { diff --git a/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Storage/DataBrokerProtectionDatabaseProvider.swift b/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Storage/DataBrokerProtectionDatabaseProvider.swift index 414b0dddc8..25eb07f181 100644 --- a/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Storage/DataBrokerProtectionDatabaseProvider.swift +++ b/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Storage/DataBrokerProtectionDatabaseProvider.swift @@ -23,7 +23,6 @@ import GRDB enum DataBrokerProtectionDatabaseErrors: Error { case elementNotFound - case migrationFailureIntegrityCheck } protocol DataBrokerProtectionDatabaseProvider: SecureStorageDatabaseProvider { From 3ed23a5bffe36e07a14c791d58ae7e7f0cd624f0 Mon Sep 17 00:00:00 2001 From: Diego Rey Mendez Date: Wed, 14 Aug 2024 01:55:54 +0200 Subject: [PATCH 4/6] VPN now recovers from WireGuard closing utun (#3084) Task/Issue URL: https://app.asana.com/0/0/1208000338328853/f iOS: https://github.com/duckduckgo/iOS/pull/3204 BSK: https://github.com/duckduckgo/BrowserServicesKit/pull/931 ## Description If we detect an error while updating the tunnel configuration we now cancel the tunnel so Apple recreates the virtual interface. I believe the underlying issue is WireGuard should not "touch" the virtual interface at all, as that responsibility is owned by Apple. --- DuckDuckGo.xcodeproj/project.pbxproj | 2 +- .../xcshareddata/swiftpm/Package.resolved | 4 ++-- .../NetworkProtectionPixelEvent.swift | 15 +++++++++++---- .../EventMapping+NetworkProtectionError.swift | 1 + .../MacPacketTunnelProvider.swift | 6 ++++-- LocalPackages/DataBrokerProtection/Package.swift | 2 +- LocalPackages/NetworkProtectionMac/Package.swift | 2 +- LocalPackages/SubscriptionUI/Package.swift | 2 +- .../NetworkProtectionPixelEventTests.swift | 14 ++++++++++---- 9 files changed, 32 insertions(+), 16 deletions(-) diff --git a/DuckDuckGo.xcodeproj/project.pbxproj b/DuckDuckGo.xcodeproj/project.pbxproj index 0a3f086eae..6633cc4470 100644 --- a/DuckDuckGo.xcodeproj/project.pbxproj +++ b/DuckDuckGo.xcodeproj/project.pbxproj @@ -13465,7 +13465,7 @@ repositoryURL = "https://github.com/duckduckgo/BrowserServicesKit"; requirement = { kind = exactVersion; - version = 183.0.1; + version = 184.0.0; }; }; 9FF521422BAA8FF300B9819B /* XCRemoteSwiftPackageReference "lottie-spm" */ = { diff --git a/DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index f252c26951..dfc932907d 100644 --- a/DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -32,8 +32,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/duckduckgo/BrowserServicesKit", "state" : { - "revision" : "f0220c164618c7ca1cbf276db644d71711b0c76a", - "version" : "183.0.1" + "revision" : "c6ce430371032930d770b0388cbe44a2d40ad729", + "version" : "184.0.0" } }, { diff --git a/DuckDuckGo/NetworkProtection/AppAndExtensionAndAgentTargets/NetworkProtectionPixelEvent.swift b/DuckDuckGo/NetworkProtection/AppAndExtensionAndAgentTargets/NetworkProtectionPixelEvent.swift index 6b0a86cfec..3a89fcb611 100644 --- a/DuckDuckGo/NetworkProtection/AppAndExtensionAndAgentTargets/NetworkProtectionPixelEvent.swift +++ b/DuckDuckGo/NetworkProtection/AppAndExtensionAndAgentTargets/NetworkProtectionPixelEvent.swift @@ -98,7 +98,8 @@ enum NetworkProtectionPixelEvent: PixelKitEventV2 { case networkProtectionWireguardErrorInvalidState(reason: String) case networkProtectionWireguardErrorFailedDNSResolution case networkProtectionWireguardErrorCannotSetNetworkSettings(_ error: Error) - case networkProtectionWireguardErrorCannotStartWireguardBackend(code: Int32) + case networkProtectionWireguardErrorCannotStartWireguardBackend(_ error: Error) + case networkProtectionWireguardErrorCannotSetWireguardConfig(_ error: Error) case networkProtectionNoAuthTokenFoundError @@ -290,6 +291,9 @@ enum NetworkProtectionPixelEvent: PixelKitEventV2 { case .networkProtectionWireguardErrorCannotStartWireguardBackend: return "netp_wireguard_error_cannot_start_wireguard_backend" + case .networkProtectionWireguardErrorCannotSetWireguardConfig: + return "netp_wireguard_error_cannot_set_wireguard_config" + case .networkProtectionNoAuthTokenFoundError: return "netp_no_auth_token_found_error" @@ -378,8 +382,10 @@ enum NetworkProtectionPixelEvent: PixelKitEventV2 { return parameters case .networkProtectionWireguardErrorCannotSetNetworkSettings(let error): return error.pixelParameters - case .networkProtectionWireguardErrorCannotStartWireguardBackend(code: let code): - return [PixelKit.Parameters.errorCode: String(code)] + case .networkProtectionWireguardErrorCannotStartWireguardBackend(let error): + return error.pixelParameters + case .networkProtectionWireguardErrorCannotSetWireguardConfig(let error): + return error.pixelParameters case .networkProtectionClientFailedToFetchServerStatus(let error): return error?.pixelParameters case .networkProtectionClientFailedToParseServerStatusResponse(let error): @@ -458,6 +464,8 @@ enum NetworkProtectionPixelEvent: PixelKitEventV2 { .networkProtectionTunnelWakeFailure(let error), .networkProtectionClientFailedToParseRedeemResponse(let error), .networkProtectionWireguardErrorCannotSetNetworkSettings(let error), + .networkProtectionWireguardErrorCannotStartWireguardBackend(let error), + .networkProtectionWireguardErrorCannotSetWireguardConfig(let error), .networkProtectionRekeyFailure(let error), .networkProtectionUnhandledError(_, _, let error), .networkProtectionSystemExtensionActivationFailure(let error), @@ -507,7 +515,6 @@ enum NetworkProtectionPixelEvent: PixelKitEventV2 { .networkProtectionWireguardErrorCannotLocateTunnelFileDescriptor, .networkProtectionWireguardErrorInvalidState, .networkProtectionWireguardErrorFailedDNSResolution, - .networkProtectionWireguardErrorCannotStartWireguardBackend, .networkProtectionNoAuthTokenFoundError, .networkProtectionRekeyAttempt, .networkProtectionRekeyCompleted, diff --git a/DuckDuckGo/NetworkProtection/AppTargets/BothAppTargets/EventMapping+NetworkProtectionError.swift b/DuckDuckGo/NetworkProtection/AppTargets/BothAppTargets/EventMapping+NetworkProtectionError.swift index fc47c35d55..93107416d4 100644 --- a/DuckDuckGo/NetworkProtection/AppTargets/BothAppTargets/EventMapping+NetworkProtectionError.swift +++ b/DuckDuckGo/NetworkProtection/AppTargets/BothAppTargets/EventMapping+NetworkProtectionError.swift @@ -82,6 +82,7 @@ extension EventMapping where Event == NetworkProtectionError { .wireGuardDnsResolution, .wireGuardSetNetworkSettings, .startWireGuardBackend, + .setWireguardConfig, .failedToRetrieveAuthToken, .failedToFetchServerStatus, .failedToParseServerStatusResponse: diff --git a/DuckDuckGo/NetworkProtection/NetworkExtensionTargets/NetworkExtensionTargets/MacPacketTunnelProvider.swift b/DuckDuckGo/NetworkProtection/NetworkExtensionTargets/NetworkExtensionTargets/MacPacketTunnelProvider.swift index c4633c14bc..46a84aeca7 100644 --- a/DuckDuckGo/NetworkProtection/NetworkExtensionTargets/NetworkExtensionTargets/MacPacketTunnelProvider.swift +++ b/DuckDuckGo/NetworkProtection/NetworkExtensionTargets/NetworkExtensionTargets/MacPacketTunnelProvider.swift @@ -110,8 +110,10 @@ final class MacPacketTunnelProvider: PacketTunnelProvider { domainEvent = .networkProtectionWireguardErrorFailedDNSResolution case .wireGuardSetNetworkSettings(let error): domainEvent = .networkProtectionWireguardErrorCannotSetNetworkSettings(error) - case .startWireGuardBackend(let code): - domainEvent = .networkProtectionWireguardErrorCannotStartWireguardBackend(code: code) + case .startWireGuardBackend(let error): + domainEvent = .networkProtectionWireguardErrorCannotStartWireguardBackend(error) + case .setWireguardConfig(let error): + domainEvent = .networkProtectionWireguardErrorCannotSetWireguardConfig(error) case .noAuthTokenFound: domainEvent = .networkProtectionNoAuthTokenFoundError case .failedToFetchServerStatus(let error): diff --git a/LocalPackages/DataBrokerProtection/Package.swift b/LocalPackages/DataBrokerProtection/Package.swift index fa17f1c540..f6320f6d43 100644 --- a/LocalPackages/DataBrokerProtection/Package.swift +++ b/LocalPackages/DataBrokerProtection/Package.swift @@ -29,7 +29,7 @@ let package = Package( targets: ["DataBrokerProtection"]) ], dependencies: [ - .package(url: "https://github.com/duckduckgo/BrowserServicesKit", exact: "183.0.1"), + .package(url: "https://github.com/duckduckgo/BrowserServicesKit", exact: "184.0.0"), .package(path: "../SwiftUIExtensions"), .package(path: "../XPCHelper"), ], diff --git a/LocalPackages/NetworkProtectionMac/Package.swift b/LocalPackages/NetworkProtectionMac/Package.swift index 4b72f71fe9..2b498a855e 100644 --- a/LocalPackages/NetworkProtectionMac/Package.swift +++ b/LocalPackages/NetworkProtectionMac/Package.swift @@ -32,7 +32,7 @@ let package = Package( .library(name: "VPNAppLauncher", targets: ["VPNAppLauncher"]), ], dependencies: [ - .package(url: "https://github.com/duckduckgo/BrowserServicesKit", exact: "183.0.1"), + .package(url: "https://github.com/duckduckgo/BrowserServicesKit", exact: "184.0.0"), .package(url: "https://github.com/airbnb/lottie-spm", exact: "4.4.3"), .package(path: "../AppLauncher"), .package(path: "../UDSHelper"), diff --git a/LocalPackages/SubscriptionUI/Package.swift b/LocalPackages/SubscriptionUI/Package.swift index 31b26c3215..ff322c42e1 100644 --- a/LocalPackages/SubscriptionUI/Package.swift +++ b/LocalPackages/SubscriptionUI/Package.swift @@ -12,7 +12,7 @@ let package = Package( targets: ["SubscriptionUI"]), ], dependencies: [ - .package(url: "https://github.com/duckduckgo/BrowserServicesKit", exact: "183.0.1"), + .package(url: "https://github.com/duckduckgo/BrowserServicesKit", exact: "184.0.0"), .package(path: "../SwiftUIExtensions") ], targets: [ diff --git a/UnitTests/NetworkProtection/NetworkProtectionPixelEventTests.swift b/UnitTests/NetworkProtection/NetworkProtectionPixelEventTests.swift index cd60e9adf7..cd27726b43 100644 --- a/UnitTests/NetworkProtection/NetworkProtectionPixelEventTests.swift +++ b/UnitTests/NetworkProtection/NetworkProtectionPixelEventTests.swift @@ -322,12 +322,18 @@ final class NetworkProtectionPixelEventTests: XCTestCase { underlyingErrors: [TestError.underlyingError]), file: #filePath, line: #line) - fire(NetworkProtectionPixelEvent.networkProtectionWireguardErrorCannotStartWireguardBackend(code: 1), + fire(NetworkProtectionPixelEvent.networkProtectionWireguardErrorCannotStartWireguardBackend(TestError.testError), frequency: .dailyAndCount, and: .expect(pixelName: "m_mac_netp_wireguard_error_cannot_start_wireguard_backend", - customFields: [ - PixelKit.Parameters.errorCode: "1" - ]), + error: TestError.testError, + underlyingErrors: [TestError.underlyingError]), + file: #filePath, + line: #line) + fire(NetworkProtectionPixelEvent.networkProtectionWireguardErrorCannotSetWireguardConfig(TestError.testError), + frequency: .dailyAndCount, + and: .expect(pixelName: "m_mac_netp_wireguard_error_cannot_set_wireguard_config", + error: TestError.testError, + underlyingErrors: [TestError.underlyingError]), file: #filePath, line: #line) fire(NetworkProtectionPixelEvent.networkProtectionNoAuthTokenFoundError, From b2c958efa9dbb4eb5c8bb50026e128e0ac1470f6 Mon Sep 17 00:00:00 2001 From: Pete Smith Date: Wed, 14 Aug 2024 11:32:24 +0200 Subject: [PATCH 5/6] Improve PIR Database Migration Test to Address CI Failure (#3095) Task/Issue URL: https://app.asana.com/0/1206488453854252/1207987874156874/f **Description**: A PIR-related test failed on CI. This logic being tested involved the generation of a random number, which is used to bucket users into a 10% group of users (which is used as a simple feature flag). We wanted to verify that when run 100 times, the average percentage would indeed be roughly 10%, and so specified that a successful test is when the average value is between 9 and 11 %. However, this proved too strict, and resulted in some rare failures. This PR updates the success criteria to be between 8 and 12 %. --- .../DataBrokerProtectionMigrationsFeatureFlaggerTests.swift | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/LocalPackages/DataBrokerProtection/Tests/DataBrokerProtectionTests/DataBrokerProtectionMigrationsFeatureFlaggerTests.swift b/LocalPackages/DataBrokerProtection/Tests/DataBrokerProtectionTests/DataBrokerProtectionMigrationsFeatureFlaggerTests.swift index 15cdea5d31..4086947c56 100644 --- a/LocalPackages/DataBrokerProtection/Tests/DataBrokerProtectionTests/DataBrokerProtectionMigrationsFeatureFlaggerTests.swift +++ b/LocalPackages/DataBrokerProtection/Tests/DataBrokerProtectionTests/DataBrokerProtectionMigrationsFeatureFlaggerTests.swift @@ -157,7 +157,6 @@ final class DataBrokerProtectionMigrationsFeatureFlaggerTests: XCTestCase { XCTAssertTrue(result) } - /* DISABLED(flaky) REF: https://app.asana.com/0/1203108348835387/1207987874156874/f func testAverageCalculatedRandomNumberAssignmentIsBetween9And11Percent() { // Given var percentages: [Double] = [] @@ -185,7 +184,6 @@ final class DataBrokerProtectionMigrationsFeatureFlaggerTests: XCTestCase { // Then let sum = percentages.reduce(0, +) let average = sum / Double(percentages.count) - XCTAssert(average > 9.0 && average < 11.0) + XCTAssert(average > 8.0 && average < 12.0) } - */ } From 30bb281270b28335d01a5b109bd5d6ea446ba75b Mon Sep 17 00:00:00 2001 From: Sam Symons Date: Wed, 14 Aug 2024 10:29:20 -0700 Subject: [PATCH 6/6] Remove waitlist beta "Thank You" logic (#3101) Task/Issue URL: https://app.asana.com/0/1199230911884351/1208050130733767/f Tech Design URL: CC: Description: This PR removes some code that was only used for the waitlist beta. It is no longer used, so it's being removed. --- DuckDuckGo.xcodeproj/project.pbxproj | 18 -- DuckDuckGo/Application/URLEventHandler.swift | 1 - .../UserText+NetworkProtection.swift | 20 -- .../Utilities/UserDefaultsWrapper.swift | 4 - DuckDuckGo/Menus/MainMenu.swift | 2 - DuckDuckGo/Menus/MainMenuActions.swift | 15 -- .../NetworkProtectionDebugUtilities.swift | 2 - .../Waitlist/Models/WaitlistViewModel.swift | 1 - .../Waitlist/UserDefaults+vpnLegacyUser.swift | 40 ---- .../Views/WaitlistModalViewController.swift | 10 - .../WaitlistThankYouPromptPresenter.swift | 69 ------ .../Waitlist/Views/WaitlistThankYouView.swift | 222 ------------------ DuckDuckGo/Waitlist/Waitlist.swift | 6 - .../WaitlistFeatureSetupHandler.swift | 7 - UnitTests/Menus/MoreOptionsMenuTests.swift | 4 - 15 files changed, 421 deletions(-) delete mode 100644 DuckDuckGo/Waitlist/UserDefaults+vpnLegacyUser.swift delete mode 100644 DuckDuckGo/Waitlist/Views/WaitlistThankYouPromptPresenter.swift delete mode 100644 DuckDuckGo/Waitlist/Views/WaitlistThankYouView.swift diff --git a/DuckDuckGo.xcodeproj/project.pbxproj b/DuckDuckGo.xcodeproj/project.pbxproj index 6633cc4470..31425b4f67 100644 --- a/DuckDuckGo.xcodeproj/project.pbxproj +++ b/DuckDuckGo.xcodeproj/project.pbxproj @@ -1212,8 +1212,6 @@ 4B4D60E22A0C883A00BCD287 /* AppMain.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B4D60E12A0C883A00BCD287 /* AppMain.swift */; }; 4B4D60E32A0C883A00BCD287 /* AppMain.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B4D60E12A0C883A00BCD287 /* AppMain.swift */; }; 4B4F72EC266B2ED300814C60 /* CollectionExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B4F72EB266B2ED300814C60 /* CollectionExtension.swift */; }; - 4B520F632BA5573A006405C7 /* WaitlistThankYouView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B520F622BA5573A006405C7 /* WaitlistThankYouView.swift */; }; - 4B520F642BA5573A006405C7 /* WaitlistThankYouView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B520F622BA5573A006405C7 /* WaitlistThankYouView.swift */; }; 4B59023E26B35F3600489384 /* ChromiumLoginReader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B59023926B35F3600489384 /* ChromiumLoginReader.swift */; }; 4B59024026B35F3600489384 /* ChromiumDataImporter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B59023B26B35F3600489384 /* ChromiumDataImporter.swift */; }; 4B59024826B3673600489384 /* ThirdPartyBrowser.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B59024726B3673600489384 /* ThirdPartyBrowser.swift */; }; @@ -1230,8 +1228,6 @@ 4B6785482AA8DE69008A5004 /* VPNUninstaller.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B6785432AA8DE1F008A5004 /* VPNUninstaller.swift */; }; 4B67854A2AA8DE75008A5004 /* VPNFeatureGatekeeper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BD8679A2A9E9E000063B9F7 /* VPNFeatureGatekeeper.swift */; }; 4B67854B2AA8DE76008A5004 /* VPNFeatureGatekeeper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BD8679A2A9E9E000063B9F7 /* VPNFeatureGatekeeper.swift */; }; - 4B6B64842BA930420009FF9F /* WaitlistThankYouPromptPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B6B64832BA930420009FF9F /* WaitlistThankYouPromptPresenter.swift */; }; - 4B6B64852BA930420009FF9F /* WaitlistThankYouPromptPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B6B64832BA930420009FF9F /* WaitlistThankYouPromptPresenter.swift */; }; 4B70C00127B0793D000386ED /* DuckDuckGo-ExampleCrash.ips in Resources */ = {isa = PBXBuildFile; fileRef = 4B70BFFF27B0793D000386ED /* DuckDuckGo-ExampleCrash.ips */; }; 4B70C00227B0793D000386ED /* CrashReportTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B70C00027B0793D000386ED /* CrashReportTests.swift */; }; 4B723E0526B0003E00E14D75 /* DataImportMocks.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B723DFF26B0003E00E14D75 /* DataImportMocks.swift */; }; @@ -1595,8 +1591,6 @@ 7B7F5D222C526CE600826256 /* AddExcludedDomainView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B7F5D202C526CE600826256 /* AddExcludedDomainView.swift */; }; 7B7F5D242C52725A00826256 /* AddExcludedDomainButtonsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B7F5D232C52725A00826256 /* AddExcludedDomainButtonsView.swift */; }; 7B7F5D252C52725A00826256 /* AddExcludedDomainButtonsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B7F5D232C52725A00826256 /* AddExcludedDomainButtonsView.swift */; }; - 7B7FCD0F2BA33B2700C04FBE /* UserDefaults+vpnLegacyUser.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B7FCD0E2BA33B2700C04FBE /* UserDefaults+vpnLegacyUser.swift */; }; - 7B7FCD102BA33B2700C04FBE /* UserDefaults+vpnLegacyUser.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B7FCD0E2BA33B2700C04FBE /* UserDefaults+vpnLegacyUser.swift */; }; 7B8594192B5B26230007EB3E /* UDSHelper in Frameworks */ = {isa = PBXBuildFile; productRef = 7B8594182B5B26230007EB3E /* UDSHelper */; }; 7B8DB31A2B504D7500EC16DA /* VPNAppEventsHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B8DB3192B504D7500EC16DA /* VPNAppEventsHandler.swift */; }; 7B934C412A866DD400FC8F9C /* UserDefaults+NetworkProtectionShared.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B934C402A866DD400FC8F9C /* UserDefaults+NetworkProtectionShared.swift */; }; @@ -3295,7 +3289,6 @@ 4B4D60D22A0C84F700BCD287 /* UserText+NetworkProtection.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UserText+NetworkProtection.swift"; sourceTree = ""; }; 4B4D60E12A0C883A00BCD287 /* AppMain.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppMain.swift; sourceTree = ""; }; 4B4F72EB266B2ED300814C60 /* CollectionExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CollectionExtension.swift; sourceTree = ""; }; - 4B520F622BA5573A006405C7 /* WaitlistThankYouView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WaitlistThankYouView.swift; sourceTree = ""; }; 4B59023926B35F3600489384 /* ChromiumLoginReader.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ChromiumLoginReader.swift; sourceTree = ""; }; 4B59023B26B35F3600489384 /* ChromiumDataImporter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ChromiumDataImporter.swift; sourceTree = ""; }; 4B59024726B3673600489384 /* ThirdPartyBrowser.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThirdPartyBrowser.swift; sourceTree = ""; }; @@ -3313,7 +3306,6 @@ 4B677440255DBEEA00025BD8 /* Database.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Database.swift; sourceTree = ""; }; 4B677454255DC18000025BD8 /* Bridging.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Bridging.h; sourceTree = ""; }; 4B6785432AA8DE1F008A5004 /* VPNUninstaller.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = VPNUninstaller.swift; sourceTree = ""; }; - 4B6B64832BA930420009FF9F /* WaitlistThankYouPromptPresenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WaitlistThankYouPromptPresenter.swift; sourceTree = ""; }; 4B70BFFF27B0793D000386ED /* DuckDuckGo-ExampleCrash.ips */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "DuckDuckGo-ExampleCrash.ips"; sourceTree = ""; }; 4B70C00027B0793D000386ED /* CrashReportTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CrashReportTests.swift; sourceTree = ""; }; 4B723DEB26B0002B00E14D75 /* DataImport.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DataImport.swift; sourceTree = ""; }; @@ -3553,7 +3545,6 @@ 7B76E6852AD5D77600186A84 /* XPCHelper */ = {isa = PBXFileReference; lastKnownFileType = wrapper; path = XPCHelper; sourceTree = ""; }; 7B7F5D202C526CE600826256 /* AddExcludedDomainView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddExcludedDomainView.swift; sourceTree = ""; }; 7B7F5D232C52725A00826256 /* AddExcludedDomainButtonsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddExcludedDomainButtonsView.swift; sourceTree = ""; }; - 7B7FCD0E2BA33B2700C04FBE /* UserDefaults+vpnLegacyUser.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UserDefaults+vpnLegacyUser.swift"; sourceTree = ""; }; 7B8594172B5B25FB0007EB3E /* UDSHelper */ = {isa = PBXFileReference; lastKnownFileType = wrapper; path = UDSHelper; sourceTree = ""; }; 7B8DB3192B504D7500EC16DA /* VPNAppEventsHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPNAppEventsHandler.swift; sourceTree = ""; }; 7B9167A82C09E88800322310 /* AppLauncher */ = {isa = PBXFileReference; lastKnownFileType = wrapper; path = AppLauncher; sourceTree = ""; }; @@ -5742,7 +5733,6 @@ 7BD8679A2A9E9E000063B9F7 /* VPNFeatureGatekeeper.swift */, 4B6785432AA8DE1F008A5004 /* VPNUninstaller.swift */, 7BFF35722C10D75000F89673 /* IPCServiceLauncher.swift */, - 7B7FCD0E2BA33B2700C04FBE /* UserDefaults+vpnLegacyUser.swift */, 31F2D1FE2AF026D800BF0144 /* WaitlistTermsAndConditionsActionHandler.swift */, 31C9ADE42AF0564500CEF57D /* WaitlistFeatureSetupHandler.swift */, 4B9DB0072A983B23000927DB /* Waitlist.swift */, @@ -5789,8 +5779,6 @@ 4B9DB0182A983B24000927DB /* WaitlistDialogView.swift */, 4B9DB0192A983B24000927DB /* WaitlistModalViewController.swift */, 3168506C2AF3AD1C009A2828 /* WaitlistViewControllerPresenter.swift */, - 4B520F622BA5573A006405C7 /* WaitlistThankYouView.swift */, - 4B6B64832BA930420009FF9F /* WaitlistThankYouPromptPresenter.swift */, ); path = Views; sourceTree = ""; @@ -9900,7 +9888,6 @@ 3706FA7E293F65D500E42796 /* LottieAnimationCache.swift in Sources */, 9F982F0E2B8224BF00231028 /* AddEditBookmarkFolderDialogViewModel.swift in Sources */, 3706FA7F293F65D500E42796 /* TabIndex.swift in Sources */, - 4B520F642BA5573A006405C7 /* WaitlistThankYouView.swift in Sources */, 3706FA80293F65D500E42796 /* TabLazyLoaderDataSource.swift in Sources */, 3706FA81293F65D500E42796 /* LoginImport.swift in Sources */, 560C40002BCD5A1E00F589CE /* PermanentSurveyManager.swift in Sources */, @@ -10223,7 +10210,6 @@ 1D4071AF2BD64267002D4537 /* DockCustomizer.swift in Sources */, 4B41EDA42B1543B9001EEDF4 /* VPNPreferencesModel.swift in Sources */, 1E559BB22BBCA9F1002B4AF6 /* RedirectNavigationResponder.swift in Sources */, - 7B7FCD102BA33B2700C04FBE /* UserDefaults+vpnLegacyUser.swift in Sources */, 3706FB6C293F65D500E42796 /* FaviconStore.swift in Sources */, 3706FB6D293F65D500E42796 /* SuggestionListCharacteristics.swift in Sources */, F1C70D7A2BFF50A400599292 /* DataBrokerProtectionLoginItemInterface.swift in Sources */, @@ -10481,7 +10467,6 @@ 4B9DB0452A983B24000927DB /* WaitlistModalViewController.swift in Sources */, B66CA41F2AD910B300447CF0 /* DataImportView.swift in Sources */, 3706FC0C293F65D500E42796 /* NSAttributedStringExtension.swift in Sources */, - 4B6B64852BA930420009FF9F /* WaitlistThankYouPromptPresenter.swift in Sources */, C1DAF3B62B9A44860059244F /* AutofillPopoverPresenter.swift in Sources */, 3706FC0D293F65D500E42796 /* AnimationView.swift in Sources */, 9FA173DB2B79BD8A00EE4E6E /* BookmarkDialogContainerView.swift in Sources */, @@ -11759,7 +11744,6 @@ 7B430EA12A71411A00BAC4A1 /* NetworkProtectionSimulateFailureMenu.swift in Sources */, 1E7E2E942902AC0E00C01B54 /* PrivacyDashboardPermissionHandler.swift in Sources */, AA9FF95F24A1FB690039E328 /* TabCollectionViewModel.swift in Sources */, - 4B520F632BA5573A006405C7 /* WaitlistThankYouView.swift in Sources */, 4BF0E5052AD2551A00FFEC9E /* NetworkProtectionPixelEvent.swift in Sources */, AAC5E4D125D6A709007F5990 /* BookmarkManager.swift in Sources */, 37CD54CD27F2FDD100F1F7B9 /* AboutPreferences.swift in Sources */, @@ -12053,7 +12037,6 @@ 4B379C1E27BDB7FF008A968E /* DeviceAuthenticator.swift in Sources */, 1456D6E124EFCBC300775049 /* TabBarCollectionView.swift in Sources */, 4B4D60BF2A0C848A00BCD287 /* NetworkProtection+ConvenienceInitializers.swift in Sources */, - 4B6B64842BA930420009FF9F /* WaitlistThankYouPromptPresenter.swift in Sources */, 7B5A23682C468233007213AC /* ExcludedDomainsViewController.swift in Sources */, BDA7647C2BC497BE00D0400C /* DefaultVPNLocationFormatter.swift in Sources */, 3158B1592B0BF76400AF130C /* DataBrokerProtectionFeatureDisabler.swift in Sources */, @@ -12156,7 +12139,6 @@ 9F514F912B7D88AD001832A9 /* AddEditBookmarkFolderDialogView.swift in Sources */, 9FA173E32B7A12B600EE4E6E /* BookmarkDialogFolderManagementView.swift in Sources */, 37534CA8281198CD002621E7 /* AdjacentItemEnumerator.swift in Sources */, - 7B7FCD0F2BA33B2700C04FBE /* UserDefaults+vpnLegacyUser.swift in Sources */, 987799F62999996B005D8EB6 /* BookmarkDatabase.swift in Sources */, 7BB4BC6A2C5CD96200E06FC8 /* ActiveDomainPublisher.swift in Sources */, 4BE53374286E39F10019DBFD /* ChromiumKeychainPrompt.swift in Sources */, diff --git a/DuckDuckGo/Application/URLEventHandler.swift b/DuckDuckGo/Application/URLEventHandler.swift index 8e79662a1c..d78142b001 100644 --- a/DuckDuckGo/Application/URLEventHandler.swift +++ b/DuckDuckGo/Application/URLEventHandler.swift @@ -135,7 +135,6 @@ final class URLEventHandler { } if url.scheme?.isNetworkProtectionScheme == false && url.scheme?.isDataBrokerProtectionScheme == false { - WaitlistModalDismisser.dismissWaitlistModalViewControllerIfNecessary(url) WindowControllersManager.shared.show(url: url, source: .appOpenUrl, newTab: true) } } diff --git a/DuckDuckGo/Common/Localizables/UserText+NetworkProtection.swift b/DuckDuckGo/Common/Localizables/UserText+NetworkProtection.swift index 4d8c4d348b..26fabdff43 100644 --- a/DuckDuckGo/Common/Localizables/UserText+NetworkProtection.swift +++ b/DuckDuckGo/Common/Localizables/UserText+NetworkProtection.swift @@ -226,23 +226,3 @@ extension UserText { return "\(city), \(country)" } } - -// MARK: - Thank You Modals - -extension UserText { - static let dbpThankYouTitle = "Personal Information Removal early access is over" - static let dbpThankYouSubtitle = "Thank you for being a tester!" - static let dbpThankYouBody1 = "To continue using Personal Information Removal, subscribe to DuckDuckGo Privacy Pro and get 40% off with promo code THANKYOU" - - static let vpnThankYouTitle = "DuckDuckGo VPN early access is over" - static let vpnThankYouSubtitle = "Thank you for being a tester!" - static let vpnThankYouBody1 = "To continue using the VPN, subscribe to DuckDuckGo Privacy Pro and get 40% off with promo code THANKYOU" - -#if APPSTORE - static let dbpThankYouBody2 = "Offer redeemable for a limited time only in the desktop version of the DuckDuckGo browser by U.S. testers when you download from duckduckgo.com/app" - static let vpnThankYouBody2 = "Offer redeemable for a limited time only in the desktop version of the DuckDuckGo browser by U.S. testers when you download from duckduckgo.com/app" -#else - static let dbpThankYouBody2 = "Offer redeemable for a limited time in the desktop version of the DuckDuckGo browser by U.S. beta testers only." - static let vpnThankYouBody2 = "Offer redeemable for a limited time in the desktop version of the DuckDuckGo browser by U.S. beta testers only." -#endif -} diff --git a/DuckDuckGo/Common/Utilities/UserDefaultsWrapper.swift b/DuckDuckGo/Common/Utilities/UserDefaultsWrapper.swift index 02e6b55d7c..470921520b 100644 --- a/DuckDuckGo/Common/Utilities/UserDefaultsWrapper.swift +++ b/DuckDuckGo/Common/Utilities/UserDefaultsWrapper.swift @@ -174,8 +174,6 @@ public struct UserDefaultsWrapper { // VPN case networkProtectionExcludedRoutes = "netp.excluded-routes" - case networkProtectionTermsAndConditionsAccepted = "network-protection.waitlist-terms-and-conditions.accepted" - case networkProtectionWaitlistSignUpPromptDismissed = "network-protection.waitlist.sign-up-prompt-dismissed" // VPN: Shared Defaults // --- @@ -183,8 +181,6 @@ public struct UserDefaultsWrapper { // or else KVO will just not work as of 2023-08-07 case networkProtectionOnboardingStatusRawValue = "networkProtectionOnboardingStatusRawValue" - case networkProtectionWaitlistActiveOverrideRawValue = "networkProtectionWaitlistActiveOverrideRawValue" - case networkProtectionWaitlistEnabledOverrideRawValue = "networkProtectionWaitlistEnabledOverrideRawValue" // Updates case automaticUpdates = "updates.automatic" diff --git a/DuckDuckGo/Menus/MainMenu.swift b/DuckDuckGo/Menus/MainMenu.swift index 4115217fad..7a0e7a4b70 100644 --- a/DuckDuckGo/Menus/MainMenu.swift +++ b/DuckDuckGo/Menus/MainMenu.swift @@ -601,8 +601,6 @@ final class MainMenu: NSMenu { NSMenuItem(title: "Show Save Credentials Popover", action: #selector(MainViewController.showSaveCredentialsPopover)) NSMenuItem(title: "Show Credentials Saved Popover", action: #selector(MainViewController.showCredentialsSavedPopover)) NSMenuItem(title: "Show Pop Up Window", action: #selector(MainViewController.showPopUpWindow)) - NSMenuItem(title: "Show VPN Thank You Modal", action: #selector(MainViewController.showVPNThankYouModal)) - NSMenuItem(title: "Reset Thank You Modal Checks", action: #selector(MainViewController.resetThankYouModalChecks)) } NSMenuItem(title: "Remote Configuration") { customConfigurationUrlMenuItem diff --git a/DuckDuckGo/Menus/MainMenuActions.swift b/DuckDuckGo/Menus/MainMenuActions.swift index 3cbe45bcdc..4eef2de651 100644 --- a/DuckDuckGo/Menus/MainMenuActions.swift +++ b/DuckDuckGo/Menus/MainMenuActions.swift @@ -834,7 +834,6 @@ extension MainViewController { /// private func clearPrivacyProState() { Application.appDelegate.subscriptionManager.accountManager.signOut() - resetThankYouModalChecks(nil) UserDefaults.netP.networkProtectionEntitlementsExpired = false } @@ -897,20 +896,6 @@ extension MainViewController { WindowsManager.openPopUpWindow(with: tab, origin: nil, contentSize: nil) } - @objc func resetThankYouModalChecks(_ sender: Any?) { - let presenter = WaitlistThankYouPromptPresenter() - presenter.resetPromptCheck() - UserDefaults.netP.removeObject(forKey: UserDefaults.vpnLegacyUserAccessDisabledOnceKey) - } - - @objc func showVPNThankYouModal(_ sender: Any?) { - let thankYouModalView = WaitlistBetaThankYouDialogViewController(copy: .vpn) - let thankYouWindowController = thankYouModalView.wrappedInWindowController() - if let thankYouWindow = thankYouWindowController.window { - WindowsManager.windows.first?.beginSheet(thankYouWindow) - } - } - @objc func resetEmailProtectionInContextPrompt(_ sender: Any?) { EmailManager().resetEmailProtectionInContextPrompt() } diff --git a/DuckDuckGo/NetworkProtection/AppTargets/BothAppTargets/NetworkProtectionDebugUtilities.swift b/DuckDuckGo/NetworkProtection/AppTargets/BothAppTargets/NetworkProtectionDebugUtilities.swift index d8d744f684..9309214418 100644 --- a/DuckDuckGo/NetworkProtection/AppTargets/BothAppTargets/NetworkProtectionDebugUtilities.swift +++ b/DuckDuckGo/NetworkProtection/AppTargets/BothAppTargets/NetworkProtectionDebugUtilities.swift @@ -63,8 +63,6 @@ final class NetworkProtectionDebugUtilities { settings.resetToDefaults() - UserDefaults().removeObject(forKey: UserDefaultsWrapper.Key.networkProtectionTermsAndConditionsAccepted.rawValue) - NotificationCenter.default.post(name: .networkProtectionWaitlistAccessChanged, object: nil) UserDefaults.netP.networkProtectionEntitlementsExpired = false } diff --git a/DuckDuckGo/Waitlist/Models/WaitlistViewModel.swift b/DuckDuckGo/Waitlist/Models/WaitlistViewModel.swift index 6419bb86c5..01f47e9998 100644 --- a/DuckDuckGo/Waitlist/Models/WaitlistViewModel.swift +++ b/DuckDuckGo/Waitlist/Models/WaitlistViewModel.swift @@ -118,7 +118,6 @@ final class WaitlistViewModel: ObservableObject { switch action { case .joinQueue: await joinWaitlist() - NotificationCenter.default.post(name: .networkProtectionWaitlistAccessChanged, object: nil) case .requestNotificationPermission: requestNotificationPermission() case .showTermsAndConditions: showTermsAndConditions() diff --git a/DuckDuckGo/Waitlist/UserDefaults+vpnLegacyUser.swift b/DuckDuckGo/Waitlist/UserDefaults+vpnLegacyUser.swift deleted file mode 100644 index 68891bc44b..0000000000 --- a/DuckDuckGo/Waitlist/UserDefaults+vpnLegacyUser.swift +++ /dev/null @@ -1,40 +0,0 @@ -// -// UserDefaults+vpnLegacyUser.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 Foundation - -extension UserDefaults { - static var vpnLegacyUserAccessDisabledOnceKey: String { - "vpnLegacyUserAccessDisabledOnce" - } - - @objc - dynamic var vpnLegacyUserAccessDisabledOnce: Bool { - get { - bool(forKey: Self.vpnLegacyUserAccessDisabledOnceKey) - } - - set { - set(newValue, forKey: Self.vpnLegacyUserAccessDisabledOnceKey) - } - } - - func resetVPNLegacyUserAccessDisabledOnce() { - removeObject(forKey: Self.vpnLegacyUserAccessDisabledOnceKey) - } -} diff --git a/DuckDuckGo/Waitlist/Views/WaitlistModalViewController.swift b/DuckDuckGo/Waitlist/Views/WaitlistModalViewController.swift index 80a977d6ae..bf9d66bb6e 100644 --- a/DuckDuckGo/Waitlist/Views/WaitlistModalViewController.swift +++ b/DuckDuckGo/Waitlist/Views/WaitlistModalViewController.swift @@ -95,13 +95,3 @@ extension WaitlistModalViewController: WaitlistViewModelDelegate { } } - -struct WaitlistModalDismisser { - - // Small hack to force the waitlist modal view controller to dismiss all instances of itself whenever the user opens a link from the T&C view. - static func dismissWaitlistModalViewControllerIfNecessary(_ url: URL) { - if ["https://duckduckgo.com/privacy", "https://duckduckgo.com/terms"].contains(url.absoluteString) { - NotificationCenter.default.post(name: .waitlistModalViewControllerShouldDismiss, object: nil) - } - } -} diff --git a/DuckDuckGo/Waitlist/Views/WaitlistThankYouPromptPresenter.swift b/DuckDuckGo/Waitlist/Views/WaitlistThankYouPromptPresenter.swift deleted file mode 100644 index 67cc8eaf59..0000000000 --- a/DuckDuckGo/Waitlist/Views/WaitlistThankYouPromptPresenter.swift +++ /dev/null @@ -1,69 +0,0 @@ -// -// WaitlistThankYouPromptPresenter.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 AppKit -import Foundation -import BrowserServicesKit -import PixelKit - -final class WaitlistThankYouPromptPresenter { - - private enum Constants { - static let didShowThankYouPromptKey = "duckduckgo.macos.browser.did-show-thank-you-prompt" - } - - private let userDefaults: UserDefaults - - init(userDefaults: UserDefaults = .standard) { - self.userDefaults = userDefaults - } - - // MARK: - Presentation - - // Presents a Thank You prompt to testers of PIR. - // If the user tested both, the PIR prompt will be displayed. - @MainActor - func presentThankYouPromptIfNecessary(in window: NSWindow) { - guard canShowPromptCheck() else { - return - } - } - - // MARK: - Eligibility - - var canShowPIRCard: Bool { - return false - } - - func canShowPromptCheck() -> Bool { - return !self.userDefaults.bool(forKey: Constants.didShowThankYouPromptKey) - } - - // MARK: - Dismissal - - private func saveDidShowPromptCheck() { - self.userDefaults.setValue(true, forKey: Constants.didShowThankYouPromptKey) - } - - // MARK: - Debug - - func resetPromptCheck() { - self.userDefaults.removeObject(forKey: Constants.didShowThankYouPromptKey) - } - -} diff --git a/DuckDuckGo/Waitlist/Views/WaitlistThankYouView.swift b/DuckDuckGo/Waitlist/Views/WaitlistThankYouView.swift deleted file mode 100644 index 541f94ff73..0000000000 --- a/DuckDuckGo/Waitlist/Views/WaitlistThankYouView.swift +++ /dev/null @@ -1,222 +0,0 @@ -// -// WaitlistThankYouView.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 Foundation -import Combine -import SwiftUI - -// MARK: - Model - -struct WaitlistBetaThankYouCopy { - static let vpn = WaitlistBetaThankYouCopy( - title: UserText.vpnThankYouTitle, - subtitle: UserText.vpnThankYouSubtitle, - body1: UserText.vpnThankYouBody1, - body2: UserText.vpnThankYouBody2 - ) - - let title: String - let subtitle: String - let body1: String - let body2: String - - @available(macOS 12.0, *) - func boldedBold1() -> AttributedString { - return bolded(text: body1, boldedStrings: ["THANKYOU"]) - } - - @available(macOS 12.0, *) - func boldedBold2() -> AttributedString { - return bolded(text: body2, boldedStrings: ["duckduckgo.com/app"]) - } - - @available(macOS 12.0, *) - private func bolded(text: String, boldedStrings: [String]) -> AttributedString { - var attributedString = AttributedString(text) - - for boldedString in boldedStrings { - if let range = attributedString.range(of: boldedString) { - attributedString[range].font = .system(size: 14, weight: .semibold) - } - } - - return attributedString - } -} - -// MARK: - View Model - -protocol WaitlistBetaThankYouDialogViewModelDelegate: AnyObject { - func waitlistBetaThankYouViewModelDismissedView(_ viewModel: WaitlistBetaThankYouDialogViewModel) -} - -final class WaitlistBetaThankYouDialogViewModel: ObservableObject { - - enum ViewAction { - case close - } - - weak var delegate: WaitlistBetaThankYouDialogViewModelDelegate? - - init() {} - - @MainActor - func process(action: ViewAction) async { - switch action { - case .close: - delegate?.waitlistBetaThankYouViewModelDismissedView(self) - } - } - -} - -// MARK: - View - -final class WaitlistBetaThankYouDialogViewController: NSViewController { - - private let defaultSize = CGSize(width: 360, height: 498) - private let viewModel: WaitlistBetaThankYouDialogViewModel - - private var heightConstraint: NSLayoutConstraint? - private var cancellables = Set() - - private let copy: WaitlistBetaThankYouCopy - - init(copy: WaitlistBetaThankYouCopy) { - self.viewModel = WaitlistBetaThankYouDialogViewModel() - self.copy = copy - super.init(nibName: nil, bundle: nil) - self.viewModel.delegate = self - } - - required init?(coder: NSCoder) { - fatalError("init(coder:) has not been implemented") - } - - override func loadView() { - view = NSView(frame: NSRect(origin: CGPoint.zero, size: defaultSize)) - } - - override func viewDidLoad() { - super.viewDidLoad() - - let feedbackFormView = WaitlistBetaThankYouView(copy: self.copy) - let hostingView = NSHostingView(rootView: feedbackFormView.environmentObject(self.viewModel)) - hostingView.translatesAutoresizingMaskIntoConstraints = false - view.addSubview(hostingView) - - let heightConstraint = hostingView.heightAnchor.constraint(equalToConstant: defaultSize.height) - self.heightConstraint = heightConstraint - - NSLayoutConstraint.activate([ - heightConstraint, - hostingView.widthAnchor.constraint(equalToConstant: defaultSize.width), - hostingView.topAnchor.constraint(equalTo: view.topAnchor), - hostingView.bottomAnchor.constraint(equalTo: view.bottomAnchor), - hostingView.leftAnchor.constraint(equalTo: view.leftAnchor), - hostingView.rightAnchor.constraint(equalTo: view.rightAnchor) - ]) - } - -} - -struct WaitlistBetaThankYouView: View { - - @EnvironmentObject var viewModel: WaitlistBetaThankYouDialogViewModel - - let copy: WaitlistBetaThankYouCopy - - var body: some View { - VStack(spacing: 0) { - VStack { - Text(copy.title) - .font(.system(size: 17, weight: .semibold)) - .padding([.leading, .trailing], 21.5) - .padding([.top, .bottom], 24) - .fixedSize(horizontal: false, vertical: true) - } - .frame(maxWidth: .infinity) - .background(Color.backgroundSecondary) - - Divider() - - Image("Gift-96") - .resizable() - .frame(width: 96, height: 96) - .padding([.top, .bottom], 24) - - Text(copy.subtitle) - .font(.system(size: 17, weight: .semibold)) - .padding([.leading, .trailing, .bottom], 14) - - if #available(macOS 12.0, *) { - Text(copy.boldedBold1()) - .font(.system(size: 14)) - .padding([.leading, .trailing, .bottom], 14) - .lineSpacing(2) - } else { - Text(copy.body1) - .font(.system(size: 14)) - .padding([.leading, .trailing, .bottom], 14) - .lineSpacing(2) - } - - if #available(macOS 12.0, *) { - Text(copy.boldedBold2()) - .font(.system(size: 14)) - .padding([.leading, .trailing, .bottom], 14) - .lineSpacing(2) - } else { - Text(copy.body2) - .font(.system(size: 14)) - .padding([.leading, .trailing, .bottom], 14) - .lineSpacing(2) - } - - Spacer() - - button(text: "Close", action: .close) - .padding(16) - } - .multilineTextAlignment(.center) - } - - @ViewBuilder - func button(text: String, action: WaitlistBetaThankYouDialogViewModel.ViewAction) -> some View { - Button(action: { - Task { - await viewModel.process(action: action) - } - }, label: { - Text(text) - .frame(maxWidth: .infinity) - }) - .controlSize(.large) - .keyboardShortcut(.defaultAction) - .frame(maxWidth: .infinity) - } - -} - -extension WaitlistBetaThankYouDialogViewController: WaitlistBetaThankYouDialogViewModelDelegate { - - func waitlistBetaThankYouViewModelDismissedView(_ viewModel: WaitlistBetaThankYouDialogViewModel) { - dismiss() - } - -} diff --git a/DuckDuckGo/Waitlist/Waitlist.swift b/DuckDuckGo/Waitlist/Waitlist.swift index 27ac30ced1..51efa27e6b 100644 --- a/DuckDuckGo/Waitlist/Waitlist.swift +++ b/DuckDuckGo/Waitlist/Waitlist.swift @@ -61,12 +61,6 @@ enum WaitlistInviteCodeFetchError: Error, Equatable { } } -extension Notification.Name { - - static let networkProtectionWaitlistAccessChanged = Notification.Name(rawValue: "networkProtectionWaitlistAccessChanged") - -} - extension Waitlist { func fetchInviteCodeIfAvailable() async -> WaitlistInviteCodeFetchError? { diff --git a/DuckDuckGo/Waitlist/WaitlistFeatureSetupHandler.swift b/DuckDuckGo/Waitlist/WaitlistFeatureSetupHandler.swift index a849b9b62a..fb306d0285 100644 --- a/DuckDuckGo/Waitlist/WaitlistFeatureSetupHandler.swift +++ b/DuckDuckGo/Waitlist/WaitlistFeatureSetupHandler.swift @@ -21,10 +21,3 @@ import Foundation protocol WaitlistFeatureSetupHandler { func confirmFeature() } - -struct NetworkProtectionWaitlistFeatureSetupHandler: WaitlistFeatureSetupHandler { - func confirmFeature() { - LocalPinningManager.shared.pin(.networkProtection) - NotificationCenter.default.post(name: .networkProtectionWaitlistAccessChanged, object: nil) - } -} diff --git a/UnitTests/Menus/MoreOptionsMenuTests.swift b/UnitTests/Menus/MoreOptionsMenuTests.swift index 5d937af6f0..97b37a84c0 100644 --- a/UnitTests/Menus/MoreOptionsMenuTests.swift +++ b/UnitTests/Menus/MoreOptionsMenuTests.swift @@ -271,10 +271,6 @@ final class NetworkProtectionVisibilityMock: VPNFeatureGatekeeper { // intentional no-op } - var isEligibleForThankYouMessage: Bool { - false - } - func disableIfUserHasNoAccess() async { // Intentional no-op }