Skip to content

Commit

Permalink
FIX addon-contexts: edge case bugs part.2
Browse files Browse the repository at this point in the history
  • Loading branch information
Leo Y. Li committed Apr 24, 2019
1 parent d66aa30 commit b178d68
Show file tree
Hide file tree
Showing 6 changed files with 22 additions and 14 deletions.
3 changes: 1 addition & 2 deletions addons/contexts/src/manager/ContextsManager.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,7 @@ export const ContextsManager: ContextsManager = ({ api }) => {
);

// from preview
useChannel(UPDATE_MANAGER, newNodes => newNodes && setNodes(newNodes), []);
useChannel(UPDATE_MANAGER, (_, newState) => newState && setState(newState), []);
useChannel(UPDATE_MANAGER, newNodes => setNodes(newNodes), []);

// to preview
useEffect(() => api.emit(REBOOT_MANAGER), []);
Expand Down
10 changes: 7 additions & 3 deletions addons/contexts/src/preview/ContextsPreviewAPI.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,13 @@ export const ContextsPreviewAPI = singleton(() => {
*/
// from manager
channel.on(SET_CURRENT_STORY, () => (contextsNodesMemo = null));
channel.on(REBOOT_MANAGER, () => channel.emit(UPDATE_MANAGER, contextsNodesMemo, selectionState));
channel.on(UPDATE_PREVIEW, state => state && (selectionState = state));
channel.on(UPDATE_PREVIEW, () => channel.emit(FORCE_RE_RENDER));
channel.on(REBOOT_MANAGER, () => channel.emit(UPDATE_MANAGER, contextsNodesMemo));
channel.on(UPDATE_PREVIEW, state => {
if (state) {
selectionState = state;
channel.emit(FORCE_RE_RENDER);
}
});

// to manager
const getContextNodesWithSideEffects: typeof getContextNodes = (...arg) => {
Expand Down
6 changes: 3 additions & 3 deletions addons/contexts/src/preview/libs/getPropsMap.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ describe('Test on behaviors from collecting the propsMap', () => {
});

it('should return "OPT_OUT" token when the context being opted out', () => {
const result = _getPropsByParamName(someParams, OPT_OUT);
const result = _getPropsByParamName(someParams, OPT_OUT, { cancelable: true });
expect(result).toBe(OPT_OUT);
});

Expand Down Expand Up @@ -66,7 +66,7 @@ describe('Test on the integrity of the method to get the propMaps', () => {
];
const someSelectionState = {
'Some Context': 'A1',
'Another Context': OPT_OUT,
'Another Context': OPT_OUT, // an inconsistent but possible state being introduced via query param
};

// exercise
Expand All @@ -75,7 +75,7 @@ describe('Test on the integrity of the method to get the propMaps', () => {
// assertion
expect(result).toEqual({
'Some Context': { a: 1 },
'Another Context': OPT_OUT,
'Another Context': { b: 1 }, // not equal to `OPT_OUT` due to the context is not cancelable
'Other Contexts': { c: 1 },
});
});
Expand Down
11 changes: 6 additions & 5 deletions addons/contexts/src/preview/libs/getPropsMap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,14 @@ import { ContextNode, GenericProp, PropsMap, SelectionState } from '../../shared
*/
type _getPropsByParamName = (
params: ContextNode['params'],
name?: string
name?: string,
options?: Partial<ContextNode['options']>
) => GenericProp | typeof OPT_OUT;

export const _getPropsByParamName: _getPropsByParamName = (params, name) => {
export const _getPropsByParamName: _getPropsByParamName = (params, name = '', options = {}) => {
const { props = null } =
// when opt-out context
(name === OPT_OUT && { props: OPT_OUT }) ||
(options.cancelable && name === OPT_OUT && { props: OPT_OUT }) ||
// when menu option get selected
(name && params.find(param => param.name === name)) ||
// when being initialized
Expand All @@ -32,7 +33,7 @@ export const _getPropsByParamName: _getPropsByParamName = (params, name) => {
type getPropsMap = (contextNodes: ContextNode[], selectionState: SelectionState) => PropsMap;

export const getPropsMap: getPropsMap = (contextNodes, selectionState) =>
contextNodes.reduce((agg, { nodeId, params }) => {
agg[nodeId] = _getPropsByParamName(params, selectionState[nodeId]);
contextNodes.reduce((agg, { nodeId, params, options }) => {
agg[nodeId] = _getPropsByParamName(params, selectionState[nodeId], options);
return agg;
}, Object());
1 change: 1 addition & 0 deletions addons/contexts/src/shared/serializers.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ describe('Test on serializers', () => {

it('Should deserialize a string representation into the represented selection state', () => {
expect(deserialize('')).toEqual(undefined);
expect(deserialize('I am a bad string=')).toEqual(undefined);
expect(deserialize(someContextsQueryParam)).toEqual(someSelectionState);
});
});
5 changes: 4 additions & 1 deletion addons/contexts/src/shared/serializers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,7 @@ export const deserialize: deserialize = param =>
: param
.split(/,+/g)
.map(str => str.split(/=+/g))
.reduce((acc, [nodeId, name]) => (nodeId && name ? { ...acc, [nodeId]: name } : acc), {});
.reduce(
(acc, [nodeId, name]) => (nodeId && name ? { ...acc, [nodeId]: name } : acc),
undefined
);

0 comments on commit b178d68

Please sign in to comment.