Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WordAds: Add block tests and fixtures #19129

Merged
merged 1 commit into from
Mar 12, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Significance: minor
Type: enhancement

WordAds: Added block tests and fixtures.
44 changes: 44 additions & 0 deletions projects/plugins/jetpack/extensions/blocks/wordads/controls.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/**
* External dependencies
*/
import { BlockControls, InspectorControls } from '@wordpress/block-editor';
import { PanelBody, ToggleControl } from '@wordpress/components';
import { __ } from '@wordpress/i18n';

/**
* Internal dependencies
*/
import FormatPicker from './format-picker';

export const AdVisibilityToggle = ( { value, onChange } ) => (
<PanelBody title={ __( 'Visibility', 'jetpack' ) }>
<ToggleControl
className="jetpack-wordads__mobile-visibility"
checked={ !! value }
label={ __( 'Hide on mobile', 'jetpack' ) }
help={ __( 'Hides this block for site visitors on mobile devices.', 'jetpack' ) }
onChange={ onChange }
/>
</PanelBody>
);

const AdControls = ( { attributes: { format, hideMobile }, setAttributes } ) => {
return (
<>
<BlockControls>
<FormatPicker
value={ format }
onChange={ nextFormat => setAttributes( { format: nextFormat } ) }
/>
</BlockControls>
<InspectorControls>
<AdVisibilityToggle
value={ hideMobile }
onChange={ hide => setAttributes( { hideMobile: !! hide } ) }
/>
</InspectorControls>
</>
);
};

export default AdControls;
98 changes: 33 additions & 65 deletions projects/plugins/jetpack/extensions/blocks/wordads/edit.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,7 @@
/**
* External dependencies
*/
import { __ } from '@wordpress/i18n';
import { BlockControls, InspectorControls } from '@wordpress/block-editor';
import { Component, Fragment } from '@wordpress/element';
import { PanelBody, ToggleControl } from '@wordpress/components';

/**
* Internal dependencies
*/
import FormatPicker from './format-picker';
import AdControls from './controls';
import { AD_FORMATS } from './constants';

import './editor.scss';
Expand All @@ -22,62 +14,38 @@ import leaderboardExample from './example_728x90.png';
import mobileLeaderboardExample from './example_320x50.png';
import wideSkyscraperExample from './example_160x600.png';

