Skip to content

Commit e702542

Browse files
Make Application Passwords toggle visible only for WP.com authenticated users (#16086)
2 parents 5d1d93f + bd7276a commit e702542

File tree

5 files changed

+78
-7
lines changed

5 files changed

+78
-7
lines changed

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

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -36,18 +36,26 @@ final class ApplicationPasswordsExperimentState {
3636
}
3737

3838
protocol ApplicationPasswordsExperimentAvailabilityCheckerProtocol {
39-
var cachedValue: Bool { get }
39+
var isAvailable: Bool { get }
4040
func fetchAvailability() async -> Bool
4141
}
4242

4343
final class ApplicationPasswordsExperimentAvailabilityChecker: ApplicationPasswordsExperimentAvailabilityCheckerProtocol {
4444
private let userDefaults: UserDefaults
45+
private let stores: StoresManager
4546

46-
init(userDefaults: UserDefaults = .standard) {
47+
init(userDefaults: UserDefaults = .standard, stores: StoresManager = ServiceLocator.stores) {
4748
self.userDefaults = userDefaults
49+
self.stores = stores
50+
}
51+
52+
var isAvailable: Bool {
53+
/// The feature is only available when the user is signed in using WordPress.com account
54+
let isUserAuthenticatedByWPCom = !stores.isAuthenticatedWithoutWPCom
55+
return isUserAuthenticatedByWPCom && cachedRemoteFFValue
4856
}
4957

50-
var cachedValue: Bool {
58+
private var cachedRemoteFFValue: Bool {
5159
get {
5260
userDefaults[.applicationPasswordsExperimentRemoteFFValue] ?? false
5361
} set {
@@ -58,13 +66,16 @@ final class ApplicationPasswordsExperimentAvailabilityChecker: ApplicationPasswo
5866
func fetchAvailability() async -> Bool {
5967
await withCheckedContinuation { continuation in
6068
//TODO: - put the remote FF checking here
61-
let mockResultValue = true
69+
//For now rely on local FF for mocked value to avoid unwanted exposure
70+
let mockResultValue = ServiceLocator.featureFlagService.isFeatureFlagEnabled(
71+
.applicationPasswordExperiment
72+
)
6273

6374
DispatchQueue.main.asyncAfter(deadline: .now() + 3) {
6475
continuation.resume(returning: mockResultValue)
6576
}
6677

67-
cachedValue = mockResultValue
78+
cachedRemoteFFValue = mockResultValue
6879
}
6980
}
7081
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ private extension BetaFeaturesConfigurationViewModel {
3232
case .viewAddOns:
3333
return true
3434
case .applicationPasswords:
35-
return appPasswordsExperimentAvailabilityChecker.cachedValue
35+
return appPasswordsExperimentAvailabilityChecker.isAvailable
3636
}
3737
}
3838

WooCommerce/WooCommerce.xcodeproj/project.pbxproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1235,6 +1235,7 @@
12351235
2D09E0D52E65C9B9005C26F3 /* ApplicationPasswordsExperimentStateTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D09E0D42E65C9B9005C26F3 /* ApplicationPasswordsExperimentStateTests.swift */; };
12361236
2D880B492DFB2F3F00A6FB2C /* OptionalBinding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D880B482DFB2F3D00A6FB2C /* OptionalBinding.swift */; };
12371237
2D88C1112DF883C300A6FB2C /* AttributedString+Helpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D88C1102DF883BD00A6FB2C /* AttributedString+Helpers.swift */; };
1238+
2DA63E042E69B6D400B0CB28 /* ApplicationPasswordsExperimentAvailabilityCheckerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2DA63E032E69B6D200B0CB28 /* ApplicationPasswordsExperimentAvailabilityCheckerTests.swift */; };
12381239
2DB877522E25466C0001B175 /* ShippingItemRowAccessibility.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2DB877512E25466B0001B175 /* ShippingItemRowAccessibility.swift */; };
12391240
2DB88DA42E27DD8D0001B175 /* MarkOrderAsReadUseCase+Woo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2DB88DA32E27DD790001B175 /* MarkOrderAsReadUseCase+Woo.swift */; };
12401241
2DB891662E27F0830001B175 /* Address+Shared.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2DB891652E27F07E0001B175 /* Address+Shared.swift */; };
@@ -4423,6 +4424,7 @@
44234424
2D09E0D42E65C9B9005C26F3 /* ApplicationPasswordsExperimentStateTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ApplicationPasswordsExperimentStateTests.swift; sourceTree = "<group>"; };
44244425
2D880B482DFB2F3D00A6FB2C /* OptionalBinding.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OptionalBinding.swift; sourceTree = "<group>"; };
44254426
2D88C1102DF883BD00A6FB2C /* AttributedString+Helpers.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AttributedString+Helpers.swift"; sourceTree = "<group>"; };
4427+
2DA63E032E69B6D200B0CB28 /* ApplicationPasswordsExperimentAvailabilityCheckerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ApplicationPasswordsExperimentAvailabilityCheckerTests.swift; sourceTree = "<group>"; };
44264428
2DB877512E25466B0001B175 /* ShippingItemRowAccessibility.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShippingItemRowAccessibility.swift; sourceTree = "<group>"; };
44274429
2DB88DA32E27DD790001B175 /* MarkOrderAsReadUseCase+Woo.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MarkOrderAsReadUseCase+Woo.swift"; sourceTree = "<group>"; };
44284430
2DB891652E27F07E0001B175 /* Address+Shared.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Address+Shared.swift"; sourceTree = "<group>"; };
@@ -11533,6 +11535,7 @@
1153311535
BA143222273662DE00E4B3AB /* Settings */ = {
1153411536
isa = PBXGroup;
1153511537
children = (
11538+
2DA63E032E69B6D200B0CB28 /* ApplicationPasswordsExperimentAvailabilityCheckerTests.swift */,
1153611539
2D09E0D42E65C9B9005C26F3 /* ApplicationPasswordsExperimentStateTests.swift */,
1153711540
023BD5892BFDCF9500A10D7B /* POS */,
1153811541
BAFEF51D273C2151005F94CC /* SettingsViewModelTests.swift */,
@@ -17335,6 +17338,7 @@
1733517338
0331A7002A334982001D2C2C /* MockInAppPurchasesForWPComPlansManager.swift in Sources */,
1733617339
02DF174B2A4A134B008FD33B /* ProductFormActionsFactory+ProductCreationTests.swift in Sources */,
1733717340
02564A88246C047C00D6DB2A /* Optional+StringTests.swift in Sources */,
17341+
2DA63E042E69B6D400B0CB28 /* ApplicationPasswordsExperimentAvailabilityCheckerTests.swift in Sources */,
1733817342
0269576D23726401001BA0BF /* KeyboardFrameObserverTests.swift in Sources */,
1733917343
7E6A01A12725DEDE001668D5 /* FilterProductCategoryListViewModelTests.swift in Sources */,
1734017344
02BF9BAF2851E7EA008CE2DD /* MockAppleIDCredentialChecker.swift in Sources */,
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
import XCTest
2+
import Yosemite
3+
@testable import WooCommerce
4+
5+
final class ApplicationPasswordsExperimentAvailabilityCheckerTests: XCTestCase {
6+
private var availabilityChecker: ApplicationPasswordsExperimentAvailabilityCheckerProtocol!
7+
private var stores: StoresManager!
8+
private var userDefaults: UserDefaults!
9+
10+
override func tearDown() {
11+
availabilityChecker = nil
12+
stores = nil
13+
userDefaults = nil
14+
super.tearDown()
15+
}
16+
17+
private func setupEnvironment(
18+
isWPComAuthenticated: Bool,
19+
isRemoteFFEnabled: Bool
20+
) throws {
21+
stores = MockStoresManager(
22+
sessionManager: .makeForTesting(
23+
authenticated: true,
24+
isWPCom: isWPComAuthenticated
25+
)
26+
)
27+
28+
userDefaults = try XCTUnwrap(UserDefaults(suiteName: "TestingSuite"))
29+
userDefaults[.applicationPasswordsExperimentRemoteFFValue] = isRemoteFFEnabled
30+
31+
availabilityChecker = ApplicationPasswordsExperimentAvailabilityChecker(
32+
userDefaults: userDefaults,
33+
stores: stores
34+
)
35+
}
36+
37+
func test_when_wpcom_authenticated_and_remote_ff_enabled_then_isAvailable_returns_true() throws {
38+
try setupEnvironment(isWPComAuthenticated: true, isRemoteFFEnabled: true)
39+
XCTAssertTrue(availabilityChecker.isAvailable)
40+
}
41+
42+
func test_when_wpcom_authenticated_and_remote_ff_disabled_then_isAvailable_returns_false() throws {
43+
try setupEnvironment(isWPComAuthenticated: true, isRemoteFFEnabled: false)
44+
XCTAssertFalse(availabilityChecker.isAvailable)
45+
}
46+
47+
func test_when_not_wpcom_authenticated_and_remote_ff_enabled_then_isAvailable_returns_false() throws {
48+
try setupEnvironment(isWPComAuthenticated: false, isRemoteFFEnabled: true)
49+
XCTAssertFalse(availabilityChecker.isAvailable)
50+
}
51+
52+
func test_when_not_wpcom_authenticated_and_remote_ff_disabled_then_isAvailable_returns_false() throws {
53+
try setupEnvironment(isWPComAuthenticated: false, isRemoteFFEnabled: false)
54+
XCTAssertFalse(availabilityChecker.isAvailable)
55+
}
56+
}

WooCommerce/WooCommerceTests/ViewRelated/Settings/ApplicationPasswordsExperimentStateTests.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ final class ApplicationPasswordsExperimentStateTests: XCTestCase {
8989
private final class ApplicationPasswordsExperimentAvailabilityCheckerMock: ApplicationPasswordsExperimentAvailabilityCheckerProtocol {
9090
var mockedAvailability = false
9191

92-
var cachedValue: Bool {
92+
var isAvailable: Bool {
9393
mockedAvailability
9494
}
9595

0 commit comments

Comments
 (0)