Skip to content

Commit

Permalink
Added @testing-library/react-hooks library to unit test custom hooks
Browse files Browse the repository at this point in the history
 Importing regenerator runtime to polyfill transpiled generator functions for react hooks testing library
 Added custom hook to fetch api data
 Added tests for custom hook and updated tests for edit.js
  • Loading branch information
ramonjd committed Mar 9, 2021
1 parent cf18bc6 commit 99d3cfe
Show file tree
Hide file tree
Showing 7 changed files with 300 additions and 82 deletions.
49 changes: 10 additions & 39 deletions projects/plugins/jetpack/extensions/blocks/gif/edit.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
*/
import classNames from 'classnames';
import { __ } from '@wordpress/i18n';
import { createRef, useState, useEffect, useCallback } from '@wordpress/element';
import { createRef, useState, useEffect } from '@wordpress/element';
import { Placeholder } from '@wordpress/components';
import { RichText } from '@wordpress/block-editor';

Expand All @@ -14,6 +14,7 @@ import { icon, title } from './';
import { getUrl, getPaddingTop, getEmbedUrl } from './utils';
import SearchForm from './components/search-form';
import Controls from './controls';
import useFetchGiphyData from './hooks/use-fetch-giphy-data';

function GifEdit( {
attributes,
Expand All @@ -24,8 +25,8 @@ function GifEdit( {
const { align, caption, giphyUrl, searchText, paddingTop } = attributes;
const classes = classNames( className, `align${ align }` );
const [ captionFocus, setCaptionFocus ] = useState( false );
const [ results, setResults ] = useState( '' );
const searchFormInputRef = createRef();
const { isFetching, giphyData, fetchGiphyData } = useFetchGiphyData();

const setSelectedGiphy = ( item ) => {
setAttributes( { giphyUrl: getEmbedUrl( item ), paddingTop: getPaddingTop( item ) } );
Expand All @@ -36,50 +37,20 @@ function GifEdit( {
setCaptionFocus( false );
};

const fetchResults = async ( requestUrl ) => {
const giphyFetch = await fetch( requestUrl )
.then( ( response ) => {
if ( response.ok ) {
return response;
}
return false;
} )
.catch( () => {
return false;
} );

if ( giphyFetch ) {
const giphyResponse = await giphyFetch.json();
// If there is only one result, Giphy's API does not return an array.
// The following statement normalizes the data into an array with one member in this case.
const giphyResults = typeof giphyResponse.data.images !== 'undefined' ? [ giphyResponse.data ] : giphyResponse.data;

// Try to grab the first result. We're going to show this as the main image.
const giphyData = giphyResults[ 0 ];

// No results
if ( ! giphyData.images ) {
return false;
}

setResults( giphyResults );
}
};

useEffect( () => {
if ( results && results[ 0 ] ) {
setSelectedGiphy( results[ 0 ] );
if ( giphyData && giphyData[ 0 ] ) {
setSelectedGiphy( giphyData[ 0 ] );
}
}, [ results ] );
}, [ giphyData ] );

const onSubmit = ( event ) => {
event.preventDefault();

if ( ! attributes.searchText ) {
if ( ! attributes.searchText || isFetching ) {
return;
}

fetchResults( getUrl( attributes.searchText ) );
fetchGiphyData( getUrl( attributes.searchText ) );
};

const onChange = ( event ) => setAttributes( { searchText: event.target.value } );
Expand Down Expand Up @@ -111,9 +82,9 @@ function GifEdit( {
ref={ searchFormInputRef }
/>
) }
{ isSelected && results && results.length > 1 && (
{ isSelected && giphyData && giphyData.length > 1 && (
<div className="wp-block-jetpack-gif_thumbnails-container">
{ results.map( thumbnail => {
{ giphyData.map( thumbnail => {
const thumbnailStyle = {
backgroundImage: `url(${ thumbnail.images.downsized_still.url })`,
};
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/**
* External dependencies
*/
import { useEffect, useState } from '@wordpress/element';

/**
* Internal dependencies
*/

const useFetchGiphyData = ( initialValue = [] ) => {
const [ isFetching, setIsFetching ] = useState( false );
const [ giphyData, setGiphyData ] = useState( initialValue );
const [ fetchUrl, setFetchUrl ] = useState( '' );

useEffect( () => {
if ( ! fetchUrl ) {
return;
}

const fetchResults = async () => {
setIsFetching( true );

const giphyFetch = await fetch( fetchUrl )
.then( ( response ) => {
if ( response.ok ) {
return response;
}
return false;
} )
.catch( () => {
return false;
} );

if ( giphyFetch ) {
const giphyResponse = await giphyFetch.json();
// If there is only one result, Giphy's API does not return an array.
// The following statement normalizes the data into an array with one member in this case.
const giphyResults = typeof giphyResponse.data.images !== 'undefined' ? [ giphyResponse.data ] : giphyResponse.data;

// Try to grab the first result. We're going to show this as the main image.
const firstResult = giphyResults[ 0 ];

// Check for results.
if ( firstResult.images ) {
setGiphyData( giphyResults );
}
}
setIsFetching( false );
};

fetchResults();
}, [ fetchUrl ] );

return { isFetching, giphyData, fetchGiphyData: setFetchUrl };
};

export default useFetchGiphyData;
114 changes: 71 additions & 43 deletions projects/plugins/jetpack/extensions/blocks/gif/test/edit.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,15 @@
/**
* External dependencies
*/
import { render, act, fireEvent } from '@testing-library/react';
import { render, fireEvent } from '@testing-library/react';
import '@testing-library/jest-dom/extend-expect';

/**
* Internal dependencies
*/
import GifEdit from '../edit';
import { getUrl } from '../utils';
import { getUrl, getPaddingTop, getEmbedUrl } from '../utils';
import useFetchGiphyData from '../hooks/use-fetch-giphy-data';

const setAttributes = jest.fn();

Expand All @@ -31,50 +32,54 @@ const defaultProps = {
isSelected: false,
};

const originalFetch = window.fetch;

/**
* Mock return value for a successful fetch JSON return value.
*
* @return {Promise} Mock return value.
*/
const GIPHY_RESPONSE = {
data: [
{
id: '9',
embed_url: 'pony',
images: {
downsized_still: {
url: 'chips',
},
original: {
height: 10,
width: 10,
},
}
const GIPHY_DATA = [
{
id: '9',
embed_url: 'pony',
images: {
downsized_still: {
url: 'chips',
},
original: {
height: 10,
width: 10,
},
}
]
};
const RESOLVED_FETCH_PROMISE = Promise.resolve( GIPHY_RESPONSE );
const DEFAULT_FETCH_MOCK_RETURN = Promise.resolve( {
status: 200,
ok: true,
json: () => RESOLVED_FETCH_PROMISE,
} );
},
{
id: '99',
embed_url: 'horsey',
images: {
downsized_still: {
url: 'fish',
},
original: {
height: 12,
width: 12,
},
}
}
];

const fetchGiphyData = jest.fn();

jest.mock('./../hooks/use-fetch-giphy-data' );

describe( 'GifEdit', () => {
beforeEach( () => {
window.fetch = jest.fn();
window.fetch.mockReturnValue( DEFAULT_FETCH_MOCK_RETURN );
useFetchGiphyData.mockImplementation( () => {
return {
fetchGiphyData,
giphyData: [],
isFetching: false,
}
} );
} );

afterEach( async () => {
await act( () => GIPHY_RESPONSE );
fetchGiphyData.mockReset();
setAttributes.mockReset();
} );

afterAll( () => {
window.fetch = originalFetch;
useFetchGiphyData.mockReset();
} );

test( 'adds class names', () => {
Expand All @@ -88,16 +93,39 @@ describe( 'GifEdit', () => {
expect( container.querySelector( 'figure' ) ).not.toBeInTheDocument();
} );

/* test( 'calls API and returns giphy images', () => {
test( 'calls API and returns giphy images', async () => {
useFetchGiphyData.mockImplementationOnce( () => {
return {
fetchGiphyData,
giphyData: GIPHY_DATA,
isFetching: false,
}
} );
const newProps = {
...defaultProps,
isSelected: true,
attributes: {
...defaultAttributes,
searchText: 'sausage roll',
giphyUrl: 'https://itsalong.way/to/the/top/if/you/want',
searchText: 'a sausage roll',
},
};
const { container } = render( <GifEdit { ...newProps } /> );
const { container, screen } = render( <GifEdit { ...newProps } /> );

expect( container.querySelector( 'form input' ).value ).toEqual( newProps.attributes.searchText );

fireEvent.submit( container.querySelector( 'form' ) );
expect( window.fetch ).toHaveBeenCalledWith( getUrl( newProps.attributes.searchText ) );
} );*/

expect( fetchGiphyData ).toHaveBeenCalledWith( getUrl( newProps.attributes.searchText ) );
expect( setAttributes.mock.calls[0][0] ).toStrictEqual( {
giphyUrl: getEmbedUrl( GIPHY_DATA[0] ),
paddingTop: getPaddingTop( GIPHY_DATA[0] ),
} );

expect( container.querySelector( 'figure' ) ).toBeInTheDocument();
expect( container.querySelector( 'figcaption' ) ).toBeInTheDocument();
expect( container.querySelector( '.wp-block-jetpack-gif-wrapper iframe' ) ).toBeInTheDocument();
expect( container.querySelectorAll( '.wp-block-jetpack-gif_thumbnail-container' ) ).toHaveLength( 2 );

} );
} );
Loading

0 comments on commit 99d3cfe

Please sign in to comment.