From f8d9253b4e4ec3caf628c7feb8d2b10e0ede9363 Mon Sep 17 00:00:00 2001 From: Alessandro Kreslin Date: Tue, 14 Apr 2026 12:52:24 -0400 Subject: [PATCH 1/6] metrics migration --- .../[locale]/metrics/_components/Analytics/utils.ts | 13 +++++++++++++ src/app/utils/analytics-types.ts | 2 +- 2 files changed, 14 insertions(+), 1 deletion(-) create mode 100644 src/app/[locale]/metrics/_components/Analytics/utils.ts diff --git a/src/app/[locale]/metrics/_components/Analytics/utils.ts b/src/app/[locale]/metrics/_components/Analytics/utils.ts new file mode 100644 index 0000000..2f374ab --- /dev/null +++ b/src/app/[locale]/metrics/_components/Analytics/utils.ts @@ -0,0 +1,13 @@ +/** + * Global analytics bucket endpoint storage and access. + */ +let globalAnalyticsBucketEndpoint: string | undefined; + +export const getAnalyticsBucketEndpoint = (): string | undefined => + globalAnalyticsBucketEndpoint; + +export const setAnalyticsBucketEndpoint = ( + endpoint: string | undefined, +): void => { + globalAnalyticsBucketEndpoint = endpoint; +}; diff --git a/src/app/utils/analytics-types.ts b/src/app/utils/analytics-types.ts index 4ad4cb6..0b6391e 100644 --- a/src/app/utils/analytics-types.ts +++ b/src/app/utils/analytics-types.ts @@ -90,4 +90,4 @@ export interface GBFSVersionMetrics { version: string; computed_on: Date[]; feeds_count: number[]; -} +} \ No newline at end of file From c23ff22931cf5aef6bc4cefde1efeadf5e246233 Mon Sep 17 00:00:00 2001 From: Alessandro Kreslin Date: Tue, 14 Apr 2026 13:17:43 -0400 Subject: [PATCH 2/6] removed legacy App component and router --- package.json | 2 - src/app/App.css | 48 -------------------- src/app/App.tsx | 53 ---------------------- src/app/AppContainer.tsx | 33 -------------- src/app/[locale]/[...slug]/page.tsx | 37 --------------- src/app/router/Router.tsx | 5 -- src/app/screens/Feeds/SearchTable.spec.tsx | 11 +---- yarn.lock | 42 ----------------- 8 files changed, 2 insertions(+), 229 deletions(-) delete mode 100644 src/app/App.css delete mode 100644 src/app/App.tsx delete mode 100644 src/app/AppContainer.tsx delete mode 100644 src/app/[locale]/[...slug]/page.tsx delete mode 100644 src/app/router/Router.tsx diff --git a/package.json b/package.json index e42b156..fac5232 100644 --- a/package.json +++ b/package.json @@ -42,7 +42,6 @@ "react-hook-form": "^7.52.1", "react-map-gl": "^8.0.4", "react-redux": "^8.1.3", - "react-router-dom": "^6.16.0", "react-window": "^2.1.2", "recharts": "^2.12.7", "redux-persist": "^6.0.0", @@ -105,7 +104,6 @@ "@types/react-dom": "^19.2.3", "@types/react-google-recaptcha": "^2.1.8", "@types/react-redux": "^7.1.27", - "@types/react-router-dom": "^5.3.3", "@types/react-window": "^2.0.0", "@types/redux-saga": "^0.10.5", "@typescript-eslint/eslint-plugin": "^6.7.0", diff --git a/src/app/App.css b/src/app/App.css deleted file mode 100644 index 8d47462..0000000 --- a/src/app/App.css +++ /dev/null @@ -1,48 +0,0 @@ -.App { - text-align: center; -} - -.App-logo { - height: 40vmin; - pointer-events: none; -} - -@media (prefers-reduced-motion: no-preference) { - .App-logo { - animation: App-logo-spin infinite 20s linear; - } -} - -.App-header { - background-color: #282c34; - min-height: 100vh; - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - font-size: calc(10px + 2vmin); - color: white; -} - -.App-link { - color: #61dafb; -} - -@keyframes App-logo-spin { - from { - transform: rotate(0deg); - } - to { - transform: rotate(360deg); - } -} - - -#app-main-container { - position: relative; - /* 100vh - header margin - header - footer - footer padding */ - /* Not perfect, to revisit: for client loading state */ - min-height: calc(100vh - 32px - 64px - 302px - 48px); - - box-sizing: border-box; -} diff --git a/src/app/App.tsx b/src/app/App.tsx deleted file mode 100644 index 721ebb0..0000000 --- a/src/app/App.tsx +++ /dev/null @@ -1,53 +0,0 @@ -'use client'; - -import './App.css'; -import AppRouter from './router/Router'; -import { MemoryRouter } from 'react-router-dom'; -import { Suspense } from 'react'; -import { useAuthSession } from './components/AuthSessionProvider'; -import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; -import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; -import AppContainer from './AppContainer'; -import { usePathname, useSearchParams } from 'next/navigation'; - -interface AppProps { - locale?: string; -} - -// Helper function to construct the full path from Next.js routing -function buildPathFromNextRouter( - pathname: string, - searchParams: URLSearchParams, - locale?: string, -): string { - const cleanPath = - locale != null && locale !== 'en' - ? (pathname.replace(`/${locale}`, '') ?? '/') - : pathname; - - const searchString = searchParams.toString(); - return searchString !== '' ? `${cleanPath}?${searchString}` : cleanPath; -} - -function App({ locale }: AppProps): React.ReactElement { - const { isAuthReady: isAppReady } = useAuthSession(); - - const pathname = usePathname(); - const searchParams = useSearchParams(); - - const initialPath = buildPathFromNextRouter(pathname, searchParams, locale); - - return ( - - - {/* MemoryRouter will be deprecated in favor of Next AppRouter */} - {/* MemoryRouter synced with Next.js routing via RouterSync component */} - - {isAppReady ? : null} - - - - ); -} - -export default App; diff --git a/src/app/AppContainer.tsx b/src/app/AppContainer.tsx deleted file mode 100644 index 3aab16e..0000000 --- a/src/app/AppContainer.tsx +++ /dev/null @@ -1,33 +0,0 @@ -'use client'; - -import * as React from 'react'; -import { Box, LinearProgress } from '@mui/material'; -import type ContextProviderProps from './interface/ContextProviderProps'; -import { usePathname } from 'next/navigation'; -import { selectLoadingApp } from './store/selectors'; -import { useSelector } from 'react-redux'; - -const AppContainer: React.FC = ({ children }) => { - const isAppLoading = useSelector(selectLoadingApp); - const pathname = usePathname(); - - React.useLayoutEffect(() => { - window.scrollTo({ top: 0, left: 0, behavior: 'instant' }); - }, [pathname]); - - return ( - <> - - {isAppLoading ? ( - - - - ) : ( - <>{children} - )} - - - ); -}; - -export default AppContainer; diff --git a/src/app/[locale]/[...slug]/page.tsx b/src/app/[locale]/[...slug]/page.tsx deleted file mode 100644 index 3143894..0000000 --- a/src/app/[locale]/[...slug]/page.tsx +++ /dev/null @@ -1,37 +0,0 @@ -'use client'; - -// This page is temporary to ease the migration to Next.js App Router -// It will be deprecated once the migration is fully complete -import { type ReactNode, use, useEffect } from 'react'; -import dynamic from 'next/dynamic'; -import { PersistGate } from 'redux-persist/integration/react'; -import { persistor } from '../../store/store'; -import { useAppDispatch } from '../../hooks'; -import { resetProfileErrors } from '../../store/profile-reducer'; - -const App = dynamic(async () => await import('../../App'), { ssr: false }); - -interface PageProps { - params: Promise<{ - locale: string; - slug: string[]; - }>; -} - -export default function Page({ params }: PageProps): ReactNode { - const { locale } = use(params); - const pathKey = use(params).slug?.join('/') ?? '/'; - const dispatch = useAppDispatch(); - - useEffect(() => { - // Clean errors from previous session - dispatch(resetProfileErrors()); - }, [dispatch]); - - // Pass locale to App so BrowserRouter can use correct basename - return ( - - ; - - ); -} diff --git a/src/app/router/Router.tsx b/src/app/router/Router.tsx deleted file mode 100644 index 1a12816..0000000 --- a/src/app/router/Router.tsx +++ /dev/null @@ -1,5 +0,0 @@ -import type React from 'react'; - -export const AppRouter: React.FC = () => null; - -export default AppRouter; diff --git a/src/app/screens/Feeds/SearchTable.spec.tsx b/src/app/screens/Feeds/SearchTable.spec.tsx index 53453aa..3bf5fde 100644 --- a/src/app/screens/Feeds/SearchTable.spec.tsx +++ b/src/app/screens/Feeds/SearchTable.spec.tsx @@ -1,6 +1,5 @@ import SearchTable, { getDataTypeElement } from './SearchTable'; import { render, cleanup, screen, within } from '@testing-library/react'; -import { MemoryRouter } from 'react-router-dom'; import { type AllFeedsType } from '../../services/feeds/utils'; import { ThemeProvider } from '@mui/material/styles'; import { theme } from '../../Theme'; @@ -140,17 +139,11 @@ const mockFeedsData: AllFeedsType = { ], }; -describe.only('getProviderElement', () => { +describe('getProviderElement', () => { afterEach(cleanup); it('should display the correct number of transit providers in table row', () => { - render( - - - - - , - ); + render(); expect(screen.getByText('Utah Transit Authority (UTA)')).toBeTruthy(); const parentElement = screen.getByText('Angel Island Tiburon Ferry'); diff --git a/yarn.lock b/yarn.lock index 2e1c9eb..b234dbb 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3006,11 +3006,6 @@ redux-thunk "^2.4.2" reselect "^4.1.8" -"@remix-run/router@1.23.2": - version "1.23.2" - resolved "https://registry.yarnpkg.com/@remix-run/router/-/router-1.23.2.tgz#156c4b481c0bee22a19f7924728a67120de06971" - integrity sha512-Ic6m2U/rMjTkhERIa/0ZtXJP17QUi2CbWE7cqx4J58M8aA3QTfW+2UlQ4psvTX9IO1RfNVhK3pcpdjej7L+t2w== - "@rollup/plugin-commonjs@28.0.1": version "28.0.1" resolved "https://registry.yarnpkg.com/@rollup/plugin-commonjs/-/plugin-commonjs-28.0.1.tgz#e2138e31cc0637676dc3d5cae7739131f7cd565e" @@ -3817,11 +3812,6 @@ resolved "https://registry.yarnpkg.com/@types/geojson/-/geojson-7946.0.16.tgz#8ebe53d69efada7044454e3305c19017d97ced2a" integrity sha512-6C8nqWur3j98U6+lXDfTUWIfgvZU+EumvpHKcYjujKH7woYyLj2sUmff0tRhrqM7BohUw7Pz3ZB1jj2gW9Fvmg== -"@types/history@^4.7.11": - version "4.7.11" - resolved "https://registry.yarnpkg.com/@types/history/-/history-4.7.11.tgz#56588b17ae8f50c53983a524fc3cc47437969d64" - integrity sha512-qjDJRrmvBMiTx+jyLxvLfJU7UznFuokDv4f3WRuriHKERccVpFU+8XMQUAbDzoiJCsmexxRExQeMwwCdamSKDA== - "@types/hoist-non-react-statics@^3.3.0", "@types/hoist-non-react-statics@^3.3.1": version "3.3.7" resolved "https://registry.yarnpkg.com/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.7.tgz#306e3a3a73828522efa1341159da4846e7573a6c" @@ -4016,23 +4006,6 @@ hoist-non-react-statics "^3.3.0" redux "^4.0.0" -"@types/react-router-dom@^5.3.3": - version "5.3.3" - resolved "https://registry.yarnpkg.com/@types/react-router-dom/-/react-router-dom-5.3.3.tgz#e9d6b4a66fcdbd651a5f106c2656a30088cc1e83" - integrity sha512-kpqnYK4wcdm5UaWI3fLcELopqLrHgLqNsdpHauzlQktfkHL3npOSwtj1Uz9oKBAzs7lFtVkV8j83voAz2D8fhw== - dependencies: - "@types/history" "^4.7.11" - "@types/react" "*" - "@types/react-router" "*" - -"@types/react-router@*": - version "5.1.20" - resolved "https://registry.yarnpkg.com/@types/react-router/-/react-router-5.1.20.tgz#88eccaa122a82405ef3efbcaaa5dcdd9f021387c" - integrity sha512-jGjmu/ZqS7FjSH6owMcD5qpq19+1RS9DeVRqfl1FeBMxTDQAGwlMWOcs52NDoXaNKyG3d1cYQFMs9rCrb88o9Q== - dependencies: - "@types/history" "^4.7.11" - "@types/react" "*" - "@types/react-transition-group@^4.4.12": version "4.4.12" resolved "https://registry.yarnpkg.com/@types/react-transition-group/-/react-transition-group-4.4.12.tgz#b5d76568485b02a307238270bfe96cb51ee2a044" @@ -11447,21 +11420,6 @@ react-redux@^8.1.3: react-is "^18.0.0" use-sync-external-store "^1.0.0" -react-router-dom@^6.16.0: - version "6.30.3" - resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-6.30.3.tgz#42ae6dc4c7158bfb0b935f162b9621b29dddf740" - integrity sha512-pxPcv1AczD4vso7G4Z3TKcvlxK7g7TNt3/FNGMhfqyntocvYKj+GCatfigGDjbLozC4baguJ0ReCigoDJXb0ag== - dependencies: - "@remix-run/router" "1.23.2" - react-router "6.30.3" - -react-router@6.30.3: - version "6.30.3" - resolved "https://registry.yarnpkg.com/react-router/-/react-router-6.30.3.tgz#994b3ccdbe0e81fe84d4f998100f62584dfbf1cf" - integrity sha512-XRnlbKMTmktBkjCLE8/XcZFlnHvr2Ltdr1eJX4idL55/9BbORzyZEaIkBFDhFGCEWBBItsVrDxwx3gnisMitdw== - dependencies: - "@remix-run/router" "1.23.2" - react-smooth@^4.0.4: version "4.0.4" resolved "https://registry.yarnpkg.com/react-smooth/-/react-smooth-4.0.4.tgz#a5875f8bb61963ca61b819cedc569dc2453894b4" From 8c44feb9378ba40ab30eeb3ebbf43cb0e894e2fa Mon Sep 17 00:00:00 2001 From: Alessandro Kreslin Date: Tue, 14 Apr 2026 13:20:15 -0400 Subject: [PATCH 3/6] update comments regarding catch-all route --- .../[locale]/feeds/[feedDataType]/[feedId]/static/layout.tsx | 3 +-- src/app/components/AuthBroadcastChannelSync.tsx | 1 - src/app/components/Context.tsx | 3 ++- src/app/components/ProtectedPageWrapper.tsx | 4 ++-- src/app/components/ReduxGateWrapper.tsx | 4 ++-- src/app/store/saga/auth-saga.ts | 3 +-- src/app/store/store.ts | 3 +-- src/proxy.ts | 5 ----- 8 files changed, 9 insertions(+), 17 deletions(-) diff --git a/src/app/[locale]/feeds/[feedDataType]/[feedId]/static/layout.tsx b/src/app/[locale]/feeds/[feedDataType]/[feedId]/static/layout.tsx index d5e52c5..2beedda 100644 --- a/src/app/[locale]/feeds/[feedDataType]/[feedId]/static/layout.tsx +++ b/src/app/[locale]/feeds/[feedDataType]/[feedId]/static/layout.tsx @@ -22,8 +22,7 @@ interface Props { * SECURITY: Direct access to /static/ routes is blocked at the proxy level * (middleware returns 404). This route is only accessible via proxy rewrite * from the clean URLs like /feeds/gtfs/mdb-123. - * NOTE: In the future we will use private route `_static` but due to our legacy handler `[...slug]` catching all routes, we need to use a public route and block access at the proxy for now. - * + * TODO: Now that legacy catch-all route is removed, change this to a private route `_static` and update proxy and links accordingly. */ export default async function StaticFeedLayout({ children, diff --git a/src/app/components/AuthBroadcastChannelSync.tsx b/src/app/components/AuthBroadcastChannelSync.tsx index 3aa7cc4..0e2db8f 100644 --- a/src/app/components/AuthBroadcastChannelSync.tsx +++ b/src/app/components/AuthBroadcastChannelSync.tsx @@ -13,7 +13,6 @@ import { /** * Registers the cross-tab auth broadcast channels once for the App Router tree. - * This replaces the legacy BrowserRouter-based registration in Router.tsx. */ export function AuthBroadcastChannelSync(): ReactElement | null { const router = useRouter(); diff --git a/src/app/components/Context.tsx b/src/app/components/Context.tsx index 672f3a5..012972d 100644 --- a/src/app/components/Context.tsx +++ b/src/app/components/Context.tsx @@ -8,7 +8,8 @@ import { store } from '../store/store'; /** * This component is used to wrap the entire application with Redux Provider * It provides the Redux store to all components in the app - * IMPORTANT: This does not include the PersistGate, which is used in the page component to delay rendering until the store is rehydrated + * IMPORTANT: This does not include the PersistGate, which is applied by + * route-level wrappers where delayed rendering is required. * This allows for a fast initial render, but makes it possible for components to access the store before it's fully rehydrated. * This also allows for us to have SSG pages that use Redux. It also allows for these pages to be rendered purely in HTML on the server side without waiting for Redux Persist to rehydrate the store. * Use the `useRehydrated` hook to check rehydration status if needed. diff --git a/src/app/components/ProtectedPageWrapper.tsx b/src/app/components/ProtectedPageWrapper.tsx index 8de3a82..9b8b2c3 100644 --- a/src/app/components/ProtectedPageWrapper.tsx +++ b/src/app/components/ProtectedPageWrapper.tsx @@ -1,7 +1,7 @@ 'use client'; -// TODO: Once the [...slug] catch-all route is removed, replace this wrapper -// with a (protected) route group layout that provides auth guarding at the layout level. +// TODO: Replace this wrapper with a (protected) route group layout that +// provides auth guarding at the layout level. // targetStatus can be used to scope groups further (e.g. (authenticated), (unverified)). import { useEffect } from 'react'; import { useSelector } from 'react-redux'; diff --git a/src/app/components/ReduxGateWrapper.tsx b/src/app/components/ReduxGateWrapper.tsx index b4b8b5b..c800de9 100644 --- a/src/app/components/ReduxGateWrapper.tsx +++ b/src/app/components/ReduxGateWrapper.tsx @@ -1,7 +1,7 @@ 'use client'; -// TODO: Once the [...slug] catch-all route is removed, replace this wrapper -// with a (store) route group layout that provides PersistGate at the layout level. +// TODO: Replace this wrapper with a (store) route group layout that provides +// PersistGate at the layout level. import { Suspense } from 'react'; import { PersistGate } from 'redux-persist/integration/react'; import { persistor } from '../store/store'; diff --git a/src/app/store/saga/auth-saga.ts b/src/app/store/saga/auth-saga.ts index 295659e..7a65177 100644 --- a/src/app/store/saga/auth-saga.ts +++ b/src/app/store/saga/auth-saga.ts @@ -98,8 +98,7 @@ function* logoutSaga({ try { broadcastMessage(LOGOUT_CHANNEL); } catch { - // Broadcast channels may not be initialised if no - // legacy [...slug] page has been rendered yet. + // Broadcast channels may not be initialised yet. } } navigateTo(redirectScreen); diff --git a/src/app/store/store.ts b/src/app/store/store.ts index a716372..be329de 100644 --- a/src/app/store/store.ts +++ b/src/app/store/store.ts @@ -85,8 +85,7 @@ if (typeof window !== 'undefined' && (window as any).Cypress) { sagaMiddleware.run(rootSaga); // Create the persistor at the store level so rehydration and -// state-persistence happen on every page load, not just on the -// legacy catch-all route. +// state-persistence can be shared by route-level gate wrappers. export const persistor = persistStore(store); export type RootState = ReturnType; diff --git a/src/proxy.ts b/src/proxy.ts index 088be3a..2bfbf3c 100644 --- a/src/proxy.ts +++ b/src/proxy.ts @@ -10,11 +10,6 @@ import { DEFAULT_LOCALE, } from './app/utils/proxy-helpers'; -/** - * IMPORTANT: The logic of this proxy will be tested once the [...slug] route is removed - * Reasoning: [...slug] will catch all routes including those with wrong locale prefixes - */ - /** * Internationalization and auth-routing proxy following the Next.js i18n guide. * @see https://nextjs.org/docs/app/guides/internationalization From 36775e8f12d4935f8d3d3d56ad7d826bc887623c Mon Sep 17 00:00:00 2001 From: Alessandro Kreslin Date: Thu, 30 Apr 2026 13:10:16 -0400 Subject: [PATCH 4/6] lint fix --- src/app/screens/Feeds/SearchTable.spec.tsx | 2 -- src/app/utils/analytics-types.ts | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/app/screens/Feeds/SearchTable.spec.tsx b/src/app/screens/Feeds/SearchTable.spec.tsx index 3bf5fde..47c7328 100644 --- a/src/app/screens/Feeds/SearchTable.spec.tsx +++ b/src/app/screens/Feeds/SearchTable.spec.tsx @@ -1,8 +1,6 @@ import SearchTable, { getDataTypeElement } from './SearchTable'; import { render, cleanup, screen, within } from '@testing-library/react'; import { type AllFeedsType } from '../../services/feeds/utils'; -import { ThemeProvider } from '@mui/material/styles'; -import { theme } from '../../Theme'; jest.mock('../../../i18n/navigation', () => ({ useRouter: () => ({ push: jest.fn() }), diff --git a/src/app/utils/analytics-types.ts b/src/app/utils/analytics-types.ts index 0b6391e..4ad4cb6 100644 --- a/src/app/utils/analytics-types.ts +++ b/src/app/utils/analytics-types.ts @@ -90,4 +90,4 @@ export interface GBFSVersionMetrics { version: string; computed_on: Date[]; feeds_count: number[]; -} \ No newline at end of file +} From 27a7c54db9ad9a020f1e5f3bff87bd5b04579880 Mon Sep 17 00:00:00 2001 From: Alessandro Kreslin Date: Thu, 30 Apr 2026 13:14:53 -0400 Subject: [PATCH 5/6] remove dead code --- .../[locale]/metrics/_components/Analytics/utils.ts | 13 ------------- 1 file changed, 13 deletions(-) delete mode 100644 src/app/[locale]/metrics/_components/Analytics/utils.ts diff --git a/src/app/[locale]/metrics/_components/Analytics/utils.ts b/src/app/[locale]/metrics/_components/Analytics/utils.ts deleted file mode 100644 index 2f374ab..0000000 --- a/src/app/[locale]/metrics/_components/Analytics/utils.ts +++ /dev/null @@ -1,13 +0,0 @@ -/** - * Global analytics bucket endpoint storage and access. - */ -let globalAnalyticsBucketEndpoint: string | undefined; - -export const getAnalyticsBucketEndpoint = (): string | undefined => - globalAnalyticsBucketEndpoint; - -export const setAnalyticsBucketEndpoint = ( - endpoint: string | undefined, -): void => { - globalAnalyticsBucketEndpoint = endpoint; -}; From 5f22b7cdd36471c6dfa88c809252fd80188b6558 Mon Sep 17 00:00:00 2001 From: Alessandro Kreslin Date: Thu, 30 Apr 2026 13:29:05 -0400 Subject: [PATCH 6/6] test fix Co-authored-by: Copilot --- src/app/screens/Feeds/SearchTable.spec.tsx | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/app/screens/Feeds/SearchTable.spec.tsx b/src/app/screens/Feeds/SearchTable.spec.tsx index 47c7328..1ae2984 100644 --- a/src/app/screens/Feeds/SearchTable.spec.tsx +++ b/src/app/screens/Feeds/SearchTable.spec.tsx @@ -1,6 +1,8 @@ import SearchTable, { getDataTypeElement } from './SearchTable'; import { render, cleanup, screen, within } from '@testing-library/react'; import { type AllFeedsType } from '../../services/feeds/utils'; +import { ThemeProvider } from '@mui/material/styles'; +import { theme } from '../../Theme'; jest.mock('../../../i18n/navigation', () => ({ useRouter: () => ({ push: jest.fn() }), @@ -141,7 +143,11 @@ describe('getProviderElement', () => { afterEach(cleanup); it('should display the correct number of transit providers in table row', () => { - render(); + render( + + + , + ); expect(screen.getByText('Utah Transit Authority (UTA)')).toBeTruthy(); const parentElement = screen.getByText('Angel Island Tiburon Ferry');