187 lines
5.7 KiB
TypeScript
187 lines
5.7 KiB
TypeScript
import {
|
|
applyVideoPreviewPolicy,
|
|
getVideoDownloadAvailability,
|
|
getVideoDownloadUnavailableMessage,
|
|
getVideoPreviewPolicyFields,
|
|
userHasVideoEarlyAccess,
|
|
VIDEO_DOWNLOAD_WAIT_DAYS,
|
|
} from '@/lib/video-download-policy'
|
|
import { DownloadErrorCode, parseDownloadError } from '@/lib/download-errors'
|
|
|
|
describe('video download policy', () => {
|
|
const now = new Date('2026-05-25T12:00:00.000Z')
|
|
|
|
test('安装视频不受 15 天限制', () => {
|
|
const availability = getVideoDownloadAvailability(
|
|
'安装视频',
|
|
'2026-05-25T11:00:00.000Z',
|
|
now,
|
|
)
|
|
|
|
expect(availability.allowed).toBe(true)
|
|
})
|
|
|
|
test('非安装视频上传未满 15 天时禁止下载', () => {
|
|
const availability = getVideoDownloadAvailability(
|
|
'淘系-主图视频',
|
|
'2026-05-20T12:00:00.000Z',
|
|
now,
|
|
)
|
|
|
|
expect(availability).toMatchObject({
|
|
allowed: false,
|
|
reason: 'VIDEO_WAIT_PERIOD',
|
|
remainingDays: 10,
|
|
})
|
|
expect(availability.availableAt?.toISOString()).toBe('2026-06-04T12:00:00.000Z')
|
|
expect(getVideoDownloadUnavailableMessage(availability)).toContain(
|
|
`满 ${VIDEO_DOWNLOAD_WAIT_DAYS} 天才能下载`,
|
|
)
|
|
})
|
|
|
|
test('非安装视频上传满 15 天后允许下载', () => {
|
|
const availability = getVideoDownloadAvailability(
|
|
'抖音-千川素材',
|
|
'2026-05-10T12:00:00.000Z',
|
|
now,
|
|
)
|
|
|
|
expect(availability.allowed).toBe(true)
|
|
})
|
|
|
|
test('兼容旧视频类型名称', () => {
|
|
const availability = getVideoDownloadAvailability(
|
|
'主图视频',
|
|
'2026-05-24T12:00:00.000Z',
|
|
now,
|
|
)
|
|
|
|
expect(availability.allowed).toBe(false)
|
|
expect(availability.reason).toBe('VIDEO_WAIT_PERIOD')
|
|
})
|
|
|
|
test('非视频素材不受限制', () => {
|
|
const availability = getVideoDownloadAvailability(
|
|
'买家秀图片',
|
|
'2026-05-25T11:00:00.000Z',
|
|
now,
|
|
)
|
|
|
|
expect(availability.allowed).toBe(true)
|
|
})
|
|
|
|
test('下载错误解析应优先展示等待期详情', () => {
|
|
const parsed = parseDownloadError({
|
|
code: DownloadErrorCode.VIDEO_WAIT_PERIOD,
|
|
error: '视频类素材上传后满 15 天才能下载',
|
|
details: '视频类素材上传后满 15 天才能下载,当前还需约 3 天',
|
|
})
|
|
|
|
expect(parsed.message).toBe('视频类素材上传后满 15 天才能下载,当前还需约 3 天')
|
|
})
|
|
|
|
test('非安装视频上传未满 15 天时禁止进入详情预览', () => {
|
|
const policy = getVideoPreviewPolicyFields(
|
|
'淘系-主图视频',
|
|
'2026-05-20T12:00:00.000Z',
|
|
now,
|
|
)
|
|
|
|
expect(policy).toMatchObject({
|
|
videoPreviewBlocked: true,
|
|
videoPreviewUnavailableReason: 'VIDEO_WAIT_PERIOD',
|
|
videoPreviewRemainingDays: 10,
|
|
})
|
|
expect(policy.videoPreviewUnavailableMessage).toContain('才能预览和下载')
|
|
})
|
|
|
|
test('预览门禁会移除视频预览和源视频地址', () => {
|
|
const material = applyVideoPreviewPolicy(
|
|
{
|
|
materialType: '抖音-千川素材',
|
|
createdAt: '2026-05-24T12:00:00.000Z',
|
|
videoSourceUrl: 'https://example.com/source.mp4',
|
|
videoPreview540Url: 'https://example.com/preview.mp4',
|
|
videoPreviewClipUrl: 'https://example.com/clip.mp4',
|
|
videoCoverUrl: 'https://example.com/cover.jpg',
|
|
},
|
|
now,
|
|
)
|
|
|
|
expect(material.videoPreviewBlocked).toBe(true)
|
|
expect(material.videoSourceUrl).toBeNull()
|
|
expect(material.videoPreview540Url).toBeNull()
|
|
expect(material.videoPreviewClipUrl).toBeNull()
|
|
expect(material.videoCoverUrl).toBe('https://example.com/cover.jpg')
|
|
})
|
|
})
|
|
|
|
describe('video download policy — 15 天保护期豁免', () => {
|
|
const now = new Date('2026-05-25T12:00:00.000Z')
|
|
|
|
test('豁免用户不受保护期限制(直接放行)', () => {
|
|
const availability = getVideoDownloadAvailability(
|
|
'淘系-主图视频',
|
|
'2026-05-20T12:00:00.000Z',
|
|
now,
|
|
{ bypassWaitPeriod: true },
|
|
)
|
|
|
|
expect(availability).toEqual({ allowed: true })
|
|
})
|
|
|
|
test('豁免时预览字段全部放行', () => {
|
|
const fields = getVideoPreviewPolicyFields(
|
|
'逛逛视频',
|
|
'2026-05-25T00:00:00.000Z',
|
|
now,
|
|
{ bypassWaitPeriod: true },
|
|
)
|
|
|
|
expect(fields.videoPreviewBlocked).toBe(false)
|
|
expect(fields.videoPreviewUnavailableReason).toBeNull()
|
|
})
|
|
|
|
test('豁免时 URL 不被抹除', () => {
|
|
const result = applyVideoPreviewPolicy(
|
|
{
|
|
materialType: '淘系-主图视频',
|
|
createdAt: '2026-05-25T00:00:00.000Z',
|
|
videoSourceUrl: 'https://example.com/video.mp4',
|
|
videoPreview540Url: 'https://example.com/540.mp4',
|
|
},
|
|
now,
|
|
{ bypassWaitPeriod: true },
|
|
)
|
|
|
|
expect(result.videoSourceUrl).toBe('https://example.com/video.mp4')
|
|
expect(result.videoPreview540Url).toBe('https://example.com/540.mp4')
|
|
expect(result.videoPreviewBlocked).toBe(false)
|
|
})
|
|
|
|
test('未豁免时行为与旧逻辑完全一致(默认参数不变)', () => {
|
|
const withOptions = getVideoDownloadAvailability(
|
|
'淘系-主图视频',
|
|
'2026-05-20T12:00:00.000Z',
|
|
now,
|
|
{ bypassWaitPeriod: false },
|
|
)
|
|
const withoutOptions = getVideoDownloadAvailability(
|
|
'淘系-主图视频',
|
|
'2026-05-20T12:00:00.000Z',
|
|
now,
|
|
)
|
|
|
|
expect(withOptions).toEqual(withoutOptions)
|
|
expect(withOptions.allowed).toBe(false)
|
|
})
|
|
|
|
test('userHasVideoEarlyAccess 只认显式 true', () => {
|
|
expect(userHasVideoEarlyAccess({ videoEarlyAccess: true })).toBe(true)
|
|
expect(userHasVideoEarlyAccess({ videoEarlyAccess: false })).toBe(false)
|
|
expect(userHasVideoEarlyAccess({})).toBe(false)
|
|
expect(userHasVideoEarlyAccess(undefined)).toBe(false)
|
|
expect(userHasVideoEarlyAccess(null)).toBe(false)
|
|
})
|
|
})
|