BangSo/apps/mobile/lib/ui-direction.test.ts

76 lines
2.6 KiB
TypeScript
Raw Normal View History

2026-09-01 16:51:19 +00:00
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
vi.mock("expo", () => ({
reloadAppAsync: vi.fn().mockResolvedValue(undefined),
}));
vi.mock("react-native", () => ({
I18nManager: {
allowRTL: vi.fn(),
forceRTL: vi.fn(),
isRTL: false,
},
Platform: { OS: "ios" },
}));
describe("mobile ui direction", () => {
beforeEach(() => {
vi.resetModules();
});
afterEach(() => {
vi.unstubAllGlobals();
vi.clearAllMocks();
});
it("resolves a locale tag from Intl", async () => {
const resolvedOptions = vi.fn().mockReturnValue({ locale: "he-IL" });
vi.stubGlobal("Intl", {
...Intl,
DateTimeFormat: vi.fn().mockImplementation(() => ({ resolvedOptions })),
});
const { resolveMobileUiLocale } = await import("./ui-direction");
expect(resolveMobileUiLocale()).toBe("he-IL");
});
it("forces rtl and reloads when the runtime is still ltr", async () => {
const { I18nManager } = await import("react-native");
const { reloadAppAsync } = await import("expo");
(I18nManager as { isRTL: boolean }).isRTL = false;
const { applyMobileUiDirection } = await import("./ui-direction");
expect(applyMobileUiDirection("he-IL")).toBe(true);
expect(I18nManager.allowRTL).toHaveBeenCalledWith(true);
expect(I18nManager.forceRTL).toHaveBeenCalledWith(true);
await Promise.resolve();
expect(reloadAppAsync).toHaveBeenCalledWith("ui-direction");
});
it("forces ltr and reloads when the runtime is still rtl", async () => {
const { I18nManager } = await import("react-native");
const { reloadAppAsync } = await import("expo");
(I18nManager as { isRTL: boolean }).isRTL = true;
const { applyMobileUiDirection } = await import("./ui-direction");
expect(applyMobileUiDirection("en-US")).toBe(false);
expect(I18nManager.allowRTL).toHaveBeenCalledWith(true);
expect(I18nManager.forceRTL).toHaveBeenCalledWith(false);
await Promise.resolve();
expect(reloadAppAsync).toHaveBeenCalledWith("ui-direction");
});
it("skips forceRTL and reload when layout already matches the locale", async () => {
const { I18nManager } = await import("react-native");
const { reloadAppAsync } = await import("expo");
(I18nManager as { isRTL: boolean }).isRTL = true;
const { applyMobileUiDirection } = await import("./ui-direction");
expect(applyMobileUiDirection("he-IL")).toBe(true);
expect(I18nManager.allowRTL).toHaveBeenCalledWith(true);
expect(I18nManager.forceRTL).not.toHaveBeenCalled();
await Promise.resolve();
expect(reloadAppAsync).not.toHaveBeenCalled();
});
});