import { isCoarsePointer, isLowPowerDevice, isMobileViewport, isSaveData, MOBILE_QUERY, } from "./device"; const originalMatchMedia = window.matchMedia; function mockMedia(active: string[]) { window.matchMedia = jest.fn().mockImplementation((query: string) => ({ matches: active.includes(query), media: query, addEventListener() {}, removeEventListener() {}, })); } function mockNavigator(values: Record) { for (const [key, value] of Object.entries(values)) Object.defineProperty(navigator, key, { configurable: true, value }); } beforeEach(() => { mockMedia([]); mockNavigator({ hardwareConcurrency: 8, deviceMemory: undefined, connection: undefined, }); }); afterEach(() => { window.matchMedia = originalMatchMedia; }); describe("device hints", () => { it("treats a capable desktop as full power", () => { expect(isLowPowerDevice()).toBe(false); expect(isCoarsePointer()).toBe(false); expect(isSaveData()).toBe(false); expect(isMobileViewport()).toBe(false); }); it("reads the phone breakpoint from the shared query", () => { mockMedia([MOBILE_QUERY]); expect(isMobileViewport()).toBe(true); expect(MOBILE_QUERY).toBe("(max-width: 767px)"); }); it.each([ ["a touch pointer", () => mockMedia(["(pointer: coarse)"])], ["reduced motion", () => mockMedia(["(prefers-reduced-motion: reduce)"])], ["the data saver", () => mockNavigator({ connection: { saveData: true } })], ["four cores", () => mockNavigator({ hardwareConcurrency: 4 })], ["two cores", () => mockNavigator({ hardwareConcurrency: 2 })], ["4 GB of memory", () => mockNavigator({ deviceMemory: 4 })], ["2 GB of memory", () => mockNavigator({ deviceMemory: 2 })], ])("is low power with %s", (_label, arrange) => { arrange(); expect(isLowPowerDevice()).toBe(true); }); it("does not penalize a browser that hides the hardware hints", () => { mockNavigator({ hardwareConcurrency: undefined, deviceMemory: undefined }); expect(isLowPowerDevice()).toBe(false); }); it("keeps 8 GB and 6 cores on the full path", () => { mockNavigator({ hardwareConcurrency: 6, deviceMemory: 8 }); expect(isLowPowerDevice()).toBe(false); }); });