Skip to content

Commit

Permalink
Update gallery block tests with new helpers
Browse files Browse the repository at this point in the history
  • Loading branch information
fluiddot committed Jun 14, 2022
1 parent 5b796d2 commit 156fd41
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 243 deletions.
209 changes: 11 additions & 198 deletions packages/block-library/src/gallery/test/helpers.native.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,83 +2,25 @@
* External dependencies
*/
import {
act,
initializeEditor,
addBlock,
fireEvent,
waitFor,
within,
waitForStoreResolvers,
getBlock,
getInnerBlock,
initializeEditor,
triggerBlockListLayout,
} from 'test/helpers';

/**
* WordPress dependencies
*/
import {
requestMediaPicker,
subscribeMediaUpload,
} from '@wordpress/react-native-bridge';
import {
MEDIA_UPLOAD_STATE_UPLOADING,
MEDIA_UPLOAD_STATE_SUCCEEDED,
MEDIA_UPLOAD_STATE_FAILED,
MEDIA_UPLOAD_STATE_RESET,
} from '@wordpress/block-editor';

/**
* Adds a Gallery block via the block picker.
*
* @return {import('@testing-library/react-native').RenderAPI} A Testing Library screen.
*/
export const addGalleryBlock = async () => {
const screen = await initializeEditor();
const { getByA11yLabel, getByTestId, getByText } = screen;

fireEvent.press( getByA11yLabel( 'Add block' ) );

const blockList = getByTestId( 'InserterUI-Blocks' );
// onScroll event used to force the FlatList to render all items
fireEvent.scroll( blockList, {
nativeEvent: {
contentOffset: { y: 0, x: 0 },
contentSize: { width: 100, height: 100 },
layoutMeasurement: { width: 100, height: 100 },
},
} );

fireEvent.press( await waitFor( () => getByText( 'Gallery' ) ) );

await addBlock( screen, 'Gallery' );
return screen;
};

/**
* The gallery items are rendered via the FlatList of the inner block list.
* In order to render the items of a FlatList, it's required to trigger the
* "onLayout" event. Additionally, the call is wrapped over "waitForStoreResolvers"
* because the gallery items request the media data associated with the image to
* be rendered via the "getMedia" selector.
*
* @param {import('react-test-renderer').ReactTestInstance} galleryBlock Gallery block instance to trigger layout event.
* @param {Object} [options] Configuration options for the event.
* @param {number} [options.width] Width value to be passed to the event.
*/
export const triggerGalleryLayout = async (
galleryBlock,
{ width = 320 } = {}
) =>
waitForStoreResolvers( () =>
fireEvent(
within( galleryBlock ).getByTestId( 'block-list-wrapper' ),
'layout',
{
nativeEvent: {
layout: {
width,
},
},
}
)
);

/**
* Initialize the editor with HTML generated of Gallery block.
*
Expand Down Expand Up @@ -106,12 +48,11 @@ export const initializeWithGalleryBlock = async ( {
useLocalUrl,
} );
const screen = await initializeEditor( { initialHtml } );
const { getByA11yLabel } = screen;

const galleryBlock = getByA11yLabel( /Gallery Block\. Row 1/ );
const galleryBlock = getBlock( screen, 'Gallery' );

if ( numberOfItems > 0 ) {
await triggerGalleryLayout( galleryBlock, { width } );
await triggerBlockListLayout( galleryBlock, { width } );
}

if ( selected ) {
Expand All @@ -125,109 +66,11 @@ export const initializeWithGalleryBlock = async ( {
* Gets a gallery item within a Gallery block.
*
* @param {import('react-test-renderer').ReactTestInstance} galleryBlock Gallery block instance.
* @param {number} rowPosition Row position within the Gallery block.
* @param {number} rowIndex Row position within the Gallery block.
* @return {import('react-test-renderer').ReactTestInstance} Gallery item.
*/
export const getGalleryItem = ( galleryBlock, rowPosition ) => {
return within( galleryBlock ).getByA11yLabel(
new RegExp( `Image Block\\. Row ${ rowPosition }` )
);
};

