test-utils.tsx 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. // See https://redux.js.org/usage/writing-tests#setting-up-a-reusable-test-render-function for more information
  2. import React, { PropsWithChildren } from "react";
  3. import { Provider } from "react-redux";
  4. import { configureStore } from "@reduxjs/toolkit";
  5. // eslint-disable-next-line import/no-extraneous-dependencies
  6. import { RenderOptions, render } from "@testing-library/react";
  7. import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
  8. import { I18nextProvider } from "react-i18next";
  9. import i18n from "i18next";
  10. import { initReactI18next } from "react-i18next";
  11. import { AppStore, RootState, rootReducer } from "./src/store";
  12. import { AuthProvider } from "#/context/auth-context";
  13. import { UserPrefsProvider } from "#/context/user-prefs-context";
  14. // Initialize i18n for tests
  15. i18n
  16. .use(initReactI18next)
  17. .init({
  18. lng: "en",
  19. fallbackLng: "en",
  20. ns: ["translation"],
  21. defaultNS: "translation",
  22. resources: {
  23. en: {
  24. translation: {},
  25. },
  26. },
  27. interpolation: {
  28. escapeValue: false,
  29. },
  30. });
  31. const setupStore = (preloadedState?: Partial<RootState>): AppStore =>
  32. configureStore({
  33. reducer: rootReducer,
  34. preloadedState,
  35. });
  36. // This type interface extends the default options for render from RTL, as well
  37. // as allows the user to specify other things such as initialState, store.
  38. interface ExtendedRenderOptions extends Omit<RenderOptions, "queries"> {
  39. preloadedState?: Partial<RootState>;
  40. store?: AppStore;
  41. }
  42. // Export our own customized renderWithProviders function that creates a new Redux store and renders a <Provider>
  43. // Note that this creates a separate Redux store instance for every test, rather than reusing the same store instance and resetting its state
  44. export function renderWithProviders(
  45. ui: React.ReactElement,
  46. {
  47. preloadedState = {},
  48. // Automatically create a store instance if no store was passed in
  49. store = setupStore(preloadedState),
  50. ...renderOptions
  51. }: ExtendedRenderOptions = {},
  52. ) {
  53. function Wrapper({ children }: PropsWithChildren<object>): JSX.Element {
  54. return (
  55. <Provider store={store}>
  56. <UserPrefsProvider>
  57. <AuthProvider>
  58. <QueryClientProvider client={new QueryClient()}>
  59. <I18nextProvider i18n={i18n}>
  60. {children}
  61. </I18nextProvider>
  62. </QueryClientProvider>
  63. </AuthProvider>
  64. </UserPrefsProvider>
  65. </Provider>
  66. );
  67. }
  68. return { store, ...render(ui, { wrapper: Wrapper, ...renderOptions }) };
  69. }