* Add changelog and testing instructions

* Set active level when matching a new item

* Add navigation container tests

* Add testing instructions and changelog

* Update testing instructions

* Fix up missing changelog entries after rebase

* Add in missing menu items from useSelect in tests
This commit is contained in:
Joshua T Flowers 2021-03-05 09:35:53 -05:00 committed by GitHub
parent 19a13ae09c
commit 198e3fb7ce
5 changed files with 273 additions and 13 deletions

View File

@ -8,6 +8,13 @@
2. Navigate to Analytics->Reports.
3. Note that all the reports exist and navigating to those reports works as expected.
4. Check that report menu items are marked active when navigating to that page.
### Add navigation container tests #6464
1. On a new site, finish the store setup wizard, but don't hide the task list.
2. Navigate to a WooCommerce Admin Analytics page.
3. Note the menu is under the "Analytics" level.
4. Click the "Store Setup" link in the top right hand corner.
5. Note that the navigation level automatically is updated to the root level where the "Home" item is marked active.
### Add preview site button on the appearance task #6457

View File

@ -26,7 +26,9 @@ jest.mock( '@wordpress/data', () => {
return {
__esModule: true, // Use it when dealing with esModules
...originalModule,
useSelect: jest.fn().mockReturnValue( {} ),
useSelect: jest.fn().mockReturnValue( {
menuItems: [],
} ),
};
} );

View File

