static-cms/packages/core/test/harnesses/widget.harness.tsx

94 lines
3.1 KiB
TypeScript
Raw Normal View History

2023-03-30 13:29:09 -04:00
/* eslint-disable import/prefer-default-export */
import { act } from '@testing-library/react';
import React from 'react';
import MediaLibraryModal from '@staticcms/core/components/media-library/MediaLibraryModal';
import { store } from '@staticcms/core/store';
import { createMockWidgetControlProps } from '@staticcms/test/data/widgets.mock';
import { renderWithProviders } from '@staticcms/test/test-utils';
import type { BaseField, ObjectValue, UnknownField, WidgetControlProps } from '@staticcms/core';
2023-03-30 13:29:09 -04:00
import type { FC } from 'react';
export interface WidgetControlHarnessOptions {
useFakeTimers?: boolean;
withMediaLibrary?: boolean;
}
export type WidgetControlHarnessParams<T, F extends BaseField = UnknownField> = Parameters<
typeof createMockWidgetControlProps<T, F>
>[0];
export type WidgetControlHarnessProps<T, F extends BaseField = UnknownField> = Omit<
WidgetControlHarnessParams<T, F>,
'field'
> &
Pick<Partial<WidgetControlHarnessParams<T, F>>, 'field'>;
export interface WidgetControlHarnessReturn<T, F extends BaseField = UnknownField>
extends Omit<ReturnType<typeof renderWithProviders>, 'rerender'> {
rerender: (rerenderProps?: Omit<WidgetControlHarnessProps<T, F>, 'field'> | undefined) => {
props: Omit<WidgetControlHarnessProps<T, F>, 'field'> | undefined;
};
store: typeof store;
props: WidgetControlProps<T, F, ObjectValue>;
}
export type WidgetControlHarness<T, F extends BaseField = UnknownField> = (
renderProps?: WidgetControlHarnessProps<T, F>,
renderOptions?: WidgetControlHarnessOptions,
) => WidgetControlHarnessReturn<T, F>;
2023-09-06 16:30:51 -04:00
export const createWidgetControlHarness = <T, F extends BaseField = UnknownField>(
2023-03-30 13:29:09 -04:00
Component: FC<WidgetControlProps<T, F>>,
defaults: Omit<Partial<WidgetControlProps<T, F>>, 'field'> &
Pick<WidgetControlProps<T, F>, 'field'>,
options?: WidgetControlHarnessOptions,
): WidgetControlHarness<T, F> => {
return (
renderProps?: WidgetControlHarnessProps<T, F>,
renderOptions?: WidgetControlHarnessOptions,
) => {
2023-03-30 13:29:09 -04:00
const { useFakeTimers = false, withMediaLibrary = false } = renderOptions ?? options ?? {};
if (useFakeTimers) {
jest.useFakeTimers({ now: new Date(2023, 1, 12, 10, 15, 35, 0) });
} else {
jest.useRealTimers();
}
const field = renderProps?.field ?? defaults.field;
const props = createMockWidgetControlProps<T, F>({ ...defaults, ...renderProps, field });
const result = renderWithProviders(
<>
<Component {...props} />
{withMediaLibrary ? <MediaLibraryModal key="library" /> : null}
</>,
);
if (useFakeTimers) {
act(() => {
jest.advanceTimersByTime(1000);
});
}
const rerender = (rerenderProps?: Omit<WidgetControlHarnessProps<T, F>, 'field'>) => {
2023-03-30 13:29:09 -04:00
const finalRerenderProps = {
...props,
...rerenderProps,
2023-09-06 16:30:51 -04:00
} as WidgetControlProps<T, F>;
2023-03-30 13:29:09 -04:00
result.rerender(
<>
<Component {...finalRerenderProps} />
{withMediaLibrary ? <MediaLibraryModal key="library" /> : null}
</>,
);
return { props: rerenderProps };
};
return { ...result, props, rerender, store };
};
};