From 829f9529ebcb94408f20133be741ee17f07a15e5 Mon Sep 17 00:00:00 2001 From: Federico Cappelli Date: Mon, 22 Apr 2024 17:24:57 +0100 Subject: [PATCH] Local PixelKit package replaced with BSK's PixelKit (#2656) Task/Issue URL: https://app.asana.com/0/1205842942115003/1206999268603553/f **Description**: Replaced local PixelKit with BSK's PixelKit --- DuckDuckGo.xcodeproj/project.pbxproj | 379 +++++++------- .../xcshareddata/swiftpm/Package.resolved | 6 +- ...kDuckGo Privacy Browser App Store.xcscheme | 20 - .../DuckDuckGo Privacy Browser.xcscheme | 20 - .../DataBrokerProtection/Package.swift | 5 +- .../NetworkProtectionMac/Package.swift | 10 +- LocalPackages/PixelKit/.gitignore | 9 - .../xcshareddata/IDEWorkspaceChecks.plist | 8 - LocalPackages/PixelKit/Package.swift | 50 -- LocalPackages/PixelKit/README.md | 11 - .../Extensions/String+StaticString.swift | 27 - .../PixelKit/Extensions/URL+PixelKit.swift | 30 -- .../PixelKit/PixelKit+Parameters.swift | 137 ----- .../PixelKit/Sources/PixelKit/PixelKit.swift | 476 ------------------ .../Sources/PixelKit/PixelKitEvent.swift | 100 ---- .../Sources/PixelKit/PixelKitEventV2.swift | 58 --- .../PixelFireExpectations.swift | 66 --- .../ValidatePixel.swift | 50 -- .../XCTestCase+PixelKit.swift | 169 ------- .../PixelKitParametersTests.swift | 75 --- .../Tests/PixelKitTests/PixelKitTests.swift | 385 -------------- LocalPackages/SubscriptionUI/Package.swift | 8 +- 22 files changed, 192 insertions(+), 1907 deletions(-) delete mode 100644 LocalPackages/PixelKit/.gitignore delete mode 100644 LocalPackages/PixelKit/.swiftpm/xcode/package.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist delete mode 100644 LocalPackages/PixelKit/Package.swift delete mode 100644 LocalPackages/PixelKit/README.md delete mode 100644 LocalPackages/PixelKit/Sources/PixelKit/Extensions/String+StaticString.swift delete mode 100644 LocalPackages/PixelKit/Sources/PixelKit/Extensions/URL+PixelKit.swift delete mode 100644 LocalPackages/PixelKit/Sources/PixelKit/PixelKit+Parameters.swift delete mode 100644 LocalPackages/PixelKit/Sources/PixelKit/PixelKit.swift delete mode 100644 LocalPackages/PixelKit/Sources/PixelKit/PixelKitEvent.swift delete mode 100644 LocalPackages/PixelKit/Sources/PixelKit/PixelKitEventV2.swift delete mode 100644 LocalPackages/PixelKit/Sources/PixelKitTestingUtilities/PixelFireExpectations.swift delete mode 100644 LocalPackages/PixelKit/Sources/PixelKitTestingUtilities/ValidatePixel.swift delete mode 100644 LocalPackages/PixelKit/Sources/PixelKitTestingUtilities/XCTestCase+PixelKit.swift delete mode 100644 LocalPackages/PixelKit/Tests/PixelKitTests/PixelKitParametersTests.swift delete mode 100644 LocalPackages/PixelKit/Tests/PixelKitTests/PixelKitTests.swift diff --git a/DuckDuckGo.xcodeproj/project.pbxproj b/DuckDuckGo.xcodeproj/project.pbxproj index 06e4ce3ba6..b706baead4 100644 --- a/DuckDuckGo.xcodeproj/project.pbxproj +++ b/DuckDuckGo.xcodeproj/project.pbxproj @@ -134,7 +134,6 @@ 1DFAB5232A8983E100A0F7F6 /* SetExtensionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1DFAB51F2A89830D00A0F7F6 /* SetExtensionTests.swift */; }; 1E0C72062ABC63BD00802009 /* SubscriptionPagesUserScript.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E0C72052ABC63BD00802009 /* SubscriptionPagesUserScript.swift */; }; 1E0C72072ABC63BD00802009 /* SubscriptionPagesUserScript.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E0C72052ABC63BD00802009 /* SubscriptionPagesUserScript.swift */; }; - 1E46E1A02BD029BD0007273A /* Subscription in Frameworks */ = {isa = PBXBuildFile; productRef = 1E46E19F2BD029BD0007273A /* Subscription */; }; 1E559BB12BBCA9F1002B4AF6 /* RedirectNavigationResponder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E559BB02BBCA9F1002B4AF6 /* RedirectNavigationResponder.swift */; }; 1E559BB22BBCA9F1002B4AF6 /* RedirectNavigationResponder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E559BB02BBCA9F1002B4AF6 /* RedirectNavigationResponder.swift */; }; 1E7E2E9029029A2A00C01B54 /* ContentBlockingRulesUpdateObserver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E7E2E8F29029A2A00C01B54 /* ContentBlockingRulesUpdateObserver.swift */; }; @@ -947,7 +946,6 @@ 373A1AB228451ED400586521 /* BookmarksHTMLImporterTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 373A1AB128451ED400586521 /* BookmarksHTMLImporterTests.swift */; }; 373D9B4829EEAC1B00381FDD /* SyncMetadataDatabase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 373D9B4729EEAC1B00381FDD /* SyncMetadataDatabase.swift */; }; 373D9B4929EEAC1B00381FDD /* SyncMetadataDatabase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 373D9B4729EEAC1B00381FDD /* SyncMetadataDatabase.swift */; }; - 373FB4B12B4D6C42004C88D6 /* PreferencesViews in Frameworks */ = {isa = PBXBuildFile; productRef = 373FB4B02B4D6C42004C88D6 /* PreferencesViews */; }; 373FB4B32B4D6C4B004C88D6 /* PreferencesViews in Frameworks */ = {isa = PBXBuildFile; productRef = 373FB4B22B4D6C4B004C88D6 /* PreferencesViews */; }; 37445F992A1566420029F789 /* SyncDataProviders.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37445F982A1566420029F789 /* SyncDataProviders.swift */; }; 37445F9A2A1566420029F789 /* SyncDataProviders.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37445F982A1566420029F789 /* SyncDataProviders.swift */; }; @@ -1028,8 +1026,6 @@ 37CD54D027F2FDD100F1F7B9 /* DefaultBrowserPreferences.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37CD54C827F2FDD100F1F7B9 /* DefaultBrowserPreferences.swift */; }; 37CEFCA92A6737A2001EF741 /* CredentialsCleanupErrorHandling.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37CEFCA82A6737A2001EF741 /* CredentialsCleanupErrorHandling.swift */; }; 37CEFCAA2A6737A2001EF741 /* CredentialsCleanupErrorHandling.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37CEFCA82A6737A2001EF741 /* CredentialsCleanupErrorHandling.swift */; }; - 37CF91592BB416A500BADCAE /* Crashes in Frameworks */ = {isa = PBXBuildFile; productRef = 37CF91582BB416A500BADCAE /* Crashes */; }; - 37CF915B2BB416AC00BADCAE /* Crashes in Frameworks */ = {isa = PBXBuildFile; productRef = 37CF915A2BB416AC00BADCAE /* Crashes */; }; 37D2377A287EB8CA00BCE03B /* TabIndex.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37D23779287EB8CA00BCE03B /* TabIndex.swift */; }; 37D2377C287EBDA300BCE03B /* TabIndexTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37D2377B287EBDA300BCE03B /* TabIndexTests.swift */; }; 37D23780287EFEE200BCE03B /* PinnedTabsManagerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37D2377F287EFEE200BCE03B /* PinnedTabsManagerTests.swift */; }; @@ -1080,7 +1076,6 @@ 4B1E6EF227AB5E5D00F51793 /* PasswordManagementItemList.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B1E6EF027AB5E5D00F51793 /* PasswordManagementItemList.swift */; }; 4B25375B2A11BE7300610219 /* NetworkExtension.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4B4D603E2A0B290200BCD287 /* NetworkExtension.framework */; }; 4B2537722A11BF8B00610219 /* main.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B25376F2A11BF8B00610219 /* main.swift */; }; - 4B2537772A11BFE100610219 /* PixelKit in Frameworks */ = {isa = PBXBuildFile; productRef = 4B2537762A11BFE100610219 /* PixelKit */; }; 4B25377A2A11C01700610219 /* UserText+NetworkProtectionExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B4D607C2A0B29FA00BCD287 /* UserText+NetworkProtectionExtensions.swift */; }; 4B29759728281F0900187C4E /* FirefoxEncryptionKeyReader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B29759628281F0900187C4E /* FirefoxEncryptionKeyReader.swift */; }; 4B2975992828285900187C4E /* FirefoxKeyReaderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B2975982828285900187C4E /* FirefoxKeyReaderTests.swift */; }; @@ -1143,7 +1138,6 @@ 4B4BEC482A11B61F001D9AC5 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 4B4BEC342A11B509001D9AC5 /* Assets.xcassets */; }; 4B4D603F2A0B290200BCD287 /* NetworkExtension.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4B4D603E2A0B290200BCD287 /* NetworkExtension.framework */; }; 4B4D60892A0B2A1C00BCD287 /* NetworkProtectionUNNotificationsPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B4D60762A0B29FA00BCD287 /* NetworkProtectionUNNotificationsPresenter.swift */; }; - 4B4D60982A0B2A5C00BCD287 /* PixelKit in Frameworks */ = {isa = PBXBuildFile; productRef = 4B4D60972A0B2A5C00BCD287 /* PixelKit */; }; 4B4D609F2A0B2C7300BCD287 /* Logging.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85799C1725DEBB3F0007EC87 /* Logging.swift */; }; 4B4D60A02A0B2D5B00BCD287 /* Bundle+VPN.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B4D605E2A0B29FA00BCD287 /* Bundle+VPN.swift */; }; 4B4D60A12A0B2D6100BCD287 /* NetworkProtectionOptionKeyExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B4D605F2A0B29FA00BCD287 /* NetworkProtectionOptionKeyExtension.swift */; }; @@ -1210,8 +1204,6 @@ 4B7534CC2A1FD7EA00158A99 /* NetworkProtectionInviteDialog.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B4D606C2A0B29FA00BCD287 /* NetworkProtectionInviteDialog.swift */; }; 4B7A57CF279A4EF300B1C70E /* ChromiumPreferences.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B7A57CE279A4EF300B1C70E /* ChromiumPreferences.swift */; }; 4B7A60A1273E0BE400BBDFEB /* WKWebsiteDataStoreExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B7A60A0273E0BE400BBDFEB /* WKWebsiteDataStoreExtension.swift */; }; - 4B81AD352B29512B00706C96 /* PixelKitTestingUtilities in Frameworks */ = {isa = PBXBuildFile; productRef = 4B81AD342B29512B00706C96 /* PixelKitTestingUtilities */; }; - 4B81AD372B29513100706C96 /* PixelKitTestingUtilities in Frameworks */ = {isa = PBXBuildFile; productRef = 4B81AD362B29513100706C96 /* PixelKitTestingUtilities */; }; 4B85A48028821CC500FC4C39 /* NSPasteboardItemExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B85A47F28821CC500FC4C39 /* NSPasteboardItemExtension.swift */; }; 4B8A4DFF27C83B29005F40E8 /* SaveIdentityViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B8A4DFE27C83B29005F40E8 /* SaveIdentityViewController.swift */; }; 4B8A4E0127C8447E005F40E8 /* SaveIdentityPopover.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B8A4E0027C8447E005F40E8 /* SaveIdentityPopover.swift */; }; @@ -1414,7 +1406,6 @@ 560C3FFD2BC9911000F589CE /* PermanentSurveyManagerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 560C3FFB2BC9911000F589CE /* PermanentSurveyManagerTests.swift */; }; 560C3FFF2BCD5A1E00F589CE /* PermanentSurveyManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 560C3FFE2BCD5A1E00F589CE /* PermanentSurveyManager.swift */; }; 560C40002BCD5A1E00F589CE /* PermanentSurveyManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 560C3FFE2BCD5A1E00F589CE /* PermanentSurveyManager.swift */; }; - 560C40012BCD5A1E00F589CE /* PermanentSurveyManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 560C3FFE2BCD5A1E00F589CE /* PermanentSurveyManager.swift */; }; 561D66662B95C45A008ACC5C /* Suggestion.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 561D66692B95C45A008ACC5C /* Suggestion.storyboard */; }; 561D66672B95C45A008ACC5C /* Suggestion.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 561D66692B95C45A008ACC5C /* Suggestion.storyboard */; }; 562984702AC4610100AC20EB /* SyncPreferencesTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5629846E2AC4610100AC20EB /* SyncPreferencesTests.swift */; }; @@ -1484,8 +1475,6 @@ 7B430EA12A71411A00BAC4A1 /* NetworkProtectionSimulateFailureMenu.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B430EA02A71411A00BAC4A1 /* NetworkProtectionSimulateFailureMenu.swift */; }; 7B430EA22A71411A00BAC4A1 /* NetworkProtectionSimulateFailureMenu.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B430EA02A71411A00BAC4A1 /* NetworkProtectionSimulateFailureMenu.swift */; }; 7B4CE8E726F02135009134B1 /* TabBarTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B4CE8E626F02134009134B1 /* TabBarTests.swift */; }; - 7B5DD69A2AE51FFA001DE99C /* PixelKit in Frameworks */ = {isa = PBXBuildFile; productRef = 7B5DD6992AE51FFA001DE99C /* PixelKit */; }; - 7B5F9A752AE2BE4E002AEBC0 /* PixelKit in Frameworks */ = {isa = PBXBuildFile; productRef = 7B5F9A742AE2BE4E002AEBC0 /* PixelKit */; }; 7B624F172BA25C1F00A6C544 /* NetworkProtectionUI in Frameworks */ = {isa = PBXBuildFile; productRef = 7B624F162BA25C1F00A6C544 /* NetworkProtectionUI */; }; 7B7DFB202B7E736B009EA1A3 /* MacPacketTunnelProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = EEF12E6D2A2111880023E6BF /* MacPacketTunnelProvider.swift */; }; 7B7DFB222B7E7473009EA1A3 /* Networking in Frameworks */ = {isa = PBXBuildFile; productRef = 7B7DFB212B7E7473009EA1A3 /* Networking */; }; @@ -1500,7 +1489,6 @@ 7B97CD5E2B7E0BEA004FEF43 /* OptionalExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = B637273C26CCF0C200C8CB02 /* OptionalExtension.swift */; }; 7B97CD5F2B7E0BF7004FEF43 /* NSApplicationExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA5C8F622591021700748EB7 /* NSApplicationExtension.swift */; }; 7B97CD602B7E0C2E004FEF43 /* Logging.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85799C1725DEBB3F0007EC87 /* Logging.swift */; }; - 7B97CD622B7E0C4B004FEF43 /* PixelKit in Frameworks */ = {isa = PBXBuildFile; productRef = 7B97CD612B7E0C4B004FEF43 /* PixelKit */; }; 7BA076BB2B65D61400D7FB72 /* NetworkProtectionProxy in Frameworks */ = {isa = PBXBuildFile; productRef = 7BA076BA2B65D61400D7FB72 /* NetworkProtectionProxy */; }; 7BA4727D26F01BC400EAA165 /* CoreDataTestUtilities.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B9292C42667104B00AD2C21 /* CoreDataTestUtilities.swift */; }; 7BA59C9B2AE18B49009A97B1 /* SystemExtensionManager in Frameworks */ = {isa = PBXBuildFile; productRef = 7BA59C9A2AE18B49009A97B1 /* SystemExtensionManager */; }; @@ -1539,10 +1527,6 @@ 7BBD45B12A691AB500C83CA9 /* NetworkProtectionDebugUtilities.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BBD45B02A691AB500C83CA9 /* NetworkProtectionDebugUtilities.swift */; }; 7BBD45B22A691AB500C83CA9 /* NetworkProtectionDebugUtilities.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BBD45B02A691AB500C83CA9 /* NetworkProtectionDebugUtilities.swift */; }; 7BBE2B7B2B61663C00697445 /* NetworkProtectionProxy in Frameworks */ = {isa = PBXBuildFile; productRef = 7BBE2B7A2B61663C00697445 /* NetworkProtectionProxy */; }; - 7BBE650D2BC67BA0008F4EE9 /* NetworkProtectionIPCTunnelControllerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BBE650C2BC67BA0008F4EE9 /* NetworkProtectionIPCTunnelControllerTests.swift */; }; - 7BBE650E2BC67BA0008F4EE9 /* NetworkProtectionIPCTunnelControllerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BBE650C2BC67BA0008F4EE9 /* NetworkProtectionIPCTunnelControllerTests.swift */; }; - 7BBE65102BC67EED008F4EE9 /* NetworkProtectionTestingSupport.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BBE650F2BC67EED008F4EE9 /* NetworkProtectionTestingSupport.swift */; }; - 7BBE65112BC67EED008F4EE9 /* NetworkProtectionTestingSupport.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BBE650F2BC67EED008F4EE9 /* NetworkProtectionTestingSupport.swift */; }; 7BD01C192AD8319C0088B32E /* IPCServiceManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BD01C182AD8319C0088B32E /* IPCServiceManager.swift */; }; 7BD1688E2AD4A4C400D24876 /* NetworkExtensionController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BD1688D2AD4A4C400D24876 /* NetworkExtensionController.swift */; }; 7BD3AF5D2A8E7AF1006F9F56 /* KeychainType+ClientDefault.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BD3AF5C2A8E7AF1006F9F56 /* KeychainType+ClientDefault.swift */; }; @@ -1558,8 +1542,6 @@ 7BEEA5122AD1235B00A9E72B /* NetworkProtectionIPC in Frameworks */ = {isa = PBXBuildFile; productRef = 7BEEA5112AD1235B00A9E72B /* NetworkProtectionIPC */; }; 7BEEA5142AD1236300A9E72B /* NetworkProtectionIPC in Frameworks */ = {isa = PBXBuildFile; productRef = 7BEEA5132AD1236300A9E72B /* NetworkProtectionIPC */; }; 7BEEA5162AD1236E00A9E72B /* NetworkProtectionUI in Frameworks */ = {isa = PBXBuildFile; productRef = 7BEEA5152AD1236E00A9E72B /* NetworkProtectionUI */; }; - 7BFCB74E2ADE7E1A00DA3EA7 /* PixelKit in Frameworks */ = {isa = PBXBuildFile; productRef = 7BFCB74D2ADE7E1A00DA3EA7 /* PixelKit */; }; - 7BFCB7502ADE7E2300DA3EA7 /* PixelKit in Frameworks */ = {isa = PBXBuildFile; productRef = 7BFCB74F2ADE7E2300DA3EA7 /* PixelKit */; }; 7BFE95522A9DF1CE0081ABE9 /* NetworkProtectionWaitlistFeatureFlagOverridesMenu.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BFE95512A9DF1CE0081ABE9 /* NetworkProtectionWaitlistFeatureFlagOverridesMenu.swift */; }; 7BFE95542A9DF2930081ABE9 /* UserDefaults+NetworkProtectionWaitlist.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BFE95532A9DF2930081ABE9 /* UserDefaults+NetworkProtectionWaitlist.swift */; }; 7BFE95552A9DF2990081ABE9 /* UserDefaults+NetworkProtectionWaitlist.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BFE95532A9DF2930081ABE9 /* UserDefaults+NetworkProtectionWaitlist.swift */; }; @@ -1684,8 +1666,6 @@ 98A50964294B691800D10880 /* Persistence in Frameworks */ = {isa = PBXBuildFile; productRef = 98A50963294B691800D10880 /* Persistence */; }; 98A95D88299A2DF900B9B81A /* BookmarkMigrationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98A95D87299A2DF900B9B81A /* BookmarkMigrationTests.swift */; }; 98EB5D1027516A4800681FE6 /* AppPrivacyConfigurationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98EB5D0F27516A4800681FE6 /* AppPrivacyConfigurationTests.swift */; }; - 9D6983F92AC773C3002C02FC /* PixelKit in Frameworks */ = {isa = PBXBuildFile; productRef = 9D6983F82AC773C3002C02FC /* PixelKit */; }; - 9D6983FB2AC773C8002C02FC /* PixelKit in Frameworks */ = {isa = PBXBuildFile; productRef = 9D6983FA2AC773C8002C02FC /* PixelKit */; }; 9D9AE8692AA76CDC0026E7DC /* LoginItem+NetworkProtection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9D9AE8682AA76CDC0026E7DC /* LoginItem+NetworkProtection.swift */; }; 9D9AE86B2AA76CF90026E7DC /* LoginItemsManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9D9AE86A2AA76CF90026E7DC /* LoginItemsManager.swift */; }; 9D9AE86C2AA76D1B0026E7DC /* LoginItemsManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9D9AE86A2AA76CF90026E7DC /* LoginItemsManager.swift */; }; @@ -1702,7 +1682,6 @@ 9D9AE92A2AAA43EB0026E7DC /* DataBrokerProtectionBackgroundManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9D9AE9282AAA43EB0026E7DC /* DataBrokerProtectionBackgroundManager.swift */; }; 9D9AE92C2AAB84FF0026E7DC /* DBPMocks.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9D9AE92B2AAB84FF0026E7DC /* DBPMocks.swift */; }; 9D9AE92D2AAB84FF0026E7DC /* DBPMocks.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9D9AE92B2AAB84FF0026E7DC /* DBPMocks.swift */; }; - 9DB6E7242AA0DC5800A17F3C /* LoginItems in Frameworks */ = {isa = PBXBuildFile; productRef = 9DB6E7232AA0DC5800A17F3C /* LoginItems */; }; 9DC70B1A2AA1FA5B005A844B /* LoginItems in Frameworks */ = {isa = PBXBuildFile; productRef = 9DC70B192AA1FA5B005A844B /* LoginItems */; }; 9DEF97E12B06C4EE00764F03 /* Networking in Frameworks */ = {isa = PBXBuildFile; productRef = 9DEF97E02B06C4EE00764F03 /* Networking */; }; 9F0A2CF82B96A58600C5B8C0 /* BaseBookmarkEntityTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F0A2CF72B96A58600C5B8C0 /* BaseBookmarkEntityTests.swift */; }; @@ -2527,6 +2506,9 @@ EEDE50122BA360C80017F3C4 /* NetworkProtection+VPNAgentConvenienceInitializers.swift in Sources */ = {isa = PBXBuildFile; fileRef = EEDE50102BA360C80017F3C4 /* NetworkProtection+VPNAgentConvenienceInitializers.swift */; }; EEF12E6F2A2111880023E6BF /* MacPacketTunnelProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = EEF12E6D2A2111880023E6BF /* MacPacketTunnelProvider.swift */; }; EEF53E182950CED5002D78F4 /* JSAlertViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = EEF53E172950CED5002D78F4 /* JSAlertViewModelTests.swift */; }; + F116A7C32BD1924B00F3FCF7 /* PixelKitTestingUtilities in Frameworks */ = {isa = PBXBuildFile; productRef = F116A7C22BD1924B00F3FCF7 /* PixelKitTestingUtilities */; }; + F116A7C72BD1925500F3FCF7 /* PixelKitTestingUtilities in Frameworks */ = {isa = PBXBuildFile; productRef = F116A7C62BD1925500F3FCF7 /* PixelKitTestingUtilities */; }; + F116A7C92BD1929000F3FCF7 /* PixelKitTestingUtilities in Frameworks */ = {isa = PBXBuildFile; productRef = F116A7C82BD1929000F3FCF7 /* PixelKitTestingUtilities */; }; F188267C2BBEB3AA00D9AC4F /* GeneralPixel.swift in Sources */ = {isa = PBXBuildFile; fileRef = F188267B2BBEB3AA00D9AC4F /* GeneralPixel.swift */; }; F188267D2BBEB3AA00D9AC4F /* GeneralPixel.swift in Sources */ = {isa = PBXBuildFile; fileRef = F188267B2BBEB3AA00D9AC4F /* GeneralPixel.swift */; }; F18826802BBEB58100D9AC4F /* PrivacyProPixel.swift in Sources */ = {isa = PBXBuildFile; fileRef = F188267F2BBEB58100D9AC4F /* PrivacyProPixel.swift */; }; @@ -2539,6 +2521,14 @@ F18826912BC0105800D9AC4F /* PixelDataStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6DA44012616B28300DD1EC2 /* PixelDataStore.swift */; }; F18826922BC0105900D9AC4F /* PixelDataRecord.swift in Sources */ = {isa = PBXBuildFile; fileRef = B68C92C32750EF76002AC6B0 /* PixelDataRecord.swift */; }; F18826932BC0105900D9AC4F /* PixelDataStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6DA44012616B28300DD1EC2 /* PixelDataStore.swift */; }; + F198C7122BD18A28000BF24D /* PixelKit in Frameworks */ = {isa = PBXBuildFile; productRef = F198C7112BD18A28000BF24D /* PixelKit */; }; + F198C7142BD18A30000BF24D /* PixelKit in Frameworks */ = {isa = PBXBuildFile; productRef = F198C7132BD18A30000BF24D /* PixelKit */; }; + F198C7162BD18A44000BF24D /* PixelKit in Frameworks */ = {isa = PBXBuildFile; productRef = F198C7152BD18A44000BF24D /* PixelKit */; }; + F198C7182BD18A4C000BF24D /* PixelKit in Frameworks */ = {isa = PBXBuildFile; productRef = F198C7172BD18A4C000BF24D /* PixelKit */; }; + F198C71A2BD18A5B000BF24D /* PixelKit in Frameworks */ = {isa = PBXBuildFile; productRef = F198C7192BD18A5B000BF24D /* PixelKit */; }; + F198C71C2BD18A61000BF24D /* PixelKit in Frameworks */ = {isa = PBXBuildFile; productRef = F198C71B2BD18A61000BF24D /* PixelKit */; }; + F198C71E2BD18D88000BF24D /* SwiftLintTool in Frameworks */ = {isa = PBXBuildFile; productRef = F198C71D2BD18D88000BF24D /* SwiftLintTool */; }; + F198C7202BD18D92000BF24D /* SwiftLintTool in Frameworks */ = {isa = PBXBuildFile; productRef = F198C71F2BD18D92000BF24D /* SwiftLintTool */; }; F1B33DF22BAD929D001128B3 /* SubscriptionAppStoreRestorer.swift in Sources */ = {isa = PBXBuildFile; fileRef = F1B33DF12BAD929D001128B3 /* SubscriptionAppStoreRestorer.swift */; }; F1B33DF32BAD929D001128B3 /* SubscriptionAppStoreRestorer.swift in Sources */ = {isa = PBXBuildFile; fileRef = F1B33DF12BAD929D001128B3 /* SubscriptionAppStoreRestorer.swift */; }; F1B33DF62BAD970E001128B3 /* SubscriptionErrorReporter.swift in Sources */ = {isa = PBXBuildFile; fileRef = F1B33DF52BAD970E001128B3 /* SubscriptionErrorReporter.swift */; }; @@ -2547,6 +2537,10 @@ F1D43AEF2B98D8DF00BAB743 /* MainMenuActions+VanillaBrowser.swift in Sources */ = {isa = PBXBuildFile; fileRef = F1D43AED2B98D8DF00BAB743 /* MainMenuActions+VanillaBrowser.swift */; }; F1D43AF32B98E47800BAB743 /* BareBonesBrowserKit in Frameworks */ = {isa = PBXBuildFile; productRef = F1D43AF22B98E47800BAB743 /* BareBonesBrowserKit */; }; F1D43AF52B98E48900BAB743 /* BareBonesBrowserKit in Frameworks */ = {isa = PBXBuildFile; productRef = F1D43AF42B98E48900BAB743 /* BareBonesBrowserKit */; }; + F1DF95E32BD1807C0045E591 /* Crashes in Frameworks */ = {isa = PBXBuildFile; productRef = 08D4923DC968236E22E373E2 /* Crashes */; }; + F1DF95E42BD1807C0045E591 /* Crashes in Frameworks */ = {isa = PBXBuildFile; productRef = 537FC71EA5115A983FAF3170 /* Crashes */; }; + F1DF95E52BD1807C0045E591 /* Subscription in Frameworks */ = {isa = PBXBuildFile; productRef = DC3F73D49B2D44464AFEFCD8 /* Subscription */; }; + F1DF95E72BD188B60045E591 /* LoginItems in Frameworks */ = {isa = PBXBuildFile; productRef = F1DF95E62BD188B60045E591 /* LoginItems */; }; F41D174125CB131900472416 /* NSColorExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = F41D174025CB131900472416 /* NSColorExtension.swift */; }; F44C130225C2DA0400426E3E /* NSAppearanceExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = F44C130125C2DA0400426E3E /* NSAppearanceExtension.swift */; }; F4A6198C283CFFBB007F2080 /* ContentScopeFeatureFlagging.swift in Sources */ = {isa = PBXBuildFile; fileRef = F4A6198B283CFFBB007F2080 /* ContentScopeFeatureFlagging.swift */; }; @@ -3182,7 +3176,6 @@ 4BD57C032AC112DF00B580EE /* NetworkProtectionRemoteMessagingTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkProtectionRemoteMessagingTests.swift; sourceTree = ""; }; 4BDFA4AD27BF19E500648192 /* ToggleableScrollView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ToggleableScrollView.swift; sourceTree = ""; }; 4BE0DF0426781961006337B7 /* NSStoryboardExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSStoryboardExtension.swift; sourceTree = ""; }; - 4BE15DB12A0B0DD500898243 /* PixelKit */ = {isa = PBXFileReference; lastKnownFileType = wrapper; path = PixelKit; sourceTree = ""; }; 4BE344ED2B2376DF003FC223 /* VPNFeedbackFormViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPNFeedbackFormViewModelTests.swift; sourceTree = ""; }; 4BE4005227CF3DC3007D3161 /* SavePaymentMethodPopover.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SavePaymentMethodPopover.swift; sourceTree = ""; }; 4BE4005427CF3F19007D3161 /* SavePaymentMethodViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SavePaymentMethodViewController.swift; sourceTree = ""; }; @@ -3279,8 +3272,6 @@ 7BB108582A43375D000AB95F /* PFMoveApplication.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PFMoveApplication.m; sourceTree = ""; }; 7BBA7CE52BAB03C1007579A3 /* DefaultSubscriptionFeatureAvailability+DefaultInitializer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "DefaultSubscriptionFeatureAvailability+DefaultInitializer.swift"; sourceTree = ""; }; 7BBD45B02A691AB500C83CA9 /* NetworkProtectionDebugUtilities.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkProtectionDebugUtilities.swift; sourceTree = ""; }; - 7BBE650C2BC67BA0008F4EE9 /* NetworkProtectionIPCTunnelControllerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkProtectionIPCTunnelControllerTests.swift; sourceTree = ""; }; - 7BBE650F2BC67EED008F4EE9 /* NetworkProtectionTestingSupport.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkProtectionTestingSupport.swift; sourceTree = ""; }; 7BD01C182AD8319C0088B32E /* IPCServiceManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IPCServiceManager.swift; sourceTree = ""; }; 7BD1688D2AD4A4C400D24876 /* NetworkExtensionController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NetworkExtensionController.swift; sourceTree = ""; }; 7BD3AF5C2A8E7AF1006F9F56 /* KeychainType+ClientDefault.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "KeychainType+ClientDefault.swift"; sourceTree = ""; }; @@ -3999,8 +3990,8 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + F1DF95E42BD1807C0045E591 /* Crashes in Frameworks */, 373FB4B32B4D6C4B004C88D6 /* PreferencesViews in Frameworks */, - 7B5F9A752AE2BE4E002AEBC0 /* PixelKit in Frameworks */, 4BF97AD32B43C43F00EB4240 /* NetworkProtectionUI in Frameworks */, 7B1459572B7D43E500047F2C /* NetworkProtectionProxy in Frameworks */, B6F7128229F6820A00594A45 /* QuickLookUI.framework in Frameworks */, @@ -4009,10 +4000,12 @@ 37A5E2F0298AA1B20047046B /* Persistence in Frameworks */, 9DC70B1A2AA1FA5B005A844B /* LoginItems in Frameworks */, 37269EFD2B332FAC005E8E46 /* Common in Frameworks */, + F198C7142BD18A30000BF24D /* PixelKit in Frameworks */, F1D43AF52B98E48900BAB743 /* BareBonesBrowserKit in Frameworks */, 378F44E629B4BDEE00899924 /* SwiftUIExtensions in Frameworks */, 3706FCA7293F65D500E42796 /* BrowserServicesKit in Frameworks */, 3129788A2B64131200B67619 /* DataBrokerProtection in Frameworks */, + F198C7202BD18D92000BF24D /* SwiftLintTool in Frameworks */, 4BCBE4582BA7E17800FC75A1 /* SubscriptionUI in Frameworks */, 3706FCA9293F65D500E42796 /* ContentBlocking in Frameworks */, 85D44B882BA08D30001B4AB5 /* Suggestions in Frameworks */, @@ -4022,7 +4015,6 @@ B6EC37FF29B8D915001ACE79 /* Configuration in Frameworks */, 372217822B33380700B8E9C2 /* TestUtils in Frameworks */, 3706FCAA293F65D500E42796 /* UserScript in Frameworks */, - 37CF915B2BB416AC00BADCAE /* Crashes in Frameworks */, 3706FCAB293F65D500E42796 /* TrackerRadarKit in Frameworks */, 85E2BBD02B8F534A00DBEC7A /* History in Frameworks */, 4BF97AD52B43C43F00EB4240 /* NetworkProtection in Frameworks */, @@ -4038,9 +4030,9 @@ buildActionMask = 2147483647; files = ( 3706FE88293F661700E42796 /* OHHTTPStubs in Frameworks */, + F116A7C72BD1925500F3FCF7 /* PixelKitTestingUtilities in Frameworks */, B65CD8CF2B316E0200A595BB /* SnapshotTesting in Frameworks */, 3706FE89293F661700E42796 /* OHHTTPStubsSwift in Frameworks */, - 4B81AD372B29513100706C96 /* PixelKitTestingUtilities in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -4063,6 +4055,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + F116A7C92BD1929000F3FCF7 /* PixelKitTestingUtilities in Frameworks */, B65CD8CD2B316DFC00A595BB /* SnapshotTesting in Frameworks */, B6AE39F329374AEC00C37AA4 /* OHHTTPStubs in Frameworks */, B6AE39F529374AEC00C37AA4 /* OHHTTPStubsSwift in Frameworks */, @@ -4075,8 +4068,8 @@ files = ( 37269F012B332FC8005E8E46 /* Common in Frameworks */, EE7295E92A545BC4008C0991 /* NetworkProtection in Frameworks */, - 4B2537772A11BFE100610219 /* PixelKit in Frameworks */, 7B37C7A52BAA32A50062546A /* Subscription in Frameworks */, + F198C7182BD18A4C000BF24D /* PixelKit in Frameworks */, 7BBE2B7B2B61663C00697445 /* NetworkProtectionProxy in Frameworks */, 4B2D062C2A11C0E100DE1F49 /* Networking in Frameworks */, 4B25375B2A11BE7300610219 /* NetworkExtension.framework in Frameworks */, @@ -4087,13 +4080,13 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + F198C71A2BD18A5B000BF24D /* PixelKit in Frameworks */, 4B41EDAB2B1544B2001EEDF4 /* LoginItems in Frameworks */, 7B00997D2B6508B700FE7C31 /* NetworkProtectionProxy in Frameworks */, 7BEEA5122AD1235B00A9E72B /* NetworkProtectionIPC in Frameworks */, 7BA7CC5F2AD1210C0042E5CE /* Networking in Frameworks */, 7BEEA5162AD1236E00A9E72B /* NetworkProtectionUI in Frameworks */, BDADBDC92BD2BC2200421B9B /* Lottie in Frameworks */, - 7BFCB74E2ADE7E1A00DA3EA7 /* PixelKit in Frameworks */, EE7295ED2A545C0A008C0991 /* NetworkProtection in Frameworks */, EE2F9C5B2B90F2FF00D45FC9 /* Subscription in Frameworks */, 7BEC182F2AD5D8DC00D30536 /* SystemExtensionManager in Frameworks */, @@ -4104,9 +4097,9 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 7BFCB7502ADE7E2300DA3EA7 /* PixelKit in Frameworks */, 4BCBE45C2BA7E18500FC75A1 /* Subscription in Frameworks */, 7BA7CC612AD1211C0042E5CE /* Networking in Frameworks */, + F198C71C2BD18A61000BF24D /* PixelKit in Frameworks */, 7BEEA5142AD1236300A9E72B /* NetworkProtectionIPC in Frameworks */, BDADBDCB2BD2BC2800421B9B /* Lottie in Frameworks */, 7B00997F2B6508C200FE7C31 /* NetworkProtectionProxy in Frameworks */, @@ -4129,10 +4122,10 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + F1DF95E52BD1807C0045E591 /* Subscription in Frameworks */, 37269EFF2B332FBB005E8E46 /* Common in Frameworks */, EE7295E72A545BBB008C0991 /* NetworkProtection in Frameworks */, - 4B4D60982A0B2A5C00BCD287 /* PixelKit in Frameworks */, - 1E46E1A02BD029BD0007273A /* Subscription in Frameworks */, + F198C7162BD18A44000BF24D /* PixelKit in Frameworks */, 4B4D60AF2A0C837F00BCD287 /* Networking in Frameworks */, 7B25856E2BA2F2ED00D49F79 /* NetworkProtectionUI in Frameworks */, 4B4D603F2A0B290200BCD287 /* NetworkExtension.framework in Frameworks */, @@ -4161,7 +4154,6 @@ files = ( 7BDA36E62B7E037100AD5388 /* NetworkExtension.framework in Frameworks */, 7B97CD592B7E0B57004FEF43 /* NetworkProtectionProxy in Frameworks */, - 7B97CD622B7E0C4B004FEF43 /* PixelKit in Frameworks */, 7B7DFB222B7E7473009EA1A3 /* Networking in Frameworks */, 7B97CD5B2B7E0B85004FEF43 /* Common in Frameworks */, ); @@ -4172,7 +4164,6 @@ buildActionMask = 2147483647; files = ( 9DEF97E12B06C4EE00764F03 /* Networking in Frameworks */, - 9D6983F92AC773C3002C02FC /* PixelKit in Frameworks */, 9D9AE8F92AAA3AD00026E7DC /* DataBrokerProtection in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; @@ -4181,7 +4172,6 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 9D6983FB2AC773C8002C02FC /* PixelKit in Frameworks */, 315A023F2B6421AE00BFA577 /* Networking in Frameworks */, 9D9AE8FB2AAA3AD90026E7DC /* DataBrokerProtection in Frameworks */, ); @@ -4191,16 +4181,13 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 37CF91592BB416A500BADCAE /* Crashes in Frameworks */, - 373FB4B12B4D6C42004C88D6 /* PreferencesViews in Frameworks */, + F1DF95E32BD1807C0045E591 /* Crashes in Frameworks */, 85E2BBCE2B8F534000DBEC7A /* History in Frameworks */, 1EA7B8D32B7E078C000330A4 /* SubscriptionUI in Frameworks */, B6F7128129F681EB00594A45 /* QuickLookUI.framework in Frameworks */, - 9DB6E7242AA0DC5800A17F3C /* LoginItems in Frameworks */, EE7295E32A545B9A008C0991 /* NetworkProtection in Frameworks */, 9807F645278CA16F00E1547B /* BrowserServicesKit in Frameworks */, 987799ED299998B1005D8EB6 /* Bookmarks in Frameworks */, - 7B5DD69A2AE51FFA001DE99C /* PixelKit in Frameworks */, 1E950E3F2912A10D0051A99B /* ContentBlocking in Frameworks */, 31A3A4E32B0C115F0021063C /* DataBrokerProtection in Frameworks */, 378F44E429B4BDE900899924 /* SwiftUIExtensions in Frameworks */, @@ -4210,8 +4197,10 @@ 7B31FD8C2AD125620086AA24 /* NetworkProtectionIPC in Frameworks */, 37269EFB2B332F9E005E8E46 /* Common in Frameworks */, AA06B6B72672AF8100F541C5 /* Sparkle in Frameworks */, + F198C71E2BD18D88000BF24D /* SwiftLintTool in Frameworks */, 1EA7B8D52B7E078C000330A4 /* Subscription in Frameworks */, B6B77BE8297973D4001E68A1 /* Navigation in Frameworks */, + F198C7122BD18A28000BF24D /* PixelKit in Frameworks */, 3739326729AE4B42009346AE /* DDGSync in Frameworks */, 7BA59C9B2AE18B49009A97B1 /* SystemExtensionManager in Frameworks */, 371D00E129D8509400EC8598 /* OpenSSL in Frameworks */, @@ -4220,6 +4209,7 @@ 85D44B862BA08D29001B4AB5 /* Suggestions in Frameworks */, 37DF000529F9C056002B7D3E /* SyncDataProviders in Frameworks */, 37BA812D29B3CD690053F1A3 /* SyncUI in Frameworks */, + F1DF95E72BD188B60045E591 /* LoginItems in Frameworks */, 372217802B3337FE00B8E9C2 /* TestUtils in Frameworks */, 7BA076BB2B65D61400D7FB72 /* NetworkProtectionProxy in Frameworks */, 4B4D60B12A0C83B900BCD287 /* NetworkProtectionUI in Frameworks */, @@ -4232,9 +4222,9 @@ buildActionMask = 2147483647; files = ( B6DA44172616C13800DD1EC2 /* OHHTTPStubs in Frameworks */, + F116A7C32BD1924B00F3FCF7 /* PixelKitTestingUtilities in Frameworks */, B65CD8CB2B316DF100A595BB /* SnapshotTesting in Frameworks */, B6DA44192616C13800DD1EC2 /* OHHTTPStubsSwift in Frameworks */, - 4B81AD352B29512B00706C96 /* PixelKitTestingUtilities in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -4665,7 +4655,6 @@ 3192A2702A4C4E330084EA89 /* DataBrokerProtection */, 9DB6E7222AA0DA7A00A17F3C /* LoginItems */, 7B25FE322AD12C990012AFAB /* NetworkProtectionMac */, - 4BE15DB12A0B0DD500898243 /* PixelKit */, 378F44E229B4B7B600899924 /* SwiftUIExtensions */, 37BA812B29B3CB8A0053F1A3 /* SyncUI */, 1E862A882A9FC01200F84D4B /* SubscriptionUI */, @@ -5589,13 +5578,11 @@ isa = PBXGroup; children = ( BDA7648F2BC4E56200D0400C /* Mocks */, - 7BBE65122BC67EF6008F4EE9 /* Support */, 4BCF15E62ABB98A20083F6DF /* Resources */, 4BCF15E42ABB98990083F6DF /* NetworkProtectionRemoteMessageTests.swift */, 4BD57C032AC112DF00B580EE /* NetworkProtectionRemoteMessagingTests.swift */, 7B09CBA72BA4BE7000CF245B /* NetworkProtectionPixelEventTests.swift */, BDA7648C2BC4E4EF00D0400C /* DefaultVPNLocationFormatterTests.swift */, - 7BBE650C2BC67BA0008F4EE9 /* NetworkProtectionIPCTunnelControllerTests.swift */, ); path = NetworkProtection; sourceTree = ""; @@ -5801,14 +5788,6 @@ path = LetsMove1.25; sourceTree = ""; }; - 7BBE65122BC67EF6008F4EE9 /* Support */ = { - isa = PBXGroup; - children = ( - 7BBE650F2BC67EED008F4EE9 /* NetworkProtectionTestingSupport.swift */, - ); - path = Support; - sourceTree = ""; - }; 7BDA36E72B7E037200AD5388 /* VPNProxyExtension */ = { isa = PBXGroup; children = ( @@ -6369,7 +6348,6 @@ 565E46DE2B2725DD0013AC2A /* SyncE2EUITests */, AA585D7F248FD31100E9A3E2 /* Products */, 85AE2FF024A33A2D002D507F /* Frameworks */, - EE0629702B90EE3500D868B4 /* Recovered References */, ); sourceTree = ""; }; @@ -7096,10 +7074,10 @@ 4B9292CD2667123700AD2C21 /* BookmarkManagementDetailViewController.swift */, 4B9292C72667123700AD2C21 /* BookmarkManagementSidebarViewController.swift */, 4B9292C82667123700AD2C21 /* BookmarkManagementSplitViewController.swift */, + 4B9292C92667123700AD2C21 /* BookmarkTableRowView.swift */, 4B92928726670D1600AD2C21 /* BookmarkOutlineCellView.swift */, 4B92928526670D1600AD2C21 /* BookmarksOutlineView.swift */, 4B92928926670D1700AD2C21 /* BookmarkTableCellView.swift */, - 4B9292C92667123700AD2C21 /* BookmarkTableRowView.swift */, 4B9292C62667123700AD2C21 /* BrowserTabSelectionDelegate.swift */, 4B92928626670D1600AD2C21 /* OutlineSeparatorViewCell.swift */, 4B0511B3262CAA5A00F6079C /* RoundedSelectionRowView.swift */, @@ -7994,13 +7972,6 @@ path = fonts; sourceTree = ""; }; - EE0629702B90EE3500D868B4 /* Recovered References */ = { - isa = PBXGroup; - children = ( - ); - name = "Recovered References"; - sourceTree = ""; - }; EEA3EEAF2B24EB5100E8333A /* VPNLocation */ = { isa = PBXGroup; children = ( @@ -8073,16 +8044,15 @@ CBCCF59F2996681700C02DFE /* Assert Xcode version */, 378E2798296F6D1D00FCADA2 /* Validate PRODUCT_NAME */, 3706FA79293F65D500E42796 /* Check Embedded Config URLs */, - B6E6BA192BA2D8BE008AA7E1 /* Run swiftlint */, 3706FA7A293F65D500E42796 /* Sources */, 3706FCA6293F65D500E42796 /* Frameworks */, 3706FCB1293F65D500E42796 /* Resources */, 4BBA2D272B6AC09D00F6A470 /* Embed Login Items */, + 6A8856B31B2BC5078B61ED81 /* Run swiftlint */, ); buildRules = ( ); dependencies = ( - B637D1BD2BC6AE6200C7DCA7 /* PBXTargetDependency */, 4BBA2D2B2B6AD01E00F6A470 /* PBXTargetDependency */, 4BBA2D292B6ACD4D00F6A470 /* PBXTargetDependency */, 4B5F14FE2A1529230060320F /* PBXTargetDependency */, @@ -8103,7 +8073,6 @@ B6EC37FE29B8D915001ACE79 /* Configuration */, 37DF000629F9C061002B7D3E /* SyncDataProviders */, 9DC70B192AA1FA5B005A844B /* LoginItems */, - 7B5F9A742AE2BE4E002AEBC0 /* PixelKit */, 37269EFC2B332FAC005E8E46 /* Common */, 372217812B33380700B8E9C2 /* TestUtils */, 4BF97AD02B43C43F00EB4240 /* NetworkProtectionIPC */, @@ -8117,8 +8086,10 @@ 4BCBE4572BA7E17800FC75A1 /* SubscriptionUI */, 85D44B872BA08D30001B4AB5 /* Suggestions */, 4BCBE4592BA7E17800FC75A1 /* Subscription */, - 37CF915A2BB416AC00BADCAE /* Crashes */, 9FF521472BAA909C00B9819B /* Lottie */, + 537FC71EA5115A983FAF3170 /* Crashes */, + F198C7132BD18A30000BF24D /* PixelKit */, + F198C71F2BD18D92000BF24D /* SwiftLintTool */, ); productName = DuckDuckGo; productReference = 3706FD05293F65D500E42796 /* DuckDuckGo App Store.app */; @@ -8142,8 +8113,8 @@ packageProductDependencies = ( 3706FDD6293F661700E42796 /* OHHTTPStubs */, 3706FDD8293F661700E42796 /* OHHTTPStubsSwift */, - 4B81AD362B29513100706C96 /* PixelKitTestingUtilities */, B65CD8CE2B316E0200A595BB /* SnapshotTesting */, + F116A7C62BD1925500F3FCF7 /* PixelKitTestingUtilities */, ); productName = DuckDuckGoTests; productReference = 3706FE99293F661700E42796 /* Unit Tests App Store.xctest */; @@ -8185,8 +8156,6 @@ 376113D62B29CD6800E794BB /* PBXTargetDependency */, ); name = "SyncE2EUITests App Store"; - packageProductDependencies = ( - ); productName = DuckDuckGoSyncUITests; productReference = 376113D42B29CD5B00E794BB /* SyncE2EUITests App Store.xctest */; productType = "com.apple.product-type.bundle.ui-testing"; @@ -8210,6 +8179,7 @@ B6AE39F229374AEC00C37AA4 /* OHHTTPStubs */, B6AE39F429374AEC00C37AA4 /* OHHTTPStubsSwift */, B65CD8CC2B316DFC00A595BB /* SnapshotTesting */, + F116A7C82BD1929000F3FCF7 /* PixelKitTestingUtilities */, ); productName = "Integration Tests"; productReference = 4B1AD89D25FC27E200261379 /* Integration Tests.xctest */; @@ -8230,12 +8200,12 @@ ); name = NetworkProtectionSystemExtension; packageProductDependencies = ( - 4B2537762A11BFE100610219 /* PixelKit */, 4B2D062B2A11C0E100DE1F49 /* Networking */, EE7295E82A545BC4008C0991 /* NetworkProtection */, 37269F002B332FC8005E8E46 /* Common */, 7BBE2B7A2B61663C00697445 /* NetworkProtectionProxy */, 7B37C7A42BAA32A50062546A /* Subscription */, + F198C7172BD18A4C000BF24D /* PixelKit */, ); productName = NetworkProtectionSystemExtension; productReference = 4B25375A2A11BE7300610219 /* com.duckduckgo.macos.vpn.network-extension.debug.systemextension */; @@ -8263,10 +8233,10 @@ 7BEEA5112AD1235B00A9E72B /* NetworkProtectionIPC */, 7BEEA5152AD1236E00A9E72B /* NetworkProtectionUI */, 7BEC182E2AD5D8DC00D30536 /* SystemExtensionManager */, - 7BFCB74D2ADE7E1A00DA3EA7 /* PixelKit */, 4B41EDAA2B1544B2001EEDF4 /* LoginItems */, 7B00997C2B6508B700FE7C31 /* NetworkProtectionProxy */, EE2F9C5A2B90F2FF00D45FC9 /* Subscription */, + F198C7192BD18A5B000BF24D /* PixelKit */, BDADBDC82BD2BC2200421B9B /* Lottie */, ); productName = DuckDuckGoAgent; @@ -8296,10 +8266,10 @@ EE7295EE2A545C12008C0991 /* NetworkProtection */, 7BA7CC602AD1211C0042E5CE /* Networking */, 7BEEA5132AD1236300A9E72B /* NetworkProtectionIPC */, - 7BFCB74F2ADE7E2300DA3EA7 /* PixelKit */, 7B00997E2B6508C200FE7C31 /* NetworkProtectionProxy */, 4BA7C4DC2B3F64E500AFE511 /* LoginItems */, 4BCBE45B2BA7E18500FC75A1 /* Subscription */, + F198C71B2BD18A61000BF24D /* PixelKit */, BDADBDCA2BD2BC2800421B9B /* Lottie */, ); productName = DuckDuckGoAgentAppStore; @@ -8343,12 +8313,12 @@ ); name = NetworkProtectionAppExtension; packageProductDependencies = ( - 4B4D60972A0B2A5C00BCD287 /* PixelKit */, 4B4D60AE2A0C837F00BCD287 /* Networking */, EE7295E62A545BBB008C0991 /* NetworkProtection */, 37269EFE2B332FBB005E8E46 /* Common */, 7B25856D2BA2F2ED00D49F79 /* NetworkProtectionUI */, - 1E46E19F2BD029BD0007273A /* Subscription */, + DC3F73D49B2D44464AFEFCD8 /* Subscription */, + F198C7152BD18A44000BF24D /* PixelKit */, ); productName = NetworkProtectionAppExtension; productReference = 4B4D603D2A0B290200BCD287 /* NetworkProtectionAppExtension.appex */; @@ -8367,8 +8337,6 @@ dependencies = ( ); name = SyncE2EUITests; - packageProductDependencies = ( - ); productName = DuckDuckGoSyncUITests; productReference = 565E46DD2B2725DC0013AC2A /* SyncE2EUITests.xctest */; productType = "com.apple.product-type.bundle.ui-testing"; @@ -8411,7 +8379,6 @@ packageProductDependencies = ( 7B97CD582B7E0B57004FEF43 /* NetworkProtectionProxy */, 7B97CD5A2B7E0B85004FEF43 /* Common */, - 7B97CD612B7E0C4B004FEF43 /* PixelKit */, 7B7DFB212B7E7473009EA1A3 /* Networking */, ); productName = VPNProxyExtension; @@ -8434,7 +8401,6 @@ name = DuckDuckGoDBPBackgroundAgent; packageProductDependencies = ( 9D9AE8F82AAA3AD00026E7DC /* DataBrokerProtection */, - 9D6983F82AC773C3002C02FC /* PixelKit */, 9DEF97E02B06C4EE00764F03 /* Networking */, ); productName = DuckDuckGoAgent; @@ -8457,7 +8423,6 @@ name = DuckDuckGoDBPBackgroundAgentAppStore; packageProductDependencies = ( 9D9AE8FA2AAA3AD90026E7DC /* DataBrokerProtection */, - 9D6983FA2AC773C8002C02FC /* PixelKit */, 315A023E2B6421AE00BFA577 /* Networking */, ); productName = DuckDuckGoAgent; @@ -8470,17 +8435,16 @@ buildPhases = ( CBCCF59E299667B700C02DFE /* Assert Xcode version */, 3705272528992C8A000C06A2 /* Check Embedded Config URLs */, - B6409DC52BC7BD1F00D66F9E /* Run swiftlint */, AA585D7A248FD31100E9A3E2 /* Sources */, AA585D7B248FD31100E9A3E2 /* Frameworks */, AA585D7C248FD31100E9A3E2 /* Resources */, B6F2C8722A7A4C7D000498CF /* Make /Applications symlink, remove app on Clean build */, 4B2D065D2A11D2AE00DE1F49 /* Embed Login Items */, + 28003FDBDB96625F1630CFF2 /* Run swiftlint */, ); buildRules = ( ); dependencies = ( - B637D1BB2BC6AE5600C7DCA7 /* PBXTargetDependency */, 7B4627742B9AF2C8004ACE0B /* PBXTargetDependency */, 4B5F14FC2A15291D0060320F /* PBXTargetDependency */, 31C6E9AD2B0C07BA0086DC30 /* PBXTargetDependency */, @@ -8503,22 +8467,22 @@ 37DF000429F9C056002B7D3E /* SyncDataProviders */, 4B4D60B02A0C83B900BCD287 /* NetworkProtectionUI */, EE7295E22A545B9A008C0991 /* NetworkProtection */, - 9DB6E7232AA0DC5800A17F3C /* LoginItems */, 7B31FD8B2AD125620086AA24 /* NetworkProtectionIPC */, 7BA59C9A2AE18B49009A97B1 /* SystemExtensionManager */, - 7B5DD6992AE51FFA001DE99C /* PixelKit */, 31A3A4E22B0C115F0021063C /* DataBrokerProtection */, 37269EFA2B332F9E005E8E46 /* Common */, 3722177F2B3337FE00B8E9C2 /* TestUtils */, - 373FB4B02B4D6C42004C88D6 /* PreferencesViews */, 7BA076BA2B65D61400D7FB72 /* NetworkProtectionProxy */, 85E2BBCD2B8F534000DBEC7A /* History */, 1EA7B8D22B7E078C000330A4 /* SubscriptionUI */, 1EA7B8D42B7E078C000330A4 /* Subscription */, F1D43AF22B98E47800BAB743 /* BareBonesBrowserKit */, 85D44B852BA08D29001B4AB5 /* Suggestions */, - 37CF91582BB416A500BADCAE /* Crashes */, 9FF521452BAA908500B9819B /* Lottie */, + 08D4923DC968236E22E373E2 /* Crashes */, + F1DF95E62BD188B60045E591 /* LoginItems */, + F198C7112BD18A28000BF24D /* PixelKit */, + F198C71D2BD18D88000BF24D /* SwiftLintTool */, ); productName = DuckDuckGo; productReference = AA585D7E248FD31100E9A3E2 /* DuckDuckGo.app */; @@ -8542,8 +8506,8 @@ packageProductDependencies = ( B6DA44162616C13800DD1EC2 /* OHHTTPStubs */, B6DA44182616C13800DD1EC2 /* OHHTTPStubsSwift */, - 4B81AD342B29512B00706C96 /* PixelKitTestingUtilities */, B65CD8CA2B316DF100A595BB /* SnapshotTesting */, + F116A7C22BD1924B00F3FCF7 /* PixelKitTestingUtilities */, ); productName = DuckDuckGoTests; productReference = AA585D90248FD31400E9A3E2 /* Unit Tests.xctest */; @@ -8986,6 +8950,25 @@ /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ + 28003FDBDB96625F1630CFF2 /* Run swiftlint */ = { + isa = PBXShellScriptBuildPhase; + alwaysOutOfDate = 1; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + ); + name = "Run swiftlint"; + outputFileListPaths = ( + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "if [ \"$CONFIGURATION\" != \"Debug\" ] || [ \"$ENABLE_PREVIEWS\" = \"YES\" ]; then exit 0; fi\n${BUILT_PRODUCTS_DIR}/SwiftLintTool\n"; + }; 3121F62B2B64266A002F706A /* Copy Swift Package resources */ = { isa = PBXShellScriptBuildPhase; alwaysOutOfDate = 1; @@ -9118,7 +9101,7 @@ shellPath = /bin/sh; shellScript = "# Embeds login items for the App Store build.\n\n# Skip login item embedding for release builds until they're ready to go live.\nif [ \"${CONFIGURATION}\" = \"Release\" ]; then\n VPN_AGENT_NAME=\"${AGENT_RELEASE_PRODUCT_NAME}\"\n PIR_AGENT_NAME=\"${DBP_BACKGROUND_AGENT_RELEASE_PRODUCT_NAME}\"\nelse\n VPN_AGENT_NAME=\"${AGENT_PRODUCT_NAME}\"\n PIR_AGENT_NAME=\"${DBP_BACKGROUND_AGENT_PRODUCT_NAME}\"\nfi\n\nVPN_AGENT_ORIGIN=$(readlink -f \"${CONFIGURATION_BUILD_DIR}/${VPN_AGENT_NAME}.app\")\nPIR_AGENT_ORIGIN=$(readlink -f \"${CONFIGURATION_BUILD_DIR}/${PIR_AGENT_NAME}.app\")\nAGENT_DESTINATION=\"${CONFIGURATION_BUILD_DIR}/${CONTENTS_FOLDER_PATH}/Library/LoginItems\"\n \n# Make sure that Library/LoginItems exists before copying\nmkdir -p \"$AGENT_DESTINATION\"\n \necho \"Copying VPN agent from $VPN_AGENT_ORIGIN to $AGENT_DESTINATION\"\nrsync -r --links \"$VPN_AGENT_ORIGIN\" \"$AGENT_DESTINATION\"\n \necho \"Copying Personal Information Removal agent from $PIR_AGENT_ORIGIN to $AGENT_DESTINATION\"\nrsync -r --links \"$PIR_AGENT_ORIGIN\" \"$AGENT_DESTINATION\"\n"; }; - 7B31FD922AD126C40086AA24 /* Embed System Network Extension */ = { + 6A8856B31B2BC5078B61ED81 /* Run swiftlint */ = { isa = PBXShellScriptBuildPhase; alwaysOutOfDate = 1; buildActionMask = 2147483647; @@ -9128,16 +9111,16 @@ ); inputPaths = ( ); - name = "Embed System Network Extension"; + name = "Run swiftlint"; outputFileListPaths = ( ); outputPaths = ( ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "if [[ -z \"${SYSEX_BUNDLE_ID}\" ]]; then\n echo \"Required build settings are not defined, please check xcconfig files\"\n exit 1\nfi\n\n\necho \"ditto ${BUILT_PRODUCTS_DIR}/${SYSEX_BUNDLE_ID}.systemextension $BUILT_PRODUCTS_DIR/${CONTENTS_FOLDER_PATH}/Library/SystemExtensions/${SYSEX_BUNDLE_ID}.systemextension\"\n\nditto \"${BUILT_PRODUCTS_DIR}/${SYSEX_BUNDLE_ID}.systemextension\" \"$BUILT_PRODUCTS_DIR/${CONTENTS_FOLDER_PATH}/Library/SystemExtensions/${SYSEX_BUNDLE_ID}.systemextension\" || exit 1\n"; + shellScript = "if [ \"$CONFIGURATION\" != \"Debug\" ] || [ \"$ENABLE_PREVIEWS\" = \"YES\" ]; then exit 0; fi\n${BUILT_PRODUCTS_DIR}/SwiftLintTool\n"; }; - 7B557F2A2B8CA2A400099746 /* Embed Debug-only Network Extensions */ = { + 7B31FD922AD126C40086AA24 /* Embed System Network Extension */ = { isa = PBXShellScriptBuildPhase; alwaysOutOfDate = 1; buildActionMask = 2147483647; @@ -9147,16 +9130,16 @@ ); inputPaths = ( ); - name = "Embed Debug-only Network Extensions"; + name = "Embed System Network Extension"; outputFileListPaths = ( ); outputPaths = ( ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "# Support for embedding debug-only extensions (https://stackoverflow.com/a/76948057/712306)\nfunction embedExtensions() {\n for extension in $1\n do\n rsync -r --copy-links \"${CONFIGURATION_BUILD_DIR}/${extension}.appex\" \"${CONFIGURATION_BUILD_DIR}/${PLUGINS_FOLDER_PATH}\"\n done\n}\n\ndebug_extensions=(\"VPNProxyExtension\")\n\nif [ \"${CONFIGURATION}\" != \"Release\" ]\nthen\n embedExtensions $debug_extensions\nfi\n"; + shellScript = "if [[ -z \"${SYSEX_BUNDLE_ID}\" ]]; then\n echo \"Required build settings are not defined, please check xcconfig files\"\n exit 1\nfi\n\n\necho \"ditto ${BUILT_PRODUCTS_DIR}/${SYSEX_BUNDLE_ID}.systemextension $BUILT_PRODUCTS_DIR/${CONTENTS_FOLDER_PATH}/Library/SystemExtensions/${SYSEX_BUNDLE_ID}.systemextension\"\n\nditto \"${BUILT_PRODUCTS_DIR}/${SYSEX_BUNDLE_ID}.systemextension\" \"$BUILT_PRODUCTS_DIR/${CONTENTS_FOLDER_PATH}/Library/SystemExtensions/${SYSEX_BUNDLE_ID}.systemextension\" || exit 1\n"; }; - 7BB34F502AD98394005691AE /* Copy Swift Package resources */ = { + 7B557F2A2B8CA2A400099746 /* Embed Debug-only Network Extensions */ = { isa = PBXShellScriptBuildPhase; alwaysOutOfDate = 1; buildActionMask = 2147483647; @@ -9166,16 +9149,16 @@ ); inputPaths = ( ); - name = "Copy Swift Package resources"; + name = "Embed Debug-only Network Extensions"; outputFileListPaths = ( ); outputPaths = ( ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "# We had issues where the Swift Package resources were not being added to the Agent Apps,\n# so we're manually coping them here.\n# It seems to be a known issue: https://forums.swift.org/t/swift-packages-resource-bundle-not-present-in-xcarchive-when-framework-using-said-package-is-archived/50084/2\ncp -RL \"${BUILT_PRODUCTS_DIR}\"/ContentScopeScripts_ContentScopeScripts.bundle \"${BUILT_PRODUCTS_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/\"\ncp -RL \"${BUILT_PRODUCTS_DIR}\"/DataBrokerProtection_DataBrokerProtection.bundle \"${BUILT_PRODUCTS_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/\"\n"; + shellScript = "# Support for embedding debug-only extensions (https://stackoverflow.com/a/76948057/712306)\nfunction embedExtensions() {\n for extension in $1\n do\n rsync -r --copy-links \"${CONFIGURATION_BUILD_DIR}/${extension}.appex\" \"${CONFIGURATION_BUILD_DIR}/${PLUGINS_FOLDER_PATH}\"\n done\n}\n\ndebug_extensions=(\"VPNProxyExtension\")\n\nif [ \"${CONFIGURATION}\" != \"Release\" ]\nthen\n embedExtensions $debug_extensions\nfi\n"; }; - B6409DC52BC7BD1F00D66F9E /* Run swiftlint */ = { + 7BB34F502AD98394005691AE /* Copy Swift Package resources */ = { isa = PBXShellScriptBuildPhase; alwaysOutOfDate = 1; buildActionMask = 2147483647; @@ -9185,14 +9168,14 @@ ); inputPaths = ( ); - name = "Run swiftlint"; + name = "Copy Swift Package resources"; outputFileListPaths = ( ); outputPaths = ( ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "if [ \"$CONFIGURATION\" != \"Debug\" ] || [ \"$ENABLE_PREVIEWS\" = \"YES\" ]; then exit 0; fi\n${BUILT_PRODUCTS_DIR}/SwiftLintTool\n"; + shellScript = "# We had issues where the Swift Package resources were not being added to the Agent Apps,\n# so we're manually coping them here.\n# It seems to be a known issue: https://forums.swift.org/t/swift-packages-resource-bundle-not-present-in-xcarchive-when-framework-using-said-package-is-archived/50084/2\ncp -RL \"${BUILT_PRODUCTS_DIR}\"/ContentScopeScripts_ContentScopeScripts.bundle \"${BUILT_PRODUCTS_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/\"\ncp -RL \"${BUILT_PRODUCTS_DIR}\"/DataBrokerProtection_DataBrokerProtection.bundle \"${BUILT_PRODUCTS_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/\"\n"; }; B6AEB5532BA3029B00781A09 /* Cleanup entitlements */ = { isa = PBXShellScriptBuildPhase; @@ -9232,25 +9215,6 @@ shellPath = /bin/sh; shellScript = "FRAMEWORKS_DIR=\"${BUILT_PRODUCTS_DIR}/${FRAMEWORKS_FOLDER_PATH}\"\nDYLIB_TARGET_PATH=\"${FRAMEWORKS_DIR}/libswift_Concurrency.dylib\"\n\nif [ ! -e \"${DYLIB_TARGET_PATH}\" ]; then\n\n DYLIB_PATH=$(find \"${TOOLCHAIN_DIR}/usr/lib\" -path \"*/${HOST_PLATFORM}/libswift_Concurrency.dylib\")\n echo \"copy ${DYLIB_PATH} to ${DYLIB_TARGET_PATH}\"\n\n mkdir -p \"${FRAMEWORKS_DIR}\"\n cp \"${DYLIB_PATH}\" \"${DYLIB_TARGET_PATH}\" || exit 1\n\nelse\n echo \"${DYLIB_TARGET_PATH} exists 👌\"\nfi\n"; }; - B6E6BA192BA2D8BE008AA7E1 /* Run swiftlint */ = { - isa = PBXShellScriptBuildPhase; - alwaysOutOfDate = 1; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - ); - inputPaths = ( - ); - name = "Run swiftlint"; - outputFileListPaths = ( - ); - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "if [ \"$CONFIGURATION\" != \"Debug\" ] || [ \"$ENABLE_PREVIEWS\" = \"YES\" ]; then exit 0; fi\n${BUILT_PRODUCTS_DIR}/SwiftLintTool\n"; - }; B6F2C8722A7A4C7D000498CF /* Make /Applications symlink, remove app on Clean build */ = { isa = PBXShellScriptBuildPhase; alwaysOutOfDate = 1; @@ -10210,10 +10174,8 @@ B630E80129C887ED00363609 /* NSErrorAdditionalInfo.swift in Sources */, 3706FE31293F661700E42796 /* TabCollectionViewModelDelegateMock.swift in Sources */, 3706FE32293F661700E42796 /* BookmarksHTMLReaderTests.swift in Sources */, - 7BBE650E2BC67BA0008F4EE9 /* NetworkProtectionIPCTunnelControllerTests.swift in Sources */, 3706FE33293F661700E42796 /* FireTests.swift in Sources */, B60C6F8229B1B4AD007BFAA8 /* TestRunHelper.swift in Sources */, - 7BBE65112BC67EED008F4EE9 /* NetworkProtectionTestingSupport.swift in Sources */, 567DA94029E8045D008AC5EE /* MockEmailStorage.swift in Sources */, 317295D32AF058D3002C3206 /* MockWaitlistTermsAndConditionsActionHandler.swift in Sources */, 3706FE34293F661700E42796 /* PermissionStoreTests.swift in Sources */, @@ -11578,7 +11540,6 @@ 1D3B1AC22936B816006F4388 /* BWMessageIdGeneratorTests.swift in Sources */, B6C2C9F62760B659005B7F0A /* TestDataModel.xcdatamodeld in Sources */, 1DA6D1022A1FFA3700540406 /* HTTPCookieTests.swift in Sources */, - 7BBE65102BC67EED008F4EE9 /* NetworkProtectionTestingSupport.swift in Sources */, 1D9FDEC02B9B5FEA0040B78C /* AccessibilityPreferencesTests.swift in Sources */, B68172AE269EB43F006D1092 /* GeolocationServiceTests.swift in Sources */, B6AE74342609AFCE005B9B1A /* ProgressEstimationTests.swift in Sources */, @@ -11658,7 +11619,6 @@ 37CD54B927F1F8AC00F1F7B9 /* AppearancePreferencesTests.swift in Sources */, EEF53E182950CED5002D78F4 /* JSAlertViewModelTests.swift in Sources */, 376C4DB928A1A48A00CC0F5B /* FirePopoverViewModelTests.swift in Sources */, - 7BBE650D2BC67BA0008F4EE9 /* NetworkProtectionIPCTunnelControllerTests.swift in Sources */, AAEC74B62642CC6A00C2EFBC /* HistoryStoringMock.swift in Sources */, AA652CB125DD825B009059CC /* LocalBookmarkStoreTests.swift in Sources */, B630794226731F5400DCEE41 /* WKDownloadMock.swift in Sources */, @@ -11774,14 +11734,6 @@ target = 4B2537592A11BE7300610219 /* NetworkProtectionSystemExtension */; targetProxy = 7BEC18302AD5DA3300D30536 /* PBXContainerItemProxy */; }; - B637D1BB2BC6AE5600C7DCA7 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - productRef = B637D1BA2BC6AE5600C7DCA7 /* SwiftLintTool */; - }; - B637D1BD2BC6AE6200C7DCA7 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - productRef = B637D1BC2BC6AE6200C7DCA7 /* SwiftLintTool */; - }; B6AEB5552BA3042300781A09 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = B6E6B9F22BA1FD90008AA7E1 /* sandbox-test-tool */; @@ -12641,7 +12593,7 @@ version = 3.1.4000; }; }; - 9807F643278CA16F00E1547B /* XCRemoteSwiftPackageReference "BrowserServicesKit" */ = { + 3FFD51CF7C19ACBDB9687474 /* XCRemoteSwiftPackageReference "BrowserServicesKit" */ = { isa = XCRemoteSwiftPackageReference; repositoryURL = "https://github.com/duckduckgo/BrowserServicesKit"; requirement = { @@ -12649,6 +12601,22 @@ version = 138.0.0; }; }; + 4311906792B7676CE9535D76 /* XCRemoteSwiftPackageReference "BrowserServicesKit" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/duckduckgo/BrowserServicesKit"; + requirement = { + kind = exactVersion; + version = 137.0.0; + }; + }; + 9807F643278CA16F00E1547B /* XCRemoteSwiftPackageReference "BrowserServicesKit" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/duckduckgo/BrowserServicesKit"; + requirement = { + kind = exactVersion; + version = 138.1.0; + }; + }; 9FF521422BAA8FF300B9819B /* XCRemoteSwiftPackageReference "lottie-spm" */ = { isa = XCRemoteSwiftPackageReference; repositoryURL = "https://github.com/airbnb/lottie-spm.git"; @@ -12705,13 +12673,21 @@ version = 0.1.0; }; }; + FAE06B199CA1F209B55B34E9 /* XCRemoteSwiftPackageReference "BrowserServicesKit" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/duckduckgo/BrowserServicesKit"; + requirement = { + kind = exactVersion; + version = 137.0.0; + }; + }; /* End XCRemoteSwiftPackageReference section */ /* Begin XCSwiftPackageProductDependency section */ - 1E46E19F2BD029BD0007273A /* Subscription */ = { + 08D4923DC968236E22E373E2 /* Crashes */ = { isa = XCSwiftPackageProductDependency; - package = 9807F643278CA16F00E1547B /* XCRemoteSwiftPackageReference "BrowserServicesKit" */; - productName = Subscription; + package = FAE06B199CA1F209B55B34E9 /* XCRemoteSwiftPackageReference "BrowserServicesKit" */; + productName = Crashes; }; 1E950E3E2912A10D0051A99B /* ContentBlocking */ = { isa = XCSwiftPackageProductDependency; @@ -12834,10 +12810,6 @@ package = 9807F643278CA16F00E1547B /* XCRemoteSwiftPackageReference "BrowserServicesKit" */; productName = DDGSync; }; - 373FB4B02B4D6C42004C88D6 /* PreferencesViews */ = { - isa = XCSwiftPackageProductDependency; - productName = PreferencesViews; - }; 373FB4B22B4D6C4B004C88D6 /* PreferencesViews */ = { isa = XCSwiftPackageProductDependency; productName = PreferencesViews; @@ -12863,16 +12835,6 @@ isa = XCSwiftPackageProductDependency; productName = SyncUI; }; - 37CF91582BB416A500BADCAE /* Crashes */ = { - isa = XCSwiftPackageProductDependency; - package = 9807F643278CA16F00E1547B /* XCRemoteSwiftPackageReference "BrowserServicesKit" */; - productName = Crashes; - }; - 37CF915A2BB416AC00BADCAE /* Crashes */ = { - isa = XCSwiftPackageProductDependency; - package = 9807F643278CA16F00E1547B /* XCRemoteSwiftPackageReference "BrowserServicesKit" */; - productName = Crashes; - }; 37DF000429F9C056002B7D3E /* SyncDataProviders */ = { isa = XCSwiftPackageProductDependency; package = 9807F643278CA16F00E1547B /* XCRemoteSwiftPackageReference "BrowserServicesKit" */; @@ -12888,10 +12850,6 @@ package = 9807F643278CA16F00E1547B /* XCRemoteSwiftPackageReference "BrowserServicesKit" */; productName = Navigation; }; - 4B2537762A11BFE100610219 /* PixelKit */ = { - isa = XCSwiftPackageProductDependency; - productName = PixelKit; - }; 4B2D062B2A11C0E100DE1F49 /* Networking */ = { isa = XCSwiftPackageProductDependency; package = 9807F643278CA16F00E1547B /* XCRemoteSwiftPackageReference "BrowserServicesKit" */; @@ -12913,10 +12871,6 @@ isa = XCSwiftPackageProductDependency; productName = NetworkProtection; }; - 4B4D60972A0B2A5C00BCD287 /* PixelKit */ = { - isa = XCSwiftPackageProductDependency; - productName = PixelKit; - }; 4B4D60AE2A0C837F00BCD287 /* Networking */ = { isa = XCSwiftPackageProductDependency; package = 9807F643278CA16F00E1547B /* XCRemoteSwiftPackageReference "BrowserServicesKit" */; @@ -12934,14 +12888,6 @@ isa = XCSwiftPackageProductDependency; productName = "plugin:InputFilesChecker"; }; - 4B81AD342B29512B00706C96 /* PixelKitTestingUtilities */ = { - isa = XCSwiftPackageProductDependency; - productName = PixelKitTestingUtilities; - }; - 4B81AD362B29513100706C96 /* PixelKitTestingUtilities */ = { - isa = XCSwiftPackageProductDependency; - productName = PixelKitTestingUtilities; - }; 4BA7C4DC2B3F64E500AFE511 /* LoginItems */ = { isa = XCSwiftPackageProductDependency; productName = LoginItems; @@ -12973,6 +12919,11 @@ package = 9807F643278CA16F00E1547B /* XCRemoteSwiftPackageReference "BrowserServicesKit" */; productName = NetworkProtection; }; + 537FC71EA5115A983FAF3170 /* Crashes */ = { + isa = XCSwiftPackageProductDependency; + package = 4311906792B7676CE9535D76 /* XCRemoteSwiftPackageReference "BrowserServicesKit" */; + productName = Crashes; + }; 7B00997C2B6508B700FE7C31 /* NetworkProtectionProxy */ = { isa = XCSwiftPackageProductDependency; productName = NetworkProtectionProxy; @@ -12998,14 +12949,6 @@ package = 9807F643278CA16F00E1547B /* XCRemoteSwiftPackageReference "BrowserServicesKit" */; productName = Subscription; }; - 7B5DD6992AE51FFA001DE99C /* PixelKit */ = { - isa = XCSwiftPackageProductDependency; - productName = PixelKit; - }; - 7B5F9A742AE2BE4E002AEBC0 /* PixelKit */ = { - isa = XCSwiftPackageProductDependency; - productName = PixelKit; - }; 7B624F162BA25C1F00A6C544 /* NetworkProtectionUI */ = { isa = XCSwiftPackageProductDependency; productName = NetworkProtectionUI; @@ -13024,10 +12967,6 @@ package = 9807F643278CA16F00E1547B /* XCRemoteSwiftPackageReference "BrowserServicesKit" */; productName = Common; }; - 7B97CD612B7E0C4B004FEF43 /* PixelKit */ = { - isa = XCSwiftPackageProductDependency; - productName = PixelKit; - }; 7BA076BA2B65D61400D7FB72 /* NetworkProtectionProxy */ = { isa = XCSwiftPackageProductDependency; productName = NetworkProtectionProxy; @@ -13066,14 +13005,6 @@ isa = XCSwiftPackageProductDependency; productName = NetworkProtectionUI; }; - 7BFCB74D2ADE7E1A00DA3EA7 /* PixelKit */ = { - isa = XCSwiftPackageProductDependency; - productName = PixelKit; - }; - 7BFCB74F2ADE7E2300DA3EA7 /* PixelKit */ = { - isa = XCSwiftPackageProductDependency; - productName = PixelKit; - }; 85D44B852BA08D29001B4AB5 /* Suggestions */ = { isa = XCSwiftPackageProductDependency; package = 9807F643278CA16F00E1547B /* XCRemoteSwiftPackageReference "BrowserServicesKit" */; @@ -13114,14 +13045,6 @@ package = 9807F643278CA16F00E1547B /* XCRemoteSwiftPackageReference "BrowserServicesKit" */; productName = Persistence; }; - 9D6983F82AC773C3002C02FC /* PixelKit */ = { - isa = XCSwiftPackageProductDependency; - productName = PixelKit; - }; - 9D6983FA2AC773C8002C02FC /* PixelKit */ = { - isa = XCSwiftPackageProductDependency; - productName = PixelKit; - }; 9D9AE8F82AAA3AD00026E7DC /* DataBrokerProtection */ = { isa = XCSwiftPackageProductDependency; productName = DataBrokerProtection; @@ -13130,10 +13053,6 @@ isa = XCSwiftPackageProductDependency; productName = DataBrokerProtection; }; - 9DB6E7232AA0DC5800A17F3C /* LoginItems */ = { - isa = XCSwiftPackageProductDependency; - productName = LoginItems; - }; 9DC70B192AA1FA5B005A844B /* LoginItems */ = { isa = XCSwiftPackageProductDependency; productName = LoginItems; @@ -13158,16 +13077,6 @@ package = AA06B6B52672AF8100F541C5 /* XCRemoteSwiftPackageReference "Sparkle" */; productName = Sparkle; }; - B637D1BA2BC6AE5600C7DCA7 /* SwiftLintTool */ = { - isa = XCSwiftPackageProductDependency; - package = B6F997B92B8F352500476735 /* XCRemoteSwiftPackageReference "apple-toolbox" */; - productName = SwiftLintTool; - }; - B637D1BC2BC6AE6200C7DCA7 /* SwiftLintTool */ = { - isa = XCSwiftPackageProductDependency; - package = B6F997B92B8F352500476735 /* XCRemoteSwiftPackageReference "apple-toolbox" */; - productName = SwiftLintTool; - }; B65CD8CA2B316DF100A595BB /* SnapshotTesting */ = { isa = XCSwiftPackageProductDependency; package = B65CD8C92B316DF100A595BB /* XCRemoteSwiftPackageReference "swift-snapshot-testing" */; @@ -13253,6 +13162,11 @@ package = 9807F643278CA16F00E1547B /* XCRemoteSwiftPackageReference "BrowserServicesKit" */; productName = Configuration; }; + DC3F73D49B2D44464AFEFCD8 /* Subscription */ = { + isa = XCSwiftPackageProductDependency; + package = 3FFD51CF7C19ACBDB9687474 /* XCRemoteSwiftPackageReference "BrowserServicesKit" */; + productName = Subscription; + }; EE02D41F2BB460C000DBE6B3 /* BrowserServicesKit */ = { isa = XCSwiftPackageProductDependency; package = 9807F643278CA16F00E1547B /* XCRemoteSwiftPackageReference "BrowserServicesKit" */; @@ -13288,6 +13202,61 @@ package = 9807F643278CA16F00E1547B /* XCRemoteSwiftPackageReference "BrowserServicesKit" */; productName = NetworkProtection; }; + F116A7C22BD1924B00F3FCF7 /* PixelKitTestingUtilities */ = { + isa = XCSwiftPackageProductDependency; + package = 9807F643278CA16F00E1547B /* XCRemoteSwiftPackageReference "BrowserServicesKit" */; + productName = PixelKitTestingUtilities; + }; + F116A7C62BD1925500F3FCF7 /* PixelKitTestingUtilities */ = { + isa = XCSwiftPackageProductDependency; + package = 9807F643278CA16F00E1547B /* XCRemoteSwiftPackageReference "BrowserServicesKit" */; + productName = PixelKitTestingUtilities; + }; + F116A7C82BD1929000F3FCF7 /* PixelKitTestingUtilities */ = { + isa = XCSwiftPackageProductDependency; + package = 9807F643278CA16F00E1547B /* XCRemoteSwiftPackageReference "BrowserServicesKit" */; + productName = PixelKitTestingUtilities; + }; + F198C7112BD18A28000BF24D /* PixelKit */ = { + isa = XCSwiftPackageProductDependency; + package = 9807F643278CA16F00E1547B /* XCRemoteSwiftPackageReference "BrowserServicesKit" */; + productName = PixelKit; + }; + F198C7132BD18A30000BF24D /* PixelKit */ = { + isa = XCSwiftPackageProductDependency; + package = 9807F643278CA16F00E1547B /* XCRemoteSwiftPackageReference "BrowserServicesKit" */; + productName = PixelKit; + }; + F198C7152BD18A44000BF24D /* PixelKit */ = { + isa = XCSwiftPackageProductDependency; + package = 9807F643278CA16F00E1547B /* XCRemoteSwiftPackageReference "BrowserServicesKit" */; + productName = PixelKit; + }; + F198C7172BD18A4C000BF24D /* PixelKit */ = { + isa = XCSwiftPackageProductDependency; + package = 9807F643278CA16F00E1547B /* XCRemoteSwiftPackageReference "BrowserServicesKit" */; + productName = PixelKit; + }; + F198C7192BD18A5B000BF24D /* PixelKit */ = { + isa = XCSwiftPackageProductDependency; + package = 9807F643278CA16F00E1547B /* XCRemoteSwiftPackageReference "BrowserServicesKit" */; + productName = PixelKit; + }; + F198C71B2BD18A61000BF24D /* PixelKit */ = { + isa = XCSwiftPackageProductDependency; + package = 9807F643278CA16F00E1547B /* XCRemoteSwiftPackageReference "BrowserServicesKit" */; + productName = PixelKit; + }; + F198C71D2BD18D88000BF24D /* SwiftLintTool */ = { + isa = XCSwiftPackageProductDependency; + package = B6F997B92B8F352500476735 /* XCRemoteSwiftPackageReference "apple-toolbox" */; + productName = SwiftLintTool; + }; + F198C71F2BD18D92000BF24D /* SwiftLintTool */ = { + isa = XCSwiftPackageProductDependency; + package = B6F997B92B8F352500476735 /* XCRemoteSwiftPackageReference "apple-toolbox" */; + productName = SwiftLintTool; + }; F1D43AF22B98E47800BAB743 /* BareBonesBrowserKit */ = { isa = XCSwiftPackageProductDependency; package = F1D43AF12B98E47800BAB743 /* XCRemoteSwiftPackageReference "BareBonesBrowser" */; @@ -13298,6 +13267,10 @@ package = F1D43AF12B98E47800BAB743 /* XCRemoteSwiftPackageReference "BareBonesBrowser" */; productName = BareBonesBrowserKit; }; + F1DF95E62BD188B60045E591 /* LoginItems */ = { + isa = XCSwiftPackageProductDependency; + productName = LoginItems; + }; /* End XCSwiftPackageProductDependency section */ /* Begin XCVersionGroup section */ diff --git a/DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index 462a0cc553..9799888051 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" : "b8f0e5db431c63943b509d522c157f870ef03ae0", - "version" : "138.0.0" + "revision" : "4ec92e6b94076c53b9b2d34fdcbc2b52cecf9c8e", + "version" : "138.1.0" } }, { @@ -120,7 +120,7 @@ { "identity" : "swift-argument-parser", "kind" : "remoteSourceControl", - "location" : "https://github.com/apple/swift-argument-parser", + "location" : "https://github.com/apple/swift-argument-parser.git", "state" : { "revision" : "46989693916f56d1186bd59ac15124caef896560", "version" : "1.3.1" diff --git a/DuckDuckGo.xcodeproj/xcshareddata/xcschemes/DuckDuckGo Privacy Browser App Store.xcscheme b/DuckDuckGo.xcodeproj/xcshareddata/xcschemes/DuckDuckGo Privacy Browser App Store.xcscheme index 86fd422c11..e343e06df9 100644 --- a/DuckDuckGo.xcodeproj/xcshareddata/xcschemes/DuckDuckGo Privacy Browser App Store.xcscheme +++ b/DuckDuckGo.xcodeproj/xcshareddata/xcschemes/DuckDuckGo Privacy Browser App Store.xcscheme @@ -157,16 +157,6 @@ ReferencedContainer = "container:LocalPackages/SyncUI"> - - - - - - - - - - - - - - - - - - - - IDEDidComputeMac32BitWarning - - - diff --git a/LocalPackages/PixelKit/Package.swift b/LocalPackages/PixelKit/Package.swift deleted file mode 100644 index f6ca4e0701..0000000000 --- a/LocalPackages/PixelKit/Package.swift +++ /dev/null @@ -1,50 +0,0 @@ -// swift-tools-version: 5.7 -// The swift-tools-version declares the minimum version of Swift required to build this package. - -import PackageDescription - -let package = Package( - name: "PixelKit", - platforms: [ - .macOS("11.4") - ], - products: [ - // Products define the executables and libraries a package produces, and make them visible to other packages. - .library( - name: "PixelKit", - targets: ["PixelKit"] - ), - .library( - name: "PixelKitTestingUtilities", - targets: ["PixelKitTestingUtilities"] - ) - ], - dependencies: [ - ], - targets: [ - .target( - name: "PixelKit", - dependencies: [ - ], - swiftSettings: [ - .define("DEBUG", .when(configuration: .debug)), - ] - ), - .testTarget( - name: "PixelKitTests", - dependencies: [ - "PixelKit", - "PixelKitTestingUtilities", - ], - swiftSettings: [ - .define("DEBUG", .when(configuration: .debug)) - ] - ), - .target( - name: "PixelKitTestingUtilities", - dependencies: [ - "PixelKit", - ] - ) - ] -) diff --git a/LocalPackages/PixelKit/README.md b/LocalPackages/PixelKit/README.md deleted file mode 100644 index 9d5094a7d8..0000000000 --- a/LocalPackages/PixelKit/README.md +++ /dev/null @@ -1,11 +0,0 @@ -# PixelKit - -This package is meant to provide basic support for firing pixel across different targets. - -This package was designed to not really know specific pixels. Those can be defined -individually by each target importing this package, or through more specialized -shared packages. - -This design decision is meant to make PixelKit lean and to make it possible to use it -for future apps we may decide to make, without it having to carry over all of the business -domain logic for any single app. diff --git a/LocalPackages/PixelKit/Sources/PixelKit/Extensions/String+StaticString.swift b/LocalPackages/PixelKit/Sources/PixelKit/Extensions/String+StaticString.swift deleted file mode 100644 index 19f9b8b692..0000000000 --- a/LocalPackages/PixelKit/Sources/PixelKit/Extensions/String+StaticString.swift +++ /dev/null @@ -1,27 +0,0 @@ -// -// String+StaticString.swift -// -// Copyright © 2023 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 String { - init(_ staticString: StaticString) { - self = staticString.withUTF8Buffer { - String(decoding: $0, as: UTF8.self) - } - } -} diff --git a/LocalPackages/PixelKit/Sources/PixelKit/Extensions/URL+PixelKit.swift b/LocalPackages/PixelKit/Sources/PixelKit/Extensions/URL+PixelKit.swift deleted file mode 100644 index 98bb77c2c4..0000000000 --- a/LocalPackages/PixelKit/Sources/PixelKit/Extensions/URL+PixelKit.swift +++ /dev/null @@ -1,30 +0,0 @@ -// -// URL+PixelKit.swift -// -// Copyright © 2023 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 URL { - - static let pixelBase = ProcessInfo.processInfo.environment["PIXEL_BASE_URL", default: "https://improving.duckduckgo.com"] - - public static func pixelUrl(forPixelNamed pixelName: String) -> URL { - let urlString = "\(Self.pixelBase)/t/\(pixelName)" - return URL(string: urlString)! - } - -} diff --git a/LocalPackages/PixelKit/Sources/PixelKit/PixelKit+Parameters.swift b/LocalPackages/PixelKit/Sources/PixelKit/PixelKit+Parameters.swift deleted file mode 100644 index b692271709..0000000000 --- a/LocalPackages/PixelKit/Sources/PixelKit/PixelKit+Parameters.swift +++ /dev/null @@ -1,137 +0,0 @@ -// -// PixelKit+Parameters.swift -// -// Copyright © 2023 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 - -public extension PixelKit { - - enum Parameters: Hashable { - public static let duration = "duration" - public static let test = "test" - public static let appVersion = "appVersion" - public static let pixelSource = "pixelSource" - public static let osMajorVersion = "osMajorVersion" - - public static let errorCode = "e" - public static let errorDomain = "d" - public static let errorCount = "c" - public static let errorSource = "error_source" - public static let sourceBrowserVersion = "source_browser_version" - public static let underlyingErrorCode = "ue" - public static let underlyingErrorDomain = "ud" - public static let underlyingErrorSQLiteCode = "sqlrc" - public static let underlyingErrorSQLiteExtendedCode = "sqlerc" - - public static let keychainFieldName = "fieldName" - public static let keychainErrorCode = "keychain_error_code" - - public static let emailCohort = "cohort" - public static let emailLastUsed = "duck_address_last_used" - - public static let assertionMessage = "message" - public static let assertionFile = "file" - public static let assertionLine = "line" - - public static let function = "function" - public static let line = "line" - - public static let latency = "latency" - public static let server = "server" - public static let networkType = "net_type" - - // Pixel experiments - public static let experimentCohort = "cohort" - - // Dashboard - public static let dashboardTriggerOrigin = "trigger_origin" - - // VPN - public static let vpnBreakageCategory = "breakageCategory" - public static let vpnBreakageDescription = "breakageDescription" - public static let vpnBreakageMetadata = "breakageMetadata" - - public static let reason = "reason" - - public static let vpnCohort = "cohort" - } - - enum Values { - public static let test = "1" - } - -} - -public protocol ErrorWithPixelParameters { - - var errorParameters: [String: String] { get } - -} - -public extension Error { - - var pixelParameters: [String: String] { - var params = [String: String]() - - if let errorWithUserInfo = self as? ErrorWithPixelParameters { - params = errorWithUserInfo.errorParameters - } - - let nsError = self as NSError - - params[PixelKit.Parameters.errorCode] = "\(nsError.code)" - params[PixelKit.Parameters.errorDomain] = nsError.domain - - let underlyingErrorParameters = self.underlyingErrorParameters(for: nsError) - params.merge(underlyingErrorParameters) { first, _ in - return first - } - - if let sqlErrorCode = nsError.userInfo["SQLiteResultCode"] as? NSNumber { - params[PixelKit.Parameters.underlyingErrorSQLiteCode] = "\(sqlErrorCode.intValue)" - } - - if let sqlExtendedErrorCode = nsError.userInfo["SQLiteExtendedResultCode"] as? NSNumber { - params[PixelKit.Parameters.underlyingErrorSQLiteExtendedCode] = "\(sqlExtendedErrorCode.intValue)" - } - - return params - } - - /// Recursive call to add underlying error information - /// - func underlyingErrorParameters(for nsError: NSError, level: Int = 0) -> [String: String] { - if let underlyingError = nsError.userInfo[NSUnderlyingErrorKey] as? NSError { - let errorCodeParameterName = PixelKit.Parameters.underlyingErrorCode + (level == 0 ? "" : String(level + 1)) - let errorDomainParameterName = PixelKit.Parameters.underlyingErrorDomain + (level == 0 ? "" : String(level + 1)) - - let currentUnderlyingErrorParameters = [ - errorCodeParameterName: "\(underlyingError.code)", - errorDomainParameterName: underlyingError.domain - ] - - // Check if the underlying error has an underlying error of its own - let additionalParameters = underlyingErrorParameters(for: underlyingError, level: level + 1) - - return currentUnderlyingErrorParameters.merging(additionalParameters) { first, _ in - return first // Doesn't really matter as there should be no conflict of parameters - } - } - - return [:] - } -} diff --git a/LocalPackages/PixelKit/Sources/PixelKit/PixelKit.swift b/LocalPackages/PixelKit/Sources/PixelKit/PixelKit.swift deleted file mode 100644 index d647b28835..0000000000 --- a/LocalPackages/PixelKit/Sources/PixelKit/PixelKit.swift +++ /dev/null @@ -1,476 +0,0 @@ -// -// PixelKit.swift -// -// Copyright © 2023 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 os.log // swiftlint:disable:this enforce_os_log_wrapper - -public final class PixelKit { - /// `true` if a request is fired, `false` otherwise - public typealias CompletionBlock = (Bool, Error?) -> Void - - /// The frequency with which a pixel is sent to our endpoint. - public enum Frequency { - /// The default frequency for pixels. This fires pixels with the event names as-is. - case standard - - /// [Legacy] Used in Pixel.fire(...) as .unique but without the `_u` requirement in the name - case legacyInitial - - /// Sent only once ever. The timestamp for this pixel is stored. - /// Note: This is the only pixel that MUST end with `_u`, Name for pixels of this type must end with if it doesn't an assertion is fired. - case unique - - /// [Legacy] Used in Pixel.fire(...) as .daily but without the `_d` automatically added to the name - case legacyDaily - - /// Sent once per day. The last timestamp for this pixel is stored and compared to the current date. Pixels of this type will have `_d` appended to their name. - case daily - - /// Sent once per day with a `_d` suffix, in addition to every time it is called with a `_c` suffix. - /// This means a pixel will get sent twice the first time it is called per-day, and subsequent calls that day will only send the `_c` variant. - /// This is useful in situations where pixels receive spikes in volume, as the daily pixel can be used to determine how many users are actually affected. - case dailyAndCount - - fileprivate var description: String { - switch self { - case .standard: - "Standard" - case .legacyInitial: - "Legacy Initial" - case .unique: - "Unique" - case .legacyDaily: - "Legacy Daily" - case .daily: - "Daily" - case .dailyAndCount: - "Daily and Count" - } - } - } - - public enum Header { - public static let acceptEncoding = "Accept-Encoding" - public static let acceptLanguage = "Accept-Language" - public static let userAgent = "User-Agent" - public static let ifNoneMatch = "If-None-Match" - public static let moreInfo = "X-DuckDuckGo-MoreInfo" - public static let client = "X-DuckDuckGo-Client" - } - - public enum Source: String { - case macStore = "browser-appstore" - case macDMG = "browser-dmg" - case iOS = "phone" - case iPadOS = "tablet" - } - - /// A closure typealias to request sending pixels through the network. - public typealias FireRequest = ( - _ pixelName: String, - _ headers: [String: String], - _ parameters: [String: String], - _ allowedQueryReservedCharacters: CharacterSet?, - _ callBackOnMainThread: Bool, - _ onComplete: @escaping CompletionBlock) -> Void - - public typealias Event = PixelKitEvent - public static let duckDuckGoMorePrivacyInfo = URL(string: "https://help.duckduckgo.com/duckduckgo-help-pages/privacy/atb/")! - private let defaults: UserDefaults - - private let logger = Logger(subsystem: "com.duckduckgo.PixelKit", category: "PixelKit") - - private static let defaultDailyPixelCalendar: Calendar = { - var calendar = Calendar.current - calendar.timeZone = TimeZone(secondsFromGMT: 0)! - return calendar - }() - - private static let weeksToCoalesceCohort = 6 - - private let dateGenerator: () -> Date - - public private(set) static var shared: PixelKit? - - private let appVersion: String - private let defaultHeaders: [String: String] - private let fireRequest: FireRequest - - /// Sets up PixelKit for the entire app. - /// - /// - Parameters: - /// - `dryRun`: if `true`, simulate requests and "send" them at an accelerated rate (once every 2 minutes instead of once a day) - /// - `source`: if set, adds a `pixelSource` parameter to the pixel call; this can be used to specify which target is sending the pixel - /// - `fireRequest`: this is not triggered when `dryRun` is `true` - public static func setUp(dryRun: Bool = false, - appVersion: String, - source: String? = nil, - defaultHeaders: [String: String], - dailyPixelCalendar: Calendar? = nil, - dateGenerator: @escaping () -> Date = Date.init, - defaults: UserDefaults, - fireRequest: @escaping FireRequest) { - shared = PixelKit(dryRun: dryRun, - appVersion: appVersion, - source: source, - defaultHeaders: defaultHeaders, - dailyPixelCalendar: dailyPixelCalendar, - dateGenerator: dateGenerator, - defaults: defaults, - fireRequest: fireRequest) - } - - public static func tearDown() { - shared = nil - } - - private var dryRun: Bool - private let source: String? - private let pixelCalendar: Calendar - - public init(dryRun: Bool, - appVersion: String, - source: String? = nil, - defaultHeaders: [String: String], - dailyPixelCalendar: Calendar? = nil, - dateGenerator: @escaping () -> Date = Date.init, - defaults: UserDefaults, - fireRequest: @escaping FireRequest) { - - self.dryRun = dryRun - self.appVersion = appVersion - self.source = source - self.defaultHeaders = defaultHeaders - self.pixelCalendar = dailyPixelCalendar ?? Self.defaultDailyPixelCalendar - self.dateGenerator = dateGenerator - self.defaults = defaults - self.fireRequest = fireRequest - logger.debug("👾 PixelKit initialised: dryRun: \(self.dryRun, privacy: .public) appVersion: \(self.appVersion, privacy: .public) source: \(self.source ?? "-", privacy: .public) defaultHeaders: \(self.defaultHeaders, privacy: .public) pixelCalendar: \(self.pixelCalendar, privacy: .public)") - } - - // swiftlint:disable:next function_body_length cyclomatic_complexity - private func fire(pixelNamed pixelName: String, - frequency: Frequency, - withHeaders headers: [String: String]?, - withAdditionalParameters params: [String: String]?, - withError error: Error?, - allowedQueryReservedCharacters: CharacterSet?, - includeAppVersionParameter: Bool, - onComplete: @escaping CompletionBlock) { - - var newParams = params ?? [:] - if includeAppVersionParameter { newParams[Parameters.appVersion] = appVersion } - if let source { newParams[Parameters.pixelSource] = source } - if let error { newParams.appendErrorPixelParams(error: error) } - - #if DEBUG - newParams[Parameters.test] = Values.test - #endif - - var headers = headers ?? defaultHeaders - headers[Header.moreInfo] = "See " + Self.duckDuckGoMorePrivacyInfo.absoluteString - headers[Header.client] = "macOS" - - switch frequency { - case .standard: - reportErrorIf(pixel: pixelName, endsWith: "_u") - reportErrorIf(pixel: pixelName, endsWith: "_d") - fireRequestWrapper(pixelName, headers, newParams, allowedQueryReservedCharacters, true, frequency, onComplete) - case .legacyInitial: - reportErrorIf(pixel: pixelName, endsWith: "_u") - reportErrorIf(pixel: pixelName, endsWith: "_d") - if !pixelHasBeenFiredEver(pixelName) { - fireRequestWrapper(pixelName, headers, newParams, allowedQueryReservedCharacters, true, frequency, onComplete) - updatePixelLastFireDate(pixelName: pixelName) - } else { - printDebugInfo(pixelName: pixelName, frequency: frequency, parameters: newParams, skipped: true) - } - case .unique: - reportErrorIf(pixel: pixelName, endsWith: "_d") - guard pixelName.hasSuffix("_u") else { - assertionFailure("Unique pixel: must end with _u") - return - } - if !pixelHasBeenFiredEver(pixelName) { - fireRequestWrapper(pixelName, headers, newParams, allowedQueryReservedCharacters, true, frequency, onComplete) - updatePixelLastFireDate(pixelName: pixelName) - } else { - printDebugInfo(pixelName: pixelName, frequency: frequency, parameters: newParams, skipped: true) - } - case .legacyDaily: - reportErrorIf(pixel: pixelName, endsWith: "_u") - reportErrorIf(pixel: pixelName, endsWith: "_d") - if !pixelHasBeenFiredToday(pixelName) { - fireRequestWrapper(pixelName, headers, newParams, allowedQueryReservedCharacters, true, frequency, onComplete) - updatePixelLastFireDate(pixelName: pixelName) - } else { - printDebugInfo(pixelName: pixelName, frequency: frequency, parameters: newParams, skipped: true) - } - case .daily: - reportErrorIf(pixel: pixelName, endsWith: "_u") - reportErrorIf(pixel: pixelName, endsWith: "_d") // Because is added automatically - if !pixelHasBeenFiredToday(pixelName) { - fireRequestWrapper(pixelName + "_d", headers, newParams, allowedQueryReservedCharacters, true, frequency, onComplete) - updatePixelLastFireDate(pixelName: pixelName) - } else { - printDebugInfo(pixelName: pixelName + "_d", frequency: frequency, parameters: newParams, skipped: true) - } - case .dailyAndCount: - reportErrorIf(pixel: pixelName, endsWith: "_u") - reportErrorIf(pixel: pixelName, endsWith: "_d") // Because is added automatically - reportErrorIf(pixel: pixelName, endsWith: "_c") // Because is added automatically - if !pixelHasBeenFiredToday(pixelName) { - fireRequestWrapper(pixelName + "_d", headers, newParams, allowedQueryReservedCharacters, true, frequency, onComplete) - updatePixelLastFireDate(pixelName: pixelName) - } else { - printDebugInfo(pixelName: pixelName + "_d", frequency: frequency, parameters: newParams, skipped: true) - } - - fireRequestWrapper(pixelName + "_c", headers, newParams, allowedQueryReservedCharacters, true, frequency, onComplete) - } - } - - /// If the pixel name ends with the forbiddenString then an error is logged or an assertion failure is fired in debug - func reportErrorIf(pixel: String, endsWith forbiddenString: String) { - if pixel.hasSuffix(forbiddenString) { - logger.error("Pixel \(pixel, privacy: .public) must not end with \(forbiddenString, privacy: .public)") - assertionFailure("Pixel \(pixel) must not end with \(forbiddenString)") - } - } - - private func printDebugInfo(pixelName: String, frequency: Frequency, parameters: [String: String], skipped: Bool = false) { - let params = parameters.filter { key, _ in !["test"].contains(key) } - logger.debug("👾[\(frequency.description, privacy: .public)-\(skipped ? "Skipped" : "Fired", privacy: .public)] \(pixelName, privacy: .public) \(params, privacy: .public)") - } - - private func fireRequestWrapper( - _ pixelName: String, - _ headers: [String: String], - _ parameters: [String: String], - _ allowedQueryReservedCharacters: CharacterSet?, - _ callBackOnMainThread: Bool, - _ frequency: Frequency, - _ onComplete: @escaping CompletionBlock) { - printDebugInfo(pixelName: pixelName, frequency: frequency, parameters: parameters, skipped: false) - guard !dryRun else { - // simulate server response time for Dry Run mode - DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) { - onComplete(true, nil) - } - return - } - fireRequest(pixelName, headers, parameters, allowedQueryReservedCharacters, callBackOnMainThread, onComplete) - } - - private func prefixedName(for event: Event) -> String { - if event.name.hasPrefix("m_mac_") { - return event.name - } - - if let debugEvent = event as? DebugEvent { - return "m_mac_debug_\(debugEvent.name)" - } else { - return "m_mac_\(event.name)" - } - } - - public func fire(_ event: Event, - frequency: Frequency = .standard, - withHeaders headers: [String: String]? = nil, - withAdditionalParameters params: [String: String]? = nil, - withError error: Error? = nil, - allowedQueryReservedCharacters: CharacterSet? = nil, - includeAppVersionParameter: Bool = true, - onComplete: @escaping CompletionBlock = { _, _ in }) { - - let pixelName = prefixedName(for: event) - - if !dryRun { - if frequency == .daily, pixelHasBeenFiredToday(pixelName) { - onComplete(false, nil) - return - } else if frequency == .unique, pixelHasBeenFiredEver(pixelName) { - onComplete(false, nil) - return - } - } - - let newParams: [String: String]? - switch (event.parameters, params) { - case (.some(let parameters), .none): - newParams = parameters - case (.none, .some(let parameters)): - newParams = parameters - case (.some(let params1), .some(let params2)): - newParams = params1.merging(params2) { $1 } - case (.none, .none): - newParams = nil - } - - let newError: Error? - - if let event = event as? PixelKitEventV2, - let error = event.error { - - // For v2 events we only consider the error specified in the event - // and purposedly ignore the parameter in this call. - // This is to encourage moving the error over to the protocol error - // instead of still relying on the parameter of this call. - newError = error - } else { - newError = error - } - - fire(pixelNamed: pixelName, - frequency: frequency, - withHeaders: headers, - withAdditionalParameters: newParams, - withError: newError, - allowedQueryReservedCharacters: allowedQueryReservedCharacters, - includeAppVersionParameter: includeAppVersionParameter, - onComplete: onComplete) - } - - public static func fire(_ event: Event, - frequency: Frequency = .standard, - withHeaders headers: [String: String] = [:], - withAdditionalParameters parameters: [String: String]? = nil, - withError error: Error? = nil, - allowedQueryReservedCharacters: CharacterSet? = nil, - includeAppVersionParameter: Bool = true, - onComplete: @escaping CompletionBlock = { _, _ in }) { - - Self.shared?.fire(event, - frequency: frequency, - withHeaders: headers, - withAdditionalParameters: parameters, - withError: error, - allowedQueryReservedCharacters: allowedQueryReservedCharacters, - includeAppVersionParameter: includeAppVersionParameter, - onComplete: onComplete) - } - - private func cohort(from cohortLocalDate: Date?, dateGenerator: () -> Date = Date.init) -> String? { - guard let cohortLocalDate, - let baseDate = pixelCalendar.date(from: .init(year: 2023, month: 1, day: 1)), - let weeksSinceCohortAssigned = pixelCalendar.dateComponents([.weekOfYear], from: cohortLocalDate, to: dateGenerator()).weekOfYear, - let assignedCohort = pixelCalendar.dateComponents([.weekOfYear], from: baseDate, to: cohortLocalDate).weekOfYear else { - return nil - } - - if weeksSinceCohortAssigned > Self.weeksToCoalesceCohort { - return "" - } else { - return "week-" + String(assignedCohort + 1) - } - } - - public static func cohort(from cohortLocalDate: Date?, dateGenerator: () -> Date = Date.init) -> String { - Self.shared?.cohort(from: cohortLocalDate, dateGenerator: dateGenerator) ?? "" - } - - public static func pixelLastFireDate(event: Event) -> Date? { - Self.shared?.pixelLastFireDate(event: event) - } - - public func pixelLastFireDate(pixelName: String) -> Date? { - var date = defaults.object(forKey: userDefaultsKeyName(forPixelName: pixelName)) as? Date - if date == nil { - date = defaults.object(forKey: legacyUserDefaultsKeyName(forPixelName: pixelName)) as? Date - } - return date - } - - public func pixelLastFireDate(event: Event) -> Date? { - pixelLastFireDate(pixelName: prefixedName(for: event)) - } - - private func updatePixelLastFireDate(pixelName: String) { - defaults.set(dateGenerator(), forKey: userDefaultsKeyName(forPixelName: pixelName)) - } - - private func pixelHasBeenFiredToday(_ name: String) -> Bool { - guard !dryRun else { - if let lastFireDate = pixelLastFireDate(pixelName: name), - let twoMinsAgo = pixelCalendar.date(byAdding: .minute, value: -2, to: dateGenerator()) { - return lastFireDate >= twoMinsAgo - } - - return false - } - - if let lastFireDate = pixelLastFireDate(pixelName: name) { - return pixelCalendar.isDate(dateGenerator(), inSameDayAs: lastFireDate) - } - - return false - } - - private func pixelHasBeenFiredEver(_ name: String) -> Bool { - pixelLastFireDate(pixelName: name) != nil - } - - public func clearFrequencyHistoryFor(pixel: PixelKitEventV2) { - guard let name = Self.shared?.userDefaultsKeyName(forPixelName: pixel.name) else { - return - } - self.defaults.removeObject(forKey: name) - } - - public func clearFrequencyHistoryForAllPixels() { - for (key, _) in self.defaults.dictionaryRepresentation() { - if key.hasPrefix(Self.storageKeyPrefixLegacy) || key.hasPrefix(Self.storageKeyPrefix) { - self.defaults.removeObject(forKey: key) - self.logger.debug("🚮 Removing from storage \(key, privacy: .public)") - } - } - } - - static let storageKeyPrefixLegacy = "com.duckduckgo.network-protection.pixel." - static let storageKeyPrefix = "com.duckduckgo.network-protection.pixel." - - /// Initially PixelKit was configured only for serving netP so these very specific keys were used, now PixelKit serves the entire app so we need to move away from them. - /// NOTE: I would remove this 6 months after release - private func legacyUserDefaultsKeyName(forPixelName pixelName: String) -> String { - dryRun - ? "\(Self.storageKeyPrefixLegacy)\(pixelName).dry-run" - : "\(Self.storageKeyPrefixLegacy)\(pixelName)" - } - - private func userDefaultsKeyName(forPixelName pixelName: String) -> String { - return "\(Self.storageKeyPrefix)\(pixelName)\( dryRun ? ".dry-run" : "" )" - } -} - -extension Dictionary where Key == String, Value == String { - - mutating func appendErrorPixelParams(error: Error) { - self.merge(error.pixelParameters) { _, second in - return second - } - } -} - -internal extension PixelKit { - - /// [USE ONLY FOR TESTS] Sets the shared PixelKit.shared singleton - /// - Parameter pixelkit: A custom instance of PixelKit - static func setSharedForTesting(pixelKit: PixelKit) { - Self.shared = pixelKit - } -} diff --git a/LocalPackages/PixelKit/Sources/PixelKit/PixelKitEvent.swift b/LocalPackages/PixelKit/Sources/PixelKit/PixelKitEvent.swift deleted file mode 100644 index ca352f3347..0000000000 --- a/LocalPackages/PixelKit/Sources/PixelKit/PixelKitEvent.swift +++ /dev/null @@ -1,100 +0,0 @@ -// -// PixelKitEvent.swift -// -// Copyright © 2023 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 - -/// An event that can be fired using PixelKit. -/// -public protocol PixelKitEvent { - var name: String { get } - var parameters: [String: String]? { get } -} - -/// Implementation of ``PixelKitEvent`` with specific logic for debug events. -/// -public final class DebugEvent: PixelKitEvent { - public enum EventType { - case assertionFailure(message: String, file: StaticString, line: UInt) - case custom(_ event: PixelKitEvent) - } - - public let eventType: EventType - public let error: Error? - - public init(eventType: EventType, error: Error? = nil) { - self.eventType = eventType - self.error = error - } - - public init(_ event: PixelKitEvent, error: Error? = nil) { - self.eventType = .custom(event) - self.error = error - } - - public var name: String { - switch eventType { - case .assertionFailure: - return "assertion_failure" - case .custom(let event): - return event.name - } - } - - public var parameters: [String: String]? { - var params: [String: String] - - if case let .custom(event) = eventType, - let eventParams = event.parameters { - params = eventParams - } else { - params = [String: String]() - } - - if let errorWithUserInfo = error as? ErrorWithPixelParameters { - params = errorWithUserInfo.errorParameters - } - - if case let .assertionFailure(message, file, line) = eventType { - params[PixelKit.Parameters.assertionMessage] = message - params[PixelKit.Parameters.assertionFile] = String(file) - params[PixelKit.Parameters.assertionLine] = String(line) - } - - if let error = error { - let nsError = error as NSError - - params[PixelKit.Parameters.errorCode] = "\(nsError.code)" - params[PixelKit.Parameters.errorDomain] = nsError.domain - - if let underlyingError = nsError.userInfo["NSUnderlyingError"] as? NSError { - params[PixelKit.Parameters.underlyingErrorCode] = "\(underlyingError.code)" - params[PixelKit.Parameters.underlyingErrorDomain] = underlyingError.domain - } - - if let sqlErrorCode = nsError.userInfo["SQLiteResultCode"] as? NSNumber { - params[PixelKit.Parameters.underlyingErrorSQLiteCode] = "\(sqlErrorCode.intValue)" - } - - if let sqlExtendedErrorCode = nsError.userInfo["SQLiteExtendedResultCode"] as? NSNumber { - params[PixelKit.Parameters.underlyingErrorSQLiteExtendedCode] = "\(sqlExtendedErrorCode.intValue)" - } - } - - return params - } -} diff --git a/LocalPackages/PixelKit/Sources/PixelKit/PixelKitEventV2.swift b/LocalPackages/PixelKit/Sources/PixelKit/PixelKitEventV2.swift deleted file mode 100644 index dc641454c9..0000000000 --- a/LocalPackages/PixelKit/Sources/PixelKit/PixelKitEventV2.swift +++ /dev/null @@ -1,58 +0,0 @@ -// -// PixelKitEventV2.swift -// -// Copyright © 2023 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 - -/// New version of this protocol that allows us to maintain backwards-compatibility with PixelKitEvent -/// -/// This new implementation seeks to unify the handling of standard pixel parameters inside PixelKit. -/// The starting example of how this can be useful is error parameter handling - this protocol allows -/// the implementer to specify an error without having to know about its parameterisation. -/// -/// The reason this wasn't done directly in `PixelKitEvent` is to reduce the risk of breaking existing -/// pixels, and to allow us to migrate towards this incrementally. -/// -public protocol PixelKitEventV2: PixelKitEvent { - var error: Error? { get } -} - -/// Protocol to support mocking pixel firing. -/// -/// We're adding support for `PixelKitEventV2` events strategically because adding support for earlier pixels -/// would be more complicated and time consuming. The idea of V2 events is that fire calls should not include a lot -/// of parameters. Parameters should be provided by the `PixelKitEventV2` protocol (extending it if necessary) -/// and the call to `fire` should process those properties to serialize in the requests. -/// -public protocol PixelFiring { - func fire(_ event: PixelKitEventV2) - - func fire(_ event: PixelKitEventV2, - frequency: PixelKit.Frequency) -} - -extension PixelKit: PixelFiring { - public func fire(_ event: PixelKitEventV2) { - fire(event, frequency: .standard) - } - - public func fire(_ event: PixelKitEventV2, - frequency: PixelKit.Frequency) { - - fire(event, frequency: frequency, onComplete: { _, _ in }) - } -} diff --git a/LocalPackages/PixelKit/Sources/PixelKitTestingUtilities/PixelFireExpectations.swift b/LocalPackages/PixelKit/Sources/PixelKitTestingUtilities/PixelFireExpectations.swift deleted file mode 100644 index 1a1d8c2f64..0000000000 --- a/LocalPackages/PixelKit/Sources/PixelKitTestingUtilities/PixelFireExpectations.swift +++ /dev/null @@ -1,66 +0,0 @@ -// -// PixelFireExpectations.swift -// -// Copyright © 2023 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 PixelKit - -/// Structure containing information about a pixel fire event. -/// -/// This is useful for test validation for libraries that rely on PixelKit, to make sure the pixels contain -/// all of the fields they are supposed to contain.. -/// -public struct PixelFireExpectations { - let pixelName: String - var error: Error? - var underlyingErrors: [Error] - var customFields: [String: String]? - - /// Convenience initializer for cleaner semantics - /// - public static func expect(pixelName: String, error: Error? = nil, underlyingErrors: [Error] = [], customFields: [String: String]? = nil) -> PixelFireExpectations { - - .init(pixelName: pixelName, error: error, underlyingErrors: underlyingErrors, customFields: customFields) - } - - public init(pixelName: String, error: Error? = nil, underlyingErrors: [Error] = [], customFields: [String: String]? = nil) { - self.pixelName = pixelName - self.error = error - self.underlyingErrors = underlyingErrors - self.customFields = customFields - } - - public var parameters: [String: String] { - var parameters = customFields ?? [String: String]() - - if let nsError = error as? NSError { - parameters[PixelKit.Parameters.errorCode] = String(nsError.code) - parameters[PixelKit.Parameters.errorDomain] = nsError.domain - } - - for (index, error) in underlyingErrors.enumerated() { - let errorCodeParameterName = PixelKit.Parameters.underlyingErrorCode + (index == 0 ? "" : String(index + 1)) - let errorDomainParameterName = PixelKit.Parameters.underlyingErrorDomain + (index == 0 ? "" : String(index + 1)) - let nsError = error as NSError - - parameters[errorCodeParameterName] = String(nsError.code) - parameters[errorDomainParameterName] = nsError.domain - } - - return parameters - } -} diff --git a/LocalPackages/PixelKit/Sources/PixelKitTestingUtilities/ValidatePixel.swift b/LocalPackages/PixelKit/Sources/PixelKitTestingUtilities/ValidatePixel.swift deleted file mode 100644 index 00547deb5b..0000000000 --- a/LocalPackages/PixelKit/Sources/PixelKitTestingUtilities/ValidatePixel.swift +++ /dev/null @@ -1,50 +0,0 @@ -// -// ValidatePixel.swift -// -// Copyright © 2023 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 PixelKit -import XCTest - -public final class PixelRequestValidator { - public init() {} - - public func validateBasicPixelParams( - expectedAppVersion: String, - expectedUserAgent: String, - requestParameters parameters: [String: String], - requestHeaders headers: [String: String]) { - - XCTAssertEqual(parameters[PixelKit.Parameters.test], "1") - XCTAssertEqual(parameters[PixelKit.Parameters.appVersion], expectedAppVersion) - - XCTAssertEqual(headers[PixelKit.Header.userAgent], expectedUserAgent) - XCTAssertEqual(headers[PixelKit.Header.acceptEncoding], "gzip;q=1.0, compress;q=0.5") - XCTAssertNotNil(headers[PixelKit.Header.acceptLanguage]) - XCTAssertNotNil(headers[PixelKit.Header.moreInfo], PixelKit.duckDuckGoMorePrivacyInfo.absoluteString) - } - - public func validateDebugPixelParams( - expectedError: Error?, - requestParameters parameters: [String: String]) { - - if let error = expectedError as? NSError { - XCTAssertEqual(parameters[PixelKit.Parameters.errorCode], "\(error.code)") - XCTAssertEqual(parameters[PixelKit.Parameters.errorDomain], error.domain) - } - } -} diff --git a/LocalPackages/PixelKit/Sources/PixelKitTestingUtilities/XCTestCase+PixelKit.swift b/LocalPackages/PixelKit/Sources/PixelKitTestingUtilities/XCTestCase+PixelKit.swift deleted file mode 100644 index 81232cd4bb..0000000000 --- a/LocalPackages/PixelKit/Sources/PixelKitTestingUtilities/XCTestCase+PixelKit.swift +++ /dev/null @@ -1,169 +0,0 @@ -// -// XCTestCase+PixelKit.swift -// -// Copyright © 2023 DuckDuckGo. All rights reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -import Foundation -@testable import PixelKit -import XCTest - -public extension XCTestCase { - - // MARK: - Parameters - - /// List of standard pixel parameters. - /// This is useful to support filtering these parameters out if needed. - private static var standardPixelParameters = [ - PixelKit.Parameters.appVersion, - PixelKit.Parameters.pixelSource, - PixelKit.Parameters.test - ] - - /// List of errror pixel parameters - private static var errorPixelParameters = [ - PixelKit.Parameters.errorCode, - PixelKit.Parameters.errorDomain - ] - - /// List of underlying error pixel parameters - private static var underlyingErrorPixelParameters = [ - PixelKit.Parameters.underlyingErrorCode, - PixelKit.Parameters.underlyingErrorDomain - ] - - /// Filter out the standard parameters. - private static func filterStandardPixelParameters(from parameters: [String: String]) -> [String: String] { - parameters.filter { element in - !standardPixelParameters.contains(element.key) - } - } - - static var pixelPlatformPrefix: String { -#if os(macOS) - return "m_mac_" -#elseif os(iOS) - return "m_" -#endif - } - - /// These parameters are known to be expected just based on the event definition. - /// - /// They're not a complete list of parameters for the event, as the fire call may contain extra information - /// that results in additional parameters. Ideally we want most (if not all) that information to eventually - /// make part of the pixel definition. - func knownExpectedParameters(for event: PixelKitEventV2) -> [String: String] { - var expectedParameters = [String: String]() - - if let error = event.error { - let nsError = error as NSError - expectedParameters[PixelKit.Parameters.errorCode] = "\(nsError.code)" - expectedParameters[PixelKit.Parameters.errorDomain] = nsError.domain - - if let underlyingError = nsError.userInfo[NSUnderlyingErrorKey] as? NSError { - expectedParameters[PixelKit.Parameters.underlyingErrorCode] = "\(underlyingError.code)" - expectedParameters[PixelKit.Parameters.underlyingErrorDomain] = underlyingError.domain - } - } - - return expectedParameters - } - - // MARK: - Misc Convenience - - private var userDefaults: UserDefaults { - UserDefaults(suiteName: "testing_\(UUID().uuidString)")! - } - - // MARK: - Pixel Firing Expectations - - func fire(_ event: PixelKitEventV2, frequency: PixelKit.Frequency, and expectations: PixelFireExpectations, file: StaticString, line: UInt) { - verifyThat(event, frequency: frequency, meets: expectations, file: file, line: line) - } - - /// Provides some snapshot of a fired pixel so that external libraries can validate all the expected info is included. - /// - /// This method also checks that there is internal consistency in the expected fields. - func verifyThat(_ event: PixelKitEventV2, - frequency: PixelKit.Frequency, - meets expectations: PixelFireExpectations, - file: StaticString, - line: UInt) { - let expectedPixelNames: [String] = expectedPixelNames(originalName: event.name, frequency: frequency) - let knownExpectedParameters = knownExpectedParameters(for: event) - let callbackExecutedExpectation = expectation(description: "The PixelKit callback has been executed") - - if frequency == .dailyAndCount { - callbackExecutedExpectation.expectedFulfillmentCount = 2 - } - - // Ensure PixelKit is torn down before setting it back up, avoiding unit test race conditions: - PixelKit.tearDown() - - PixelKit.setUp(dryRun: false, - appVersion: "1.0.5", - source: "test-app", - defaultHeaders: [:], - defaults: userDefaults) { firedPixelName, _, firedParameters, _, _, completion in - callbackExecutedExpectation.fulfill() - - let firedParameters = Self.filterStandardPixelParameters(from: firedParameters) - - // Internal validations - XCTAssertTrue(expectedPixelNames.contains(firedPixelName), file: file, line: line) - XCTAssertTrue(knownExpectedParameters.allSatisfy { (key, value) in - firedParameters[key] == value - }) - - if frequency == .dailyAndCount { - XCTAssertTrue(firedPixelName.hasPrefix(expectations.pixelName)) - XCTAssertTrue(firedPixelName.hasSuffix("_c") || firedPixelName.hasSuffix("_d")) - XCTAssertEqual(firedPixelName.count, expectations.pixelName.count + 2) - let exp = self.expectedPixelNames(originalName: expectations.pixelName, frequency: frequency) - XCTAssertTrue(exp.contains(firedPixelName)) - } else { - XCTAssertEqual(expectations.pixelName, firedPixelName) - } - XCTAssertEqual(firedParameters, expectations.parameters) - - completion(true, nil) - } - - PixelKit.fire(event, frequency: frequency) - waitForExpectations(timeout: 0.1) - } - - func expectedPixelNames(originalName: String, frequency: PixelKit.Frequency) -> [String] { - let expectedPixelNameWithoutSuffix = originalName.hasPrefix(Self.pixelPlatformPrefix) ? originalName : Self.pixelPlatformPrefix + originalName - var expectedPixelNames: [String] = [] - - switch frequency { - case .standard: - expectedPixelNames.append(expectedPixelNameWithoutSuffix) - case .legacyInitial: - expectedPixelNames.append(expectedPixelNameWithoutSuffix) - case .unique: - expectedPixelNames.append(expectedPixelNameWithoutSuffix) - case .legacyDaily: - expectedPixelNames.append(expectedPixelNameWithoutSuffix) - case .daily: - expectedPixelNames.append(expectedPixelNameWithoutSuffix.appending("_d")) - case .dailyAndCount: - expectedPixelNames.append(expectedPixelNameWithoutSuffix.appending("_d")) - expectedPixelNames.append(expectedPixelNameWithoutSuffix.appending("_c")) - } - return expectedPixelNames - } -} diff --git a/LocalPackages/PixelKit/Tests/PixelKitTests/PixelKitParametersTests.swift b/LocalPackages/PixelKit/Tests/PixelKitTests/PixelKitParametersTests.swift deleted file mode 100644 index 4d661d3336..0000000000 --- a/LocalPackages/PixelKit/Tests/PixelKitTests/PixelKitParametersTests.swift +++ /dev/null @@ -1,75 +0,0 @@ -// -// PixelKitParametersTests.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 XCTest -@testable import PixelKit -import PixelKitTestingUtilities - -final class PixelKitParametersTests: XCTestCase { - - /// Test events for convenience - /// - private enum TestEvent: PixelKitEventV2 { - case errorEvent(error: Error) - - var name: String { - switch self { - case .errorEvent: - return "error_event" - } - } - - var parameters: [String: String]? { - nil - } - - var error: Error? { - switch self { - case .errorEvent(let error): - error - } - } - } - - /// Test that when firing pixels that include multiple levels of underlying error information, all levels - /// are properly included in the pixel. - /// - func testUnderlyingErrorInformationParameters() { - let underlyingError3 = NSError(domain: "test", code: 3) - let underlyingError2 = NSError( - domain: "test", - code: 2, - userInfo: [ - NSUnderlyingErrorKey: underlyingError3 as NSError - ]) - let topLevelError = NSError( - domain: "test", - code: 1, - userInfo: [ - NSUnderlyingErrorKey: underlyingError2 as NSError - ]) - - fire(TestEvent.errorEvent(error: topLevelError), - frequency: .standard, - and: .expect(pixelName: "m_mac_error_event", - error: topLevelError, - underlyingErrors: [underlyingError2, underlyingError3]), - file: #filePath, - line: #line) - } -} diff --git a/LocalPackages/PixelKit/Tests/PixelKitTests/PixelKitTests.swift b/LocalPackages/PixelKit/Tests/PixelKitTests/PixelKitTests.swift deleted file mode 100644 index fed5b7789d..0000000000 --- a/LocalPackages/PixelKit/Tests/PixelKitTests/PixelKitTests.swift +++ /dev/null @@ -1,385 +0,0 @@ -// -// PixelKitTests.swift -// -// Copyright © 2023 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 XCTest -@testable import PixelKit -import os.log // swiftlint:disable:this enforce_os_log_wrapper - -final class PixelKitTests: XCTestCase { - - private func userDefaults() -> UserDefaults { - UserDefaults(suiteName: "testing_\(UUID().uuidString)")! - } - - /// Test events for convenience - /// - private enum TestEvent: String, PixelKitEvent { - case testEvent - case testEventWithoutParameters - case dailyEvent - case dailyEventWithoutParameters - case dailyAndContinuousEvent - case dailyAndContinuousEventWithoutParameters - case uniqueEvent - - var name: String { - switch self { - case .uniqueEvent: - return "\(rawValue)_u" - default: - return rawValue - } - } - - var parameters: [String: String]? { - switch self { - case .testEvent, .dailyEvent, .dailyAndContinuousEvent, .uniqueEvent: - return [ - "eventParam1": "eventParamValue1", - "eventParam2": "eventParamValue2" - ] - case .testEventWithoutParameters, .dailyEventWithoutParameters, .dailyAndContinuousEventWithoutParameters: - return nil - } - } - - var frequency: PixelKit.Frequency { - switch self { - case .testEvent, .testEventWithoutParameters: - return .standard - case .uniqueEvent: - return .unique - case .dailyEvent, .dailyEventWithoutParameters: - return .daily - case .dailyAndContinuousEvent, .dailyAndContinuousEventWithoutParameters: - return .dailyAndCount - } - } - } - - /// Test that a dry run won't execute the fire request callback. - /// - func testDryRunWontExecuteCallback() async { - let appVersion = "1.0.5" - let headers: [String: String] = [:] - - let pixelKit = PixelKit(dryRun: true, appVersion: appVersion, defaultHeaders: headers, dailyPixelCalendar: nil, defaults: userDefaults()) { _, _, _, _, _, _ in - - XCTFail("This callback should not be executed when doing a dry run") - } - - pixelKit.fire(TestEvent.testEvent) - } - - /// Tests firing a sample pixel and ensuring that all fields are properly set in the fire request callback. - /// - func testFiringASamplePixel() { - // Prepare test parameters - let appVersion = "1.0.5" - let headers = ["a": "2", "b": "3", "c": "2000"] - let event = TestEvent.testEvent - let userDefaults = userDefaults() - - // Set expectations - let expectedPixelName = "m_mac_\(event.name)" - let fireCallbackCalled = expectation(description: "Expect the pixel firing callback to be called") - - // Prepare mock to validate expectations - let pixelKit = PixelKit(dryRun: false, - appVersion: appVersion, - defaultHeaders: headers, - dailyPixelCalendar: nil, - defaults: userDefaults) { firedPixelName, firedHeaders, parameters, _, _, _ in - - fireCallbackCalled.fulfill() - - XCTAssertEqual(expectedPixelName, firedPixelName) - XCTAssertTrue(headers.allSatisfy({ key, value in - firedHeaders[key] == value - })) - - XCTAssertEqual(firedHeaders[PixelKit.Header.moreInfo], "See \(PixelKit.duckDuckGoMorePrivacyInfo)") - - XCTAssertEqual(parameters[PixelKit.Parameters.appVersion], appVersion) -#if DEBUG - XCTAssertEqual(parameters[PixelKit.Parameters.test], PixelKit.Values.test) -#else - XCTAssertNil(parameters[PixelKit.Parameters.test]) -#endif - } - - // Run test - pixelKit.fire(event) - - // Wait for expectations to be fulfilled - wait(for: [fireCallbackCalled], timeout: 0.5) - } - - /// We test firing a daily pixel for the first time executes the fire request callback with the right parameters - /// - func testFiringDailyPixelForTheFirstTime() { - // Prepare test parameters - let appVersion = "1.0.5" - let headers = ["a": "2", "b": "3", "c": "2000"] - let event = TestEvent.dailyEvent - let userDefaults = userDefaults() - - // Set expectations - let expectedPixelName = "m_mac_\(event.name)_d" - let expectedMoreInfoString = "See \(PixelKit.duckDuckGoMorePrivacyInfo)" - let fireCallbackCalled = expectation(description: "Expect the pixel firing callback to be called") - - // Prepare mock to validate expectations - let pixelKit = PixelKit(dryRun: false, - appVersion: appVersion, - defaultHeaders: headers, - dailyPixelCalendar: nil, - defaults: userDefaults) { firedPixelName, firedHeaders, parameters, _, _, _ in - - fireCallbackCalled.fulfill() - - XCTAssertEqual(expectedPixelName, firedPixelName) - XCTAssertTrue(headers.allSatisfy({ key, value in - firedHeaders[key] == value - })) - - XCTAssertEqual(firedHeaders[PixelKit.Header.moreInfo], expectedMoreInfoString) - XCTAssertEqual(parameters[PixelKit.Parameters.appVersion], appVersion) -#if DEBUG - XCTAssertEqual(parameters[PixelKit.Parameters.test], PixelKit.Values.test) -#else - XCTAssertNil(parameters[PixelKit.Parameters.test]) -#endif - } - - // Run test - pixelKit.fire(event, frequency: .daily) - - // Wait for expectations to be fulfilled - wait(for: [fireCallbackCalled], timeout: 0.5) - } - - /// We test firing a daily pixel a second time does not execute the fire request callback. - /// - func testDailyPixelDoubleFiringFrequency() { - // Prepare test parameters - let appVersion = "1.0.5" - let headers = ["a": "2", "b": "3", "c": "2000"] - let event = TestEvent.dailyEvent - let userDefaults = userDefaults() - - // Set expectations - let expectedPixelName = "m_mac_\(event.name)_d" - let expectedMoreInfoString = "See \(PixelKit.duckDuckGoMorePrivacyInfo)" - let fireCallbackCalled = expectation(description: "Expect the pixel firing callback to be called") - fireCallbackCalled.expectedFulfillmentCount = 1 - fireCallbackCalled.assertForOverFulfill = true - - // Prepare mock to validate expectations - let pixelKit = PixelKit(dryRun: false, - appVersion: appVersion, - defaultHeaders: headers, - dailyPixelCalendar: nil, - defaults: userDefaults) { firedPixelName, firedHeaders, parameters, _, _, _ in - - fireCallbackCalled.fulfill() - - XCTAssertEqual(expectedPixelName, firedPixelName) - XCTAssertTrue(headers.allSatisfy({ key, value in - firedHeaders[key] == value - })) - - XCTAssertEqual(firedHeaders[PixelKit.Header.moreInfo], expectedMoreInfoString) - XCTAssertEqual(parameters[PixelKit.Parameters.appVersion], appVersion) -#if DEBUG - XCTAssertEqual(parameters[PixelKit.Parameters.test], PixelKit.Values.test) -#else - XCTAssertNil(parameters[PixelKit.Parameters.test]) -#endif - } - - // Run test - pixelKit.fire(event, frequency: .daily) - pixelKit.fire(event, frequency: .daily) - - // Wait for expectations to be fulfilled - wait(for: [fireCallbackCalled], timeout: 0.5) - } - - /// Test firing a daily pixel a few times - func testDailyPixelFrequency() { - // Prepare test parameters - let appVersion = "1.0.5" - let headers = ["a": "2", "b": "3", "c": "2000"] - let event = TestEvent.dailyEvent - let userDefaults = userDefaults() - - let timeMachine = TimeMachine() - - // Set expectations - let fireCallbackCalled = expectation(description: "Expect the pixel firing callback to be called") - fireCallbackCalled.expectedFulfillmentCount = 3 - fireCallbackCalled.assertForOverFulfill = true - - // Prepare mock to validate expectations - let pixelKit = PixelKit(dryRun: false, - appVersion: appVersion, - defaultHeaders: headers, - dailyPixelCalendar: nil, - dateGenerator: timeMachine.now, - defaults: userDefaults) { _, _, _, _, _, _ in - fireCallbackCalled.fulfill() - } - - // Run test - pixelKit.fire(event, frequency: .daily) // Fired - timeMachine.travel(by: .hour, value: 2) - pixelKit.fire(event, frequency: .legacyDaily) // Skipped - - timeMachine.travel(by: .day, value: 1) - timeMachine.travel(by: .hour, value: 2) - pixelKit.fire(event, frequency: .legacyDaily) // Fired - - timeMachine.travel(by: .hour, value: 10) - pixelKit.fire(event, frequency: .legacyDaily) // Skipped - - timeMachine.travel(by: .day, value: 1) - pixelKit.fire(event, frequency: .legacyDaily) // Fired - - // Wait for expectations to be fulfilled - wait(for: [fireCallbackCalled], timeout: 0.5) - } - - /// Test firing a unique pixel - func testUniquePixel() { - // Prepare test parameters - let appVersion = "1.0.5" - let headers = ["a": "2", "b": "3", "c": "2000"] - let event = TestEvent.uniqueEvent - let userDefaults = userDefaults() - - let timeMachine = TimeMachine() - - // Set expectations - let fireCallbackCalled = expectation(description: "Expect the pixel firing callback to be called") - fireCallbackCalled.expectedFulfillmentCount = 1 - fireCallbackCalled.assertForOverFulfill = true - - let pixelKit = PixelKit(dryRun: false, - appVersion: appVersion, - defaultHeaders: headers, - dailyPixelCalendar: nil, - dateGenerator: timeMachine.now, - defaults: userDefaults) { _, _, _, _, _, _ in - fireCallbackCalled.fulfill() - } - - // Run test - pixelKit.fire(event, frequency: .unique) // Fired - timeMachine.travel(by: .hour, value: 2) - pixelKit.fire(event, frequency: .unique) // Skipped (already fired) - - timeMachine.travel(by: .day, value: 1) - timeMachine.travel(by: .hour, value: 2) - pixelKit.fire(event, frequency: .unique) // Skipped (already fired) - - timeMachine.travel(by: .hour, value: 10) - pixelKit.fire(event, frequency: .unique) // Skipped (already fired) - - timeMachine.travel(by: .day, value: 1) - pixelKit.fire(event, frequency: .unique) // Skipped (already fired) - - // Wait for expectations to be fulfilled - wait(for: [fireCallbackCalled], timeout: 0.5) - } - - func testVPNCohort() { - XCTAssertEqual(PixelKit.cohort(from: nil), "") - assertCohortEqual(.init(year: 2023, month: 1, day: 1), reportAs: "week-1") - assertCohortEqual(.init(year: 2024, month: 2, day: 24), reportAs: "week-60") - } - - private func assertCohortEqual(_ cohort: DateComponents, reportAs reportedCohort: String) { - var calendar = Calendar.current - calendar.timeZone = TimeZone(secondsFromGMT: 0)! - calendar.locale = Locale(identifier: "en_US_POSIX") - - let cohort = calendar.date(from: cohort) - let timeMachine = TimeMachine(calendar: calendar, date: cohort) - - PixelKit.setUp(appVersion: "test", - defaultHeaders: [:], - dailyPixelCalendar: calendar, - dateGenerator: timeMachine.now, - defaults: userDefaults()) { _, _, _, _, _, _ in } - - // 1st week - XCTAssertEqual(PixelKit.cohort(from: cohort, dateGenerator: timeMachine.now), reportedCohort) - - // 2nd week - timeMachine.travel(by: .weekOfYear, value: 1) - XCTAssertEqual(PixelKit.cohort(from: cohort, dateGenerator: timeMachine.now), reportedCohort) - - // 3rd week - timeMachine.travel(by: .weekOfYear, value: 1) - XCTAssertEqual(PixelKit.cohort(from: cohort, dateGenerator: timeMachine.now), reportedCohort) - - // 4th week - timeMachine.travel(by: .weekOfYear, value: 1) - XCTAssertEqual(PixelKit.cohort(from: cohort, dateGenerator: timeMachine.now), reportedCohort) - - // 5th week - timeMachine.travel(by: .weekOfYear, value: 1) - XCTAssertEqual(PixelKit.cohort(from: cohort, dateGenerator: timeMachine.now), reportedCohort) - - // 6th week - timeMachine.travel(by: .weekOfYear, value: 1) - XCTAssertEqual(PixelKit.cohort(from: cohort, dateGenerator: timeMachine.now), reportedCohort) - - // 7th week - timeMachine.travel(by: .weekOfYear, value: 1) - XCTAssertEqual(PixelKit.cohort(from: cohort, dateGenerator: timeMachine.now), reportedCohort) - - // 8th week - timeMachine.travel(by: .weekOfYear, value: 1) - XCTAssertEqual(PixelKit.cohort(from: cohort, dateGenerator: timeMachine.now), "") - } -} - -private class TimeMachine { - private var date: Date - private let calendar: Calendar - - init(calendar: Calendar? = nil, date: Date? = nil) { - self.calendar = calendar ?? { - var calendar = Calendar.current - calendar.timeZone = TimeZone(secondsFromGMT: 0)! - calendar.locale = Locale(identifier: "en_US_POSIX") - return calendar - }() - self.date = date ?? .init(timeIntervalSince1970: 0) - } - - func travel(by component: Calendar.Component, value: Int) { - date = calendar.date(byAdding: component, value: value, to: now())! - } - - func now() -> Date { - date - } -} diff --git a/LocalPackages/SubscriptionUI/Package.swift b/LocalPackages/SubscriptionUI/Package.swift index 9092bb8c50..31a96e104f 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: "138.0.0"), + .package(url: "https://github.com/duckduckgo/BrowserServicesKit", exact: "138.1.0"), .package(path: "../SwiftUIExtensions") ], targets: [ @@ -24,7 +24,11 @@ let package = Package( ], resources: [ .process("Resources") - ]), + ], + swiftSettings: [ + .define("DEBUG", .when(configuration: .debug)) + ] + ), .testTarget( name: "SubscriptionUITests", dependencies: ["SubscriptionUI"]),