import assert from 'node:assert/strict' import test from 'node:test' import { detectMediaKind, detectMediaRole, escapePostgresLikeLiteral, extractMediaReferences, normalizeMediaCatalogUrl } from '../lib/media-catalog.js' test('SQL LIKE wildcard 검색 문자를 리터럴로 이스케이프한다', () => { assert.equal(escapePostgresLikeLiteral('100%_done!'), '100!%!_done!!') }) test('미디어 URL을 저장 키로 정규화하고 쿼리를 제거한다', () => { assert.deepEqual( normalizeMediaCatalogUrl('/uploads/posts/2026/07/%ED%95%9C%EA%B8%80.png?v=1'), { url: '/uploads/posts/2026/07/한글.png', storageKey: 'posts/2026/07/한글.png' } ) assert.deepEqual( normalizeMediaCatalogUrl('/uploads/posts/literal-100%.png'), { url: '/uploads/posts/literal-100%.png', storageKey: 'posts/literal-100%.png' } ) }) test('업로드 루트 이탈과 인코딩된 traversal을 차단한다', () => { assert.throws(() => normalizeMediaCatalogUrl('/uploads/../secret.txt'), /MEDIA_URL_TRAVERSAL/) assert.throws(() => normalizeMediaCatalogUrl('/uploads/%2e%2e/secret.txt'), /MEDIA_URL_TRAVERSAL/) assert.throws(() => normalizeMediaCatalogUrl('/etc/passwd'), /MEDIA_URL_OUTSIDE_UPLOADS/) }) test('확장자 종류와 시스템 역할 및 파생 원본 후보를 판별한다', () => { assert.equal(detectMediaKind('photo.webp'), 'image') assert.equal(detectMediaKind('clip.mp4'), 'video') assert.equal(detectMediaKind('voice.m4a'), 'audio') assert.equal(detectMediaKind('document.pdf'), 'file') assert.deepEqual(detectMediaRole('exports/posts.zip'), { role: 'export', parentStorageKey: null }) assert.deepEqual(detectMediaRole('posts/2026/07/thumbs/photo-card.webp'), { role: 'card', parentStorageKey: 'posts/2026/07/photo.jpg' }) assert.equal(detectMediaRole('members/avatars/2026/07/profile.webp').role, 'avatar') }) test('본문 720·1600 파생 URL을 레거시 body와 구분한다', async () => { const { isPostBody1600ThumbnailUrl, isPostBody720ThumbnailUrl, isPostBodyThumbnailUrl } = await import('../lib/post-card-thumbnail-url.js') assert.equal( isPostBodyThumbnailUrl('/uploads/posts/2026/07/thumbs/photo-body.webp'), true ) assert.equal( isPostBody1600ThumbnailUrl('/uploads/posts/2026/07/thumbs/photo-body.webp'), false ) assert.equal( isPostBody720ThumbnailUrl('/uploads/posts/2026/07/thumbs/photo-body.webp'), false ) assert.equal( isPostBody1600ThumbnailUrl('/uploads/posts/2026/07/thumbs/photo-body-1600.webp'), true ) assert.equal( isPostBody720ThumbnailUrl('/uploads/posts/2026/07/thumbs/photo-body-720.webp'), true ) }) test('필드별 미디어 참조를 추출하고 같은 필드 중복을 제거한다', () => { assert.deepEqual(extractMediaReferences({ content: '![a](/uploads/posts/a.png) 다시 /uploads/posts/a.png', featuredImage: '/uploads/posts/a.png', external: 'https://example.com/image.png' }), [ { mediaUrl: '/uploads/posts/a.png', referenceField: 'content' }, { mediaUrl: '/uploads/posts/a.png', referenceField: 'featuredImage' } ]) })