diff --git a/projects/plugins/jetpack/changelog/add-image-compare-block-tests b/projects/plugins/jetpack/changelog/add-image-compare-block-tests new file mode 100644 index 0000000000000..348e569fe3852 --- /dev/null +++ b/projects/plugins/jetpack/changelog/add-image-compare-block-tests @@ -0,0 +1,4 @@ +Significance: minor +Type: enhancement + +Image Compare: Add block tests and fixtures. diff --git a/projects/plugins/jetpack/extensions/blocks/image-compare/controls.js b/projects/plugins/jetpack/extensions/blocks/image-compare/controls.js new file mode 100644 index 0000000000000..38f3cef427408 --- /dev/null +++ b/projects/plugins/jetpack/extensions/blocks/image-compare/controls.js @@ -0,0 +1,21 @@ +/** + * External dependencies + */ +import { PanelBody, RadioControl } from '@wordpress/components'; +import { __ } from '@wordpress/i18n'; + +export default function ImageCompareControls( { attributes, setAttributes } ) { + const { orientation } = attributes; + return ( + + setAttributes( { orientation: value } ) } + /> + + ); +} diff --git a/projects/plugins/jetpack/extensions/blocks/image-compare/edit.js b/projects/plugins/jetpack/extensions/blocks/image-compare/edit.js index 076246080c132..f12ad0042a28d 100644 --- a/projects/plugins/jetpack/extensions/blocks/image-compare/edit.js +++ b/projects/plugins/jetpack/extensions/blocks/image-compare/edit.js @@ -2,7 +2,7 @@ * External dependencies */ import { InspectorControls, RichText } from '@wordpress/block-editor'; -import { PanelBody, Placeholder, RadioControl } from '@wordpress/components'; +import { Placeholder } from '@wordpress/components'; import { useResizeObserver } from '@wordpress/compose'; import { useLayoutEffect } from '@wordpress/element'; import { __ } from '@wordpress/i18n'; @@ -11,6 +11,7 @@ import { __ } from '@wordpress/i18n'; * Internal dependencies */ import { photonizedImgProps } from '../tiled-gallery/utils'; +import ImageCompareControls from './controls'; import ImgUpload from './img-upload'; import useDebounce from './use-debounce'; import './editor.scss'; @@ -48,7 +49,7 @@ const Edit = ( { attributes, className, clientId, isSelected, setAttributes } ) } // Initial state if attributes already set or not. - // If both images are set, add juxtaspose class, which is picked up by the library. + // If both images are set, add juxtapose class, which is picked up by the library. const isComplete = imageBefore && imageBefore.url && imageAfter && imageAfter.url; const classes = isComplete ? 'image-compare__comparison juxtapose' : 'image-compare__placeholder'; @@ -63,20 +64,7 @@ const Edit = ( { attributes, className, clientId, isSelected, setAttributes } )
{ resizeListener } - - { - setAttributes( { - orientation: value, - } ); - } } - /> - +
diff --git a/projects/plugins/jetpack/extensions/blocks/image-compare/img-upload.js b/projects/plugins/jetpack/extensions/blocks/image-compare/img-upload.js index 76ec4c4b08893..df18dfc3ffba8 100644 --- a/projects/plugins/jetpack/extensions/blocks/image-compare/img-upload.js +++ b/projects/plugins/jetpack/extensions/blocks/image-compare/img-upload.js @@ -6,8 +6,8 @@ import { MediaPlaceholder } from '@wordpress/block-editor'; import { withNotices } from '@wordpress/components'; import { Fragment } from '@wordpress/element'; -const ImgUpload = props => { - const { image, noticeOperations, noticeUI, onChange, placeHolderTitle, placeHolderLabel } = props; +export const ImgUpload = props => { + const { image, noticeOperations, noticeUI, onChange, placeHolderLabel } = props; const renderImage = {; diff --git a/projects/plugins/jetpack/extensions/blocks/image-compare/test/controls.js b/projects/plugins/jetpack/extensions/blocks/image-compare/test/controls.js new file mode 100644 index 0000000000000..90dd0e2e9aea0 --- /dev/null +++ b/projects/plugins/jetpack/extensions/blocks/image-compare/test/controls.js @@ -0,0 +1,55 @@ +/** + * @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 ImageCompareControls from '../controls'; + +describe( 'ImageCompareControls', () => { + const setAttributes = jest.fn(); + const defaultProps = { + attributes: { orientation: undefined }, + setAttributes, + }; + + beforeEach( () => { + setAttributes.mockClear(); + } ); + + test( 'loads and displays orientation controls', () => { + render( ); + + expect( screen.getByText( 'Orientation' ) ).toBeInTheDocument(); + expect( screen.getByLabelText( 'Side by side' ) ).toBeInTheDocument(); + expect( screen.getByLabelText( 'Above and below' ) ).toBeInTheDocument(); + } ); + + test( 'defaults orientation selection to horizontal', () => { + render( ); + + expect( screen.getByLabelText( 'Side by side' ) ).toHaveAttribute( 'checked' ); + } ); + + test( 'selects option according to orientation attribute', () => { + const attributes = { orientation: 'vertical' }; + render( ); + + expect( screen.getByLabelText( 'Above and below' ) ).toHaveAttribute( 'checked' ); + } ); + + test( 'sets the orientation attribute ', () => { + render( ) + userEvent.click( screen.getByLabelText( 'Above and below' ) ); + + expect( setAttributes ).toHaveBeenCalledWith( { orientation: 'vertical' } ); + } ); +} ); diff --git a/projects/plugins/jetpack/extensions/blocks/image-compare/test/edit.js b/projects/plugins/jetpack/extensions/blocks/image-compare/test/edit.js new file mode 100644 index 0000000000000..949d585a29903 --- /dev/null +++ b/projects/plugins/jetpack/extensions/blocks/image-compare/test/edit.js @@ -0,0 +1,112 @@ +/** + * @jest-environment jsdom + */ + +/** + * External dependencies + */ +import '@testing-library/jest-dom/extend-expect'; +import { render, screen, waitFor } from '@testing-library/react'; + +/** + * Internal dependencies + */ +import ImageCompareEdit from '../edit'; + +function renderImageCompare( props ) { + const { container } = render( ); + return container.querySelector( `.${ props.className } > div` ); +} + +describe( 'ImageCompareEdit', () => { + const emptyImages = { imageBefore: {}, imageAfter: {} }; + const defaultAttributes = { + orientation: undefined, + imageBefore: { + id: 1, + url: 'http://test.com/1.jpg', + alt: 'Test image one', + }, + imageAfter: { + id: 2, + url: 'http://test.com/2.jpg', + alt: 'Test image two', + }, + caption: 'Default caption', + }; + + const defaultProps = { + attributes: defaultAttributes, + isSelected: true, + className: 'custom-image-compare-class', + clientId: '1', + }; + + test( 'applies correct attributes to block wrapper', () => { + render( ); + const wrapper = screen.getByRole( 'figure' ); + + expect( wrapper ).toHaveClass( defaultProps.className ); + expect( wrapper ).toHaveAttribute( 'id', defaultProps.clientId ); + } ) + + test( 'applies juxtapose classes when images present', () => { + const element = renderImageCompare( defaultProps ); + + expect( element ).toHaveClass( 'image-compare__comparison' ); + expect( element ).toHaveClass( 'juxtapose' ); + expect( element ).not.toHaveClass( 'image-compare__placeholder' ); + } ); + + test( 'applies placeholder classes when without images', () => { + const attributes = { ...defaultAttributes, ...emptyImages }; + const element = renderImageCompare( { ...defaultProps, attributes } ); + + expect( element ).not.toHaveClass( 'image-compare__comparison' ); + expect( element ).not.toHaveClass( 'juxtapose' ); + expect( element ).toHaveClass( 'image-compare__placeholder' ); + } ); + + test( 'applies fallback horizontal orientation in data-mode attribute', () => { + const element = renderImageCompare( defaultProps ); + + expect( element ).toHaveAttribute( 'data-mode', 'horizontal' ); + } ); + + test( 'applies selected orientation in data-mode attribute', () => { + const attributes = { ...defaultAttributes, orientation: 'vertical' }; + const element = renderImageCompare( { ...defaultProps, attributes } ); + + expect( element ).toHaveAttribute( 'data-mode', 'vertical' ); + } ); + + test( 'displays Placeholder without selected images', () => { + const attributes = { ...defaultAttributes, ...emptyImages }; + render( ); + + expect( screen.getByText( 'Image before' ) ).toBeInTheDocument(); + expect( screen.getByText( 'Image after' ) ).toBeInTheDocument(); + } ); + + test( 'displays caption component when selected and images present', () => { + const attributes = { ...defaultAttributes, caption: undefined }; + render( ); + + expect( screen.getByLabelText( 'Write caption' ) ).toBeInTheDocument(); + } ); + + test( 'displays caption component when attribute set and block not selected', () => { + render( ); + const caption = screen.getByLabelText( 'Write caption' ); + + expect( caption ).toBeInTheDocument(); + expect( caption ).toHaveTextContent( defaultAttributes.caption ); + } ); + + test( 'caption hidden when no value set and block not selected', () => { + const attributes = { ...defaultAttributes, caption: undefined }; + render( ); + + expect( screen.queryByLabelText( 'Write caption' ) ).not.toBeInTheDocument(); + } ); +} ); diff --git a/projects/plugins/jetpack/extensions/blocks/image-compare/test/fixtures/jetpack__image-compare.html b/projects/plugins/jetpack/extensions/blocks/image-compare/test/fixtures/jetpack__image-compare.html new file mode 100644 index 0000000000000..df86dd92a0013 --- /dev/null +++ b/projects/plugins/jetpack/extensions/blocks/image-compare/test/fixtures/jetpack__image-compare.html @@ -0,0 +1,4 @@ + +
+ + diff --git a/projects/plugins/jetpack/extensions/blocks/image-compare/test/fixtures/jetpack__image-compare.json b/projects/plugins/jetpack/extensions/blocks/image-compare/test/fixtures/jetpack__image-compare.json new file mode 100644 index 0000000000000..cc05d5c1cfc78 --- /dev/null +++ b/projects/plugins/jetpack/extensions/blocks/image-compare/test/fixtures/jetpack__image-compare.json @@ -0,0 +1,26 @@ +[ + { + "clientId": "_clientId_0", + "name": "jetpack/image-compare", + "isValid": true, + "attributes": { + "imageBefore": { + "id": 181, + "url": "http://localhost:4759/wp-content/uploads/2021/03/jorge-gardner-hsU_aix2rVk-unsplash.jpg", + "alt": "", + "width": 1024, + "height": 872 + }, + "imageAfter": { + "id": 182, + "url": "http://localhost:4759/wp-content/uploads/2021/03/jorge-gardner-hsU_aix2rVk-unsplash2.jpg", + "alt": "", + "width": 1024, + "height": 872 + }, + "orientation": "horizontal" + }, + "innerBlocks": [], + "originalContent": "
\"\"\"\"
" + } +] diff --git a/projects/plugins/jetpack/extensions/blocks/image-compare/test/fixtures/jetpack__image-compare.parsed.json b/projects/plugins/jetpack/extensions/blocks/image-compare/test/fixtures/jetpack__image-compare.parsed.json new file mode 100644 index 0000000000000..eba8a29012880 --- /dev/null +++ b/projects/plugins/jetpack/extensions/blocks/image-compare/test/fixtures/jetpack__image-compare.parsed.json @@ -0,0 +1,35 @@ +[ + { + "blockName": "jetpack/image-compare", + "attrs": { + "imageBefore": { + "id": 181, + "url": "http://localhost:4759/wp-content/uploads/2021/03/jorge-gardner-hsU_aix2rVk-unsplash.jpg", + "alt": "", + "width": 1024, + "height": 872 + }, + "imageAfter": { + "id": 182, + "url": "http://localhost:4759/wp-content/uploads/2021/03/jorge-gardner-hsU_aix2rVk-unsplash2.jpg", + "alt": "", + "width": 1024, + "height": 872 + } + }, + "innerBlocks": [], + "innerHTML": "\n
\"\"\"\"
\n", + "innerContent": [ + "\n
\"\"\"\"
\n" + ] + }, + { + "blockName": null, + "attrs": {}, + "innerBlocks": [], + "innerHTML": "\n\n", + "innerContent": [ + "\n\n" + ] + } +] diff --git a/projects/plugins/jetpack/extensions/blocks/image-compare/test/fixtures/jetpack__image-compare.serialized.html b/projects/plugins/jetpack/extensions/blocks/image-compare/test/fixtures/jetpack__image-compare.serialized.html new file mode 100644 index 0000000000000..d4c888a260922 --- /dev/null +++ b/projects/plugins/jetpack/extensions/blocks/image-compare/test/fixtures/jetpack__image-compare.serialized.html @@ -0,0 +1,3 @@ + +
+ diff --git a/projects/plugins/jetpack/extensions/blocks/image-compare/test/img-upload.js b/projects/plugins/jetpack/extensions/blocks/image-compare/test/img-upload.js new file mode 100644 index 0000000000000..8b814583a27d2 --- /dev/null +++ b/projects/plugins/jetpack/extensions/blocks/image-compare/test/img-upload.js @@ -0,0 +1,46 @@ +/** + * @jest-environment jsdom + */ + +/** + * External dependencies + */ +import '@testing-library/jest-dom/extend-expect'; +import { render, screen, waitFor } from '@testing-library/react'; + +/** + * Internal dependencies + */ +import ImgUpload from '../img-upload'; + +describe( 'ImgUpload', () => { + const onChange = jest.fn(); + const image = { + id: 1, + url: 'https://test.com/test.jpg', + alt: 'Image description', + }; + const defaultProps = { + image, + placeHolderLabel: 'Image Placeholder Label', + onChange, + }; + + test( 'display placeholder when no image present', () => { + render( ); + + expect( screen.getByText( defaultProps.placeHolderLabel ) ).toBeInTheDocument(); + expect( screen.queryByRole( 'img' ) ).not.toBeInTheDocument(); + } ) + + test( 'displays image when available', () => { + render( ); + const element = screen.getByRole( 'img' ); + + expect( screen.queryByText( defaultProps.placeHolderLabel ) ).not.toBeInTheDocument(); + expect( element ).toBeInTheDocument(); + expect( element ).toHaveAttribute( 'id', `${ image.id }` ); + expect( element ).toHaveAttribute( 'src', image.url ); + expect( element ).toHaveAttribute( 'alt', image.alt ); + } ); +} ); diff --git a/projects/plugins/jetpack/extensions/blocks/image-compare/test/validate.js b/projects/plugins/jetpack/extensions/blocks/image-compare/test/validate.js new file mode 100644 index 0000000000000..6068bba0b13cf --- /dev/null +++ b/projects/plugins/jetpack/extensions/blocks/image-compare/test/validate.js @@ -0,0 +1,8 @@ +/** + * Internal dependencies + */ +import { name, settings } from '../'; +import runBlockFixtureTests from '../../../shared/test/block-fixtures'; + +const blocks = [ { name: `jetpack/${ name }`, settings } ]; +runBlockFixtureTests( `jetpack/${ name }`, blocks, __dirname ); diff --git a/tools/eslint-excludelist.json b/tools/eslint-excludelist.json index 55a7c291c6675..087c09ba64034 100644 --- a/tools/eslint-excludelist.json +++ b/tools/eslint-excludelist.json @@ -113,7 +113,6 @@ "projects/plugins/jetpack/extensions/blocks/eventbrite/utils.js", "projects/plugins/jetpack/extensions/blocks/google-calendar/utils.js", "projects/plugins/jetpack/extensions/blocks/image-compare/edit.js", - "projects/plugins/jetpack/extensions/blocks/image-compare/img-upload.js", "projects/plugins/jetpack/extensions/blocks/image-compare/use-debounce.js", "projects/plugins/jetpack/extensions/blocks/image-compare/view.js", "projects/plugins/jetpack/extensions/blocks/opentable/edit.js",