Skip to content

Commit

Permalink
Post international Privacy Pro launch cleanup (#3778)
Browse files Browse the repository at this point in the history
Task/Issue URL:
https://app.asana.com/0/1203936086921904/1208836865988474/f

CC: @federicocappelli 

**Description**:
Post launch remove isLaunchedROW and isLaunchedROWOverride feature flags
and clean related business logic

**Steps to test this PR**:
- Verify purchase paths for both US and non-US Privacy Pro variants work
correctly (no functional changes expected)

<!--
Before submitting a PR, please ensure you have tested the combinations
you expect the reviewer to test, then delete configurations you *know*
do not need explicit testing.

Using a simulator where a physical device is unavailable is acceptable.
-->

**Definition of Done (Internal Only)**:

* [ ] Does this PR satisfy our [Definition of
Done](https://app.asana.com/0/1202500774821704/1207634633537039/f)?

---
###### Internal references:
[Software Engineering
Expectations](https://app.asana.com/0/59792373528535/199064865822552)
[Technical Design
Template](https://app.asana.com/0/59792373528535/184709971311943)
  • Loading branch information
miasma13 authored Jan 9, 2025
1 parent bb26dd2 commit d0a3183
Show file tree
Hide file tree
Showing 10 changed files with 15 additions and 80 deletions.
9 changes: 0 additions & 9 deletions Core/FeatureFlag.swift
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,6 @@ public enum FeatureFlag: String {
/// https://app.asana.com/0/1208592102886666/1208613627589762/f
case crashReportOptInStatusResetting

case isPrivacyProLaunchedROW
case isPrivacyProLaunchedROWOverride

/// https://app.asana.com/0/0/1208767141940869/f
case freeTrials
}
Expand All @@ -71,8 +68,6 @@ extension FeatureFlag: FeatureFlagDescribing {

public var supportsLocalOverriding: Bool {
switch self {
case .isPrivacyProLaunchedROWOverride:
return true
default:
return false
}
Expand Down Expand Up @@ -140,10 +135,6 @@ extension FeatureFlag: FeatureFlagDescribing {
return .remoteReleasable(.feature(.adAttributionReporting))
case .crashReportOptInStatusResetting:
return .internalOnly()
case .isPrivacyProLaunchedROW:
return .remoteReleasable(.subfeature(PrivacyProSubfeature.isLaunchedROW))
case .isPrivacyProLaunchedROWOverride:
return .remoteReleasable(.subfeature(PrivacyProSubfeature.isLaunchedROWOverride))
case .freeTrials:
return .remoteDevelopment(.subfeature(PrivacyProSubfeature.freeTrials))
}
Expand Down
2 changes: 1 addition & 1 deletion DuckDuckGo.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -11865,7 +11865,7 @@
repositoryURL = "https://github.com/DuckDuckGo/BrowserServicesKit";
requirement = {
kind = exactVersion;
version = 223.0.0;
version = "223.0.0-1";
};
};
9F8FE9472BAE50E50071E372 /* XCRemoteSwiftPackageReference "lottie-spm" */ = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,17 +32,17 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/DuckDuckGo/BrowserServicesKit",
"state" : {
"revision" : "e8f94cf597f4a447f86f39f461b736ac9ea280ce",
"version" : "223.0.0"
"revision" : "a87790835c140e4399ac85bb5b3c39d4c5f4ff03",
"version" : "223.0.0-1"
}
},
{
"identity" : "content-scope-scripts",
"kind" : "remoteSourceControl",
"location" : "https://github.com/duckduckgo/content-scope-scripts",
"state" : {
"revision" : "93ea6c3e771bc0b743b38cefbff548c10add9898",
"version" : "6.42.0"
"revision" : "bc808eb735d9eb72d5c54cf2452b104b6a370e25",
"version" : "6.43.0"
}
},
{
Expand Down Expand Up @@ -122,8 +122,8 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/duckduckgo/privacy-dashboard",
"state" : {
"revision" : "022c845b06ace6a4aa712a4fa3e79da32193d5c6",
"version" : "7.4.0"
"revision" : "2e2baf7d31c7d8e158a58bc1cb79498c1c727fd2",
"version" : "7.5.0"
}
},
{
Expand Down
18 changes: 2 additions & 16 deletions DuckDuckGo/AppDependencyProvider.swift
Original file line number Diff line number Diff line change
Expand Up @@ -124,28 +124,14 @@ final class AppDependencyProvider: DependencyProvider {
subscriptionEndpointService: subscriptionService,
authEndpointService: authService)

let theFeatureFlagger = featureFlagger
let subscriptionFeatureFlagger: FeatureFlaggerMapping<SubscriptionFeatureFlags> = FeatureFlaggerMapping { feature in
switch feature {
case .isLaunchedROW:
return theFeatureFlagger.isFeatureOn(.isPrivacyProLaunchedROW)
case .isLaunchedROWOverride:
return theFeatureFlagger.isFeatureOn(.isPrivacyProLaunchedROWOverride)
default:
return feature.defaultState
}
}

let storePurchaseManager = DefaultStorePurchaseManager(subscriptionFeatureMappingCache: subscriptionFeatureMappingCache,
subscriptionFeatureFlagger: subscriptionFeatureFlagger)
let storePurchaseManager = DefaultStorePurchaseManager(subscriptionFeatureMappingCache: subscriptionFeatureMappingCache)

let subscriptionManager = DefaultSubscriptionManager(storePurchaseManager: storePurchaseManager,
accountManager: accountManager,
subscriptionEndpointService: subscriptionService,
authEndpointService: authService,
subscriptionFeatureMappingCache: subscriptionFeatureMappingCache,
subscriptionEnvironment: subscriptionEnvironment,
subscriptionFeatureFlagger: subscriptionFeatureFlagger)
subscriptionEnvironment: subscriptionEnvironment)
accountManager.delegate = subscriptionManager

self.subscriptionManager = subscriptionManager
Expand Down
4 changes: 1 addition & 3 deletions DuckDuckGo/SettingsState.swift
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ struct SettingsState {
}

struct Subscription: Codable {
var enabled: Bool
var canPurchase: Bool
var isSignedIn: Bool
var hasActiveSubscription: Bool
Expand Down Expand Up @@ -136,8 +135,7 @@ struct SettingsState {
speechRecognitionAvailable: false,
loginsEnabled: false,
networkProtectionConnected: false,
subscription: Subscription(enabled: false,
canPurchase: false,
subscription: Subscription(canPurchase: false,
isSignedIn: false,
hasActiveSubscription: false,
isRestoring: false,
Expand Down
2 changes: 1 addition & 1 deletion DuckDuckGo/SettingsSubscriptionView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,7 @@ struct SettingsSubscriptionView: View {
}
}
.onReceive(settingsViewModel.$state) { state in
isShowingPrivacyPro = state.subscription.enabled && (state.subscription.isSignedIn || state.subscription.canPurchase)
isShowingPrivacyPro = (state.subscription.isSignedIn || state.subscription.canPurchase)
}
}
}
3 changes: 0 additions & 3 deletions DuckDuckGo/SettingsViewModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -757,9 +757,6 @@ extension SettingsViewModel {
state.subscription = SettingsState.defaults.subscription
}

// Update visibility based on Feature flag
state.subscription.enabled = subscriptionFeatureAvailability.isFeatureAvailable

// Update if can purchase based on App Store product availability
state.subscription.canPurchase = subscriptionManager.canPurchase

Expand Down
33 changes: 1 addition & 32 deletions DuckDuckGo/SubscriptionDebugViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,7 @@ final class SubscriptionDebugViewController: UITableViewController {
Sections.appstore: "App Store",
Sections.environment: "Environment",
Sections.pixels: "Promo Pixel Parameters",
Sections.metadata: "StoreKit Metadata",
Sections.featureFlags: "Feature flags"
Sections.metadata: "StoreKit Metadata"
]

enum Sections: Int, CaseIterable {
Expand All @@ -55,7 +54,6 @@ final class SubscriptionDebugViewController: UITableViewController {
case environment
case pixels
case metadata
case featureFlags
}

enum AuthorizationRows: Int, CaseIterable {
Expand Down Expand Up @@ -88,10 +86,6 @@ final class SubscriptionDebugViewController: UITableViewController {
case countryCode
}

enum FeatureFlagRows: Int, CaseIterable {
case isLaunchedROW
}

private var storefrontID = "Loading"
private var storefrontCountryCode = "Loading"

Expand Down Expand Up @@ -184,15 +178,6 @@ final class SubscriptionDebugViewController: UITableViewController {
break
}

case .featureFlags:
switch FeatureFlagRows(rawValue: indexPath.row) {
case .isLaunchedROW:
cell.textLabel?.text = "isPrivacyProLaunchedROWOverride"
cell.accessoryType = featureFlagger.isFeatureOn(.isPrivacyProLaunchedROWOverride) ? .checkmark : .none
case .none:
break
}

case .none:
break
}
Expand All @@ -208,7 +193,6 @@ final class SubscriptionDebugViewController: UITableViewController {
case .environment: return EnvironmentRows.allCases.count
case .pixels: return PixelsRows.allCases.count
case .metadata: return MetadataRows.allCases.count
case .featureFlags: return FeatureFlagRows.allCases.count
case .none: return 0
}
}
Expand Down Expand Up @@ -244,11 +228,6 @@ final class SubscriptionDebugViewController: UITableViewController {
}
case .metadata:
break
case .featureFlags:
switch FeatureFlagRows(rawValue: indexPath.row) {
case .isLaunchedROW: toggleIsLaunchedROWFlag()
default: break
}
case .none:
break
}
Expand Down Expand Up @@ -357,16 +336,6 @@ final class SubscriptionDebugViewController: UITableViewController {
showAlert(title: "", message: message)
}

private func toggleIsLaunchedROWFlag() {
let flag = FeatureFlag.isPrivacyProLaunchedROWOverride
if featureFlagger.localOverrides?.override(for: flag) == nil {
featureFlagger.localOverrides?.toggleOverride(for: flag)
} else {
featureFlagger.localOverrides?.clearOverride(for: flag)
}
tableView.reloadData()
}

private func syncAppleIDAccount() {
Task {
do {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,13 @@ import Foundation

public final class SubscriptionFeatureAvailabilityMock: SubscriptionFeatureAvailability {
static var enabled: SubscriptionFeatureAvailabilityMock {
return SubscriptionFeatureAvailabilityMock(isFeatureAvailable: true, isSubscriptionPurchaseAllowed: true, usesUnifiedFeedbackForm: true)
return SubscriptionFeatureAvailabilityMock(isSubscriptionPurchaseAllowed: true, usesUnifiedFeedbackForm: true)
}

public var isFeatureAvailable: Bool
public var isSubscriptionPurchaseAllowed: Bool
public var usesUnifiedFeedbackForm: Bool

public init(isFeatureAvailable: Bool, isSubscriptionPurchaseAllowed: Bool, usesUnifiedFeedbackForm: Bool) {
self.isFeatureAvailable = isFeatureAvailable
public init(isSubscriptionPurchaseAllowed: Bool, usesUnifiedFeedbackForm: Bool) {
self.isSubscriptionPurchaseAllowed = isSubscriptionPurchaseAllowed
self.usesUnifiedFeedbackForm = usesUnifiedFeedbackForm
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,6 @@ final class SubscriptionPagesUseSubscriptionFeatureTests: XCTestCase {
var subscriptionEnvironment: SubscriptionEnvironment!

var subscriptionFeatureMappingCache: SubscriptionFeatureMappingCacheMock!
var subscriptionFeatureFlagger: FeatureFlaggerMapping<SubscriptionFeatureFlags>!

var appStorePurchaseFlow: AppStorePurchaseFlow!
var appStoreRestoreFlow: AppStoreRestoreFlow!
Expand Down Expand Up @@ -134,7 +133,6 @@ final class SubscriptionPagesUseSubscriptionFeatureTests: XCTestCase {
settings: UserDefaultsCacheSettings(defaultExpirationInterval: .minutes(20)))

subscriptionFeatureMappingCache = SubscriptionFeatureMappingCacheMock()
subscriptionFeatureFlagger = FeatureFlaggerMapping<SubscriptionFeatureFlags>(mapping: { $0.defaultState })

// Real AccountManager
accountManager = DefaultAccountManager(storage: accountStorage,
Expand Down Expand Up @@ -164,8 +162,7 @@ final class SubscriptionPagesUseSubscriptionFeatureTests: XCTestCase {
subscriptionEndpointService: subscriptionService,
authEndpointService: authService,
subscriptionFeatureMappingCache: subscriptionFeatureMappingCache,
subscriptionEnvironment: subscriptionEnvironment,
subscriptionFeatureFlagger: subscriptionFeatureFlagger)
subscriptionEnvironment: subscriptionEnvironment)

feature = SubscriptionPagesUseSubscriptionFeature(subscriptionManager: subscriptionManager,
subscriptionFeatureAvailability: subscriptionFeatureAvailability,
Expand Down Expand Up @@ -318,7 +315,6 @@ final class SubscriptionPagesUseSubscriptionFeatureTests: XCTestCase {
func testGetSubscriptionOptionsReturnsEmptyOptionsWhenPurchaseNotAllowed() async throws {
// Given
let subscriptionFeatureAvailabilityWithoutPurchaseAllowed = SubscriptionFeatureAvailabilityMock(
isFeatureAvailable: true,
isSubscriptionPurchaseAllowed: false,
usesUnifiedFeedbackForm: true
)
Expand Down

0 comments on commit d0a3183

Please sign in to comment.