import assert from 'node:assert/strict' import test from 'node:test' import { useContentMarkdownLightbox } from '../composables/useContentMarkdownLightbox.js' /** * 라이트박스 키보드 이벤트 테스트용 대상을 만든다. * @returns {{ target: { addEventListener: Function, removeEventListener: Function }, listeners: Set, addCount: () => number, removeCount: () => number }} 이벤트 대상 */ const createKeyboardTarget = () => { const listeners = new Set() let added = 0 let removed = 0 return { listeners, addCount: () => added, removeCount: () => removed, target: { addEventListener: (type, handler) => { if (type !== 'keydown') { return } added += 1 listeners.add(handler) }, removeEventListener: (type, handler) => { if (type !== 'keydown') { return } removed += 1 listeners.delete(handler) } } } } /** * 키보드 이벤트 스텁을 만든다. * @param {string} key - 키 이름 * @returns {{ key: string, prevented: boolean, preventDefault: Function }} 이벤트 스텁 */ const createKeyboardEvent = (key) => ({ key, prevented: false, preventDefault () { this.prevented = true } }) test('본문 라이트박스는 키로 이미지를 열고 순환 이동한다', () => { const { target } = createKeyboardTarget() const lightbox = useContentMarkdownLightbox({ getKeyboardTarget: () => target }) const images = [ { lightboxKey: 'a', url: '/a.jpg' }, { lightboxKey: 'b', url: '/b.jpg' }, { lightboxKey: 'c', url: '/c.jpg' } ] lightbox.openContentLightbox(images, 'b') assert.equal(lightbox.activeLightboxImage.value.url, '/b.jpg') lightbox.showNextImage() assert.equal(lightbox.activeLightboxImage.value.url, '/c.jpg') lightbox.showNextImage() assert.equal(lightbox.activeLightboxImage.value.url, '/a.jpg') lightbox.showPreviousImage() assert.equal(lightbox.activeLightboxImage.value.url, '/c.jpg') }) test('본문 라이트박스는 열릴 때 키보드 이벤트를 한 번만 연결하고 닫힐 때 해제한다', () => { const keyboard = createKeyboardTarget() const lightbox = useContentMarkdownLightbox({ getKeyboardTarget: () => keyboard.target }) const images = [ { lightboxKey: 'a', url: '/a.jpg' }, { lightboxKey: 'b', url: '/b.jpg' } ] lightbox.openLightbox(images, 0) lightbox.openLightbox(images, 1) assert.equal(keyboard.addCount(), 1) assert.equal(keyboard.listeners.size, 1) assert.equal(lightbox.activeLightboxImage.value.url, '/b.jpg') const event = createKeyboardEvent('Escape') const [handler] = keyboard.listeners handler(event) assert.equal(event.prevented, true) assert.equal(lightbox.activeLightboxImage.value, undefined) assert.equal(keyboard.removeCount(), 1) assert.equal(keyboard.listeners.size, 0) }) test('본문 라이트박스 키보드 조작은 좌우 이동과 단일 이미지 예외를 처리한다', () => { const lightbox = useContentMarkdownLightbox() const images = [ { lightboxKey: 'a', url: '/a.jpg' }, { lightboxKey: 'b', url: '/b.jpg' } ] lightbox.openLightbox(images, 0) const rightEvent = createKeyboardEvent('ArrowRight') lightbox.handleLightboxKeydown(rightEvent) assert.equal(rightEvent.prevented, true) assert.equal(lightbox.activeLightboxImage.value.url, '/b.jpg') const leftEvent = createKeyboardEvent('ArrowLeft') lightbox.handleLightboxKeydown(leftEvent) assert.equal(leftEvent.prevented, true) assert.equal(lightbox.activeLightboxImage.value.url, '/a.jpg') lightbox.openLightbox([{ lightboxKey: 'single', url: '/single.jpg' }], 0) const singleLeftEvent = createKeyboardEvent('ArrowLeft') lightbox.handleLightboxKeydown(singleLeftEvent) assert.equal(singleLeftEvent.prevented, false) assert.equal(lightbox.activeLightboxImage.value.url, '/single.jpg') })