import { expect, test, vi } from "vitest" import { Device } from "#Source/environment/index.ts" const setupForGetDeviceNavigatorInfo = (): (() => void) => { vi.stubGlobal("navigator", { oscpu: "Windows NT 10.0", hardwareConcurrency: 8, deviceMemory: 16, maxTouchPoints: 5, platform: "Win32", devicePosture: { type: "continuous" }, connection: { downlink: 10, downlinkMax: 100, effectiveType: "4g", rtt: 40, saveData: false, type: "wifi", }, onLine: true, cookieEnabled: true, language: "en-US", languages: ["en-US", "zh-CN"], pdfViewerEnabled: true, userAgent: "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36", }) return () => { vi.unstubAllGlobals() } } test("getDeviceNavigatorInfo collects navigator metadata", () => { const restore = setupForGetDeviceNavigatorInfo() const info = Device.getDeviceNavigatorInfo() expect(info.oscpu).toBe("Windows NT 10.0") expect(info.hardwareConcurrency).toBe(8) expect(info.connectionType).toBe("wifi") expect(info.languages).toEqual(["en-US", "zh-CN"]) restore() }) test("parseUserAgent normalizes user-agent metadata", () => { const userAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36" const info = Device.parseUserAgent(userAgent) expect(info.ua).toBe(userAgent) expect(typeof info.browserIsBot).toBe("boolean") expect(typeof info.browserIsChromeFamily).toBe("boolean") expect(typeof info.deviceIsAppleSilicon).toBe("boolean") }) const setupForGetDeviceScreenInfo = (): (() => void) => { vi.stubGlobal("document", { documentElement: { clientWidth: 1_200, clientHeight: 700, scrollWidth: 2_000, scrollHeight: 3_000, }, }) vi.stubGlobal("window", { devicePixelRatio: 2, screen: { width: 1_920, height: 1_080, availWidth: 1_900, availHeight: 1_060, orientation: { type: "landscape-primary" }, }, outerWidth: 1_400, outerHeight: 900, innerWidth: 1_200, innerHeight: 700, visualViewport: { width: 1_180, height: 680, offsetLeft: 10, offsetTop: 8, pageLeft: 0, pageTop: 0, scale: 1, }, }) vi.stubGlobal("getComputedStyle", () => ({ getPropertyValue: (name: string): string => { if (name.includes("top")) { return "10" } if (name.includes("bottom")) { return "20" } if (name.includes("left")) { return "30" } if (name.includes("right")) { return "40" } return "0" }, })) return () => { vi.unstubAllGlobals() } } test("getDeviceScreenInfo collects screen and viewport metadata", () => { const restore = setupForGetDeviceScreenInfo() const info = Device.getDeviceScreenInfo() expect(info.pixelRatio).toBe(2) expect(info.screenWidth).toBe(1_920) expect(info.viewportAvailableWidth).toBe(1_200) expect(info.safeAreaTop).toBe(10) expect(info.safeAreaRight).toBe(40) restore() }) test("getDeviceInfo aggregates navigator, user-agent, and screen metadata", () => { const restore1 = setupForGetDeviceNavigatorInfo() const restore2 = setupForGetDeviceScreenInfo() const userAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36" const info = Device.getDeviceInfo(userAgent) expect(info.navigator.language).toBe("en-US") expect(info.userAgent.ua).toBe(userAgent) expect(info.screen.viewportHeight).toBe(700) restore1() restore2() })