diff --git a/apps/frontend/src/layouts/index.test.tsx b/apps/frontend/src/layouts/index.test.tsx new file mode 100644 index 000000000..005db3749 --- /dev/null +++ b/apps/frontend/src/layouts/index.test.tsx @@ -0,0 +1,39 @@ +// @vitest-environment jsdom +import { render, screen } from "@testing-library/react"; +import { HttpResponse, http } from "msw"; +import { describe, expect, it, vi } from "vitest"; +import "../test/i18n"; +import { API_BASE_URL, server } from "../test/msw-server"; + +// Only the maintenance wiring is under test; stub the layout's unrelated chrome and hooks. +vi.mock("../components/Navbar", () => ({ Navbar: () => null })); +vi.mock("../components/Footer", () => ({ Footer: () => null })); +vi.mock("../components/Stepper", () => ({ default: () => null })); +vi.mock("../hooks/useInitTokenBalances", () => ({ useInitTokenBalances: () => undefined })); +vi.mock("../hooks/useStepper", () => ({ useStepper: () => ({ steps: [] }) })); +vi.mock("../hooks/useWidgetMode", () => ({ useWidgetMode: () => false })); +vi.mock("../hooks/ramp/useIsQuoteComponentDisplayed", () => ({ useIsQuoteComponentDisplayed: () => false })); + +import { BaseLayout } from "./index"; + +describe("BaseLayout", () => { + it("fetches the maintenance status on mount and shows an active maintenance banner", async () => { + server.use( + http.get(`${API_BASE_URL}/maintenance/status`, () => + HttpResponse.json({ + is_maintenance_active: true, + maintenance_details: { + end_datetime: "2026-10-02T12:00:00Z", + message: "Ramps are paused while we upgrade.", + start_datetime: "2026-10-02T10:00:00Z", + title: "Scheduled maintenance" + } + }) + ) + ); + + render(} />); + + expect(await screen.findByText("Scheduled maintenance")).toBeTruthy(); + }); +}); diff --git a/apps/frontend/src/layouts/index.tsx b/apps/frontend/src/layouts/index.tsx index 6deb7ae8e..6e8b734a2 100644 --- a/apps/frontend/src/layouts/index.tsx +++ b/apps/frontend/src/layouts/index.tsx @@ -1,13 +1,13 @@ -import { FC, ReactNode, useEffect } from "react"; +import { FC, ReactNode } from "react"; import { Footer } from "../components/Footer"; import { MaintenanceBanner } from "../components/MaintenanceBanner"; import { Navbar } from "../components/Navbar"; import Stepper from "../components/Stepper"; import { useIsQuoteComponentDisplayed } from "../hooks/ramp/useIsQuoteComponentDisplayed"; import { useInitTokenBalances } from "../hooks/useInitTokenBalances"; +import { useMaintenanceStatus } from "../hooks/useMaintenanceStatus"; import { useStepper } from "../hooks/useStepper"; import { useWidgetMode } from "../hooks/useWidgetMode"; -import { useFetchMaintenanceStatus } from "../stores/maintenanceStore"; interface BaseLayoutProps { main: ReactNode; @@ -21,7 +21,7 @@ export const BaseLayout: FC = ({ main, modals }) => { const isQuoteComponentDisplayed = useIsQuoteComponentDisplayed(); useInitTokenBalances(); - useFetchMaintenanceStatus(); + useMaintenanceStatus(); const isStepperHidden = isWidgetMode && isQuoteComponentDisplayed;