-
Notifications
You must be signed in to change notification settings - Fork 2k
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
Guided Tours: Find & show tours based on state selectors #6417
Conversation
cdab56f
to
36369be
Compare
One thing I noticed worries me. The following breaks the tests, as it should: diff --git a/client/state/ui/guided-tours/selectors.js b/client/state/ui/guided-tours/selectors.js
index 74af0d5..e7e3d1b 100644
--- a/client/state/ui/guided-tours/selectors.js
+++ b/client/state/ui/guided-tours/selectors.js
@@ -92,7 +92,7 @@ export const findEligibleTour = createSelector(
return context( state );
} );
},
- [ getActionLog, getToursHistory ]
+ getActionLog
);
/** because the However, the following does not break the tests, when I believe it should be functionally equivalent to the previous diff: diff --git a/client/state/ui/guided-tours/selectors.js b/client/state/ui/guided-tours/selectors.js
index 74af0d5..2c4059f 100644
--- a/client/state/ui/guided-tours/selectors.js
+++ b/client/state/ui/guided-tours/selectors.js
@@ -92,7 +92,7 @@ export const findEligibleTour = createSelector(
return context( state );
} );
},
- [ getActionLog, getToursHistory ]
+ [ getActionLog ]
);
/** @aduth, since we've been discussing selectors and have just merged #6391, I'm cc'ing you for a sanity check. It's getting late here. Edit: this happens regardless of using shorthand, thus |
Quite possibly because memoization cache is not reset between tests. See posts tests as an example. |
Yes, but I expect memoization to be working. However, I'm surprised that |
Hmm, equally confusing, I find all tests passing when applying your first diff, but resetting selectors cache between tests. diff --git a/client/state/ui/guided-tours/selectors.js b/client/state/ui/guided-tours/selectors.js
index 74af0d5..e279a62 100644
--- a/client/state/ui/guided-tours/selectors.js
+++ b/client/state/ui/guided-tours/selectors.js
@@ -45,7 +45,7 @@ const relevantFeatures = [
},
];
-const getToursFromFeaturesReached = createSelector(
+export const getToursFromFeaturesReached = createSelector(
state => reverse( uniq(
getActionLog( state )
.filter( ( { type } ) => type === ROUTE_SET )
@@ -63,7 +63,7 @@ const getToursFromFeaturesReached = createSelector(
getActionLog
);
-const getToursSeen = createSelector(
+export const getToursSeen = createSelector(
state => uniq(
getToursHistory( state )
.map( ( { tourName } ) => tourName )
@@ -92,7 +92,7 @@ export const findEligibleTour = createSelector(
return context( state );
} );
},
- [ getActionLog, getToursHistory ]
+ getActionLog
);
/**
diff --git a/client/state/ui/guided-tours/test/selectors.js b/client/state/ui/guided-tours/test/selectors.js
index 94b4557..bb1b0c4 100644
--- a/client/state/ui/guided-tours/test/selectors.js
+++ b/client/state/ui/guided-tours/test/selectors.js
@@ -7,12 +7,21 @@ import { expect } from 'chai';
* Internal dependencies
*/
import {
+ getToursFromFeaturesReached,
+ getToursSeen,
getGuidedTourState,
findEligibleTour,
} from '../selectors';
import guidedToursConfig from 'layout/guided-tours/config';
describe( 'selectors', () => {
+ beforeEach( () => {
+ getToursFromFeaturesReached.memoizedSelector.cache.clear();
+ getToursSeen.memoizedSelector.cache.clear();
+ getGuidedTourState.memoizedSelector.cache.clear();
+ findEligibleTour.memoizedSelector.cache.clear();
+ } );
+
describe( '#getGuidedTourState()', () => {
it( 'should return an empty object if no state is present', () => {
const tourState = getGuidedTourState( { |
Aside: I contemplated the idea that we could check in |
That one actually sounds correct, because — even though we're setting the wrong dependencies by only mentioning |
That's an interesting idea. I bet there's a higher probability of a bug not being spotted due to a selector's cache not being cleared than the opposite — even though, in this particular instance, I spotted the need to add the |
bd6694a
to
afc2dd7
Compare
Rebased against |
@@ -36,10 +36,11 @@ export function createNotice( status, text, options = {} ) { | |||
}; | |||
} | |||
|
|||
export function setRoute( path ) { | |||
export function setRoute( path, query = {} ) { |
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.
In #6306 (to be merged shortly), this action creator is moved to state/ui/actions.js
afc2dd7
to
047e9ae
Compare
56ae182
to
c99b1c8
Compare
c93fdce
to
35cdd84
Compare
Thanks for tackling those outstanding items, @lsinger! The logic after the removal of the dummy tours seems good. |
We should test whether the |
35cdd84
to
8cf91cb
Compare
GuidedTours needs access to query arguments to determine whether a tour is being forced (e.g. .../?tour=main). This puts the query arguments into the redux state tree. This avoids having to read from interfaces like `location`, which are impure and make testing more difficult. Props @mcsf.
Previously, GuidedTours was able to trigger only a single tour -- ` main`. This was based solely on the presence of `tour=main` in the query arguments. This change introduces a selectors-based approach to triggering tours that is based on the current context and tour-specific requirements for that context.
8cf91cb
to
fbb5cdb
Compare
Rebased. |
Let's merge this. |
Stumbled across the Do we really need both? |
tl;dr: IIRC, the following would happen:
This led to the need for |
I noticed today that triggering tours using Something @markryall found:
Does anyone have any clue how this might have come to be? |
Yes, thanks @ockham. Documented here: #20553 (comment) |
Previously, GuidedTours was able to trigger only a single tour --
main
. This was based solely on the presence oftour=main
in the query arguments. This change introduces a selectors-based approach to triggering tours that is based on the current context and tour-specific requirements for that context.Duplicate of #6335, but based on
master
this time.Product of exploration in #6146. See that PR for context.
Before merging
tour
ortourName
(punted)relevantFeatures
into config, or leave that to next PR? (next PR)ROUTE_SET
actions in state, for performance (punted, later when we need it)Testing
?tour=main
URL?tour=main
bit***
localStorage.setItem( 'ABTests', '{"guidedTours_20160603":"guided"}' );
Test live: https://calypso.live/?branch=add/guided-tours-log-selectors-rebased