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%")
})
})