-
Notifications
You must be signed in to change notification settings - Fork 117
[Woo POS] Fix POS menu item visibility issues with unit tests #12808
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
…turn `isEligible` as a publisher.
…es POS eligibility for available features.
…, with minor comment updates.
…SEligibilityChecker`.
Generated by 🚫 Danger |
|
…hared onboarding state.
…nu for shared onboarding state." This reverts commit 8352ec8.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A few things I noticed while testing:
Disabling the experimental feature toggle is not reflected in the menu until you switch store – whereas enabling it is reflected immediately.
disable-pos-broken.mp4
Onboarding completion isn't reflected until you switch tab. This is only possible if you've turned on the feature switch on another store previously, otherwise you don't even see the switch until you complete onboarding:
onboarding-refresh-tab-change.mp4
I'm not sure how much effort we should invest in making onboarding handling better now, as I think we may remove it as a condition and handle it within POS mode if needed. I just wanted to note it in case other issues are hiding in the woodwork like this. I suspect the tab switches are still required even for some other requirements changing, or perhaps when the onboarding cache is being refreshed.
Section(footer: Text(feature.description)) { | ||
TitleAndToggleRow(title: feature.title, isOn: appSettings.betaFeatureEnabledBinding(feature)) | ||
TitleAndToggleRow(title: feature.title, isOn: viewModel.isOn(feature: feature)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What benefit do we get from moving this to the viewModel?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good question - as I had to create a view model to observe POS eligibility check (from the onboarding state observation), I thought moving the appSettings
dependency to the view model would enable unit testing in the future even though we don't have unit tests on it right now.
.map { isBetaFeatureEnabled, isEligibleForPOS in | ||
if isBetaFeatureEnabled && isEligibleForPOS { | ||
return PointOfSaleEntryPoint() | ||
} else { | ||
return nil | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: it might be clearer to use a filter then a map:
.map { isBetaFeatureEnabled, isEligibleForPOS in | |
if isBetaFeatureEnabled && isEligibleForPOS { | |
return PointOfSaleEntryPoint() | |
} else { | |
return nil | |
} | |
} | |
.filter { isBetaFeatureEnabled, isEligibleForPOS in | |
isBetaFeatureEnabled && isEligibleForPOS | |
} | |
.map { _ in | |
PointOfSaleEntryPoint() | |
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If the downstream value is nil
from isBetaFeatureEnabled && isEligibleForPOS = false
=> PointOfSaleEntryPoint
from isBetaFeatureEnabled && isEligibleForPOS = true
, then when isBetaFeatureEnabled && isEligibleForPOS = false
, would filter + map set the value back to nil
? I'll do a quick experiment and update.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tested in Playground today, if we apply the filter, the view model doesn't get reset back to nil
when the entry point is not eligible anymore.
…inations to `menuList` view itself.
* trunk: (28 commits) Fix issue displaying dashboard cards when there is no saved cards in storage Remove extra space when there is no selected shipping method Show selected shipping method in shipping section of order details Use SwiftUI view for order details shipping line rows Add shipping section to order details Hide shipping notice when multiple shipping lines are supported Add feature flag for milestone 2 of enhancing order shipping lines project Add ShippingLineRowView for order shipping lines add padding to avoid overflow on landscape Make subviews computed Extract TotalsView to own file Wrap totals in ScrollView Adjust init access to internal Make pos vm StateObject Add release notes. Preserve existing ordering when refreshing cards. Add gh reference to internal comment Render list of products in-cart within total list Add addMoreButton Use OrderStage to switch building-finalizing views ... # Conflicts: # WooCommerce/WooCommerceTests/Mocks/MockFeatureFlagService.swift
I can't reproduce the first one 100%, but I think this is likely caused by the menu view's
After moving the
I agree, I'm hoping the |
Part of: #12779
Closes #12780
Why
As we're coming to a conclusion (at least for the first iteration) on the POS eligibility conditions in p91TBi-beb-p2#comment-12134, we're good with the checks that were implemented in #12783. Some basic test cases before closing this issue. In the meanwhile, there are two issues with the visibility of the POS menu item:
Note that we haven't made a decision about whether to keep the feature switch in Settings > Experimental Features so we have to continue supporting it p91TBi-beb-p2#comment-12143.
🗒️ Apology on the 500 diffs, More than half of the diffs are on the unit tests, as setting up dependencies for the POS eligibility checker isn't super straightforward.
How
The main cause for the visibility issue is that the onboarding state isn't refreshed if no other parts of the app has, and
POSEligibilityChecker
was just using the latest onboarding state value instead of observing the state publisher. In this PR, the major changes toPOSEligibilityChecker
are:isEligible
boolean is now a publisher to emit values on changessiteSettings
(for the country check) from[SiteSetting]
toSelectedSiteSettings
to allow potential changes that could be checked on the next onboarding state changePOSEligibilityCheckerProtocol
was created for easier unit testing in its consumerUIUserInterfaceIdiom
is now DI'edNow the checks are broken into 3 parts:
The checker first checks the fixed conditions, and then observes the onboarding state. On onboarding state changes, it first performs the site-specific checks and then the onboarding state check.
This observable isEligible boolean is tricky for the BetaFeaturesConfiguration screen. Before this PR, the availability of beta features is fixed. However, as we can't easily DI
POSEligibilityChecker
because the Settings (where BetaFeaturesConfiguration screen is in) is in UIKit with a SwiftUI wrapper, the BetaFeaturesConfiguration screen has to now observe the eligibility check as well. I thought about opening up a readonlyisEligible
boolean value type, but the onboarding state observation will result in the latest value async and thus missed in the BetaFeaturesConfiguration screen. In the end, I created a view model forBetaFeaturesConfiguration
that observes the eligibility value to show the available features.I originally wanted to share the onboarding use case with
InPersonPaymentsMenuViewModel
, but got some SwiftUI warning aboutPublishing changes from within view updates is not allowed, this will cause undefined behavior.
, so I decided to revert it.Please feel free to share any suggestions on a different approach!
Testing instructions
There are a few scenarios that @jaclync will test again after approval:
Continue with an iPad with the POS feature switch enabled for the following cases:
Screenshots
Simulator.Screen.Recording.-.iPad.10th.generation.-.2024-05-22.at.16.46.01.mp4
RELEASE-NOTES.txt
if necessary.