Skip to content

Commit

Permalink
Merge branch 'main' into sam/vpn-ship-review-problems
Browse files Browse the repository at this point in the history
* main:
  Bug fixed for subscription restore from app store (#2478)
  Subscription pixels refinements  (#2472)
  Adds VPN PrivacyPro pixels and ensure App Store runs all tests (#2468)
  • Loading branch information
samsymons committed Mar 22, 2024
2 parents 4e4a3d6 + 9da0cee commit f4dd479
Show file tree
Hide file tree
Showing 23 changed files with 444 additions and 162 deletions.
26 changes: 25 additions & 1 deletion DuckDuckGo.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -3273,6 +3273,12 @@
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 */; };
F1B33DF22BAD929D001128B3 /* SubscriptionAppStoreRestorer.swift in Sources */ = {isa = PBXBuildFile; fileRef = F1B33DF12BAD929D001128B3 /* SubscriptionAppStoreRestorer.swift */; };
F1B33DF32BAD929D001128B3 /* SubscriptionAppStoreRestorer.swift in Sources */ = {isa = PBXBuildFile; fileRef = F1B33DF12BAD929D001128B3 /* SubscriptionAppStoreRestorer.swift */; };
F1B33DF42BAD929D001128B3 /* SubscriptionAppStoreRestorer.swift in Sources */ = {isa = PBXBuildFile; fileRef = F1B33DF12BAD929D001128B3 /* SubscriptionAppStoreRestorer.swift */; };
F1B33DF62BAD970E001128B3 /* SubscriptionErrorReporter.swift in Sources */ = {isa = PBXBuildFile; fileRef = F1B33DF52BAD970E001128B3 /* SubscriptionErrorReporter.swift */; };
F1B33DF72BAD970E001128B3 /* SubscriptionErrorReporter.swift in Sources */ = {isa = PBXBuildFile; fileRef = F1B33DF52BAD970E001128B3 /* SubscriptionErrorReporter.swift */; };
F1B33DF82BAD970E001128B3 /* SubscriptionErrorReporter.swift in Sources */ = {isa = PBXBuildFile; fileRef = F1B33DF52BAD970E001128B3 /* SubscriptionErrorReporter.swift */; };
F1D43AEE2B98D8DF00BAB743 /* MainMenuActions+VanillaBrowser.swift in Sources */ = {isa = PBXBuildFile; fileRef = F1D43AED2B98D8DF00BAB743 /* MainMenuActions+VanillaBrowser.swift */; };
F1D43AEF2B98D8DF00BAB743 /* MainMenuActions+VanillaBrowser.swift in Sources */ = {isa = PBXBuildFile; fileRef = F1D43AED2B98D8DF00BAB743 /* MainMenuActions+VanillaBrowser.swift */; };
F1D43AF02B98D8DF00BAB743 /* MainMenuActions+VanillaBrowser.swift in Sources */ = {isa = PBXBuildFile; fileRef = F1D43AED2B98D8DF00BAB743 /* MainMenuActions+VanillaBrowser.swift */; };
Expand Down Expand Up @@ -4666,6 +4672,8 @@
EEDE50102BA360C80017F3C4 /* NetworkProtection+VPNAgentConvenienceInitializers.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NetworkProtection+VPNAgentConvenienceInitializers.swift"; sourceTree = "<group>"; };
EEF12E6D2A2111880023E6BF /* MacPacketTunnelProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MacPacketTunnelProvider.swift; sourceTree = "<group>"; };
EEF53E172950CED5002D78F4 /* JSAlertViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JSAlertViewModelTests.swift; sourceTree = "<group>"; };
F1B33DF12BAD929D001128B3 /* SubscriptionAppStoreRestorer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SubscriptionAppStoreRestorer.swift; sourceTree = "<group>"; };
F1B33DF52BAD970E001128B3 /* SubscriptionErrorReporter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SubscriptionErrorReporter.swift; sourceTree = "<group>"; };
F1D43AED2B98D8DF00BAB743 /* MainMenuActions+VanillaBrowser.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "MainMenuActions+VanillaBrowser.swift"; sourceTree = "<group>"; };
F41D174025CB131900472416 /* NSColorExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSColorExtension.swift; sourceTree = "<group>"; };
F44C130125C2DA0400426E3E /* NSAppearanceExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSAppearanceExtension.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -8430,7 +8438,7 @@
4BB88B4425B7B55C006F6B06 /* DebugUserScript.swift */,
856CADEF271710F400E79BB0 /* HoverUserScript.swift */,
4B2E7D6226FF9D6500D2DB17 /* PrintingUserScript.swift */,
1E0C72052ABC63BD00802009 /* SubscriptionPagesUserScript.swift */,
F1B33DF92BAD9C83001128B3 /* Subscription */,
1ED910D42B63BFB300936947 /* IdentityTheftRestorationPagesUserScript.swift */,
85AC3AEE25D5CE9800C7D2AA /* UserScripts.swift */,
);
Expand Down Expand Up @@ -8653,6 +8661,16 @@
path = JSAlert;
sourceTree = "<group>";
};
F1B33DF92BAD9C83001128B3 /* Subscription */ = {
isa = PBXGroup;
children = (
1E0C72052ABC63BD00802009 /* SubscriptionPagesUserScript.swift */,
F1B33DF12BAD929D001128B3 /* SubscriptionAppStoreRestorer.swift */,
F1B33DF52BAD970E001128B3 /* SubscriptionErrorReporter.swift */,
);
path = Subscription;
sourceTree = "<group>";
};
/* End PBXGroup section */