@ -3,11 +3,10 @@
*/
import { useEffect, useMemo, useState, useRef } from '@wordpress/element';
import classnames from 'classnames';
import { compose } from '@wordpress/compose';
import { Navigation } from '@woocommerce/experimental';
import { NAVIGATION_STORE_NAME, useUser } from '@woocommerce/data';
import { recordEvent } from '@woocommerce/tracks';
import { withSelect } from '@wordpress/data';
import { useSelect } from '@wordpress/data';
/**
* Internal dependencies
@ -21,7 +20,13 @@ import Header from '../header';
import { PrimaryMenu } from './primary-menu';
import { SecondaryMenu } from './secondary-menu';
const Container = ( { menuItems } ) => {
const Container = () => {
const { menuItems } = useSelect( ( select ) => {
return {
menuItems: select( NAVIGATION_STORE_NAME ).getMenuItems(),
};
} );
useEffect( () => {
// Collapse the original WP Menu.
document.documentElement.classList.remove( 'wp-toolbar' );
@ -50,6 +55,7 @@ const Container = ( { menuItems } ) => {
const matchedItem = getMatchingItem( menuItems );
if ( matchedItem ) {
setActiveItem( matchedItem );
setActiveLevel( matchedItem.parent );
}
}, 0 );
} );
@ -123,12 +129,4 @@ const Container = ( { menuItems } ) => {
);
};
export default compose(
withSelect( ( select ) => {
const { getMenuItems } = select( NAVIGATION_STORE_NAME );
return {
menuItems: getMenuItems(),
};
} )
)( Container );
export default Container;

View File

@ -0,0 +1,252 @@
/**
* External dependencies
*/
import { act, render } from '@testing-library/react';
import { getAdminLink } from '@woocommerce/wc-admin-settings';
import { getHistory } from '@woocommerce/navigation';
import { useSelect } from '@wordpress/data';
import userEvent from '@testing-library/user-event';
/**
* Internal dependencies
*/
import Container from '../';
jest.mock( '@wordpress/data', () => {
// Require the original module to not be mocked...
const originalModule = jest.requireActual( '@wordpress/data' );
return {
__esModule: true, // Use it when dealing with esModules
...originalModule,
useSelect: jest.fn().mockReturnValue( {} ),
};
} );
const originalLocation = window.location;
global.window = Object.create( window );
window.wcNavigation = {
rootBackLabel: 'Root Back',
rootBackUrl: 'http://custombackbutton.com',
};
const menuItems = [
{
id: 'woocommerce-home',
title: 'Home',
parent: 'woocommerce',
menuId: 'primary',
url: 'admin.php?page=wc-admin',
},
{
id: 'primary-category',
title: 'Primary Category',
isCategory: true,
parent: 'woocommerce',
backButtonLabel: 'Custom Back Label',
menuId: 'primary',
},
{
id: 'primary-child',
title: 'Primary Child',
parent: 'primary-category',
menuId: 'primary',
url: 'admin.php?page=wc-admin&path=/child',
},
{
id: 'favorite-category',
title: 'Favorite Category',
isCategory: true,
parent: 'woocommerce',
menuId: 'favorites',
},
{
id: 'favorite-child',
title: 'Favorite Child',
parent: 'favorite-category',
menuId: 'plugins',
},
{
id: 'plugin-category',
title: 'Plugin Category',
isCategory: true,
parent: 'woocommerce',
menuId: 'plugins',
},
{
id: 'plugin-child',
title: 'Plugin Child',
parent: 'plugin-category',
menuId: 'plugins',
url: 'admin.php?page=my-plugin',
},
{
id: 'secondary-category',
title: 'Secondary Category',
isCategory: true,
parent: 'woocommerce',
menuId: 'secondary',
},
{
id: 'secondary-child',
title: 'Secondary Child',
parent: 'secondary-category',
menuId: 'secondary',
},
];
describe( 'Container', () => {
beforeEach( () => {
delete window.location;
window.location = new URL( getAdminLink( 'admin.php?page=wc-admin' ) );
useSelect.mockImplementation( () => ( {
menuItems,
favorites: [ 'favorite-category' ],
} ) );
} );
afterAll( () => {
window.location = originalLocation;
} );
test( 'should show the woocommerce root items initially', () => {
const { container } = render( <Container /> );
expect(
container.querySelectorAll( '.components-navigation__item' ).length
).toBe( 5 );
} );
test( 'should set the active item based on initial location', async () => {
const { queryByText } = render( <Container /> );
expect(
queryByText( 'Home' ).parentElement.parentElement.classList
).toContain( 'is-active' );
} );
test( 'should set the initial active item based on current location', () => {
window.location = new URL( getAdminLink( 'admin.php?page=my-plugin' ) );
const { container, queryByText } = render( <Container /> );
expect(
container.querySelector( '.woocommerce-navigation-category-title' )
.textContent
).toBe( 'Plugin Category' );
expect(
queryByText( 'Plugin Child' ).parentElement.parentElement.classList
).toContain( 'is-active' );
} );
test( 'should update the active item and level when location changes', async () => {
window.location = new URL( getAdminLink( 'admin.php?page=wc-admin' ) );
const { container, queryByText } = render( <Container /> );
expect( queryByText( 'Primary Child' ) ).toBeNull();
// Trigger and wait for history change.
await act( async () => {
delete window.location;
window.location = new URL(
getAdminLink( 'admin.php?page=wc-admin&path=/child' )
);
getHistory().push( getAdminLink( '/child' ) );
await new Promise( ( resolve ) => {
setTimeout( () => {
resolve();
}, 0 );
} );
} );
expect(
container.querySelector( '.woocommerce-navigation-category-title' )
.textContent
).toBe( 'Primary Category' );
expect(
queryByText( 'Primary Child' ).parentElement.parentElement.classList
).toContain( 'is-active' );
} );
test( 'should update the active level when a category is clicked', () => {
const { container, queryByText } = render( <Container /> );
userEvent.click( queryByText( 'Secondary Category' ) );
expect(
container.querySelector( '.woocommerce-navigation-category-title' )
.textContent
).toBe( 'Secondary Category' );
} );
test( 'should show the back button in each category', () => {
const { container, queryByText } = render( <Container /> );
userEvent.click( queryByText( 'Primary Category' ) );
const backButton = container.querySelector(
'.components-navigation__back-button'
);
expect( backButton.textContent ).toBe( 'Custom Back Label' );
} );
test( 'should go up a level on back button click', () => {
const { container, queryByText } = render( <Container /> );
userEvent.click( queryByText( 'Primary Category' ) );
const backButton = container.querySelector(
'.components-navigation__back-button'
);
userEvent.click( backButton );
expect(
container.querySelector( '.woocommerce-navigation-category-title' )
.textContent
).toBe( 'WooCommerce' );
} );
test( 'should show the favorite items after the primary items', () => {
const { container } = render( <Container /> );
const navigationGroups = container.querySelectorAll(
'.components-navigation__group'
);
expect(
navigationGroups[ 0 ].querySelector( 'li:nth-child(1)' ).textContent
).toBe( 'Home' );
expect(
navigationGroups[ 0 ].querySelector( 'li:nth-child(2)' ).textContent
).toBe( 'Primary Category' );
expect(
navigationGroups[ 0 ].querySelector( 'li:nth-child(3)' ).textContent
).toBe( 'Favorite Category' );
expect(
navigationGroups[ 1 ].querySelector( 'li:nth-child(1)' ).textContent
).toBe( 'Plugin Category' );
} );
test( 'should not show multiple menus outside of the root category', () => {
const { container, queryByText } = render( <Container /> );
const rootNavigationGroups = container.querySelectorAll(
'.components-navigation__group'
);
expect( rootNavigationGroups.length ).toBe( 3 );
userEvent.click( queryByText( 'Primary Category' ) );
const categoryNavigationGroups = container.querySelectorAll(
'.components-navigation__group'
);
expect( categoryNavigationGroups.length ).toBe( 1 );
} );
} );

View File

@ -79,6 +79,7 @@ Release and roadmap notes are available on the [WooCommerce Developers Blog](htt
- Add: Add legacy report items to new navigation #6507
- Dev: Add initial tests for navigation Menu class #6492
- Dev: Remove active item from navigation store #6486
- Dev: Add navigation container tests #6464
- Add: Add preview site button on the appearance task #6457
- Fix: Add check for navigating being enabled. #6462
- Dev: Add nav favorite button tests #6446