import { render, screen } from "@testing-library/react" import { describe, expect, it } from "vitest" import { GestureHUD, resolveHudState } from "@/features/gesture/GestureHUD" /* DESIGN-SYSTEM ยง11: HUD gesture memakai `role="status"`. Keadaan `holding` tidak bisa dipicu kamera palsu, jadi dibuktikan di sini. */ const BASE = { cameraActive: true, enabled: true, status: "ready" as const, phase: "ready" as const, holdAction: null, } describe("resolveHudState", () => { it("menyembunyikan HUD saat kamera belum aktif atau model gagal", () => { expect(resolveHudState({ ...BASE, cameraActive: false })).toBe("hidden") expect( resolveHudState({ ...BASE, cameraActive: false, holdAction: "snap" }) ).toBe("hidden") expect(resolveHudState({ ...BASE, status: "failed" })).toBe("hidden") expect( resolveHudState({ ...BASE, status: "failed", phase: "complete" }) ).toBe("hidden") }) it("menahan selalu menang atas keadaan lain", () => { expect(resolveHudState({ ...BASE, holdAction: "snap" })).toBe("holding") expect( resolveHudState({ ...BASE, enabled: false, holdAction: "retake" }) ).toBe("holding") expect( resolveHudState({ ...BASE, status: "loading", holdAction: "snap" }) ).toBe("holding") }) it("sakelar mati: mati saat siap, selesai saat semua slot terisi", () => { expect(resolveHudState({ ...BASE, enabled: false })).toBe("off") expect( resolveHudState({ ...BASE, enabled: false, phase: "complete" }) ).toBe("done") expect( resolveHudState({ ...BASE, enabled: false, phase: "countdown" }) ).toBe("hidden") }) it("menampilkan status memuat hanya saat pratinjau siap", () => { expect(resolveHudState({ ...BASE, status: "loading" })).toBe("loading") expect( resolveHudState({ ...BASE, status: "loading", phase: "countdown" }) ).toBe("hidden") }) it("siap: siap saat pratinjau siap, selesai saat semua slot terisi, sisanya sembunyi", () => { expect(resolveHudState(BASE)).toBe("ready") expect(resolveHudState({ ...BASE, phase: "complete" })).toBe("done") expect(resolveHudState({ ...BASE, phase: "countdown" })).toBe("hidden") expect(resolveHudState({ ...BASE, phase: "capturing" })).toBe("hidden") expect(resolveHudState({ ...BASE, phase: "pause" })).toBe("hidden") expect(resolveHudState({ ...BASE, phase: "holding" })).toBe("hidden") }) it("status idle saat sakelar menyala tidak menampilkan apa pun", () => { expect(resolveHudState({ ...BASE, status: "idle" })).toBe("hidden") }) }) describe("GestureHUD", () => { it("keadaan siap menyebut perintahnya", () => { render() expect(screen.getByRole("status")).toBeTruthy() expect(screen.getByText("Angkat dua jari, tahan sebentar")).toBeTruthy() }) it("keadaan memuat menyebut sedang menyiapkan", () => { render() expect(screen.getByText("Menyiapkan gesture...")).toBeTruthy() }) it("keadaan mati menyebut jalan lain", () => { render() expect(screen.getByText("Gesture mati. Pakai tombol kamera.")).toBeTruthy() }) it("keadaan selesai menyebut jumlah foto", () => { render() expect(screen.getByText("4 foto siap dihias")).toBeTruthy() }) it("keadaan tersembunyi tidak merender apa pun", () => { const { container } = render() expect(container.firstChild).toBeNull() }) it("keadaan menahan mengisi batang sesuai progres", () => { const { container } = render() expect(screen.getByText("Terdeteksi. Tahan...")).toBeTruthy() const bar = container.querySelector("div[style]") expect(bar?.style.width).toBe("35%") }) it("progres nol dan penuh dipotong ke 0 dan 100 persen", () => { const kosong = render() expect( kosong.container.querySelector("div[style]")?.style.width ).toBe("0%") kosong.unmount() const penuh = render() expect( penuh.container.querySelector("div[style]")?.style.width ).toBe("100%") }) })