// 已读取AGENTS.md import * as fs from 'fs'; import * as path from 'path'; /** * 友圈短视频发布链路回归闸门: * - 上传必须走独立接口、独立限流与体积/格式白名单; * - posts 表必须持久化 video_url / video_cover; * - 视频与图片二选一,避免混排; * - 小程序与后台都必须能播放/预览视频。 */ describe('友圈短视频发布链路', () => { const root = path.resolve(__dirname, '../../'); const read = (rel: string) => fs.readFileSync(path.join(root, rel), 'utf-8'); const indexCode = read('server/src/index.ts'); const mysql = read('server/src/db/mysql.ts'); const repo = read('server/src/db/repository.ts'); const security = read('server/src/core/security/content-security.service.ts'); const api = read('pwuniapp/common/api.js'); const community = read('pwuniapp/pages/community/index.vue'); const detail = read('pwuniapp/pages/community/detail.vue'); const admin = read('admin/arco-design-pro-vite/src/views/community/post-manage/index.vue'); it('短视频上传必须使用独立接口、独立限流与 30MB 上限', () => { expect(indexCode).toContain("app.post('/api/upload/video'"); expect(indexCode).toContain('uploadVideo'); expect(indexCode).toContain('30 * 1024 * 1024'); expect(indexCode).toContain('video/mp4'); }); it('短视频上传必须要求登录并做格式/体积校验', () => { expect(security).toContain('public checkVideo'); expect(security).toContain('视频体积超过 30MB 上限'); expect(indexCode).toContain("ensureUploadAuthorized(req, res, '上传视频')"); }); it('posts 表必须持久化 video_url / video_cover', () => { expect(mysql).toContain('video_url VARCHAR(512)'); expect(mysql).toContain('video_cover VARCHAR(512)'); expect(repo).toContain('video_url as videoUrl'); expect(repo).toContain('INSERT INTO posts'); expect(repo).toContain('video_url, video_cover'); }); it('视频与图片可同发:两条媒体链路都要落库', () => { expect(repo).toContain("const images = Array.isArray(data.images) ? data.images : [];"); expect(repo).toContain('videoUrl, videoCover, actionText, category'); }); it('小程序必须支持选择、上传与播放短视频', () => { expect(api).toContain('export function uploadVideo'); expect(api).toContain("'/api/upload/video'"); expect(community).toContain('uni.chooseVideo'); expect(community).toContain('uploadVideo(newPostForm.value.video.path)'); expect(community).toContain('post.videoUrl'); expect(detail).toContain('post.videoUrl'); }); it('动态列表映射必须保留视频字段,且视频点击不得冒泡跳转详情', () => { expect(api).toContain("videoUrl: p.videoUrl || ''"); expect(api).toContain("videoCover: p.videoCover || ''"); expect(community).toContain('@click.stop="stopPropagation"'); }); it('后台动态管理必须可预览短视频', () => { expect(admin).toContain('openVideoPreview'); expect(admin).toContain('record.videoUrl'); }); });