reactTestingLibrary.tsx 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  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 as reactTestingLibraryRender,
  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?
  50. * Try avoiding unnecessary context and just mount your component. If it works, then you dont need anything else.
  51. * render(<TestedComponent />);
  52. *
  53. * If your component requires routerContext or organization to render, pass it via context options argument.
  54. * render(<TestedComponent />, {context: routerContext, organization});
  55. */
  56. function render(ui: React.ReactElement, options?: Options) {
  57. const {context, organization, ...otherOptions} = options ?? {};
  58. const AllTheProviders = makeAllTheProviders({context, organization});
  59. return reactTestingLibraryRender(ui, {wrapper: AllTheProviders, ...otherOptions});
  60. }
  61. /**
  62. * @deprecated
  63. * Use userEvent over fireEvent where possible.
  64. * More details: https://kentcdodds.com/blog/common-mistakes-with-react-testing-library#not-using-testing-libraryuser-event
  65. */
  66. const fireEvent = reactRtlFireEvent;
  67. function renderGlobalModal(options?: Options) {
  68. return render(<GlobalModal />, options);
  69. }
  70. export * from '@testing-library/react'; // eslint-disable-line no-restricted-imports
  71. export {render, renderGlobalModal, userEvent, reactHooks, fireEvent};