import { describe, expect, it } from "vitest"; import { resolveChatKeyboardFallbackInset, resolveChatKeyboardInset, type ChatKeyboardViewportBaseline, type ChatKeyboardViewportSnapshot, } from "../chat-keyboard-geometry"; const baseline: ChatKeyboardViewportBaseline = { layoutHeight: 800, layoutWidth: 390, visualHeight: 760, }; function makeSnapshot( overrides: Partial = {}, ): ChatKeyboardViewportSnapshot { return { layoutHeight: 800, visualHeight: 760, visualScale: 1, virtualKeyboardHeight: 0, ...overrides, }; } describe("resolveChatKeyboardInset", () => { it("does not add an inset when the content viewport already resized", () => { expect( resolveChatKeyboardInset( baseline, makeSnapshot({ layoutHeight: 500, visualHeight: 500 }), ), ).toEqual({ keyboardVisible: true, bottomInset: 0, source: "content-resize", }); }); it("uses the visual viewport occlusion with the target gap", () => { expect( resolveChatKeyboardInset( baseline, makeSnapshot({ visualHeight: 460 }), ), ).toEqual({ keyboardVisible: true, bottomInset: 316, source: "visual-viewport", }); }); it("prefers Virtual Keyboard geometry when available", () => { expect( resolveChatKeyboardInset( baseline, makeSnapshot({ visualHeight: 520, virtualKeyboardHeight: 320, }), ), ).toEqual({ keyboardVisible: true, bottomInset: 336, source: "virtual-keyboard", }); }); it("ignores visual viewport changes caused by page zoom", () => { expect( resolveChatKeyboardInset( baseline, makeSnapshot({ visualHeight: 460, visualScale: 1.2 }), ), ).toEqual({ keyboardVisible: false, bottomInset: 0, source: "none", }); }); }); describe("resolveChatKeyboardFallbackInset", () => { it.each([ [{ layoutWidth: 320, layoutHeight: 568 }, 260], [{ layoutWidth: 360, layoutHeight: 640 }, 291], [{ layoutWidth: 390, layoutHeight: 844 }, 344], [{ layoutWidth: 430, layoutHeight: 932 }, 356], ])("fits common viewport %o", (viewport, expectedInset) => { expect(resolveChatKeyboardFallbackInset(viewport)).toBe(expectedInset); }); it("covers the reported 392 by 760 Facebook viewport", () => { expect( resolveChatKeyboardFallbackInset({ layoutWidth: 392, layoutHeight: 760, }), ).toBe(343); }); it("stays stable across tall viewports with the same width", () => { expect( resolveChatKeyboardFallbackInset({ layoutWidth: 390, layoutHeight: 760, }), ).toBe(343); expect( resolveChatKeyboardFallbackInset({ layoutWidth: 390, layoutHeight: 900, }), ).toBe(344); }); it("keeps the keyboard estimate within its bounds", () => { expect( resolveChatKeyboardFallbackInset({ layoutWidth: 300, layoutHeight: 400, }), ).toBe(256); expect( resolveChatKeyboardFallbackInset({ layoutWidth: 600, layoutHeight: 1_000, }), ).toBe(356); }); });