修改功能
This commit is contained in:
@@ -0,0 +1,80 @@
|
||||
const test = require('node:test');
|
||||
const assert = require('node:assert/strict');
|
||||
const { readFileSync } = require('node:fs');
|
||||
|
||||
const MediaDisplay = require('../public/js/media-display');
|
||||
|
||||
const imageFile = {
|
||||
fileId: '2060000000000000001',
|
||||
ossId: 'private-oss-key',
|
||||
fileName: 'family-cover.jpg',
|
||||
mediaType: 'image/jpeg',
|
||||
fileSize: 1024,
|
||||
accessUrl: 'https://files.example/family-cover.jpg?signature=a&expires=1',
|
||||
expiresAt: '2026-08-28T03:00:00+08:00'
|
||||
};
|
||||
|
||||
test('attachment galleries keep a human-sized thumbnail grid and preserve the whole image', () => {
|
||||
const css = readFileSync(require.resolve('../public/css/public.css'), 'utf8');
|
||||
const moduleCss = readFileSync(require.resolve('../public/css/profile-module.css'), 'utf8');
|
||||
|
||||
assert.match(css, /\.media-gallery\s*\{[^}]*grid-template-columns:\s*repeat\(auto-fill,\s*minmax\(min\(200px,\s*100%\),\s*280px\)\)/s);
|
||||
assert.match(css, /\.media-gallery\s+\.media-frame\s+img\s*\{[^}]*object-fit:\s*contain/s);
|
||||
assert.match(moduleCss, /:is\(\.article-cover-media,\s*\.album-cover-media,\s*\.ceremony-cover-media\)\s+img\s*\{[^}]*object-fit:\s*contain/s);
|
||||
assert.match(moduleCss, /\.video-detail-media\s+video\s*\{[^}]*object-fit:\s*contain/s);
|
||||
});
|
||||
|
||||
test('normalizes authorized file access without exposing storage identifiers', () => {
|
||||
const normalized = MediaDisplay.normalizeFileAccess(imageFile);
|
||||
|
||||
assert.deepEqual(normalized, {
|
||||
fileId: '2060000000000000001',
|
||||
fileName: 'family-cover.jpg',
|
||||
mediaType: 'image/jpeg',
|
||||
fileSize: 1024,
|
||||
accessUrl: imageFile.accessUrl,
|
||||
expiresAt: imageFile.expiresAt
|
||||
});
|
||||
assert.equal('ossId' in normalized, false);
|
||||
});
|
||||
|
||||
test('rejects unsafe and incomplete media URLs', () => {
|
||||
assert.equal(MediaDisplay.normalizeFileAccess({ accessUrl: 'javascript:alert(1)' }), null);
|
||||
assert.equal(MediaDisplay.normalizeFileAccess({ accessUrl: '/resource/oss/1' }), null);
|
||||
assert.equal(MediaDisplay.normalizeFileAccess({ fileId: '1' }), null);
|
||||
});
|
||||
|
||||
test('renders an accessible lazy image and escapes signed URLs', () => {
|
||||
const html = MediaDisplay.renderImage(imageFile, {
|
||||
alt: '彭氏家谱封面',
|
||||
className: 'family-cover',
|
||||
caption: '彭氏家谱'
|
||||
});
|
||||
|
||||
assert.match(html, /<figure class="media-frame family-cover"/);
|
||||
assert.match(html, /<img[^>]+alt="彭氏家谱封面"/);
|
||||
assert.match(html, /loading="lazy"/);
|
||||
assert.match(html, /signature=a&expires=1/);
|
||||
assert.match(html, /<figcaption>彭氏家谱<\/figcaption>/);
|
||||
assert.doesNotMatch(html, /private-oss-key|ossId/);
|
||||
});
|
||||
|
||||
test('renders avatar initials when no authorized image exists', () => {
|
||||
assert.equal(
|
||||
MediaDisplay.renderAvatar(null, { name: '彭小雨' }),
|
||||
'<span class="media-avatar" aria-label="彭小雨的头像">彭</span>'
|
||||
);
|
||||
});
|
||||
|
||||
test('renders mixed media gallery with image, video and downloadable files', () => {
|
||||
const gallery = MediaDisplay.renderGallery([
|
||||
imageFile,
|
||||
{ ...imageFile, fileId: '2', fileName: 'memory.mp4', mediaType: 'video/mp4', accessUrl: 'https://files.example/memory.mp4' },
|
||||
{ ...imageFile, fileId: '3', fileName: 'record.pdf', mediaType: 'application/pdf', accessUrl: 'https://files.example/record.pdf' }
|
||||
], { label: '成长日志附件' });
|
||||
|
||||
assert.match(gallery, /aria-label="成长日志附件"/);
|
||||
assert.match(gallery, /<img/);
|
||||
assert.match(gallery, /<video[^>]+controls/);
|
||||
assert.match(gallery, /下载 record\.pdf/);
|
||||
});
|
||||
Reference in New Issue
Block a user