Skip to content

Commit

Permalink
Block Editor: Improve ImageSizeControl tests (#46765)
Browse files Browse the repository at this point in the history
  • Loading branch information
tyxla authored Dec 23, 2022
1 parent 52f3db6 commit 783ae6a
Showing 1 changed file with 147 additions and 79 deletions.
226 changes: 147 additions & 79 deletions packages/block-editor/src/components/image-size-control/test/index.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
/**
* External dependencies
*/
import { render, screen, fireEvent } from '@testing-library/react';
import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';

/**
* Internal dependencies
Expand All @@ -11,8 +12,6 @@ import ImageSizeControl from '../index';
describe( 'ImageSizeControl', () => {
const mockOnChange = jest.fn();
const mockOnChangeImage = jest.fn();
const getHeightInput = () => screen.getByLabelText( 'Height' );
const getWidthInput = () => screen.getByLabelText( 'Width' );

afterEach( () => {
// Cleanup on exiting.
Expand All @@ -31,8 +30,12 @@ describe( 'ImageSizeControl', () => {
/>
);

expect( getHeightInput().value ).toBe( '300' );
expect( getWidthInput().value ).toBe( '400' );
expect(
screen.getByRole( 'spinbutton', { name: 'Height' } )
).toHaveValue( 300 );
expect(
screen.getByRole( 'spinbutton', { name: 'Width' } )
).toHaveValue( 400 );
} );

it( 'returns default dimensions when custom dimensions are undefined', () => {
Expand All @@ -44,15 +47,23 @@ describe( 'ImageSizeControl', () => {
/>
);

expect( getHeightInput().value ).toBe( '100' );
expect( getWidthInput().value ).toBe( '200' );
expect(
screen.getByRole( 'spinbutton', { name: 'Height' } )
).toHaveValue( 100 );
expect(
screen.getByRole( 'spinbutton', { name: 'Width' } )
).toHaveValue( 200 );
} );

it( 'returns empty string when custom and default dimensions are undefined', () => {
it( 'returns no value when custom and default dimensions are undefined', () => {
render( <ImageSizeControl onChange={ mockOnChange } /> );

expect( getHeightInput().value ).toBe( '' );
expect( getWidthInput().value ).toBe( '' );
expect(
screen.getByRole( 'spinbutton', { name: 'Height' } )
).toHaveValue( null );
expect(
screen.getByRole( 'spinbutton', { name: 'Width' } )
).toHaveValue( null );
} );

it( 'returns default dimensions when initially undefined defaults are defined on rerender', () => {
Expand All @@ -62,12 +73,14 @@ describe( 'ImageSizeControl', () => {
<ImageSizeControl onChange={ mockOnChange } />
);

const heightInput = getHeightInput();
const widthInput = getWidthInput();
const heightInput = screen.getByRole( 'spinbutton', {
name: 'Height',
} );
const widthInput = screen.getByRole( 'spinbutton', { name: 'Width' } );

// The dimensions are initially set to an empty string.
expect( heightInput.value ).toBe( '' );
expect( widthInput.value ).toBe( '' );
expect( heightInput ).toHaveValue( null );
expect( widthInput ).toHaveValue( null );

// When new default dimensions are passed on a rerender (for example after they
// are calculated following an image upload), update values to the new defaults.
Expand All @@ -80,48 +93,66 @@ describe( 'ImageSizeControl', () => {
);

// The dimensions should update to the defaults.
expect( heightInput.value ).toBe( '300' );
expect( widthInput.value ).toBe( '400' );
expect( heightInput ).toHaveValue( 300 );
expect( widthInput ).toHaveValue( 400 );
} );

describe( 'updating dimension inputs', () => {
it( 'updates height and calls onChange', () => {
it( 'updates height and calls onChange', async () => {
const user = userEvent.setup();
render( <ImageSizeControl onChange={ mockOnChange } /> );

const heightInput = getHeightInput();
const widthInput = getWidthInput();
const heightInput = screen.getByRole( 'spinbutton', {
name: 'Height',
} );
const widthInput = screen.getByRole( 'spinbutton', {
name: 'Width',
} );

expect( heightInput.value ).toBe( '' );
expect( widthInput.value ).toBe( '' );
expect( heightInput ).toHaveValue( null );
expect( widthInput ).toHaveValue( null );

fireEvent.change( heightInput, { target: { value: '500' } } );
const newHeight = '500';

expect( mockOnChange ).toHaveBeenCalledTimes( 1 );
expect( mockOnChange ).toHaveBeenCalledWith( { height: 500 } );
await user.clear( heightInput );
await user.type( heightInput, newHeight );

expect( heightInput.value ).toBe( '500' );
expect( widthInput.value ).toBe( '' );
expect( mockOnChange ).toHaveBeenCalledTimes( newHeight.length );
expect( mockOnChange ).toHaveBeenLastCalledWith( { height: 500 } );

expect( heightInput ).toHaveValue( 500 );
expect( widthInput ).toHaveValue( null );
} );

it( 'updates width and calls onChange', () => {
it( 'updates width and calls onChange', async () => {
const user = userEvent.setup();

render( <ImageSizeControl onChange={ mockOnChange } /> );

const heightInput = getHeightInput();
const widthInput = getWidthInput();
const heightInput = screen.getByRole( 'spinbutton', {
name: 'Height',
} );
const widthInput = screen.getByRole( 'spinbutton', {
name: 'Width',
} );

expect( heightInput.value ).toBe( '' );
expect( widthInput.value ).toBe( '' );
expect( heightInput ).toHaveValue( null );
expect( widthInput ).toHaveValue( null );

fireEvent.change( widthInput, { target: { value: '500' } } );
const newWidth = '500';
await user.clear( widthInput );
await user.type( widthInput, newWidth );

expect( mockOnChange ).toHaveBeenCalledTimes( 1 );
expect( mockOnChange ).toHaveBeenCalledWith( { width: 500 } );
expect( mockOnChange ).toHaveBeenCalledTimes( newWidth.length );
expect( mockOnChange ).toHaveBeenLastCalledWith( { width: 500 } );

expect( heightInput.value ).toBe( '' );
expect( widthInput.value ).toBe( '500' );
expect( heightInput ).toHaveValue( null );
expect( widthInput ).toHaveValue( 500 );
} );

it( 'updates height and calls onChange for empty value', () => {
it( 'updates height and calls onChange for empty value', async () => {
const user = userEvent.setup();

render(
<ImageSizeControl
imageHeight="100"
Expand All @@ -130,27 +161,33 @@ describe( 'ImageSizeControl', () => {
/>
);

const heightInput = getHeightInput();
const widthInput = getWidthInput();
const heightInput = screen.getByRole( 'spinbutton', {
name: 'Height',
} );
const widthInput = screen.getByRole( 'spinbutton', {
name: 'Width',
} );

expect( heightInput.value ).toBe( '100' );
expect( widthInput.value ).toBe( '100' );
expect( heightInput ).toHaveValue( 100 );
expect( widthInput ).toHaveValue( 100 );

fireEvent.change( heightInput, { target: { value: '' } } );
await user.clear( heightInput );

// onChange is called and sets the dimension to undefined rather than
// the empty string.
expect( mockOnChange ).toHaveBeenCalledTimes( 1 );
expect( mockOnChange ).toHaveBeenCalledWith( {
expect( mockOnChange ).toHaveBeenLastCalledWith( {
height: undefined,
} );

// Height is updated to empty value and does not reset to default.
expect( heightInput.value ).toBe( '' );
expect( widthInput.value ).toBe( '100' );
expect( heightInput ).toHaveValue( null );
expect( widthInput ).toHaveValue( 100 );
} );

it( 'updates width and calls onChange for empty value', () => {
it( 'updates width and calls onChange for empty value', async () => {
const user = userEvent.setup();

render(
<ImageSizeControl
imageHeight="100"
Expand All @@ -159,29 +196,35 @@ describe( 'ImageSizeControl', () => {
/>
);

const heightInput = getHeightInput();
const widthInput = getWidthInput();
const heightInput = screen.getByRole( 'spinbutton', {
name: 'Height',
} );
const widthInput = screen.getByRole( 'spinbutton', {
name: 'Width',
} );

expect( heightInput.value ).toBe( '100' );
expect( widthInput.value ).toBe( '100' );
expect( heightInput ).toHaveValue( 100 );
expect( widthInput ).toHaveValue( 100 );

fireEvent.change( widthInput, { target: { value: '' } } );
await user.clear( widthInput );

// onChange is called and sets the dimension to undefined rather than
// the empty string.
expect( mockOnChange ).toHaveBeenCalledTimes( 1 );
expect( mockOnChange ).toHaveBeenCalledWith( {
expect( mockOnChange ).toHaveBeenLastCalledWith( {
width: undefined,
} );

// Width is updated to empty value and does not reset to default.
expect( heightInput.value ).toBe( '100' );
expect( widthInput.value ).toBe( '' );
expect( heightInput ).toHaveValue( 100 );
expect( widthInput ).toHaveValue( null );
} );
} );

describe( 'reset button', () => {
it( 'resets both height and width to default values', () => {
it( 'resets both height and width to default values', async () => {
const user = userEvent.setup();

render(
<ImageSizeControl
imageHeight="100"
Expand All @@ -192,29 +235,35 @@ describe( 'ImageSizeControl', () => {
/>
);

const heightInput = getHeightInput();
const widthInput = getWidthInput();
const heightInput = screen.getByRole( 'spinbutton', {
name: 'Height',
} );
const widthInput = screen.getByRole( 'spinbutton', {
name: 'Width',
} );

// The initial dimension values display first.
expect( heightInput.value ).toBe( '300' );
expect( widthInput.value ).toBe( '400' );
expect( heightInput ).toHaveValue( 300 );
expect( widthInput ).toHaveValue( 400 );

fireEvent.click( screen.getByText( 'Reset' ) );
await user.click( screen.getByRole( 'button', { name: 'Reset' } ) );

// Both attributes are set to undefined to clear custom values.
expect( mockOnChange ).toHaveBeenCalledWith( {
expect( mockOnChange ).toHaveBeenLastCalledWith( {
height: undefined,
width: undefined,
} );

// The inputs display the default values once more.
expect( heightInput.value ).toBe( '100' );
expect( widthInput.value ).toBe( '200' );
expect( heightInput ).toHaveValue( 100 );
expect( widthInput ).toHaveValue( 200 );
} );
} );

describe( 'image size percentage presets', () => {
it( 'updates height and width attributes on selection', () => {
it( 'updates height and width attributes on selection', async () => {
const user = userEvent.setup();

render(
<ImageSizeControl
imageHeight="100"
Expand All @@ -223,18 +272,25 @@ describe( 'ImageSizeControl', () => {
/>
);

fireEvent.click( screen.getByText( '50%' ) );
const button = screen.getByRole( 'button', {
name: '50%',
pressed: false,
} );

await user.click( button );

expect( screen.getByText( '50%' ) ).toHaveClass( 'is-pressed' );
expect( button ).toHaveClass( 'is-pressed' );

// Both attributes are set to the rounded scaled value.
expect( mockOnChange ).toHaveBeenCalledWith( {
expect( mockOnChange ).toHaveBeenLastCalledWith( {
height: 50,
width: 101,
} );
} );

it( 'updates height and width inputs on selection', () => {
it( 'updates height and width inputs on selection', async () => {
const user = userEvent.setup();

render(
<ImageSizeControl
imageHeight="100"
Expand All @@ -243,11 +299,20 @@ describe( 'ImageSizeControl', () => {
/>
);

fireEvent.click( screen.getByText( '50%' ) );
const button = screen.getByRole( 'button', {
name: '50%',
pressed: false,
} );

await user.click( button );

// Both attributes are set to the rounded scaled value.
expect( getHeightInput().value ).toBe( '50' );
expect( getWidthInput().value ).toBe( '101' );
expect(
screen.getByRole( 'spinbutton', { name: 'Height' } )
).toHaveValue( 50 );
expect(
screen.getByRole( 'spinbutton', { name: 'Width' } )
).toHaveValue( 101 );
} );
} );

Expand All @@ -268,12 +333,14 @@ describe( 'ImageSizeControl', () => {
/>
);

expect( screen.getByLabelText( 'Image size' ).value ).toBe(
'medium'
);
expect(
screen.getByRole( 'combobox', { name: 'Image size' } )
).toHaveValue( 'medium' );
} );

it( 'calls onChangeImage with selected slug on selection', () => {
it( 'calls onChangeImage with selected slug on selection', async () => {
const user = userEvent.setup();

render(
<ImageSizeControl
imageSizeOptions={ IMAGE_SIZE_OPTIONS }
Expand All @@ -283,12 +350,13 @@ describe( 'ImageSizeControl', () => {
/>
);

fireEvent.change( screen.getByLabelText( 'Image size' ), {
target: { value: 'thumbnail' },
} );
await user.selectOptions(
screen.getByRole( 'combobox', { name: 'Image size' } ),
'thumbnail'
);

// onChangeImage is called with the slug and the event.
expect( mockOnChangeImage ).toHaveBeenCalledWith(
expect( mockOnChangeImage ).toHaveBeenLastCalledWith(
'thumbnail',
expect.any( Object )
);
Expand Down

0 comments on commit 783ae6a

Please sign in to comment.