woocommerce/plugins/woocommerce-admin/client/navigation/components/container/test/index.js

254 lines
6.4 KiB
JavaScript
Raw Normal View History

/**
* External dependencies
*/
import { act, render, waitFor } from '@testing-library/react';
import { getAdminLink } from '@woocommerce/settings';
import { getHistory } from '@woocommerce/navigation';
import { useSelect } from '@wordpress/data';
import userEvent from '@testing-library/user-event';
Allow packages to be built in isolation. (https://github.com/woocommerce/woocommerce-admin/pull/7286) * Use yarn instead of npm. In prep for workspaces, since we're locked to npm < 7. See: https://github.com/woocommerce/woocommerce-admin/pull/7126#issue-661287749 * Initial workspace creation. * Add initial tsc build to @woocommerce/number. * Attempt to build experimental package. * Try currency package. * Define all packages as workspaces. * Use tsconfig common to packages. * Fix currency package build. * Build csv-export with tsc. * Try to build customer-effort-score with tsc. * Fix JSX pragma. * Build data package with tsc. * Build date package with tsc. * Build experimental package with tsc. * Try to build explat package with tsc. * Build navigation package with tsc. * Build notices package with tsc. * Build onboarding package with tsc. * Build components package with tsc. * Swap in package JS build into main script. * Fix experimental package build. * Try per-package css build with components. * Try to run components package tests in isolation. Broken on JSX in test files not being transformed. * Move @woocommerce/wc-admin-settings into a package. * Try to fix components package tests. Fails because we aren't setting up the jest/jest-dom globals. * Move JS test code to reusable (private) package. * Enable incremental TS builds. * Use workspaces to run JS tests. * Use new jest configs for update snapshot scripts. * Fix style builds. * Fix package version in components. * Fix client test debug and watch scripts. * Update yarn lock. * Update test-staged behavior. * Try to fix storybook. * Fix storybook. * Update more npm commands to yarn. * Add changelog. * Fix lint errors. * Update packages readme script references. * Clean up unused gitignore match. * Fix another npm command. * Fix JS builds on watch. * Fix start script. * Fix start scripts for packages. * Use tsc to build packages before tests * yarn -> npm. # Conflicts: # package-lock.json # package.json * Fix linter error. * Remove workspace definitions. * Fix missing Fragment import. * Fix package lock. * Fix missing reference. * Only build commonjs module for js-tests helper. * Remove errant dependency from components. * Remove noop scripts. * Fix package JS build before testing. * Revert noisy formatting changes. * Fix precommit and test scripts. * Fix minimum expected recommended extension count. Japan test case breaks this. * Revert babel config changes. * chore(release): publish - @woocommerce/components@7.2.0 - @woocommerce/csv-export@1.4.0 - @woocommerce/currency@3.2.0 - @woocommerce/customer-effort-score@1.1.0 - @woocommerce/data@1.4.0 - @woocommerce/date@3.1.0 - @woocommerce/dependency-extraction-webpack-plugin@1.7.0 - @woocommerce/eslint-plugin@1.3.0 - @woocommerce/experimental@1.5.0 - @woocommerce/explat@1.1.0 - @woocommerce/js-tests@1.1.0 - @woocommerce/navigation@6.1.0 - @woocommerce/notices@3.1.0 - @woocommerce/number@2.2.0 - @woocommerce/onboarding@1.1.0 - @woocommerce/tracks@1.1.0 - @woocommerce/wc-admin-settings@1.1.0 * Add script for running 'start' in a package. * Remove yarn from gitignore. * Update package changelogs, prep versions for release. * Try to fix E2E tests after main merge. * Some cleanup. * Add changelog. Co-authored-by: Paul Sealock <psealock@gmail.com>
2021-07-14 20:38:57 +00:00
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( <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' )
);
2022-05-19 22:00:26 +00:00
getHistory().push( new URL( 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( <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 );
} );
} );