From 2c3bf490f26f6ac39fc6ab76472cbb7324e3dde5 Mon Sep 17 00:00:00 2001 From: George Mamadashvili Date: Mon, 20 Mar 2023 12:09:57 +0400 Subject: [PATCH] Plugins: Add unit tests for the 'PluginArea' component (#49138) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Fix typos in the test descriptions * Add an explanation for manual cleanup Co-authored-by: Greg Ziółkowski --- .../src/components/test/plugin-area.js | 121 ++++++++++++++++++ 1 file changed, 121 insertions(+) create mode 100644 packages/plugins/src/components/test/plugin-area.js diff --git a/packages/plugins/src/components/test/plugin-area.js b/packages/plugins/src/components/test/plugin-area.js new file mode 100644 index 00000000000000..68ed2b5368d032 --- /dev/null +++ b/packages/plugins/src/components/test/plugin-area.js @@ -0,0 +1,121 @@ +/** + * External dependencies + */ +import { act, render, cleanup } from '@testing-library/react'; + +/** + * Internal dependencies + */ +import { getPlugins, unregisterPlugin, registerPlugin } from '../../api'; +import PluginArea from '../plugin-area'; + +describe( 'PluginArea', () => { + afterEach( () => { + // Unmount components before unregistering the plugins. + // RTL uses top-level `afterEach` for cleanup, executed after this teardown. + cleanup(); + getPlugins().forEach( ( plugin ) => { + unregisterPlugin( plugin.name ); + } ); + getPlugins( 'my-app' ).forEach( ( plugin ) => { + unregisterPlugin( plugin.name ); + } ); + } ); + + const TestComponent = ( { content } ) => { + return `plugin: ${ content }.`; + }; + + test( 'renders unscoped plugin', () => { + registerPlugin( 'unscoped', { + render: () => , + icon: 'smiley', + } ); + + const { container } = render( ); + + expect( container ).toHaveTextContent( 'plugin: unscoped.' ); + } ); + + test( 'renders scoped plugin', () => { + registerPlugin( 'scoped', { + render: () => , + icon: 'smiley', + scope: 'my-app', + } ); + + const { container } = render( ); + + expect( container ).toHaveTextContent( 'plugin: scoped.' ); + } ); + + test( 'rerenders when a new plugin is registered', () => { + registerPlugin( 'foo', { + render: () => , + icon: 'smiley', + scope: 'my-app', + } ); + + const { container } = render( ); + + act( () => { + registerPlugin( 'bar', { + render: () => , + icon: 'smiley', + scope: 'my-app', + } ); + } ); + + expect( container ).toHaveTextContent( 'plugin: bar.' ); + } ); + + test( 'rerenders when a plugin is unregistered', () => { + registerPlugin( 'one', { + render: () => , + icon: 'smiley', + scope: 'my-app', + } ); + registerPlugin( 'two', { + render: () => , + icon: 'smiley', + scope: 'my-app', + } ); + + const { container } = render( ); + + expect( container ).toHaveTextContent( 'plugin: one.plugin: two.' ); + + act( () => { + unregisterPlugin( 'one' ); + } ); + + expect( container ).toHaveTextContent( 'plugin: two.' ); + } ); + + test.failing( + 'does not rerender when a plugin is added to a different scope', + () => { + const ComponentSpy = jest.fn( ( { content } ) => { + return `plugin: ${ content }.`; + } ); + + registerPlugin( 'scoped', { + render: () => , + icon: 'smiley', + scope: 'my-app', + } ); + + render( ); + + act( () => { + registerPlugin( 'unscoped', { + render: () => , + icon: 'smiley', + } ); + } ); + + // Any store update triggers setState and causes PluginArea to rerender. + expect( ComponentSpy ).toHaveBeenCalledTimes( 1 ); + } + ); +} );