Navigation: Add test to container component (https://github.com/woocommerce/woocommerce-admin/pull/6344)
* getCategoriesMap * getMenuItemsByCategory * changelog
This commit is contained in:
parent
8371325ba6
commit
3483f1930e
|
@ -22,6 +22,70 @@ import CategoryTitle from '../category-title';
|
||||||
import Header from '../header';
|
import Header from '../header';
|
||||||
import Item from '../../components/Item';
|
import Item from '../../components/Item';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a map of all categories, including the topmost WooCommerce parentCategory
|
||||||
|
*
|
||||||
|
* @param {Array} menuItems Array of menuItems
|
||||||
|
* @return {Object} Map of categories by id
|
||||||
|
*/
|
||||||
|
export const getCategoriesMap = ( menuItems ) => {
|
||||||
|
return menuItems.reduce(
|
||||||
|
( acc, item ) => {
|
||||||
|
if ( item.isCategory ) {
|
||||||
|
return { ...acc, [ item.id ]: item };
|
||||||
|
}
|
||||||
|
return acc;
|
||||||
|
},
|
||||||
|
{
|
||||||
|
woocommerce: {
|
||||||
|
capability: 'manage_woocommerce',
|
||||||
|
id: 'woocommerce',
|
||||||
|
isCategory: true,
|
||||||
|
menuId: 'primary',
|
||||||
|
migrate: true,
|
||||||
|
order: 10,
|
||||||
|
parent: '',
|
||||||
|
title: 'WooCommerce',
|
||||||
|
},
|
||||||
|
}
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a flat tree structure of all Categories and thier children grouped by menuId
|
||||||
|
*
|
||||||
|
* @param {Object} categoriesMap Map of categories by id
|
||||||
|
* @param {Array} menuItems Array of menuItems
|
||||||
|
* @return {Object} a;dslkfj
|
||||||
|
*/
|
||||||
|
export const getMenuItemsByCategory = ( categoriesMap, menuItems ) => {
|
||||||
|
return menuItems.reduce( ( acc, item ) => {
|
||||||
|
// Set up the category if it doesn't yet exist.
|
||||||
|
if ( ! acc[ item.parent ] ) {
|
||||||
|
acc[ item.parent ] = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if parent category is in the same menu.
|
||||||
|
if (
|
||||||
|
item.parent !== 'woocommerce' &&
|
||||||
|
categoriesMap[ item.parent ] &&
|
||||||
|
categoriesMap[ item.parent ].menuId !== item.menuId &&
|
||||||
|
// Allow favorites to exist under any menu.
|
||||||
|
categoriesMap[ item.parent ].menuId !== 'favorites'
|
||||||
|
) {
|
||||||
|
return acc;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the menu object if it doesn't exist in this category.
|
||||||
|
if ( ! acc[ item.parent ][ item.menuId ] ) {
|
||||||
|
acc[ item.parent ][ item.menuId ] = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
acc[ item.parent ][ item.menuId ].push( item );
|
||||||
|
return acc;
|
||||||
|
}, {} );
|
||||||
|
};
|
||||||
|
|
||||||
const Container = ( { menuItems } ) => {
|
const Container = ( { menuItems } ) => {
|
||||||
useEffect( () => {
|
useEffect( () => {
|
||||||
// Collapse the original WP Menu.
|
// Collapse the original WP Menu.
|
||||||
|
@ -38,27 +102,7 @@ const Container = ( { menuItems } ) => {
|
||||||
|
|
||||||
const { rootBackLabel, rootBackUrl } = window.wcNavigation;
|
const { rootBackLabel, rootBackUrl } = window.wcNavigation;
|
||||||
|
|
||||||
const parentCategory = {
|
const categoriesMap = getCategoriesMap( menuItems );
|
||||||
capability: 'manage_woocommerce',
|
|
||||||
id: 'woocommerce',
|
|
||||||
isCategory: true,
|
|
||||||
menuId: 'primary',
|
|
||||||
migrate: true,
|
|
||||||
order: 10,
|
|
||||||
parent: '',
|
|
||||||
title: 'WooCommerce',
|
|
||||||
};
|
|
||||||
const categoriesMap = menuItems.reduce(
|
|
||||||
( acc, item ) => {
|
|
||||||
if ( item.isCategory ) {
|
|
||||||
return { ...acc, [ item.id ]: item };
|
|
||||||
}
|
|
||||||
return acc;
|
|
||||||
},
|
|
||||||
{
|
|
||||||
woocommerce: parentCategory,
|
|
||||||
}
|
|
||||||
);
|
|
||||||
const categories = Object.values( categoriesMap );
|
const categories = Object.values( categoriesMap );
|
||||||
|
|
||||||
const [ activeItem, setActiveItem ] = useState( 'woocommerce-home' );
|
const [ activeItem, setActiveItem ] = useState( 'woocommerce-home' );
|
||||||
|
@ -83,37 +127,9 @@ const Container = ( { menuItems } ) => {
|
||||||
return removeListener;
|
return removeListener;
|
||||||
}, [ menuItems ] );
|
}, [ menuItems ] );
|
||||||
|
|
||||||
const getMenuItemsByCategory = ( items ) => {
|
|
||||||
return items.reduce( ( acc, item ) => {
|
|
||||||
// Set up the category if it doesn't yet exist.
|
|
||||||
if ( ! acc[ item.parent ] ) {
|
|
||||||
acc[ item.parent ] = {};
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if parent category is in the same menu.
|
|
||||||
if (
|
|
||||||
item.parent !== 'woocommerce' &&
|
|
||||||
categoriesMap[ item.parent ] &&
|
|
||||||
categoriesMap[ item.parent ].menuId !== item.menuId &&
|
|
||||||
// Allow favorites to exist under any menu.
|
|
||||||
categoriesMap[ item.parent ].menuId !== 'favorites'
|
|
||||||
) {
|
|
||||||
return acc;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create the menu object if it doesn't exist in this category.
|
|
||||||
if ( ! acc[ item.parent ][ item.menuId ] ) {
|
|
||||||
acc[ item.parent ][ item.menuId ] = [];
|
|
||||||
}
|
|
||||||
|
|
||||||
acc[ item.parent ][ item.menuId ].push( item );
|
|
||||||
return acc;
|
|
||||||
}, {} );
|
|
||||||
};
|
|
||||||
|
|
||||||
const categorizedItems = useMemo(
|
const categorizedItems = useMemo(
|
||||||
() => getMenuItemsByCategory( menuItems ),
|
() => getMenuItemsByCategory( categoriesMap, menuItems ),
|
||||||
[ menuItems ]
|
[ categoriesMap, menuItems ]
|
||||||
);
|
);
|
||||||
|
|
||||||
const navDomRef = useRef( null );
|
const navDomRef = useRef( null );
|
||||||
|
|
|
@ -0,0 +1,204 @@
|
||||||
|
/**
|
||||||
|
* Internal dependencies
|
||||||
|
*/
|
||||||
|
import { getCategoriesMap, getMenuItemsByCategory } from '../';
|
||||||
|
|
||||||
|
describe( 'getCategoriesMap', () => {
|
||||||
|
const menuItems = [
|
||||||
|
{ id: 'zero', title: 'zero', isCategory: true },
|
||||||
|
{ id: 'one', title: 'one', isCategory: true },
|
||||||
|
{ id: 'two', title: 'two', isCategory: true },
|
||||||
|
{ id: 'three', title: 'three', isCategory: false },
|
||||||
|
{ id: 'four', title: 'four', isCategory: false },
|
||||||
|
];
|
||||||
|
|
||||||
|
it( 'should get a map of all categories', () => {
|
||||||
|
const categoriesMap = getCategoriesMap( menuItems );
|
||||||
|
|
||||||
|
expect( categoriesMap.zero ).toMatchObject( menuItems[ 0 ] );
|
||||||
|
expect( categoriesMap.one ).toMatchObject( menuItems[ 1 ] );
|
||||||
|
expect( categoriesMap.two ).toMatchObject( menuItems[ 2 ] );
|
||||||
|
expect( categoriesMap.three ).toBeUndefined();
|
||||||
|
expect( categoriesMap.four ).toBeUndefined();
|
||||||
|
} );
|
||||||
|
|
||||||
|
it( 'should include the topmost WooCommerce parent category', () => {
|
||||||
|
const categoriesMap = getCategoriesMap( menuItems );
|
||||||
|
|
||||||
|
expect( categoriesMap.woocommerce ).toBeDefined();
|
||||||
|
} );
|
||||||
|
|
||||||
|
it( 'should have the correct number of values', () => {
|
||||||
|
const categoriesMap = getCategoriesMap( menuItems );
|
||||||
|
|
||||||
|
expect( Object.keys( categoriesMap ).length ).toBe( 4 );
|
||||||
|
} );
|
||||||
|
} );
|
||||||
|
|
||||||
|
describe( 'getMenuItemsByCategory', () => {
|
||||||
|
it( 'should get a map of all categories and child elements', () => {
|
||||||
|
const menuItems = [
|
||||||
|
{
|
||||||
|
id: 'child-one',
|
||||||
|
title: 'child-one',
|
||||||
|
isCategory: false,
|
||||||
|
parent: 'parent',
|
||||||
|
menuId: 'plugins',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'child-two',
|
||||||
|
title: 'child-two',
|
||||||
|
isCategory: false,
|
||||||
|
parent: 'parent',
|
||||||
|
menuId: 'plugins',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'parent',
|
||||||
|
title: 'parent',
|
||||||
|
isCategory: true,
|
||||||
|
parent: 'woocommerce',
|
||||||
|
menuId: 'plugins',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
const categoriesMap = getCategoriesMap( menuItems );
|
||||||
|
const categorizedItems = getMenuItemsByCategory(
|
||||||
|
categoriesMap,
|
||||||
|
menuItems
|
||||||
|
);
|
||||||
|
|
||||||
|
expect( categorizedItems.woocommerce ).toBeDefined();
|
||||||
|
expect( categorizedItems.woocommerce.plugins ).toBeDefined();
|
||||||
|
expect( categorizedItems.woocommerce.plugins.length ).toBe( 1 );
|
||||||
|
|
||||||
|
expect( categorizedItems.parent ).toBeDefined();
|
||||||
|
expect( categorizedItems.parent.plugins ).toBeDefined();
|
||||||
|
expect( categorizedItems.parent.plugins.length ).toBe( 2 );
|
||||||
|
} );
|
||||||
|
|
||||||
|
it( 'should handle multiple depths', () => {
|
||||||
|
const menuItems = [
|
||||||
|
{
|
||||||
|
id: 'grand-child',
|
||||||
|
title: 'grand-child',
|
||||||
|
isCategory: false,
|
||||||
|
parent: 'child',
|
||||||
|
menuId: 'plugins',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'child',
|
||||||
|
title: 'child',
|
||||||
|
isCategory: true,
|
||||||
|
parent: 'grand-parent',
|
||||||
|
menuId: 'plugins',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'grand-parent',
|
||||||
|
title: 'grand-parent',
|
||||||
|
isCategory: true,
|
||||||
|
parent: 'woocommerce',
|
||||||
|
menuId: 'plugins',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
const categoriesMap = getCategoriesMap( menuItems );
|
||||||
|
const categorizedItems = getMenuItemsByCategory(
|
||||||
|
categoriesMap,
|
||||||
|
menuItems
|
||||||
|
);
|
||||||
|
|
||||||
|
expect( categorizedItems[ 'grand-parent' ] ).toBeDefined();
|
||||||
|
expect( categorizedItems[ 'grand-parent' ] ).toBeDefined();
|
||||||
|
expect( categorizedItems[ 'grand-parent' ].plugins.length ).toBe( 1 );
|
||||||
|
|
||||||
|
expect( categorizedItems.child ).toBeDefined();
|
||||||
|
expect( categorizedItems.child ).toBeDefined();
|
||||||
|
expect( categorizedItems.child.plugins.length ).toBe( 1 );
|
||||||
|
|
||||||
|
expect( categorizedItems[ 'grand-child' ] ).not.toBeDefined();
|
||||||
|
} );
|
||||||
|
|
||||||
|
it( 'should group by menuId', () => {
|
||||||
|
const menuItems = [
|
||||||
|
{
|
||||||
|
id: 'parent',
|
||||||
|
title: 'parent',
|
||||||
|
isCategory: true,
|
||||||
|
parent: 'woocommerce',
|
||||||
|
menuId: 'primary',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'primary-one',
|
||||||
|
title: 'primary-one',
|
||||||
|
isCategory: false,
|
||||||
|
parent: 'parent',
|
||||||
|
menuId: 'primary',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'primary-two',
|
||||||
|
title: 'primary-two',
|
||||||
|
isCategory: false,
|
||||||
|
parent: 'parent',
|
||||||
|
menuId: 'primary',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
const categoriesMap = getCategoriesMap( menuItems );
|
||||||
|
const categorizedItems = getMenuItemsByCategory(
|
||||||
|
categoriesMap,
|
||||||
|
menuItems
|
||||||
|
);
|
||||||
|
|
||||||
|
expect( categorizedItems.parent ).toBeDefined();
|
||||||
|
expect( categorizedItems.parent.primary ).toBeDefined();
|
||||||
|
expect( categorizedItems.parent.primary.length ).toBe( 2 );
|
||||||
|
} );
|
||||||
|
|
||||||
|
it( 'should group children only if their menuId matches parent', () => {
|
||||||
|
const menuItems = [
|
||||||
|
{
|
||||||
|
id: 'plugin-one',
|
||||||
|
title: 'plugin-one',
|
||||||
|
isCategory: false,
|
||||||
|
parent: 'parent',
|
||||||
|
menuId: 'plugins',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'plugin-two',
|
||||||
|
title: 'plugin-two',
|
||||||
|
isCategory: false,
|
||||||
|
parent: 'parent',
|
||||||
|
menuId: 'plugins',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'parent',
|
||||||
|
title: 'parent',
|
||||||
|
isCategory: true,
|
||||||
|
parent: 'woocommerce',
|
||||||
|
menuId: 'plugins',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'primary-one',
|
||||||
|
title: 'primary-one',
|
||||||
|
isCategory: false,
|
||||||
|
parent: 'parent',
|
||||||
|
menuId: 'primary',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'primary-two',
|
||||||
|
title: 'primary-two',
|
||||||
|
isCategory: false,
|
||||||
|
parent: 'parent',
|
||||||
|
menuId: 'primary',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
const categoriesMap = getCategoriesMap( menuItems );
|
||||||
|
const categorizedItems = getMenuItemsByCategory(
|
||||||
|
categoriesMap,
|
||||||
|
menuItems
|
||||||
|
);
|
||||||
|
|
||||||
|
expect( categorizedItems.parent ).toBeDefined();
|
||||||
|
expect( categorizedItems.parent.plugins ).toBeDefined();
|
||||||
|
expect( categorizedItems.parent.plugins.length ).toBe( 2 );
|
||||||
|
|
||||||
|
expect( categorizedItems.primary ).not.toBeDefined();
|
||||||
|
} );
|
||||||
|
} );
|
|
@ -48,6 +48,7 @@
|
||||||
"config": "^3.2.4",
|
"config": "^3.2.4",
|
||||||
"eslint": "6.7.2",
|
"eslint": "6.7.2",
|
||||||
"jest": "^24.9.0",
|
"jest": "^24.9.0",
|
||||||
|
"prettier": "npm:wp-prettier@1.19.1",
|
||||||
"puppeteer": "^2.0.0"
|
"puppeteer": "^2.0.0"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
@ -142,6 +143,11 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"prettier": {
|
||||||
|
"version": "npm:wp-prettier@1.19.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/wp-prettier/-/wp-prettier-1.19.1.tgz",
|
||||||
|
"integrity": "sha512-mqAC2r1NDmRjG+z3KCJ/i61tycKlmADIjxnDhQab+KBxSAGbF/W7/zwB2guy/ypIeKrrftNsIYkNZZQKf3vJcg=="
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -9049,8 +9055,7 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@woocommerce/currency": {
|
"@woocommerce/currency": {
|
||||||
"version": "3.0.0",
|
"version": "file:packages/currency",
|
||||||
"resolved": "/mnt/renovate/gh/woocommerce/woocommerce-admin/packages/currency",
|
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"@babel/runtime-corejs2": "7.12.5",
|
"@babel/runtime-corejs2": "7.12.5",
|
||||||
|
@ -9167,8 +9172,7 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@woocommerce/data": {
|
"@woocommerce/data": {
|
||||||
"version": "1.1.1",
|
"version": "file:packages/data",
|
||||||
"resolved": "/mnt/renovate/gh/woocommerce/woocommerce-admin/packages/data",
|
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"@babel/runtime-corejs2": "7.12.5",
|
"@babel/runtime-corejs2": "7.12.5",
|
||||||
|
@ -9178,8 +9182,7 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@woocommerce/date": {
|
"@woocommerce/date": {
|
||||||
"version": "2.1.0",
|
"version": "file:packages/date",
|
||||||
"resolved": "/mnt/renovate/gh/woocommerce/woocommerce-admin/packages/date",
|
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"@babel/runtime-corejs2": "7.12.5",
|
"@babel/runtime-corejs2": "7.12.5",
|
||||||
|
@ -10192,8 +10195,7 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@woocommerce/navigation": {
|
"@woocommerce/navigation": {
|
||||||
"version": "5.2.0",
|
"version": "file:packages/navigation",
|
||||||
"resolved": "/mnt/renovate/gh/woocommerce/woocommerce-admin/packages/navigation",
|
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"lodash": "4.17.15"
|
"lodash": "4.17.15"
|
||||||
|
|
|
@ -78,6 +78,7 @@ Release and roadmap notes are available on the [WooCommerce Developers Blog](htt
|
||||||
- Dev: Allow highlight tooltip to use body tag as parent. #6309
|
- Dev: Allow highlight tooltip to use body tag as parent. #6309
|
||||||
- Dev: Remove Google fonts and material icons. #6343
|
- Dev: Remove Google fonts and material icons. #6343
|
||||||
- Add: Remove CES actions for adding and editing a product and editing an order #6355
|
- Add: Remove CES actions for adding and editing a product and editing an order #6355
|
||||||
|
- Dev: Add unit tests to Navigation's Container component. #6344
|
||||||
|
|
||||||
== 2.0.0 02/05/2021 ==
|
== 2.0.0 02/05/2021 ==
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue