Run component tests with a real store and use renderWithContext everywhere (#25217)

* Change renderWithFullContext to not mock Redux store

* Remove renderWithIntl and renderWithIntlAndStore

* Rename renderWithFullContext to renderWithContext

* Use renderWithContext for WS context
Этот коммит содержится в:
Harrison Healey
2023-11-08 17:02:40 -05:00
коммит произвёл GitHub
родитель ab349946db
Коммит be34a5d2df
82 изменённых файлов: 1355 добавлений и 1421 удалений

Просмотреть файл

@@ -22,50 +22,42 @@ import type {GlobalState} from 'types/store';
export * from '@testing-library/react';
export {userEvent};
export const renderWithIntl = (component: React.ReactNode | React.ReactNodeArray, locale = 'en') => {
return render(<IntlProvider locale={locale}>{component}</IntlProvider>);
};
export type FullContextOptions = {
locale?: string;
useMockedStore?: boolean;
}
export const renderWithIntlAndStore = (component: React.ReactNode | React.ReactNodeArray, initialState: DeepPartial<GlobalState> = {}, locale = 'en', divContainer?: HTMLDivElement) => {
// We use a redux-mock-store store for testing, but we set up a real store to ensure the initial state is complete
const realStore = configureStore(initialState);
export const renderWithContext = (
component: React.ReactElement,
initialState: DeepPartial<GlobalState> = {},
partialOptions?: FullContextOptions,
) => {
const options = {
locale: partialOptions?.locale ?? 'en',
useMockedStore: partialOptions?.useMockedStore ?? false,
};
const store = mockStore(realStore.getState());
return render(
<IntlProvider locale={locale}>
<Provider store={store}>
{component}
</Provider>
</IntlProvider>,
{container: divContainer},
);
};
export const renderWithFullContext = (component: React.ReactNode | React.ReactNodeArray, initialState: DeepPartial<GlobalState> = {}, locale = 'en') => {
// We use a redux-mock-store store for testing, but we set up a real store to ensure the initial state is complete
const testState = configureStore(initialState).getState();
const testStore = configureOrMockStore(initialState, options.useMockedStore);
// Store these in an object so that they can be maintained through rerenders
const renderState = {
component,
history: createBrowserHistory(),
locale,
state: testState,
store: mockStore(testState),
options,
store: testStore,
};
// This should wrap the component in roughly the same providers used in App and RootProvider
function wrapComponent() {
function WrapComponent(props: {children: React.ReactElement}) {
// Every time this is called, these values should be updated from `renderState`
return (
<Provider store={renderState.store}>
<Router history={renderState.history}>
<IntlProvider
locale={renderState.locale}
locale={renderState.options.locale}
>
<WebSocketContext.Provider value={WebSocketClient}>
{renderState.component}
{props.children}
</WebSocketContext.Provider>
</IntlProvider>
</Router>
@@ -73,36 +65,41 @@ export const renderWithFullContext = (component: React.ReactNode | React.ReactNo
);
}
const results = render(wrapComponent());
const results = render(component, {wrapper: WrapComponent});
return {
...results,
rerender: (newComponent: React.ReactNode | React.ReactNodeArray) => {
rerender: (newComponent: React.ReactElement) => {
renderState.component = newComponent;
results.rerender(wrapComponent());
results.rerender(renderState.component);
},
/**
* Rerenders the component after replacing the entire store state with the provided one.
*/
replaceStoreState: (newInitialState: DeepPartial<GlobalState>) => {
const newTestState = configureStore(newInitialState).getState();
renderState.state = newTestState;
renderState.store = mockStore(newTestState);
renderState.store = configureOrMockStore(newInitialState, renderState.options.useMockedStore);
results.rerender(wrapComponent());
results.rerender(renderState.component);
},
/**
* Rerenders the component after merging the current store state with the provided one.
*/
updateStoreState: (stateDiff: DeepPartial<GlobalState>) => {
const newTestState = mergeObjects(renderState.state, stateDiff);
renderState.state = newTestState;
renderState.store = mockStore(newTestState);
const newInitialState = mergeObjects(renderState.store.getState(), stateDiff);
renderState.store = configureOrMockStore(newInitialState, renderState.options.useMockedStore);
results.rerender(wrapComponent());
results.rerender(renderState.component);
},
};
};
function configureOrMockStore<T>(initialState: DeepPartial<T>, useMockedStore: boolean) {
let testStore = configureStore(initialState);
if (useMockedStore) {
testStore = mockStore(testStore.getState());
}
return testStore;
}