/* Begin PBXNativeTarget section */
Expand Down Expand Up @@ -10160,6 +10178,7 @@
B65211262B29A42E00B30633 /* BookmarkStoreMock.swift in Sources */,
3706FAF5293F65D500E42796 /* SafariVersionReader.swift in Sources */,
3706FAF6293F65D500E42796 /* LoginFaviconView.swift in Sources */,
F1B33DF72BAD970E001128B3 /* SubscriptionErrorReporter.swift in Sources */,
3706FEC0293F6EFF00E42796 /* BWRequest.swift in Sources */,
3706FAF7293F65D500E42796 /* FireproofDomainsViewController.swift in Sources */,
4BF0E5062AD2551A00FFEC9E /* NetworkProtectionPixelEvent.swift in Sources */,
Expand Down Expand Up @@ -10577,6 +10596,7 @@
3706FC1B293F65D500E42796 /* TabCollectionViewModel+NSSecureCoding.swift in Sources */,
3706FC1D293F65D500E42796 /* EmailManagerRequestDelegate.swift in Sources */,
3706FC1E293F65D500E42796 /* ApplicationVersionReader.swift in Sources */,
F1B33DF32BAD929D001128B3 /* SubscriptionAppStoreRestorer.swift in Sources */,
3706FC1F293F65D500E42796 /* BookmarksBarViewController.swift in Sources */,
1DDC85042B83903E00670238 /* PreferencesWebTrackingProtectionView.swift in Sources */,
3706FC20293F65D500E42796 /* PreferencesAutofillView.swift in Sources */,
Expand Down Expand Up @@ -11766,6 +11786,7 @@
4B957B182AC7AE700062CA31 /* PreferencesDataClearingView.swift in Sources */,
4B957B192AC7AE700062CA31 /* NSPasteboardExtension.swift in Sources */,
4B957B1A2AC7AE700062CA31 /* OnboardingViewModel.swift in Sources */,
F1B33DF42BAD929D001128B3 /* SubscriptionAppStoreRestorer.swift in Sources */,
4B957B1B2AC7AE700062CA31 /* ScriptSourceProviding.swift in Sources */,
4B957B1C2AC7AE700062CA31 /* CoreDataBookmarkImporter.swift in Sources */,
4B957B1D2AC7AE700062CA31 /* SuggestionViewModel.swift in Sources */,
Expand Down Expand Up @@ -11883,6 +11904,7 @@
4B957B7E2AC7AE700062CA31 /* NetworkProtection+ConvenienceInitializers.swift in Sources */,
7BA7CC502AD11F6F0042E5CE /* NetworkProtectionIPCTunnelController.swift in Sources */,
4B957B7F2AC7AE700062CA31 /* NavigationActionExtension.swift in Sources */,
F1B33DF82BAD970E001128B3 /* SubscriptionErrorReporter.swift in Sources */,
4B957B802AC7AE700062CA31 /* NSAlertExtension.swift in Sources */,
4B957B812AC7AE700062CA31 /* ThirdPartyBrowser.swift in Sources */,
4B957B822AC7AE700062CA31 /* SearchNonexistentDomainNavigationResponder.swift in Sources */,
Expand Down Expand Up @@ -12520,6 +12542,7 @@
EE339228291BDEFD009F62C1 /* JSAlertController.swift in Sources */,
4B9DB04A2A983B24000927DB /* NotificationService.swift in Sources */,
3775912D29AAC72700E26367 /* SyncPreferences.swift in Sources */,
F1B33DF22BAD929D001128B3 /* SubscriptionAppStoreRestorer.swift in Sources */,
1DB9618329F67F6200CF5568 /* FaviconNullStore.swift in Sources */,
BB5789722B2CA70F0009DFE2 /* DataBrokerProtectionSubscriptionEventHandler.swift in Sources */,
B693954F26F04BEB0015B914 /* PaddedImageButton.swift in Sources */,
Expand Down Expand Up @@ -12652,6 +12675,7 @@
AA97BF4625135DD30014931A /* ApplicationDockMenu.swift in Sources */,
4B8A4DFF27C83B29005F40E8 /* SaveIdentityViewController.swift in Sources */,
1DDC84FB2B8356CE00670238 /* PreferencesDefaultBrowserView.swift in Sources */,
F1B33DF62BAD970E001128B3 /* SubscriptionErrorReporter.swift in Sources */,
EEC589D92A4F1CE300BCD60C /* AppLauncher.swift in Sources */,
4BA1A69B258B076900F6F690 /* FileStore.swift in Sources */,
B6A9E47F26146A800067D1B9 /* PixelArguments.swift in Sources */,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,26 @@
ReferencedContainer = "container:LocalPackages/PixelKit">
</BuildableReference>
</TestableReference>
<TestableReference
skipped = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "VPNPrivacyProTests"
BuildableName = "VPNPrivacyProTests"
BlueprintName = "VPNPrivacyProTests"
ReferencedContainer = "container:LocalPackages/NetworkProtectionMac">
</BuildableReference>
</TestableReference>
<TestableReference
skipped = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "NetworkProtectionUITests"
BuildableName = "NetworkProtectionUITests"
BlueprintName = "NetworkProtectionUITests"
ReferencedContainer = "container:LocalPackages/NetworkProtectionMac">
</BuildableReference>
</TestableReference>
</Testables>
</TestAction>
<LaunchAction
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,16 @@
ReferencedContainer = "container:LocalPackages/DataBrokerProtection">
</BuildableReference>
</TestableReference>
<TestableReference
skipped = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "VPNPrivacyProTests"
BuildableName = "VPNPrivacyProTests"
BlueprintName = "VPNPrivacyProTests"
ReferencedContainer = "container:LocalPackages/NetworkProtectionMac">
</BuildableReference>
</TestableReference>
</Testables>
</TestAction>
<LaunchAction
Expand Down
1 change: 1 addition & 0 deletions DuckDuckGo/Application/URLEventHandler.swift
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,7 @@ final class URLEventHandler {
#if SUBSCRIPTION
case AppLaunchCommand.showPrivacyPro.launchURL:
WindowControllersManager.shared.showTab(with: .subscription(.subscriptionPurchase))
Pixel.fire(.privacyProOfferScreenImpression)
#endif
#if !APPSTORE && !DEBUG
case AppLaunchCommand.moveAppToApplications.launchURL:
Expand Down
15 changes: 12 additions & 3 deletions DuckDuckGo/Menus/MainMenuActions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import Common
import WebKit
import Configuration
import History
import PixelKit

// Actions are sent to objects of responder chain

Expand Down Expand Up @@ -717,11 +718,19 @@ extension MainViewController {
let state = internalUserDecider.isInternalUser
internalUserDecider.debugSetInternalUserState(!state)

// Aid to transition VPN from waitlist to subscription
// by resetting this we allow users to go back to waitlist
// and re-test.
clearPrivacyProState()
}

/// Clears the PrivacyPro state to make testing easier.
///
private func clearPrivacyProState() {
resetThankYouModalChecks(nil)
UserDefaults.netP.networkProtectionEntitlementsExpired = false

// Clear pixel data
DailyPixel.clearLastFireDate(pixel: .privacyProFeatureEnabled)
Pixel.shared?.clearRepetitions(for: .privacyProBetaUserThankYouDBP)
Pixel.shared?.clearRepetitions(for: .privacyProBetaUserThankYouVPN)
}

@objc func resetDailyPixels(_ sender: Any?) {
Expand Down
1 change: 0 additions & 1 deletion DuckDuckGo/NavigationBar/View/MoreOptionsMenu.swift
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,6 @@ final class MoreOptionsMenu: NSMenu {

#if SUBSCRIPTION
@objc func openSubscriptionPurchasePage(_ sender: NSMenuItem) {
Pixel.fire(.privacyProOfferScreenImpression)
actionDelegate?.optionsButtonMenuRequestedSubscriptionPurchasePage(self)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1094,6 +1094,7 @@ extension NavigationBarViewController: OptionsButtonMenuDelegate {
#if SUBSCRIPTION
func optionsButtonMenuRequestedSubscriptionPurchasePage(_ menu: NSMenu) {
WindowControllersManager.shared.showTab(with: .subscription(.subscriptionPurchase))
Pixel.fire(.privacyProOfferScreenImpression)
}

func optionsButtonMenuRequestedIdentityTheftRestoration(_ menu: NSMenu) {
Expand Down
11 changes: 9 additions & 2 deletions DuckDuckGo/Preferences/View/PreferencesRootView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ enum Preferences {
}

#if SUBSCRIPTION
// swiftlint:disable:next cyclomatic_complexity
// swiftlint:disable:next cyclomatic_complexity function_body_length
private func makeSubscriptionViewModel() -> PreferencesSubscriptionModel {
let openURL: (URL) -> Void = { url in
DispatchQueue.main.async {
Expand Down Expand Up @@ -179,7 +179,14 @@ enum Preferences {

let sheetActionHandler = SubscriptionAccessActionHandlers(restorePurchases: {
if #available(macOS 12.0, *) {
SubscriptionPagesUseSubscriptionFeature.startAppStoreRestoreFlow { _ in }
Task {
guard let mainViewController = WindowControllersManager.shared.lastKeyMainWindowController?.mainViewController,
let windowControllerManager = WindowControllersManager.shared.lastKeyMainWindowController else {
return
}

await SubscriptionAppStoreRestorer.restoreAppStoreSubscription(mainViewController: mainViewController, windowController: windowControllerManager)
}
}
},
openURLHandler: openURL,
Expand Down
4 changes: 4 additions & 0 deletions DuckDuckGo/Statistics/DailyPixel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,10 @@ final class DailyPixel {
storage.set(Date(), forKey: pixel.name)
}

static func clearLastFireDate(pixel: Pixel.Event) {
storage.removeObject(forKey: pixel.name)
}

}

private extension Pixel.Event {
Expand Down
3 changes: 3 additions & 0 deletions DuckDuckGo/Statistics/Pixel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,9 @@ final class Pixel {
onComplete: onComplete)
}

func clearRepetitions(for event: Pixel.Event) {
store().removeValue(forKey: event.name)
}
}

public func pixelAssertionFailure(_ message: @autoclosure () -> String = String(), file: StaticString = #fileID, line: UInt = #line) {
Expand Down
10 changes: 9 additions & 1 deletion DuckDuckGo/Statistics/PixelEvent.swift
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,9 @@ extension Pixel {
case dataBrokerProtectionErrorWhenFetchingSubscriptionAuthTokenAfterSignIn

// Subscription
case privacyProFeatureEnabled
case privacyProBetaUserThankYouVPN
case privacyProBetaUserThankYouDBP
case privacyProSubscriptionActive
case privacyProOfferScreenImpression
case privacyProPurchaseAttempt
Expand Down Expand Up @@ -250,6 +253,7 @@ extension Pixel {
case privacyProSubscriptionManagementEmail
case privacyProSubscriptionManagementPlanBilling
case privacyProSubscriptionManagementRemoval
case privacyProPurchaseStripeSuccess
// Web pixels
case privacyProOfferMonthlyPriceClick
case privacyProOfferYearlyPriceClick
Expand Down Expand Up @@ -655,6 +659,10 @@ extension Pixel.Event {
case .defaultRequestedFromOnboarding: return "m_mac_default_requested_from_onboarding"

// MARK: - Subscription
case .privacyProFeatureEnabled: return
"m_mac_\(appDistribution)_privacy-pro_feature_enabled"
case .privacyProBetaUserThankYouVPN: return "m_mac_\(appDistribution)_privacy-pro_promotion-dialog_shown_vpn"
case .privacyProBetaUserThankYouDBP: return "m_mac_\(appDistribution)_privacy-pro_promotion-dialog_shown_dbp"
case .privacyProSubscriptionActive: return "m_mac_\(appDistribution)_privacy-pro_app_subscription_active"
case .privacyProOfferScreenImpression: return "m_mac_\(appDistribution)_privacy-pro_offer_screen_impression"
case .privacyProPurchaseAttempt: return "m_mac_\(appDistribution)_privacy-pro_terms-conditions_subscribe_click"
Expand Down Expand Up @@ -687,6 +695,7 @@ extension Pixel.Event {
case .privacyProSubscriptionManagementEmail: return "m_mac_\(appDistribution)_privacy-pro_manage-email_edit_click"
case .privacyProSubscriptionManagementPlanBilling: return "m_mac_\(appDistribution)_privacy-pro_settings_change-plan-or-billing_click"
case .privacyProSubscriptionManagementRemoval: return "m_mac_\(appDistribution)_privacy-pro_settings_remove-from-device_click"
case .privacyProPurchaseStripeSuccess: return "m_mac_\(appDistribution)_privacy-pro_app_subscription-purchase_stripe_success"
// Web
case .privacyProOfferMonthlyPriceClick: return "m_mac_\(appDistribution)_privacy-pro_offer_monthly-price_click"
case .privacyProOfferYearlyPriceClick: return "m_mac_\(appDistribution)_privacy-pro_offer_yearly-price_click"
Expand All @@ -701,7 +710,6 @@ extension Pixel.Event {
// Password Import Keychain Prompt
case .passwordImportKeychainPrompt: return "m_mac_password_import_keychain_prompt"
case .passwordImportKeychainPromptDenied: return "m_mac_password_import_keychain_prompt_denied"

}
}
}
Expand Down
4 changes: 4 additions & 0 deletions DuckDuckGo/Statistics/PixelParameters.swift
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,9 @@ extension Pixel.Event {
.defaultRequestedFromHomepageSetupView,
.defaultRequestedFromSettings,
.defaultRequestedFromOnboarding,
.privacyProFeatureEnabled,
.privacyProBetaUserThankYouVPN,
.privacyProBetaUserThankYouDBP,
.privacyProSubscriptionActive,
.privacyProOfferScreenImpression,
.privacyProPurchaseAttempt,
Expand Down Expand Up @@ -210,6 +213,7 @@ extension Pixel.Event {
.privacyProOfferYearlyPriceClick,
.privacyProAddEmailSuccess,
.privacyProWelcomeFAQClick,
.privacyProPurchaseStripeSuccess,
.passwordImportKeychainPrompt,
.passwordImportKeychainPromptDenied:
return nil
Expand Down
Loading

0 comments on commit f4dd479

Please sign in to comment.