class WordAdsEdit extends Component {
handleHideMobileChange = hideMobile => {
this.props.setAttributes( { hideMobile: !! hideMobile } );
};
const WordAdsEdit = ( { attributes, setAttributes } ) => {
const { format } = attributes;
const selectedFormatObject = AD_FORMATS.find( ( { tag } ) => tag === format );

render() {
const { attributes, setAttributes, isSelected } = this.props;
const { format, hideMobile } = attributes;
const selectedFormatObject = AD_FORMATS.filter( ( { tag } ) => tag === format )[ 0 ];
const adControls = (
<InspectorControls>
<PanelBody title={ __( 'Visibility', 'jetpack' ) }>
<ToggleControl
className="jetpack-wordads__mobile-visibility"
checked={ Boolean( hideMobile ) }
label={ __( 'Hide on mobile', 'jetpack' ) }
help={ __( 'Hides this block for site visitors on mobile devices.', 'jetpack' ) }
onChange={ this.handleHideMobileChange }
/>
</PanelBody>
</InspectorControls>
);
function getExampleAd( formatting ) {
switch ( formatting ) {
case 'leaderboard':
return leaderboardExample;
case 'mobile_leaderboard':
return mobileLeaderboardExample;
case `wideskyscraper`:
return wideSkyscraperExample;
default:
return rectangleExample;
}
const getExampleAd = formatting => {
switch ( formatting ) {
case 'leaderboard':
return leaderboardExample;
case 'mobile_leaderboard':
return mobileLeaderboardExample;
case `wideskyscraper`:
return wideSkyscraperExample;
default:
return rectangleExample;
}
return (
<Fragment>
<BlockControls>
<FormatPicker
value={ format }
onChange={ nextFormat => setAttributes( { format: nextFormat } ) }
/>
</BlockControls>
<div className={ `wp-block-jetpack-wordads jetpack-wordads-${ format }` }>
<div
className="jetpack-wordads__ad"
style={ {
width: selectedFormatObject.width,
height: selectedFormatObject.height,
backgroundImage: `url( ${ getExampleAd( format ) } )`,
backgroundSize: 'cover',
} }
></div>
{ isSelected && adControls }
</div>
</Fragment>
);
}
}
};

return (
<>
<AdControls { ...{ attributes, setAttributes } } />
<div className={ `wp-block-jetpack-wordads jetpack-wordads-${ format }` }>
<div
className="jetpack-wordads__ad"
style={ {
width: selectedFormatObject.width,
height: selectedFormatObject.height,
backgroundImage: `url( ${ getExampleAd( format ) } )`,
backgroundSize: 'cover',
} }
></div>
</div>
</>
);
};
export default WordAdsEdit;
150 changes: 150 additions & 0 deletions projects/plugins/jetpack/extensions/blocks/wordads/test/controls.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
/**
* @jest-environment jsdom
*/

/**
* External dependencies
*/
import '@testing-library/jest-dom/extend-expect';
import userEvent from '@testing-library/user-event';
import { render, screen, waitFor } from '@testing-library/react';

/**
* Internal dependencies
*/
import FormatPicker from '../format-picker';
import { AD_FORMATS, DEFAULT_FORMAT } from '../constants';
import { AdVisibilityToggle } from '../controls';

const getFormat = format => AD_FORMATS.find( ( { tag } ) => tag === format );

describe( 'AdVisibilityToggle', () => {
const onChange = jest.fn();
const defaultProps = { value: false, onChange };
const checkedProps = { value: true, onChange };

beforeEach( () => {
onChange.mockClear();
} );

test( 'renders visibility panel header', () => {
render( <AdVisibilityToggle { ...defaultProps } /> );

expect( screen.getByRole( 'button' ) ).toHaveTextContent( 'Visibility' );
} );

test( 'applies correct class to toggle control', () => {
const { container } = render( <AdVisibilityToggle { ...defaultProps } /> );
const toggle = container.querySelector( '.components-toggle-control' );

expect( toggle ).toHaveClass( 'jetpack-wordads__mobile-visibility' );
} );

test( 'renders unchecked checkbox', () => {
render( <AdVisibilityToggle { ...defaultProps } /> );
const checkbox = screen.getByRole( 'checkbox' );

expect( checkbox ).toBeInTheDocument();
expect( checkbox ).not.toBeChecked();
} );

test( 'renders checked checkbox', () => {
render( <AdVisibilityToggle { ...checkedProps } /> );
const checkbox = screen.getByRole( 'checkbox' );

expect( checkbox ).toBeInTheDocument();
expect( checkbox ).toBeChecked();
} );

test( 'renders supplied label', () => {
render( <AdVisibilityToggle { ...defaultProps } /> );

expect( screen.getByText( 'Hide on mobile' ) ).toBeInTheDocument();
} );

test( 'displays help text', () => {
render( <AdVisibilityToggle { ...defaultProps } /> );
const help = 'Hides this block for site visitors on mobile devices.';

expect( screen.getByText( help ) ).toBeInTheDocument();
} );

test( 'calls onChange when checkbox clicked', () => {
render( <AdVisibilityToggle { ...defaultProps } /> );

userEvent.click( screen.getByRole( 'checkbox' ) );
expect( onChange ).toHaveBeenCalledWith( true );
} );

test( 'calls onChange when label clicked', () => {
render( <AdVisibilityToggle { ...checkedProps } /> );

userEvent.click( screen.getByText( 'Hide on mobile' ) );
expect( onChange ).toHaveBeenCalledWith( false );
} );
} );

describe( 'FormatPicker', () => {
const onChange = jest.fn();
const defaultFormat = getFormat( DEFAULT_FORMAT );
const defaultProps = { value: DEFAULT_FORMAT, onChange };

beforeEach( () => {
onChange.mockClear();
} );

test( 'renders toolbar settings button with formats not visible', () => {
render( <FormatPicker { ...defaultProps } /> );

expect( screen.getByLabelText( 'Pick an ad format' ) ).toBeInTheDocument();
expect( screen.queryByText( defaultFormat.name ) ).not.toBeInTheDocument();
} );

test( 'displays dropdown with available options on toolbar button click', async () => {
render( <FormatPicker { ...defaultProps } /> );

userEvent.click( screen.getByLabelText( 'Pick an ad format' ) );
await waitFor( () => screen.getByText( defaultFormat.name ) );

AD_FORMATS.forEach( format => {
expect( screen.getByText( format.name ) ).toBeInTheDocument();
} );
} );

test( 'selects current format in dropdown', async () => {
render( <FormatPicker { ...defaultProps } /> );

userEvent.click( screen.getByLabelText( 'Pick an ad format' ) );
await waitFor( () => screen.getByText( defaultFormat.name ) );

expect( screen.getByText( defaultFormat.name ) ).toBeChecked();
} );

test( 'applies correct class to toolbar button', () => {
render( <FormatPicker { ...defaultProps } /> );

expect( screen.getByLabelText( 'Pick an ad format' ) ).toHaveClass( 'wp-block-jetpack-wordads__format-picker-icon' );
} );

test( 'applies format picker class to menu', async () => {
render( <FormatPicker { ...defaultProps } /> );

userEvent.click( screen.getByLabelText( 'Pick an ad format' ) );
await waitFor( () => screen.getByText( defaultFormat.name ) );
const menu = screen.getByRole( 'menu' );

expect( menu ).toBeInTheDocument();
expect( menu ).toHaveClass( 'wp-block-jetpack-wordads__format-picker' );
} );

test( 'calls onChange when option is clicked', async () => {
render( <FormatPicker { ...defaultProps } /> );
const leaderboard = getFormat( 'leaderboard' );

userEvent.click( screen.getByLabelText( 'Pick an ad format' ) );
await waitFor( () => screen.getByText( leaderboard.name ) );
userEvent.click( screen.getByText( leaderboard.name ) );

expect( onChange ).toHaveBeenCalledWith( leaderboard.tag );
} );
} );
Loading