Created
December 10, 2019 00:22
-
-
Save kadamwhite/f4959c157389abccca80f924ff663e50 to your computer and use it in GitHub Desktop.
TypeScript Gutenberg connected component test
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React from 'react'; | |
import { render, cleanup, fireEvent } from '@testing-library/react'; | |
import { useSelect, useDispatch } from '@wordpress/data'; | |
import '@testing-library/jest-dom/extend-expect'; | |
import { storeProvider } from '../store-provider'; | |
describe('storeProvider', () => { | |
afterEach(cleanup); | |
it('returns a React component', () => { | |
const StoreWrapper = storeProvider(); | |
const { container } = render(( | |
<StoreWrapper /> | |
)); | |
expect(container.innerHTML).toBe(''); | |
}); | |
it('exposes store selectors to child components', () => { | |
const StoreWrapper = storeProvider({ | |
'store/name': { | |
selectors: { | |
getValue: (): string => 'store content', | |
}, | |
}, | |
}); | |
const Test: React.FC = () => { | |
const data = useSelect((select): { value: string } => ({ | |
value: select('store/name').getValue(), | |
})); | |
return ( | |
<p>{data.value}</p> | |
); | |
}; | |
const { getByText } = render(( | |
<StoreWrapper> | |
<Test /> | |
</StoreWrapper> | |
)); | |
expect(getByText('store content')).toBeInTheDocument(); | |
}); | |
it('exposes store actions to child components', () => { | |
const noop = (): { type: string } => ({ type: '__INERT__' }); | |
const onClick = jest.fn().mockImplementation(noop); | |
const StoreWrapper = storeProvider({ | |
'store/name': { | |
actions: { | |
onClick, | |
}, | |
}, | |
}); | |
const Test: React.FC = () => { | |
// eslint-disable-next-line no-shadow | |
const { onClick } = useDispatch('store/name'); | |
return ( | |
<button type="button" onClick={onClick}>Click Me</button> | |
); | |
}; | |
const { getByText } = render(( | |
<StoreWrapper> | |
<Test /> | |
</StoreWrapper> | |
)); | |
const button = getByText('Click Me'); | |
expect(onClick).not.toHaveBeenCalled(); | |
expect(button).toBeInTheDocument(); | |
fireEvent.click(button, {}); | |
expect(onClick).toHaveBeenCalledTimes(1); | |
}); | |
}); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React from 'react'; | |
import { createRegistry, RegistryProvider } from '@wordpress/data'; | |
/** | |
* Accept a dictionary of mock store selectors & actions and return a | |
* React wrapper component which uses WP's RegistryProvider to expose | |
* that store data to wrapped child components. | |
* | |
* @param {Object} stores Dictionary of mock store actions or selectors keyed by store. | |
* @returns {React.FC} Store provider wrapper component. | |
*/ | |
export const storeProvider = ( | |
stores: { | |
// Keyed by name of store, e.g. `core/block-editor`. | |
[storeKey: string]: { | |
actions?: KeyedObject; | |
selectors?: KeyedObject; | |
}; | |
} = {}, | |
): React.FC => ({ children }): JSX.Element => { | |
const registry = createRegistry(); | |
// Register all provided stores. | |
Object.keys(stores).forEach((storeKey) => { | |
const store = stores[storeKey]; | |
registry.registerStore(storeKey, { | |
reducer: () => ({}), | |
actions: store.actions || {}, | |
selectors: store.selectors || {}, | |
}); | |
}); | |
return ( | |
<RegistryProvider value={registry}> | |
{ children } | |
</RegistryProvider> | |
); | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment