1import { fireEvent, render, screen } from "@testing-library/react"
2import { describe, expect, it, vi } from "vitest"
3
4import { ShotTray } from "@/features/capture/ShotTray"
5import type { Shot } from "@/stores/booth"
6
7const SLOT_RATIO = 528 / 372
8
9function shot(still: string): Shot {
10 return { still, capturedAt: 1 }
11}
12
13describe("ShotTray", () => {
14 it("menampilkan nomor slot untuk tiap slot kosong", () => {
15 render(
16 <ShotTray
17 shots={[null, null, null, null]}
18 slotRatio={SLOT_RATIO}
19 busy={false}
20 onRetake={() => undefined}
21 />
22 )
23
24 for (const nomor of ["1", "2", "3", "4"]) {
25 expect(screen.getByText(nomor)).toBeTruthy()
26 }
27 expect(screen.queryByRole("button")).toBeNull()
28 })
29
30 it("slot terisi jadi tombol ulang foto yang menunjuk indeksnya sendiri", () => {
31 const onRetake = vi.fn()
32 render(
33 <ShotTray
34 shots={[shot("data:image/jpeg;base64,a"), null, shot("data:image/jpeg;base64,b"), null]}
35 slotRatio={SLOT_RATIO}
36 busy={false}
37 onRetake={onRetake}
38 />
39 )
40
41 /* Slot 3 tetap menyediakan tombol ulangnya sendiri meski slot 2 kosong. */
42 fireEvent.click(screen.getByRole("button", { name: "Ulang foto 3" }))
43 expect(onRetake).toHaveBeenCalledWith(2)
44
45 fireEvent.click(screen.getByRole("button", { name: "Ulang foto 1" }))
46 expect(onRetake).toHaveBeenLastCalledWith(0)
47
48 /* Slot kosong tidak bisa ditekan. */
49 expect(screen.queryByRole("button", { name: "Ulang foto 2" })).toBeNull()
50 })
51
52 it("mengunci tombol selama pengambilan berlangsung", () => {
53 render(
54 <ShotTray
55 shots={[shot("data:image/jpeg;base64,a"), null]}
56 slotRatio={SLOT_RATIO}
57 busy
58 onRetake={() => undefined}
59 />
60 )
61
62 const tombol = screen.getByRole("button", { name: "Ulang foto 1" })
63 expect((tombol as HTMLButtonElement).disabled).toBe(true)
64 })
65})
66