Skip to content

Commit 4c6a250

Browse files
committed
Replace local feature flag with remote feature flag
1 parent 710519d commit 4c6a250

File tree

5 files changed

+86
-29
lines changed

5 files changed

+86
-29
lines changed

Modules/Sources/Experiments/DefaultFeatureFlagService.swift

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -100,8 +100,6 @@ public struct DefaultFeatureFlagService: FeatureFlagService {
100100
return true
101101
case .pointOfSaleHistoricalOrdersi1:
102102
return buildConfig == .localDeveloper || buildConfig == .alpha
103-
case .applicationPasswordExperiment:
104-
return buildConfig == .localDeveloper || buildConfig == .alpha
105103
case .pointOfSaleLocalCatalogi1:
106104
return buildConfig == .localDeveloper || buildConfig == .alpha
107105
default:

Modules/Sources/Experiments/FeatureFlag.swift

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -207,10 +207,6 @@ public enum FeatureFlag: Int {
207207
///
208208
case pointOfSaleHistoricalOrdersi1
209209

210-
/// Enables switching Jetpack requests to use application password
211-
///
212-
case applicationPasswordExperiment
213-
214210
/// Enables Local Catalog i1 in Point of Sale.
215211
/// It syncs products and variations to local storage and display them in POS for quick access.
216212
///

Modules/Sources/Networking/Remote/FeatureFlagRemote.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ public enum RemoteFeatureFlag: Decodable {
3030
case storeCreationCompleteNotification
3131
case hardcodedPlanUpgradeDetailsMilestone1AreAccurate
3232
case pointOfSale
33+
case appPasswordsForJetpackSites
3334

3435
init?(rawValue: String) {
3536
switch rawValue {
@@ -39,6 +40,8 @@ public enum RemoteFeatureFlag: Decodable {
3940
self = .hardcodedPlanUpgradeDetailsMilestone1AreAccurate
4041
case "woo_pos":
4142
self = .pointOfSale
43+
case "woo_app_passwords_for_jetpack_sites":
44+
self = .appPasswordsForJetpackSites
4245
default:
4346
return nil
4447
}

WooCommerce/Classes/ViewRelated/Dashboard/Settings/Beta features/ApplicationPasswordsExperimentState.swift

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -63,19 +63,17 @@ final class ApplicationPasswordsExperimentAvailabilityChecker: ApplicationPasswo
6363
}
6464
}
6565

66+
@MainActor
6667
func fetchAvailability() async -> Bool {
67-
await withCheckedContinuation { continuation in
68-
//TODO: - put the remote FF checking here
69-
//For now rely on local FF for mocked value to avoid unwanted exposure
70-
let mockResultValue = ServiceLocator.featureFlagService.isFeatureFlagEnabled(
71-
.applicationPasswordExperiment
72-
)
73-
74-
DispatchQueue.main.asyncAfter(deadline: .now() + 3) {
75-
continuation.resume(returning: mockResultValue)
76-
}
77-
78-
cachedRemoteFFValue = mockResultValue
68+
let isEnabled = await withCheckedContinuation { continuation in
69+
stores.dispatch(FeatureFlagAction.isRemoteFeatureFlagEnabled(
70+
.appPasswordsForJetpackSites,
71+
defaultValue: false
72+
) { isEnabled in
73+
continuation.resume(returning: isEnabled)
74+
})
7975
}
76+
cachedRemoteFFValue = isEnabled
77+
return isEnabled
8078
}
8179
}

WooCommerce/WooCommerceTests/ViewRelated/Settings/ApplicationPasswordsExperimentAvailabilityCheckerTests.swift

Lines changed: 73 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import Yosemite
44

55
final class ApplicationPasswordsExperimentAvailabilityCheckerTests: XCTestCase {
66
private var availabilityChecker: ApplicationPasswordsExperimentAvailabilityCheckerProtocol!
7-
private var stores: StoresManager!
7+
private var stores: MockStoresManager!
88
private var userDefaults: UserDefaults!
99

1010
override func tearDown() {
@@ -16,7 +16,7 @@ final class ApplicationPasswordsExperimentAvailabilityCheckerTests: XCTestCase {
1616

1717
private func setupEnvironment(
1818
isWPComAuthenticated: Bool,
19-
isRemoteFFEnabled: Bool
19+
cachedRemoteFFEnabled: Bool
2020
) throws {
2121
stores = MockStoresManager(
2222
sessionManager: .makeForTesting(
@@ -26,31 +26,93 @@ final class ApplicationPasswordsExperimentAvailabilityCheckerTests: XCTestCase {
2626
)
2727

2828
userDefaults = try XCTUnwrap(UserDefaults(suiteName: "TestingSuite"))
29-
userDefaults[.applicationPasswordsExperimentRemoteFFValue] = isRemoteFFEnabled
29+
userDefaults[.applicationPasswordsExperimentRemoteFFValue] = cachedRemoteFFEnabled
3030

3131
availabilityChecker = ApplicationPasswordsExperimentAvailabilityChecker(
3232
userDefaults: userDefaults,
3333
stores: stores
3434
)
3535
}
3636

37-
func test_when_wpcom_authenticated_and_remote_ff_enabled_then_isAvailable_returns_true() throws {
38-
try setupEnvironment(isWPComAuthenticated: true, isRemoteFFEnabled: true)
37+
func test_when_wpcom_authenticated_and_cached_remote_ff_enabled_then_isAvailable_returns_true() throws {
38+
try setupEnvironment(isWPComAuthenticated: true, cachedRemoteFFEnabled: true)
3939
XCTAssertTrue(availabilityChecker.isAvailable)
4040
}
4141

42-
func test_when_wpcom_authenticated_and_remote_ff_disabled_then_isAvailable_returns_false() throws {
43-
try setupEnvironment(isWPComAuthenticated: true, isRemoteFFEnabled: false)
42+
func test_when_wpcom_authenticated_and_cached_remote_ff_disabled_then_isAvailable_returns_false() throws {
43+
try setupEnvironment(isWPComAuthenticated: true, cachedRemoteFFEnabled: false)
4444
XCTAssertFalse(availabilityChecker.isAvailable)
4545
}
4646

47-
func test_when_not_wpcom_authenticated_and_remote_ff_enabled_then_isAvailable_returns_false() throws {
48-
try setupEnvironment(isWPComAuthenticated: false, isRemoteFFEnabled: true)
47+
func test_when_not_wpcom_authenticated_and_cached_remote_ff_enabled_then_isAvailable_returns_false() throws {
48+
try setupEnvironment(isWPComAuthenticated: false, cachedRemoteFFEnabled: true)
4949
XCTAssertFalse(availabilityChecker.isAvailable)
5050
}
5151

52-
func test_when_not_wpcom_authenticated_and_remote_ff_disabled_then_isAvailable_returns_false() throws {
53-
try setupEnvironment(isWPComAuthenticated: false, isRemoteFFEnabled: false)
52+
func test_when_not_wpcom_authenticated_and_cached_remote_ff_disabled_then_isAvailable_returns_false() throws {
53+
try setupEnvironment(isWPComAuthenticated: false, cachedRemoteFFEnabled: false)
5454
XCTAssertFalse(availabilityChecker.isAvailable)
5555
}
56+
57+
@MainActor
58+
func test_when_cached_flag_is_disabled_and_remote_flag_is_enabled_then_fetchAvailability_returns_true() async throws {
59+
// Given
60+
stores = MockStoresManager(
61+
sessionManager: .makeForTesting(
62+
authenticated: true,
63+
isWPCom: true
64+
)
65+
)
66+
stores.whenReceivingAction(ofType: FeatureFlagAction.self) { action in
67+
switch action {
68+
case .isRemoteFeatureFlagEnabled(_, _, let completion):
69+
completion(true)
70+
}
71+
}
72+
73+
userDefaults = try XCTUnwrap(UserDefaults(suiteName: UUID().uuidString))
74+
userDefaults[.applicationPasswordsExperimentRemoteFFValue] = false
75+
76+
availabilityChecker = ApplicationPasswordsExperimentAvailabilityChecker(
77+
userDefaults: userDefaults,
78+
stores: stores
79+
)
80+
81+
// When
82+
let availability = await availabilityChecker.fetchAvailability()
83+
84+
// Then
85+
XCTAssertTrue(availability)
86+
}
87+
88+
@MainActor
89+
func test_when_cached_flag_is_enabled_and_remote_flag_is_disabled_then_fetchAvailability_returns_false() async throws {
90+
// Given
91+
stores = MockStoresManager(
92+
sessionManager: .makeForTesting(
93+
authenticated: true,
94+
isWPCom: true
95+
)
96+
)
97+
stores.whenReceivingAction(ofType: FeatureFlagAction.self) { action in
98+
switch action {
99+
case .isRemoteFeatureFlagEnabled(_, _, let completion):
100+
completion(false)
101+
}
102+
}
103+
104+
userDefaults = try XCTUnwrap(UserDefaults(suiteName: UUID().uuidString))
105+
userDefaults[.applicationPasswordsExperimentRemoteFFValue] = true
106+
107+
availabilityChecker = ApplicationPasswordsExperimentAvailabilityChecker(
108+
userDefaults: userDefaults,
109+
stores: stores
110+
)
111+
112+
// When
113+
let availability = await availabilityChecker.fetchAvailability()
114+
115+
// Then
116+
XCTAssertFalse(availability)
117+
}
56118
}

0 commit comments

Comments
 (0)