/**
* External dependencies
*/
import { act, render, waitFor } 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';
import { createElement } from '@wordpress/element';
/**
* 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( );
expect(
container.querySelectorAll( '.components-navigation__item' ).length
).toBe( 5 );
} );
test( 'should set the active item based on initial location', async () => {
const { queryByText } = render( );
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( );
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( );
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 waitFor( () =>
expect(
container.querySelector(
'.woocommerce-navigation-category-title'
).textContent
).toBe( 'Primary Category' )
);
await waitFor( () =>
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( );
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( );
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( );
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( );
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( );
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 );
} );
} );