reactTestingLibrary.tsx 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. import {Component, Fragment} from 'react';
  2. import {cache} from '@emotion/css';
  3. import {CacheProvider, ThemeProvider} from '@emotion/react';
  4. // eslint-disable-next-line no-restricted-imports
  5. import {
  6. fireEvent as reactRtlFireEvent,
  7. render,
  8. RenderOptions,
  9. } from '@testing-library/react';
  10. import * as reactHooks from '@testing-library/react-hooks'; // eslint-disable-line no-restricted-imports
  11. import userEvent from '@testing-library/user-event'; // eslint-disable-line no-restricted-imports
  12. import GlobalModal from 'sentry/components/globalModal';
  13. import {Organization} from 'sentry/types';
  14. import {lightTheme} from 'sentry/utils/theme';
  15. import {OrganizationContext} from 'sentry/views/organizationContext';
  16. type ProviderOptions = {
  17. context?: Record<string, any>;
  18. organization?: Organization;
  19. };
  20. type Options = ProviderOptions & RenderOptions;
  21. function createProvider(contextDefs: Record<string, any>) {
  22. return class ContextProvider extends Component {
  23. static childContextTypes = contextDefs.childContextTypes;
  24. getChildContext() {
  25. return contextDefs.context;
  26. }
  27. render() {
  28. return this.props.children;
  29. }
  30. };
  31. }
  32. function makeAllTheProviders({context, organization}: ProviderOptions) {
  33. const ContextProvider = context ? createProvider(context) : Fragment;
  34. return function ({children}: {children?: React.ReactNode}) {
  35. return (
  36. <ContextProvider>
  37. <CacheProvider value={cache}>
  38. <ThemeProvider theme={lightTheme}>
  39. <OrganizationContext.Provider value={organization ?? null}>
  40. {children}
  41. </OrganizationContext.Provider>
  42. </ThemeProvider>
  43. </CacheProvider>
  44. </ContextProvider>
  45. );
  46. };
  47. }
  48. /**
  49. * Migrating from enzyme? Pass context via the options object
  50. * Before
  51. * mountWithTheme(<Something />, routerContext);
  52. * After
  53. * mountWithTheme(<Something />, {context: routerContext});
  54. */
  55. function mountWithTheme(ui: React.ReactElement, options?: Options) {
  56. const {context, organization, ...otherOptions} = options ?? {};
  57. const AllTheProviders = makeAllTheProviders({context, organization});
  58. return render(ui, {wrapper: AllTheProviders, ...otherOptions});
  59. }
  60. /**
  61. * @deprecated
  62. * Use userEvent over fireEvent where possible.
  63. * More details: https://kentcdodds.com/blog/common-mistakes-with-react-testing-library#not-using-testing-libraryuser-event
  64. */
  65. const fireEvent = reactRtlFireEvent;
  66. function mountGlobalModal(options?: Options) {
  67. return mountWithTheme(<GlobalModal />, options);
  68. }
  69. export * from '@testing-library/react'; // eslint-disable-line no-restricted-imports
  70. export {mountWithTheme, mountGlobalModal, userEvent, reactHooks, fireEvent};