관리자 미디어 선택 상태 분리
This commit is contained in:
@@ -8,6 +8,7 @@ import {
|
||||
buildMediaPickerUploadHint,
|
||||
createMediaBlockMarkdown,
|
||||
createDefaultMediaPickerPagination,
|
||||
createSelectedMediaInsertPlan,
|
||||
findUploadSizeLimitError,
|
||||
formatMediaFileSize,
|
||||
getGallerySelectionOrder,
|
||||
@@ -157,6 +158,100 @@ test('미디어 항목으로 fenced 미디어 블록을 만든다', () => {
|
||||
}), [':::file', 'url=/uploads/a.pdf', 'title=a.pdf', 'description=', 'name=a.pdf', 'size=2 KB', ':::'])
|
||||
})
|
||||
|
||||
test('선택 미디어 삽입 계획은 슬래시 줄 삽입과 일반 삽입을 구분한다', () => {
|
||||
assert.deepEqual(createSelectedMediaInsertPlan({
|
||||
target: 'image',
|
||||
selectedItems: [{ url: '/uploads/a.png' }],
|
||||
liveSlashLine: 3
|
||||
}), {
|
||||
kind: 'insert-at-line',
|
||||
line: 3,
|
||||
lines: ['']
|
||||
})
|
||||
|
||||
assert.deepEqual(createSelectedMediaInsertPlan({
|
||||
target: 'gallery',
|
||||
selectedItems: [{ url: '/uploads/a.png' }, { url: '/uploads/b.png' }],
|
||||
liveSlashLine: 1
|
||||
}), {
|
||||
kind: 'insert-at-line',
|
||||
line: 1,
|
||||
lines: [':::gallery', '', '', ':::']
|
||||
})
|
||||
|
||||
assert.deepEqual(createSelectedMediaInsertPlan({
|
||||
target: 'video',
|
||||
selectedItems: [{ url: '/uploads/a.mp4', title: '영상' }],
|
||||
liveSlashLine: 2
|
||||
}), {
|
||||
kind: 'insert-at-line',
|
||||
line: 2,
|
||||
lines: [':::video', 'url=/uploads/a.mp4', 'title=영상', 'caption=', ':::']
|
||||
})
|
||||
})
|
||||
|
||||
test('선택 미디어 삽입 계획은 일반 삽입 대상을 구분한다', () => {
|
||||
assert.deepEqual(createSelectedMediaInsertPlan({
|
||||
target: 'image',
|
||||
selectedItems: [{ url: '/uploads/a.png' }],
|
||||
liveSlashLine: null
|
||||
}), {
|
||||
kind: 'image',
|
||||
image: {
|
||||
url: '/uploads/a.png',
|
||||
useAlt: false,
|
||||
caption: ''
|
||||
}
|
||||
})
|
||||
|
||||
assert.deepEqual(createSelectedMediaInsertPlan({
|
||||
target: 'active-gallery',
|
||||
selectedItems: [{ url: '/uploads/a.png' }, { url: '/uploads/b.png' }],
|
||||
liveSlashLine: null
|
||||
}), {
|
||||
kind: 'active-gallery',
|
||||
images: [
|
||||
{
|
||||
url: '/uploads/a.png',
|
||||
useAlt: false,
|
||||
caption: ''
|
||||
},
|
||||
{
|
||||
url: '/uploads/b.png',
|
||||
useAlt: false,
|
||||
caption: ''
|
||||
}
|
||||
]
|
||||
})
|
||||
|
||||
assert.deepEqual(createSelectedMediaInsertPlan({
|
||||
target: 'file',
|
||||
selectedItems: [{ url: '/uploads/a.pdf', name: 'a.pdf', size: 2048 }],
|
||||
liveSlashLine: null
|
||||
}), {
|
||||
kind: 'block',
|
||||
lines: [':::file', 'url=/uploads/a.pdf', 'title=a.pdf', 'description=', 'name=a.pdf', 'size=2 KB', ':::']
|
||||
})
|
||||
})
|
||||
|
||||
test('선택 미디어 삽입 계획은 적용할 항목이 없으면 무시한다', () => {
|
||||
assert.deepEqual(createSelectedMediaInsertPlan({
|
||||
target: 'image',
|
||||
selectedItems: [],
|
||||
liveSlashLine: null
|
||||
}), {
|
||||
kind: 'none'
|
||||
})
|
||||
|
||||
assert.deepEqual(createSelectedMediaInsertPlan({
|
||||
target: 'unknown',
|
||||
selectedItems: [{ url: '/uploads/a.png' }],
|
||||
liveSlashLine: 1
|
||||
}), {
|
||||
kind: 'none'
|
||||
})
|
||||
})
|
||||
|
||||
test('갤러리 선택 순서를 선택 URL 순서로 반환한다', () => {
|
||||
assert.equal(getGallerySelectionOrder(['/a.png', '/b.png'], '/b.png'), 2)
|
||||
assert.equal(getGallerySelectionOrder(['/a.png'], '/b.png'), 0)
|
||||
|
||||
109
tests/useAdminMarkdownMediaPicker.test.js
Normal file
109
tests/useAdminMarkdownMediaPicker.test.js
Normal file
@@ -0,0 +1,109 @@
|
||||
import assert from 'node:assert/strict'
|
||||
import test from 'node:test'
|
||||
import { computed } from 'vue'
|
||||
import { useAdminMarkdownMediaPicker } from '../composables/useAdminMarkdownMediaPicker.js'
|
||||
|
||||
const uploadSizeLimits = computed(() => ({
|
||||
image: 10485760,
|
||||
video: 209715200,
|
||||
audio: 52428800,
|
||||
document: 52428800
|
||||
}))
|
||||
|
||||
test('관리자 Markdown 미디어 선택 모달은 열기와 닫기 상태를 관리한다', () => {
|
||||
const picker = useAdminMarkdownMediaPicker({ uploadSizeLimits })
|
||||
|
||||
picker.openMediaPickerState('gallery')
|
||||
|
||||
assert.equal(picker.isMediaPickerOpen.value, true)
|
||||
assert.equal(picker.mediaPickerTarget.value, 'gallery')
|
||||
assert.equal(picker.activeMediaPickerTab.value, 'upload')
|
||||
assert.equal(picker.mediaSearchQuery.value, '')
|
||||
assert.equal(picker.mediaPickerPage.value, 1)
|
||||
assert.deepEqual(picker.selectedMediaUrls.value, [])
|
||||
assert.equal(picker.isGalleryMediaPicker.value, true)
|
||||
assert.equal(picker.mediaPickerAccept.value, 'image/*')
|
||||
assert.equal(picker.mediaPickerTitle.value, '갤러리 이미지 선택')
|
||||
|
||||
assert.equal(picker.closeMediaPickerState(), true)
|
||||
assert.equal(picker.isMediaPickerOpen.value, false)
|
||||
assert.equal(picker.activeMediaPickerTab.value, 'upload')
|
||||
assert.deepEqual(picker.mediaItems.value, [])
|
||||
})
|
||||
|
||||
test('관리자 Markdown 미디어 선택 모달은 업로드 중 닫기를 막는다', () => {
|
||||
const picker = useAdminMarkdownMediaPicker({ uploadSizeLimits })
|
||||
|
||||
picker.openMediaPickerState('image')
|
||||
picker.isUploading.value = true
|
||||
|
||||
assert.equal(picker.closeMediaPickerState(), false)
|
||||
assert.equal(picker.isMediaPickerOpen.value, true)
|
||||
})
|
||||
|
||||
test('관리자 Markdown 미디어 선택 모달은 API 응답과 페이지를 상태에 반영한다', () => {
|
||||
const picker = useAdminMarkdownMediaPicker({ uploadSizeLimits, pageSize: 20 })
|
||||
|
||||
picker.applyMediaPickerResponse({
|
||||
items: [{ url: '/uploads/a.png' }],
|
||||
pagination: {
|
||||
page: 3,
|
||||
pageSize: 20,
|
||||
total: 42,
|
||||
pageCount: 3
|
||||
}
|
||||
})
|
||||
|
||||
assert.equal(picker.mediaPickerPage.value, 3)
|
||||
assert.equal(picker.mediaPickerPageCount.value, 3)
|
||||
assert.equal(picker.mediaPickerRangeLabel.value, '42개 중 41-42개')
|
||||
assert.deepEqual(picker.filteredMediaItems.value, [{ url: '/uploads/a.png' }])
|
||||
|
||||
picker.setMediaPickerPage(99)
|
||||
|
||||
assert.equal(picker.mediaPickerPage.value, 3)
|
||||
})
|
||||
|
||||
test('관리자 Markdown 미디어 선택 모달은 단일·갤러리 선택을 관리한다', () => {
|
||||
const picker = useAdminMarkdownMediaPicker({ uploadSizeLimits })
|
||||
|
||||
picker.openMediaPickerState('image')
|
||||
picker.mediaItems.value = [
|
||||
{ url: '/uploads/a.png' },
|
||||
{ url: '/uploads/b.png' }
|
||||
]
|
||||
picker.toggleMediaSelection({ url: '/uploads/a.png' })
|
||||
picker.toggleMediaSelection({ url: '/uploads/b.png' })
|
||||
|
||||
assert.deepEqual(picker.selectedMediaUrls.value, ['/uploads/b.png'])
|
||||
assert.deepEqual(picker.resolveCurrentSelectedMediaItems(), [{ url: '/uploads/b.png' }])
|
||||
|
||||
picker.openMediaPickerState('gallery')
|
||||
picker.toggleMediaSelection({ url: '/uploads/a.png' })
|
||||
picker.toggleMediaSelection({ url: '/uploads/b.png' })
|
||||
|
||||
assert.deepEqual(picker.selectedMediaUrls.value, ['/uploads/a.png', '/uploads/b.png'])
|
||||
assert.equal(picker.getGallerySelectionOrder('/uploads/b.png'), 2)
|
||||
assert.deepEqual(picker.mediaPickerApplyState.value, {
|
||||
disabled: false,
|
||||
label: '2개 삽입'
|
||||
})
|
||||
})
|
||||
|
||||
test('관리자 Markdown 미디어 선택 모달은 업로드 파일 선택 상태와 fallback 목록을 만든다', () => {
|
||||
const picker = useAdminMarkdownMediaPicker({ uploadSizeLimits })
|
||||
|
||||
picker.openMediaPickerState('image')
|
||||
picker.selectUploadedMediaFiles([
|
||||
{ url: '/uploads/a.png', kind: 'image' },
|
||||
{ url: '/uploads/a.mp4', kind: 'video' }
|
||||
])
|
||||
|
||||
assert.deepEqual(picker.selectedMediaUrls.value, ['/uploads/a.png'])
|
||||
|
||||
picker.prependUploadedMediaItems([{ url: '/uploads/a.png' }])
|
||||
|
||||
assert.deepEqual(picker.mediaItems.value, [{ url: '/uploads/a.png' }])
|
||||
assert.equal(picker.isUploadFileAllowedForPicker({ type: 'image/png' }), true)
|
||||
assert.equal(picker.isUploadFileAllowedForPicker({ type: 'video/mp4' }), false)
|
||||
})
|
||||
Reference in New Issue
Block a user