// @vitest-environment jsdom import { strict as assert } from "node:assert"; import { afterEach, test } from "vitest"; import { renderHook } from "@testing-library/react"; import { useSaveShortcut } from "../../../src/features/tech-log/presentation/studio/components/use-save-shortcut.ts"; function pressSave(overrides: Partial = {}) { const event = new KeyboardEvent("keydown", { key: "s", ctrlKey: true, cancelable: true, bubbles: true, ...overrides, }); window.dispatchEvent(event); return event; } afterEach(() => { document.body.innerHTML = ""; }); /* 브라우저의 Ctrl+S 는 "페이지를 파일로 저장"이다. 글을 쓰다가 그 손버릇이 나오면 저장 대화상자가 뜨고 편집한 내용은 그대로 남는다 — 저장한 줄 알고 창을 닫으면 잃는다. 그래서 기본 동작을 막는 것까지가 이 훅의 일이다. */ test("Ctrl+S saves and keeps the browser from offering the page as a file", () => { let saved = 0; const { unmount } = renderHook(() => useSaveShortcut(() => { saved += 1; })); const event = pressSave(); assert.equal(saved, 1); assert.equal(event.defaultPrevented, true); unmount(); }); test("Cmd+S does the same, because the habit is the same on a Mac", () => { let saved = 0; const { unmount } = renderHook(() => useSaveShortcut(() => { saved += 1; })); pressSave({ ctrlKey: false, metaKey: true }); assert.equal(saved, 1); unmount(); }); /* 저장할 것이 없을 때도 기본 동작은 막는다. 막지 않으면 "저장할 것이 없다"는 화면 상태와 브라우저의 저장 대화상자가 동시에 나와, 무엇이 일어났는지 알 수 없다. */ test("a disabled shortcut still swallows the browser default", () => { let saved = 0; const { unmount } = renderHook(() => useSaveShortcut(() => { saved += 1; }, false), ); const event = pressSave(); assert.equal(saved, 0); assert.equal(event.defaultPrevented, true); unmount(); }); test("modified chords are left to whoever else wants them", () => { let saved = 0; const { unmount } = renderHook(() => useSaveShortcut(() => { saved += 1; })); const shift = pressSave({ shiftKey: true }); const alt = pressSave({ altKey: true }); const plain = pressSave({ ctrlKey: false }); assert.equal(saved, 0); assert.equal(shift.defaultPrevented, false); assert.equal(alt.defaultPrevented, false); assert.equal(plain.defaultPrevented, false); unmount(); }); test("the listener goes away with the screen", () => { let saved = 0; const { unmount } = renderHook(() => useSaveShortcut(() => { saved += 1; })); unmount(); pressSave(); assert.equal(saved, 0); });