go.chromium.org/luci@v0.0.0-20240309015107-7cdc2e660f33/milo/ui/src/testing_tools/fakes/fake_context_provider.tsx (about)

     1  // Copyright 2023 The LUCI Authors.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //      http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  import { ThemeProvider } from '@emotion/react';
    16  import { LocalizationProvider } from '@mui/x-date-pickers';
    17  import { AdapterLuxon } from '@mui/x-date-pickers/AdapterLuxon';
    18  import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
    19  import React, { useState } from 'react';
    20  import { Outlet, RouterProvider, createMemoryRouter } from 'react-router-dom';
    21  
    22  import { PageConfigStateProvider } from '@/common/components/page_config_state_provider';
    23  import { PageMetaProvider } from '@/common/components/page_meta/page_meta_provider';
    24  import { UiPage } from '@/common/constants/view';
    25  import { theme } from '@/common/themes/base';
    26  import { ReleaseNotesProvider } from '@/core/components/release_notes';
    27  import { SyncedSearchParamsProvider } from '@/generic_libs/hooks/synced_search_params';
    28  
    29  import { FakeAuthStateProvider } from './fake_auth_state_provider';
    30  
    31  interface FakeContextProviderProps {
    32    readonly mountedPath?: string;
    33    readonly routerOptions?: Parameters<typeof createMemoryRouter>[1];
    34    readonly children: React.ReactNode;
    35    readonly pageMeta?: {
    36      project?: string;
    37      selectedPage?: UiPage;
    38    };
    39  }
    40  
    41  /**
    42   * Provides various contexts for testing purpose.
    43   */
    44  export function FakeContextProvider({
    45    mountedPath,
    46    children,
    47    pageMeta,
    48    routerOptions,
    49  }: FakeContextProviderProps) {
    50    const [client] = useState(() => {
    51      const errorMock = jest
    52        .spyOn(console, 'error')
    53        .mockImplementationOnce(() => {
    54          // Prevent react query from complaining about the custom logger.
    55          //
    56          // Custom logger is deprecated and will be removed in
    57          // `@tanstack/react-query@5`. However, we still need to use it here to
    58          // disable unnecessary network call error logs in unit tests.
    59          //
    60          // In the next react-query release, this will no longer be necessary
    61          // since network call errors will no longer be logged anyway. See the
    62          // `remove custom logger` section on
    63          // https://github.com/TanStack/query/discussions/4252
    64        });
    65      const c = new QueryClient({
    66        defaultOptions: {
    67          queries: {
    68            retry: false,
    69          },
    70        },
    71        logger: {
    72          log: () => {},
    73          warn: () => {},
    74          error: () => {},
    75        },
    76      });
    77      errorMock.mockRestore();
    78      return c;
    79    });
    80  
    81    const router = createMemoryRouter(
    82      [
    83        {
    84          element: (
    85            <SyncedSearchParamsProvider>
    86              <Outlet />
    87            </SyncedSearchParamsProvider>
    88          ),
    89          children: [
    90            {
    91              path: mountedPath || '/',
    92              element: children,
    93            },
    94          ],
    95        },
    96      ],
    97      routerOptions,
    98    );
    99  
   100    return (
   101      <ThemeProvider theme={theme}>
   102        <LocalizationProvider dateAdapter={AdapterLuxon}>
   103          <FakeAuthStateProvider>
   104            <QueryClientProvider client={client}>
   105              <PageMetaProvider
   106                initPage={pageMeta?.selectedPage}
   107                initProject={pageMeta?.project}
   108              >
   109                <ReleaseNotesProvider
   110                  initReleaseNotes={{ latest: '', latestVersion: -1, past: '' }}
   111                >
   112                  <PageConfigStateProvider>
   113                    <RouterProvider router={router} />
   114                  </PageConfigStateProvider>
   115                </ReleaseNotesProvider>
   116              </PageMetaProvider>
   117            </QueryClientProvider>
   118          </FakeAuthStateProvider>
   119        </LocalizationProvider>
   120      </ThemeProvider>
   121    );
   122  }