From e2e5bbe29a76ed0fbb0c1148a1331c2fdf8b2587 Mon Sep 17 00:00:00 2001 From: Michal Smaga Date: Mon, 25 Nov 2024 16:09:38 +0100 Subject: [PATCH] Add support for feature flag local override --- Core/FeatureFlag.swift | 3 ++ DuckDuckGo/AppDependencyProvider.swift | 7 +++- .../SubscriptionDebugViewController.swift | 36 +++++++++++++++++++ 3 files changed, 45 insertions(+), 1 deletion(-) diff --git a/Core/FeatureFlag.swift b/Core/FeatureFlag.swift index 05f6782195..796c0f56fb 100644 --- a/Core/FeatureFlag.swift +++ b/Core/FeatureFlag.swift @@ -61,6 +61,9 @@ public enum FeatureFlag: String { } extension FeatureFlag: FeatureFlagDescribing { + + public static var localOverrideStoreName: String = "com.duckduckgo.app.featureFlag.localOverrides" + public var supportsLocalOverriding: Bool { switch self { case .isPrivacyProLaunchedROWOverride: diff --git a/DuckDuckGo/AppDependencyProvider.swift b/DuckDuckGo/AppDependencyProvider.swift index 0c308cf126..5dacc1637e 100644 --- a/DuckDuckGo/AppDependencyProvider.swift +++ b/DuckDuckGo/AppDependencyProvider.swift @@ -94,7 +94,12 @@ final class AppDependencyProvider: DependencyProvider { private init() { featureFlagger = DefaultFeatureFlagger(internalUserDecider: internalUserDecider, - privacyConfigManager: ContentBlocking.shared.privacyConfigurationManager) + privacyConfigManager: ContentBlocking.shared.privacyConfigurationManager, + localOverrides: FeatureFlagLocalOverrides( + keyValueStore: UserDefaults(suiteName: FeatureFlag.localOverrideStoreName)!, + actionHandler: FeatureFlagOverridesPublishingHandler() + ), + for: FeatureFlag.self) configurationManager = ConfigurationManager(store: configurationStore) diff --git a/DuckDuckGo/SubscriptionDebugViewController.swift b/DuckDuckGo/SubscriptionDebugViewController.swift index 45247ddb76..894136322f 100644 --- a/DuckDuckGo/SubscriptionDebugViewController.swift +++ b/DuckDuckGo/SubscriptionDebugViewController.swift @@ -22,6 +22,7 @@ import UIKit import Subscription import Core import NetworkProtection +import BrowserServicesKit final class SubscriptionDebugViewController: UITableViewController { @@ -29,6 +30,9 @@ final class SubscriptionDebugViewController: UITableViewController { private var subscriptionManager: SubscriptionManager { AppDependencyProvider.shared.subscriptionManager } + private var featureFlagger: FeatureFlagger { + AppDependencyProvider.shared.featureFlagger + } // swiftlint:disable:next force_cast private let reporter = (UIApplication.shared.delegate as! AppDelegate).privacyProDataReporter as! PrivacyProDataReporter @@ -39,6 +43,7 @@ final class SubscriptionDebugViewController: UITableViewController { Sections.appstore: "App Store", Sections.environment: "Environment", Sections.pixels: "Promo Pixel Parameters", + Sections.featureFlags: "Feature flags" ] enum Sections: Int, CaseIterable { @@ -47,6 +52,7 @@ final class SubscriptionDebugViewController: UITableViewController { case appstore case environment case pixels + case featureFlags } enum AuthorizationRows: Int, CaseIterable { @@ -74,6 +80,10 @@ final class SubscriptionDebugViewController: UITableViewController { case randomize } + enum FeatureFlagRows: Int, CaseIterable { + case isLaunchedROW + } + override func numberOfSections(in tableView: UITableView) -> Int { return Sections.allCases.count } @@ -145,6 +155,16 @@ final class SubscriptionDebugViewController: UITableViewController { case .none: break } + + case .featureFlags: + + switch FeatureFlagRows(rawValue: indexPath.row) { + case .isLaunchedROW: + cell.textLabel?.text = "isLaunchedROW" + cell.accessoryType = featureFlagger.isFeatureOn(.isPrivacyProLaunchedROWOverride) ? .checkmark : .none + case .none: + break + } case .none: break } @@ -159,6 +179,7 @@ final class SubscriptionDebugViewController: UITableViewController { case .appstore: return AppStoreRows.allCases.count case .environment: return EnvironmentRows.allCases.count case .pixels: return PixelsRows.allCases.count + case .featureFlags: return FeatureFlagRows.allCases.count case .none: return 0 } @@ -193,6 +214,11 @@ final class SubscriptionDebugViewController: UITableViewController { case .randomize: showRandomizedParamters() default: break } + case .featureFlags: + switch FeatureFlagRows(rawValue: indexPath.row) { + case .isLaunchedROW: toggleIsLaunchedROWFlag() + default: break + } case .none: break } @@ -301,6 +327,16 @@ 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 {