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, /