231 lines
7.4 KiB
JavaScript
231 lines
7.4 KiB
JavaScript
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)
|
|
})
|
|
|
|
test('관리자 Markdown 미디어 선택 모달은 서버 목록 조회를 상태에 반영한다', async () => {
|
|
const originalFetch = globalThis.$fetch
|
|
const calls = []
|
|
globalThis.$fetch = async (url, options) => {
|
|
calls.push({ url, options })
|
|
return {
|
|
items: [{ url: '/uploads/a.png', kind: 'image' }],
|
|
pagination: {
|
|
page: 2,
|
|
pageSize: 20,
|
|
total: 21,
|
|
pageCount: 2
|
|
}
|
|
}
|
|
}
|
|
|
|
try {
|
|
const picker = useAdminMarkdownMediaPicker({ uploadSizeLimits, pageSize: 20 })
|
|
picker.openMediaPickerState('image')
|
|
picker.mediaSearchQuery.value = ' a '
|
|
picker.mediaPickerPage.value = 2
|
|
|
|
await picker.fetchMediaItems()
|
|
|
|
assert.equal(picker.isLoadingMedia.value, false)
|
|
assert.deepEqual(picker.mediaItems.value, [{ url: '/uploads/a.png', kind: 'image' }])
|
|
assert.equal(picker.mediaPickerPage.value, 2)
|
|
assert.deepEqual(calls[0], {
|
|
url: '/admin/api/media',
|
|
options: {
|
|
query: {
|
|
paged: '1',
|
|
tab: 'library',
|
|
page: 2,
|
|
pageSize: 20,
|
|
kind: 'image',
|
|
search: 'a'
|
|
}
|
|
}
|
|
})
|
|
} finally {
|
|
globalThis.$fetch = originalFetch
|
|
}
|
|
})
|
|
|
|
test('관리자 Markdown 미디어 선택 모달은 업로드 후 라이브러리 탭과 선택 상태를 갱신한다', async () => {
|
|
const originalFetch = globalThis.$fetch
|
|
const uploadedFile = { url: '/uploads/a.png', kind: 'image' }
|
|
const calls = []
|
|
globalThis.$fetch = async (url, options) => {
|
|
calls.push({ url, options })
|
|
|
|
if (url === '/admin/api/uploads') {
|
|
return { files: [uploadedFile] }
|
|
}
|
|
|
|
return {
|
|
items: [uploadedFile],
|
|
pagination: {
|
|
page: 1,
|
|
pageSize: 50,
|
|
total: 1,
|
|
pageCount: 1
|
|
}
|
|
}
|
|
}
|
|
|
|
try {
|
|
const picker = useAdminMarkdownMediaPicker({
|
|
uploadSizeLimits,
|
|
uploadMaxFileCount: computed(() => 3),
|
|
uploadMaxTotalSize: computed(() => 1024 * 1024)
|
|
})
|
|
picker.openMediaPickerState('image')
|
|
|
|
const uploadedFiles = await picker.uploadFilesIntoMediaPicker([
|
|
new File(['image'], 'a.png', { type: 'image/png' })
|
|
])
|
|
|
|
assert.deepEqual(uploadedFiles, [uploadedFile])
|
|
assert.equal(picker.isUploading.value, false)
|
|
assert.equal(picker.activeMediaPickerTab.value, 'library')
|
|
assert.deepEqual(picker.selectedMediaUrls.value, ['/uploads/a.png'])
|
|
assert.deepEqual(picker.mediaItems.value, [uploadedFile])
|
|
assert.equal(calls[0].url, '/admin/api/uploads')
|
|
assert.equal(calls[0].options.method, 'POST')
|
|
assert.ok(calls[0].options.body instanceof FormData)
|
|
assert.equal(calls[1].url, '/admin/api/media')
|
|
} finally {
|
|
globalThis.$fetch = originalFetch
|
|
}
|
|
})
|
|
|
|
test('관리자 Markdown 미디어 선택 모달 업로드는 한도 초과 시 요청하지 않는다', async () => {
|
|
const originalFetch = globalThis.$fetch
|
|
let called = false
|
|
globalThis.$fetch = async () => {
|
|
called = true
|
|
return { files: [] }
|
|
}
|
|
|
|
try {
|
|
const picker = useAdminMarkdownMediaPicker({
|
|
uploadSizeLimits,
|
|
uploadMaxFileCount: computed(() => 1),
|
|
uploadMaxTotalSize: computed(() => 1024 * 1024)
|
|
})
|
|
|
|
await assert.rejects(
|
|
() => picker.uploadMediaFiles([
|
|
new File(['a'], 'a.png', { type: 'image/png' }),
|
|
new File(['b'], 'b.png', { type: 'image/png' })
|
|
]),
|
|
/최대 1개/
|
|
)
|
|
assert.equal(called, false)
|
|
} finally {
|
|
globalThis.$fetch = originalFetch
|
|
}
|
|
})
|