feat: export daily practice image packages

This commit is contained in:
Codex
2026-06-29 17:40:10 +08:00
parent 60501a0f70
commit a68b4ab9e3
16 changed files with 809 additions and 62 deletions
+44
View File
@@ -2849,6 +2849,47 @@ async function testTenantContentAdmin() {
'daily practice export should cap question count for nine-grid material',
);
const invalidDailyPracticeZip = await request('/api/tenant-content/exports/questions', {
userId: TENANT_ADMIN_USER_ID,
method: 'POST',
body: {
scopeType: 'collection',
scopeId: collection.item.id,
format: 'daily_practice_zip',
exportType: 'paper',
},
expectStatus: 400,
});
assert.equal(
invalidDailyPracticeZip.code,
'DAILY_PRACTICE_ZIP_REQUIRES_DAILY_PRACTICE',
'daily practice ZIP export should reject non-daily-practice export types',
);
const dailyPracticeZipJob = await request('/api/tenant-content/exports/questions', {
userId: TENANT_ADMIN_USER_ID,
method: 'POST',
body: {
scopeType: 'collection',
scopeId: collection.item.id,
format: 'daily_practice_zip',
exportType: 'daily_practice',
includeAnswers: false,
includeExplanations: false,
limit: 99,
options: {
title: '集成测试每日一练图片包',
issue: '每日一练 图片包',
date: '2026-06-29',
theme: 'default',
publishToAssets: true,
assetVisibility: 'tenant',
},
},
});
assert.equal(dailyPracticeZipJob.job?.status, 'pending', 'daily practice ZIP export should create a pending async job');
assert.equal(dailyPracticeZipJob.export, null, 'daily practice ZIP export should not return inline ZIP payload');
const pdfExportJob = await request('/api/tenant-content/exports/questions', {
userId: TENANT_ADMIN_USER_ID,
method: 'POST',
@@ -2909,6 +2950,9 @@ async function testTenantContentAdmin() {
assert.equal(listedPdfJob?.status, 'pending', 'question export jobs should expose pending binary export jobs');
assert.equal(listedPdfJob?.assetId, null, 'pending binary export job should not have an asset yet');
assert.equal(listedPdfJob?.attemptCount, 0, 'pending binary export job should expose worker attempt count');
const listedDailyPracticeZipJob = exportJobs.items?.find(item => item.id === dailyPracticeZipJob.job.id);
assert.equal(listedDailyPracticeZipJob?.format, 'daily_practice_zip', 'export jobs should list pending daily practice ZIP jobs');
assert.equal(listedDailyPracticeZipJob?.status, 'pending', 'pending daily practice ZIP job should be visible to tenant content admins');
const invalidExportJobsScope = await request('/api/tenant-content/exports/jobs', {
userId: TENANT_ADMIN_USER_ID,
query: { scopeType: 'not_supported' },