Skip to content

Commit 7fa5258

Browse files
[CIAB] Hide POS tab for CIAB sites (#16147)
2 parents 5b30ba0 + 8b32ea3 commit 7fa5258

16 files changed

+306
-139
lines changed

Modules/Sources/Yosemite/Base/StoresManager.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ public protocol StoresManager {
6363

6464
/// The currently logged in store/site ID. Nil when the app is logged out.
6565
///
66+
/// periphery: ignore - used in tests
6667
var siteID: AnyPublisher<Int64?, Never> { get }
6768

6869
/// Observable currently selected site.

Modules/Sources/Yosemite/Model/Mocks/Graphs/ScreenshotsObjectGraph.swift

Lines changed: 1 addition & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -33,34 +33,7 @@ struct ScreenshotObjectGraph: MockObjectGraph {
3333
gravatarUrl: nil
3434
)
3535

36-
let defaultSite = Site(
37-
siteID: 1,
38-
name: Defaults.Site.name,
39-
description: "",
40-
url: Defaults.Site.url,
41-
adminURL: Defaults.Site.adminURL,
42-
loginURL: Defaults.Site.loginURL,
43-
isSiteOwner: false,
44-
frameNonce: "",
45-
plan: "",
46-
isAIAssistantFeatureActive: false,
47-
isJetpackThePluginInstalled: true,
48-
isJetpackConnected: true,
49-
isWooCommerceActive: true,
50-
isWordPressComStore: false,
51-
jetpackConnectionActivePlugins: [],
52-
timezone: "UTC",
53-
gmtOffset: 0,
54-
visibility: .publicSite,
55-
canBlaze: false,
56-
isAdmin: false,
57-
wasEcommerceTrial: false,
58-
hasSSOEnabled: false,
59-
applicationPasswordAvailable: false,
60-
isGarden: false,
61-
gardenName: nil,
62-
gardenPartner: nil
63-
)
36+
let defaultSite = Site.defaultMock()
6437

6538
/// May not be needed anymore if we're not mocking the API
6639
let defaultSiteAPI = SiteAPI(siteID: 1, namespaces: [
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import Foundation
2+
import struct Networking.Site
3+
4+
public extension Site {
5+
static func defaultMock() -> Self {
6+
return Site(
7+
siteID: 1,
8+
name: Defaults.Site.name,
9+
description: "",
10+
url: Defaults.Site.url,
11+
adminURL: Defaults.Site.adminURL,
12+
loginURL: Defaults.Site.loginURL,
13+
isSiteOwner: false,
14+
frameNonce: "",
15+
plan: "",
16+
isAIAssistantFeatureActive: false,
17+
isJetpackThePluginInstalled: true,
18+
isJetpackConnected: true,
19+
isWooCommerceActive: true,
20+
isWordPressComStore: false,
21+
jetpackConnectionActivePlugins: [],
22+
timezone: "UTC",
23+
gmtOffset: 0,
24+
visibility: .publicSite,
25+
canBlaze: false,
26+
isAdmin: false,
27+
wasEcommerceTrial: false,
28+
hasSSOEnabled: false,
29+
applicationPasswordAvailable: false,
30+
isGarden: false,
31+
gardenName: nil,
32+
gardenPartner: nil
33+
)
34+
}
35+
}

WooCommerce/Classes/CIAB/CIABAffectedFeature.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ enum CIABAffectedFeature: CaseIterable {
1010
case variableProducts
1111
case giftCardEditing
1212
case productsStockDashboardCard
13+
case pointOfSale
1314
}
1415

1516
extension CIABAffectedFeature {

WooCommerce/Classes/POS/Analytics/WooAnalyticsEvent+PointOfSaleIneligibleUI.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ private extension POSIneligibleReason {
2828
return "unknown_wc_plugin"
2929
case .unsupportedIOSVersion:
3030
return "ios_version"
31+
case .unsupportedInCIABSites:
32+
return "feature_unsupported_in_ciab"
3133
case .siteSettingsNotAvailable,
3234
.selfDeallocated:
3335
return "other"

WooCommerce/Classes/POS/Models/POSIneligibleReason.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ enum POSIneligibleReason: Equatable {
1111
case featureSwitchDisabled
1212
case unsupportedCurrency(countryCode: CountryCode, supportedCurrencies: [CurrencyCode])
1313
case selfDeallocated
14+
case unsupportedInCIABSites
1415
}
1516

1617
/// Represents the eligibility state for POS.

WooCommerce/Classes/POS/Presentation/PointOfSaleEntryPointView.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ struct PointOfSaleEntryPointView: View {
129129
searchHistoryService: PointOfSalePreviewHistoryService(),
130130
popularPurchasableItemsController: PointOfSalePreviewItemsController(),
131131
barcodeScanService: PointOfSalePreviewBarcodeScanService(),
132-
posEligibilityChecker: POSTabEligibilityChecker(siteID: 0),
132+
posEligibilityChecker: POSTabEligibilityChecker(site: .defaultMock()),
133133
services: POSPreviewServices())
134134
}
135135

WooCommerce/Classes/POS/TabBar/POSIneligibleView.swift

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,12 @@ struct POSIneligibleView: View {
154154
return NSLocalizedString("pos.ineligible.suggestion.selfDeallocated",
155155
value: "Try relaunching the app to resolve this issue.",
156156
comment: "Suggestion for self deallocated: relaunch")
157+
case .unsupportedInCIABSites:
158+
return NSLocalizedString(
159+
"pos.ineligible.suggestion.notSupportedForCIAB",
160+
value: "The POS system is not supported for your store.",
161+
comment: "Suggestion for CIAB sites: feature is not supported"
162+
)
157163
}
158164
}
159165
}
@@ -177,7 +183,8 @@ private extension POSIneligibleView {
177183
private extension POSIneligibleReason {
178184
var shouldShowRetryButton: Bool {
179185
switch self {
180-
case .unsupportedIOSVersion:
186+
case .unsupportedIOSVersion,
187+
.unsupportedInCIABSites:
181188
return false
182189
case .unsupportedWooCommerceVersion,
183190
.siteSettingsNotAvailable,
@@ -208,6 +215,9 @@ private extension POSIneligibleReason {
208215
value: "Retry",
209216
comment: "Button title to refresh POS eligibility check"
210217
)
218+
case .unsupportedInCIABSites:
219+
assertionFailure("Retry button should not be shown for `unsupportedInCIABSites`")
220+
return String()
211221
}
212222
}
213223
}

WooCommerce/Classes/POS/Utils/PreviewHelpers.swift

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import struct Yosemite.POSOrderRefund
2828
import typealias Yosemite.OrderItemAttribute
2929
import class Yosemite.POSOrderListService
3030
import class Yosemite.POSOrderListFetchStrategyFactory
31+
import struct Yosemite.Site
3132

3233
// MARK: - PreviewProvider helpers
3334
//
@@ -224,8 +225,9 @@ struct POSPreviewHelpers {
224225
featureFlags: POSFeatureFlagProviding = EmptyPOSFeatureFlags()
225226
) -> PointOfSaleAggregateModel {
226227
return PointOfSaleAggregateModel(
227-
entryPointController: POSEntryPointController(eligibilityChecker: LegacyPOSTabEligibilityChecker(siteID: 0),
228-
featureFlagService: featureFlags),
228+
entryPointController: POSEntryPointController(
229+
eligibilityChecker: LegacyPOSTabEligibilityChecker(site: Site.defaultMock()),
230+
featureFlagService: featureFlags),
229231
itemsController: itemsController,
230232
purchasableItemsSearchController: purchasableItemsSearchController,
231233
couponsController: couponsController,

WooCommerce/Classes/ViewRelated/Dashboard/Settings/POS/LegacyPOSTabEligibilityChecker.swift

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import enum WooFoundation.CountryCode
55
import enum WooFoundation.CurrencyCode
66
import protocol Experiments.FeatureFlagService
77
import struct Yosemite.SiteSetting
8+
import struct Yosemite.Site
89
import protocol Yosemite.POSEligibilityServiceProtocol
910
import protocol Yosemite.StoresManager
1011
import class Yosemite.POSEligibilityService
@@ -28,6 +29,7 @@ private enum LegacyPOSIneligibleReason: Equatable {
2829
case unsupportedCountry(supportedCountries: [CountryCode])
2930
case unsupportedCurrency(supportedCurrencies: [CurrencyCode])
3031
case selfDeallocated
32+
case unsupportedInCIABSites
3133
}
3234

3335
/// Legacy POS eligibility state for i1.
@@ -38,33 +40,36 @@ private enum LegacyPOSEligibilityState: Equatable {
3840

3941
/// POS tab eligibility checker for i1. Will be replaced by `POSTabEligibilityCheckerI2` when removing `pointOfSaleAsATabi2` feature flag.
4042
final class LegacyPOSTabEligibilityChecker: POSEntryPointEligibilityCheckerProtocol {
41-
private let siteID: Int64
43+
private let site: Site
4244
private let userInterfaceIdiom: UIUserInterfaceIdiom
4345
private let siteSettings: SelectedSiteSettingsProtocol
4446
private let pluginsService: PluginsServiceProtocol
4547
private let eligibilityService: POSEligibilityServiceProtocol
4648
private let stores: StoresManager
4749
private let featureFlagService: FeatureFlagService
50+
private let siteCIABEligibilityChecker: CIABEligibilityCheckerProtocol
4851

49-
init(siteID: Int64,
52+
init(site: Site,
5053
userInterfaceIdiom: UIUserInterfaceIdiom = UIDevice.current.userInterfaceIdiom,
5154
siteSettings: SelectedSiteSettingsProtocol = ServiceLocator.selectedSiteSettings,
5255
pluginsService: PluginsServiceProtocol = PluginsService(storageManager: ServiceLocator.storageManager),
5356
eligibilityService: POSEligibilityServiceProtocol = POSEligibilityService(),
5457
stores: StoresManager = ServiceLocator.stores,
55-
featureFlagService: FeatureFlagService = ServiceLocator.featureFlagService) {
56-
self.siteID = siteID
58+
featureFlagService: FeatureFlagService = ServiceLocator.featureFlagService,
59+
siteCIABEligibilityChecker: CIABEligibilityCheckerProtocol = CIABEligibilityChecker()) {
60+
self.site = site
5761
self.userInterfaceIdiom = userInterfaceIdiom
5862
self.siteSettings = siteSettings
5963
self.pluginsService = pluginsService
6064
self.eligibilityService = eligibilityService
6165
self.stores = stores
6266
self.featureFlagService = featureFlagService
67+
self.siteCIABEligibilityChecker = siteCIABEligibilityChecker
6368
}
6469

6570
/// Checks the initial visibility of the POS tab without dependance on network requests.
6671
func checkInitialVisibility() -> Bool {
67-
eligibilityService.loadCachedPOSTabVisibility(siteID: siteID) ?? false
72+
eligibilityService.loadCachedPOSTabVisibility(siteID: site.siteID) ?? false
6873
}
6974

7075
/// Determines whether the POS entry point can be shown based on the selected store and feature gates.
@@ -73,6 +78,10 @@ final class LegacyPOSTabEligibilityChecker: POSEntryPointEligibilityCheckerProto
7378
}
7479

7580
private func checkI1Eligibility() async -> LegacyPOSEligibilityState {
81+
guard siteCIABEligibilityChecker.isFeatureSupported(.pointOfSale, for: site) else {
82+
return .ineligible(reason: .unsupportedInCIABSites)
83+
}
84+
7685
switch checkDeviceEligibility() {
7786
case .eligible:
7887
break
@@ -139,7 +148,7 @@ private extension LegacyPOSTabEligibilityChecker {
139148

140149
private extension LegacyPOSTabEligibilityChecker {
141150
func checkPluginEligibility() async -> LegacyPOSEligibilityState {
142-
let wcPlugin = await fetchWooCommercePlugin(siteID: siteID)
151+
let wcPlugin = await fetchWooCommercePlugin(siteID: site.siteID)
143152

144153
guard VersionHelpers.isVersionSupported(version: wcPlugin.version,
145154
minimumRequired: Constants.wcPluginMinimumVersion) else {
@@ -155,7 +164,7 @@ private extension LegacyPOSTabEligibilityChecker {
155164
}
156165

157166
// For versions that support the feature switch, checks if the feature switch is enabled.
158-
return await checkFeatureSwitchEnabled(siteID: siteID)
167+
return await checkFeatureSwitchEnabled(siteID: site.siteID)
159168
}
160169

161170
@MainActor
@@ -201,7 +210,7 @@ private extension LegacyPOSTabEligibilityChecker {
201210

202211
func waitForSiteSettingsRefresh() async -> [SiteSetting] {
203212
for await siteSettings in siteSettings.settingsStream.values {
204-
guard siteSettings.siteID == siteID, siteSettings.settings.isNotEmpty, siteSettings.source != .initialLoad else {
213+
guard siteSettings.siteID == site.siteID, siteSettings.settings.isNotEmpty, siteSettings.source != .initialLoad else {
205214
continue
206215
}
207216
return siteSettings.settings

0 commit comments

Comments
 (0)