Files
sori.studio/tests/useContentMarkdownLightbox.test.js

130 lines
3.9 KiB
JavaScript

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<Function>, 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')
})