const assert = require('node:assert/strict');
const fs = require('node:fs');
const path = require('node:path');
const test = require('node:test');
const VideoPages = require('../public/js/video-pages.js');
test('视频页只从 URL 读取真实家谱和视频编号', () => {
assert.equal(VideoPages.getCurrentGenealogyId('?genealogyId=2060000000000000001&videoId=2060000000000000002'), '2060000000000000001');
assert.equal(VideoPages.getCurrentVideoId('?genealogyId=2060000000000000001&videoId=2060000000000000002'), '2060000000000000002');
assert.equal(VideoPages.getCurrentGenealogyId(''), '');
assert.equal(VideoPages.getCurrentVideoId('?videoId=unsafe'), '');
});
test('视频写入只构造 YAML VideoBody 字段并保持 OSS ID 为字符串', () => {
assert.deepEqual(VideoPages.buildVideoBody({
videoTitle: ' 家族活动记录 ',
videoDesc: ' 清明祭祖活动视频 ',
coverOssId: '2060000000000000001',
videoOssId: '2060000000000000002',
durationSeconds: '181',
sortOrder: '3',
status: '0',
publisherUserId: 'should-not-send',
viewCount: 99
}), {
videoTitle: '家族活动记录',
videoDesc: '清明祭祖活动视频',
coverOssId: '2060000000000000001',
videoOssId: '2060000000000000002',
durationSeconds: 181,
sortOrder: 3,
status: '0'
});
});
test('视频校验标题、上传文件、时长、排序和状态', () => {
assert.equal(VideoPages.validateVideoBody({ videoTitle: '', videoOssId: '1' }), '请填写视频标题');
assert.equal(VideoPages.validateVideoBody({ videoTitle: '标题' }), '请先选择并上传视频文件');
assert.equal(VideoPages.validateVideoBody({ videoTitle: '标题', videoOssId: '0' }), '视频文件上传结果无效');
assert.equal(VideoPages.validateVideoBody({ videoTitle: '标题', videoOssId: '1', coverOssId: 'abc' }), '封面上传结果无效');
assert.equal(VideoPages.validateVideoBody({ videoTitle: '标题', videoOssId: '1', durationSeconds: -1 }), '视频时长不能小于 0');
assert.equal(VideoPages.validateVideoBody({ videoTitle: '标题', videoOssId: '1', sortOrder: undefined, invalidSortOrder: true }), '排序值必须是安全整数');
assert.equal(VideoPages.validateVideoBody({ videoTitle: '标题', videoOssId: '1', status: '1' }), '当前 PC 无法重新读取停用视频,暂不开放停用');
assert.equal(VideoPages.validateVideoBody({ videoTitle: '标题', videoOssId: '1', status: '0' }), '');
});
test('视频响应使用 PC VideoVo 字段并拒绝不安全长 ID', () => {
assert.deepEqual(VideoPages.normalizeVideo({
videoId: '2060000000000000001',
genealogyId: '2060000000000000002',
genealogyNo: 'G20260729001',
genealogyName: '叶氏家谱',
surname: '叶',
videoTitle: '祭祖活动记录',
videoDesc: '活动影像',
coverOssId: '2060000000000000003',
videoOssId: '2060000000000000004',
durationSeconds: 180,
publisherUserId: '2060000000000000005',
publisherNickName: '叶子',
publisherPhone: '19100000000',
publishTime: '2026-07-29 10:00:00',
viewCount: 12,
sortOrder: 1,
status: '0',
remark: '归档'
}), {
videoId: '2060000000000000001',
genealogyId: '2060000000000000002',
genealogyNo: 'G20260729001',
genealogyName: '叶氏家谱',
surname: '叶',
videoTitle: '祭祖活动记录',
videoDesc: '活动影像',
coverOssId: '2060000000000000003',
videoOssId: '2060000000000000004',
durationSeconds: 180,
publisherUserId: '2060000000000000005',
publisherNickName: '叶子',
publisherPhone: '19100000000',
publishTime: '2026-07-29 10:00:00',
viewCount: 12,
sortOrder: 1,
status: '0',
remark: '归档'
});
assert.equal(VideoPages.normalizeVideo({
videoId: Number('2060000000000000001'),
genealogyId: '2',
videoTitle: '标题',
videoOssId: '3',
status: '0'
}), null);
});
test('视频渲染展示业务信息但不直接暴露 OSS ID 和发布人手机号', () => {
const video = VideoPages.normalizeVideo({
videoId: '1',
genealogyId: '2',
videoTitle: '',
videoDesc: '活动影像',
coverOssId: '3',
videoOssId: '4',
durationSeconds: 180,
publisherUserId: '5',
publisherNickName: '叶子',
publisherPhone: '19100000000',
publishTime: '2026-07-29 10:00:00',
viewCount: 12,
sortOrder: 1,
status: '0'
});
const html = VideoPages.renderVideoDetail(video, true);
assert.doesNotMatch(html, /