import { CacheProvider } from "@emotion/react"; import { render, screen, within } from "@testing-library/react"; import userEvent from "@testing-library/user-event"; import { MemoryRouter, Route, Routes } from "react-router-dom"; import { beforeEach, describe, expect, test, vi } from "vitest"; import { externalEmotionCache } from "../i18n/emotionCache.js"; import { ExternalI18nProvider } from "../i18n/ExternalI18nProvider.jsx"; import { EXTERNAL_LOCALE_STORAGE_KEY } from "../i18n/messages.js"; import { ExternalAdminLayout } from "./ExternalAdminLayout.jsx"; const auth = vi.hoisted(() => ({ logout: vi.fn(), session: { account: "fami-manager", appCode: "fami", appName: "Fami", logoUrl: "https://media.example.com/apps/fami.png", capabilities: ["user:list", "room:list"] } })); const viewport = vi.hoisted(() => ({ mobile: false })); vi.mock("../auth/ExternalAuthProvider.jsx", () => ({ useExternalAuth: () => auth })); vi.mock("@mui/material/useMediaQuery", () => ({ default: () => viewport.mobile })); describe("ExternalAdminLayout RTL", () => { beforeEach(() => { localStorage.setItem(EXTERNAL_LOCALE_STORAGE_KEY, "ar"); viewport.mobile = false; auth.session = { account: "fami-manager", appCode: "fami", appName: "Fami", logoUrl: "https://media.example.com/apps/fami.png", capabilities: ["user:list", "room:list"] }; }); test("shows the H5 tab bar and opens the more sheet in Arabic", async () => { const user = userEvent.setup(); viewport.mobile = true; renderLayout(); const tabbar = document.querySelector(".external-tabbar"); expect(tabbar).toBeInTheDocument(); expect(within(tabbar).getByRole("link", { name: "الرئيسية" })).toBeInTheDocument(); await user.click(within(tabbar).getByRole("button", { name: "المزيد" })); const sheet = document.querySelector(".MuiDrawer-paper.external-sheet"); expect(sheet).toBeInTheDocument(); expect(sheet.closest(".MuiModal-root")).not.toBeNull(); expect(within(sheet).getByRole("link", { name: "الرئيسية" })).toBeInTheDocument(); expect(within(sheet).getByRole("button", { name: "تسجيل الخروج" })).toBeInTheDocument(); }); test("places the desktop navigation drawer on the right for Arabic", () => { const view = renderLayout(); expect(document.documentElement).toHaveAttribute("dir", "rtl"); expect(document.documentElement).toHaveAttribute("lang", "ar"); const permanentDrawer = document.querySelectorAll(".MuiDrawer-paper")[0]; // Emotion prefixes generated classes with the cache key, so the RTL cache yields external-rtl-*. const generatedClass = Array.from(permanentDrawer.classList).find((className) => className.startsWith("external-rtl-") || className.startsWith("css-")); const drawerRule = Array.from(document.styleSheets) .flatMap((sheet) => Array.from(sheet.cssRules || [])) .map((rule) => rule.cssText) .find((cssText) => cssText.includes(`.${generatedClass}`)); expect(drawerRule).toContain("right: 0px"); expect(drawerRule).toContain("border-left:"); expect(document.querySelector(".external-sidebar-brand img")).toHaveAttribute("src", "https://media.example.com/apps/fami.png"); expect(screen.getAllByText("Fami").length).toBeGreaterThan(0); expect(screen.queryByText("إدارة HYApp الخارجية")).not.toBeInTheDocument(); expect(document.title).toBe("Fami"); expect(document.head.querySelector('link[data-external-app-favicon="true"]')).toHaveAttribute("href", "https://media.example.com/apps/fami.png"); expect(screen.getAllByText("الرئيسية").length).toBeGreaterThan(0); expect(screen.getByRole("combobox", { name: "اللغة" })).toHaveTextContent("العربية"); view.unmount(); expect(document.title).toBe("الإدارة الخارجية"); expect(document.head.querySelector('link[data-external-app-favicon="true"]')).not.toBeInTheDocument(); }); test("uses the App name, logo and title resolved by the authenticated session", () => { auth.session = { ...auth.session, account: "lalu-manager", appCode: "lalu", appName: "Lalu", logoUrl: "https://media.example.com/apps/lalu.png" }; const view = renderLayout(); expect(screen.getAllByText("Lalu").length).toBeGreaterThan(0); expect(document.querySelector(".external-sidebar-brand img")).toHaveAttribute("src", "https://media.example.com/apps/lalu.png"); expect(document.title).toBe("Lalu"); expect(document.head.querySelector('link[data-external-app-favicon="true"]')).toHaveAttribute("href", "https://media.example.com/apps/lalu.png"); view.unmount(); expect(document.title).toBe("الإدارة الخارجية"); expect(document.head.querySelector('link[data-external-app-favicon="true"]')).not.toBeInTheDocument(); }); }); function renderLayout() { // The RTL Emotion cache is part of the production setup: physical styles are written // for LTR and flipped by the cache, so the test must run the same pipeline. return render( }> overview content} path="/overview" /> ); }