forked from wangziqi/gongxue-base
feat: add media access analytics
This commit is contained in:
@@ -3709,6 +3709,59 @@ async function testTenantContentAssetsAndImports() {
|
||||
'admin preview access event should include watermark trace id',
|
||||
);
|
||||
|
||||
const mediaSummary = await request('/api/tenant-content/media-analytics/summary', {
|
||||
userId: TENANT_ADMIN_USER_ID,
|
||||
query: { timeRange: '30d', assetId: localAsset.item.id, traceId: localPreview.watermark.traceId },
|
||||
});
|
||||
assert.equal(mediaSummary.assetAccess?.previews >= 1, true, 'media analytics summary should count asset previews');
|
||||
assert.equal(mediaSummary.assetAccess?.watermarkEvents >= 1, true, 'media analytics summary should count watermark asset events');
|
||||
assert.equal(mediaSummary.traceMatches?.assets >= 1, true, 'media analytics summary should support trace id asset lookup');
|
||||
assert.ok(mediaSummary.daily?.some(item => item.assetEvents >= 1), 'media analytics daily series should include asset events');
|
||||
|
||||
const mediaAssetEvents = await request('/api/tenant-content/media-analytics/asset-events', {
|
||||
userId: TENANT_ADMIN_USER_ID,
|
||||
query: { timeRange: '30d', traceId: localPreview.watermark.traceId, limit: 5 },
|
||||
});
|
||||
assert.ok(
|
||||
mediaAssetEvents.items?.some(item => item.assetId === localAsset.item.id && item.watermarkTraceId === localPreview.watermark.traceId),
|
||||
'media analytics asset event list should search by watermark trace id',
|
||||
);
|
||||
assert.ok(!JSON.stringify(mediaAssetEvents).includes('signature='), 'media analytics asset events should not leak signed URLs');
|
||||
|
||||
const mediaVideoSummary = await request('/api/tenant-content/media-analytics/summary', {
|
||||
userId: TENANT_ADMIN_USER_ID,
|
||||
query: { timeRange: '30d', videoId: ids.video },
|
||||
});
|
||||
assert.equal(mediaVideoSummary.videoPlay?.svipPlays >= 1, true, 'media analytics summary should count SVIP video plays');
|
||||
assert.ok(mediaVideoSummary.videoTop?.some(item => item.videoId === ids.video), 'media analytics summary should include top videos');
|
||||
|
||||
const mediaVideoEventsByVideo = await request('/api/tenant-content/media-analytics/video-events', {
|
||||
userId: TENANT_ADMIN_USER_ID,
|
||||
query: { timeRange: '30d', videoId: ids.video, limit: 5 },
|
||||
});
|
||||
const videoTraceId = mediaVideoEventsByVideo.items?.find(item => item.videoId === ids.video)?.watermarkTraceId;
|
||||
assert.ok(videoTraceId, 'media analytics video event list should include watermark trace id');
|
||||
|
||||
const mediaVideoEvents = await request('/api/tenant-content/media-analytics/video-events', {
|
||||
userId: TENANT_ADMIN_USER_ID,
|
||||
query: { timeRange: '30d', traceId: videoTraceId, limit: 5 },
|
||||
});
|
||||
assert.ok(
|
||||
mediaVideoEvents.items?.some(item => item.videoId === ids.video && item.watermarkTraceId === videoTraceId),
|
||||
'media analytics video event list should search by watermark trace id',
|
||||
);
|
||||
assert.ok(!JSON.stringify(mediaVideoEvents).includes('vp_'), 'media analytics video events should not leak play tokens');
|
||||
|
||||
const teacherAnalyticsDenied = await request('/api/tenant-content/media-analytics/summary', {
|
||||
userId: TENANT_TEACHER_USER_ID,
|
||||
expectStatus: 403,
|
||||
});
|
||||
assert.equal(
|
||||
teacherAnalyticsDenied.code,
|
||||
'TENANT_CONTENT_PERMISSION_REQUIRED',
|
||||
'teacher without analytics permission should not access media audit analytics',
|
||||
);
|
||||
|
||||
const failedAsset = await request('/api/tenant-content/assets', {
|
||||
userId: TENANT_ADMIN_USER_ID,
|
||||
method: 'PUT',
|
||||
|
||||
Reference in New Issue
Block a user