UNPKG

@wordpress/block-library

Version:
233 lines (196 loc) 5.94 kB
/** * @jest-environment jsdom */ /** * External dependencies */ import { render, screen, fireEvent } from '@testing-library/react'; /** * Internal dependencies */ import { Controls } from '../controls'; // Mock the updateAttributes function let mockUpdateAttributes; jest.mock( '../update-attributes', () => ( { updateAttributes: ( ...args ) => mockUpdateAttributes( ...args ), } ) ); // Mock the useToolsPanelDropdownMenuProps hook jest.mock( '../../../utils/hooks', () => ( { useToolsPanelDropdownMenuProps: () => ( {} ), } ) ); // Mock the useEntityBinding hook jest.mock( '../use-entity-binding', () => ( { useEntityBinding: jest.fn( () => ( { hasUrlBinding: false, isBoundEntityAvailable: false, clearBinding: jest.fn(), } ) ), } ) ); describe( 'Controls', () => { // Initialize the mock function beforeAll( () => { mockUpdateAttributes = jest.fn(); } ); const defaultProps = { attributes: { label: 'Test Link', url: 'https://example.com', description: 'Test description', rel: 'nofollow', opensInNewTab: false, }, setAttributes: jest.fn(), setIsEditingControl: jest.fn(), clientId: 'test-client-id', }; beforeEach( () => { jest.clearAllMocks(); mockUpdateAttributes.mockClear(); } ); it( 'renders all form controls', () => { render( <Controls { ...defaultProps } /> ); expect( screen.getByLabelText( 'Text' ) ).toBeInTheDocument(); expect( screen.getByText( 'Link to' ) ).toBeInTheDocument(); expect( screen.getByLabelText( 'Open in new tab' ) ).toBeInTheDocument(); expect( screen.getByLabelText( 'Description' ) ).toBeInTheDocument(); expect( screen.getByLabelText( 'Rel attribute' ) ).toBeInTheDocument(); } ); it( 'strips HTML from label values', () => { const propsWithHtml = { ...defaultProps, attributes: { ...defaultProps.attributes, label: '<strong>Bold Text</strong>', }, }; render( <Controls { ...propsWithHtml } /> ); const textInput = screen.getByLabelText( 'Text' ); expect( textInput.value ).toBe( 'Bold Text' ); } ); it( 'handles all form field changes correctly', () => { render( <Controls { ...defaultProps } /> ); // Test text change const textInput = screen.getByLabelText( 'Text' ); fireEvent.change( textInput, { target: { value: 'New Label' } } ); expect( defaultProps.setAttributes ).toHaveBeenCalledWith( { label: 'New Label', } ); // Test description change const descriptionInput = screen.getByLabelText( 'Description' ); fireEvent.change( descriptionInput, { target: { value: 'New Description' }, } ); expect( defaultProps.setAttributes ).toHaveBeenCalledWith( { description: 'New Description', } ); // Test rel change const relInput = screen.getByLabelText( 'Rel attribute' ); fireEvent.change( relInput, { target: { value: 'nofollow noopener' }, } ); expect( defaultProps.setAttributes ).toHaveBeenCalledWith( { rel: 'nofollow noopener', } ); // Test checkbox change const checkbox = screen.getByLabelText( 'Open in new tab' ); fireEvent.click( checkbox ); expect( defaultProps.setAttributes ).toHaveBeenCalledWith( { opensInNewTab: true, } ); } ); describe( 'URL binding help text', () => { it( 'shows help text when URL is bound to an entity', () => { const { useEntityBinding } = require( '../use-entity-binding' ); useEntityBinding.mockReturnValue( { hasUrlBinding: true, isBoundEntityAvailable: true, clearBinding: jest.fn(), } ); const propsWithBinding = { ...defaultProps, attributes: { ...defaultProps.attributes, type: 'page', kind: 'post-type', }, }; render( <Controls { ...propsWithBinding } /> ); expect( screen.getByText( 'Synced with the selected page.' ) ).toBeInTheDocument(); } ); it( 'shows help text for different entity types', () => { const { useEntityBinding } = require( '../use-entity-binding' ); useEntityBinding.mockReturnValue( { hasUrlBinding: true, isBoundEntityAvailable: true, clearBinding: jest.fn(), } ); const propsWithCategoryBinding = { ...defaultProps, attributes: { ...defaultProps.attributes, type: 'category', kind: 'taxonomy', }, }; render( <Controls { ...propsWithCategoryBinding } /> ); expect( screen.getByText( 'Synced with the selected category.' ) ).toBeInTheDocument(); } ); it( 'does not show help text when URL is not bound', () => { const { useEntityBinding } = require( '../use-entity-binding' ); useEntityBinding.mockReturnValue( { hasUrlBinding: false, clearBinding: jest.fn(), } ); render( <Controls { ...defaultProps } /> ); expect( screen.queryByText( /Synced with the selected/ ) ).not.toBeInTheDocument(); } ); it( 'shows help text for post entity type', () => { const { useEntityBinding } = require( '../use-entity-binding' ); useEntityBinding.mockReturnValue( { hasUrlBinding: true, isBoundEntityAvailable: true, clearBinding: jest.fn(), } ); const propsWithPostBinding = { ...defaultProps, attributes: { ...defaultProps.attributes, type: 'post', kind: 'post-type', }, }; render( <Controls { ...propsWithPostBinding } /> ); expect( screen.getByText( 'Synced with the selected post.' ) ).toBeInTheDocument(); } ); it( 'shows help text for tag entity type', () => { const { useEntityBinding } = require( '../use-entity-binding' ); useEntityBinding.mockReturnValue( { hasUrlBinding: true, isBoundEntityAvailable: true, clearBinding: jest.fn(), } ); const propsWithTagBinding = { ...defaultProps, attributes: { ...defaultProps.attributes, type: 'tag', kind: 'taxonomy', }, }; render( <Controls { ...propsWithTagBinding } /> ); expect( screen.getByText( 'Synced with the selected tag.' ) ).toBeInTheDocument(); } ); } ); } );