/**
* Sets up the media upload mock functions for testing.
*
* @typedef {Object} MediaUploadMockFunctions
* @property {Function} notifyUploadingState Notify uploading state for a media item.
* @property {Function} notifySucceedState Notify succeed state for a media item.
* @property {Function} notifyFailedState Notify failed state for a media item.
* @property {Function} notifyResetState Notify reset state for a media item.
*
* @return {MediaUploadMockFunctions} Notify state functions.
*/
export const setupMediaUpload = () => {
const mediaUploadListeners = [];
subscribeMediaUpload.mockImplementation( ( callback ) => {
mediaUploadListeners.push( callback );
return { remove: jest.fn() };
} );
const notifyMediaUpload = ( payload ) =>
mediaUploadListeners.forEach( ( listener ) => listener( payload ) );

return {
notifyUploadingState: async ( mediaItem ) =>
act( async () => {
notifyMediaUpload( {
state: MEDIA_UPLOAD_STATE_UPLOADING,
mediaId: mediaItem.localId,
progress: 0.25,
} );
} ),
notifySucceedState: async ( mediaItem ) =>
act( async () => {
notifyMediaUpload( {
state: MEDIA_UPLOAD_STATE_SUCCEEDED,
mediaId: mediaItem.localId,
mediaUrl: mediaItem.serverUrl,
mediaServerId: mediaItem.serverId,
} );
} ),
notifyFailedState: async ( mediaItem ) =>
act( async () => {
notifyMediaUpload( {
state: MEDIA_UPLOAD_STATE_FAILED,
mediaId: mediaItem.localId,
progress: 0.5,
} );
} ),
notifyResetState: async ( mediaItem ) =>
act( async () => {
notifyMediaUpload( {
state: MEDIA_UPLOAD_STATE_RESET,
mediaId: mediaItem.localId,
progress: 0,
} );
} ),
};
};

/**
*
* Sets up Media Picker mock functions.
*
* @typedef {Object} MediaPickerMockFunctions
* @property {Function} expectMediaPickerCall Checks if the request media picker function has been called with specific arguments.
* @property {Function} mediaPickerCallback Callback function to notify the media items picked from the media picker.
*
* @return {MediaPickerMockFunctions} Media picker mock functions.
*/
export const setupMediaPicker = () => {
let mediaPickerCallback;
requestMediaPicker.mockImplementation(
( source, filter, multiple, callback ) => {
mediaPickerCallback = callback;
}
);
return {
expectMediaPickerCall: ( source, filter, multiple ) =>
expect( requestMediaPicker ).toHaveBeenCalledWith(
source,
filter,
multiple,
mediaPickerCallback
),
mediaPickerCallback: async ( ...mediaItems ) =>
act( async () =>
mediaPickerCallback(
mediaItems.map( ( { localId, localUrl } ) => ( {
type: 'image',
url: localUrl,
id: localId,
} ) )
)
),
};
};
export const getGalleryItem = ( galleryBlock, rowIndex ) =>
getInnerBlock( galleryBlock, 'Image', { rowIndex } );

/**
* Generates the HTML of a Gallery block.
Expand Down Expand Up @@ -261,33 +104,3 @@ export const generateGalleryBlock = (
<figure class="wp-block-gallery has-nested-images columns-default is-cropped">${ galleryItems }</figure>
<!-- /wp:gallery -->`;
};

/**
* Sets the text of a caption.
*
* @param {import('react-test-renderer').ReactTestInstance} element Caption test instance.
* @param {string} text Text to be set.
*/
export const setCaption = ( element, text ) => {
fireEvent( element, 'focus' );
fireEvent( element, 'onChange', {
nativeEvent: {
eventCount: 1,
target: undefined,
text,
},
} );
};

/**
* Opens the block settings of the current selected block.
*
* @param {import('@testing-library/react-native').RenderAPI} screen The Testing Library screen.
*/
export const openBlockSettings = async ( screen ) => {
const { getByA11yLabel, getByTestId } = screen;
fireEvent.press( getByA11yLabel( 'Open Settings' ) );
await waitFor(
() => getByTestId( 'block-settings-modal' ).props.isVisible
);
};
Loading

0 comments on commit 156fd41

Please sign in to comment.