feat: 作业纸
This commit is contained in:
@@ -11,6 +11,11 @@ import { PrismaService } from '../src/database/prisma.service';
|
||||
import { JwtTokenService } from '../src/auth/jwt-token.service';
|
||||
import { ASSET_STORAGE } from '../src/assets/qiniu.gateway';
|
||||
import { AssetService } from '../src/assets/asset.service';
|
||||
import { seedPaperSheets } from '../src/worksheets/paper-sheet-seed';
|
||||
import {
|
||||
PAPER_SHEET_PATH,
|
||||
PAPER_SHEET_PRESETS,
|
||||
} from '../src/worksheets/paper-sheet-presets';
|
||||
import { SiteService } from '../src/site/site.service';
|
||||
import { testConfig } from './test-config';
|
||||
|
||||
@@ -707,6 +712,147 @@ test(
|
||||
);
|
||||
},
|
||||
);
|
||||
await context.test(
|
||||
'纸张拆分:预演不写库、草稿幂等、独立发布/收藏/下载及历史兼容',
|
||||
async () => {
|
||||
const parent = await db.worksheet.create({
|
||||
data: {
|
||||
id: 'paper-sheet',
|
||||
title: '作业纸',
|
||||
subtitle: '',
|
||||
categoryId,
|
||||
path: `${PAPER_SHEET_PATH}?id=paper-sheet`,
|
||||
ageMin: 3,
|
||||
ageMax: 12,
|
||||
difficulty: 1,
|
||||
previewAssetId: previewId,
|
||||
status: 'active',
|
||||
downloads: 123n,
|
||||
likes: 9n,
|
||||
},
|
||||
});
|
||||
await db.worksheetGrade.create({
|
||||
data: { worksheetId: parent.id, grade: 0 },
|
||||
});
|
||||
const dry = await seedPaperSheets(app.get(PrismaService), true);
|
||||
assert.equal(
|
||||
dry.changes.filter((row) => row.action === 'insert-draft')
|
||||
.length,
|
||||
10,
|
||||
);
|
||||
assert.equal(
|
||||
await db.worksheet.count({
|
||||
where: { rendererKey: 'paper-sheet' },
|
||||
}),
|
||||
0,
|
||||
);
|
||||
await seedPaperSheets(app.get(PrismaService), false);
|
||||
assert.ok(
|
||||
(
|
||||
await seedPaperSheets(app.get(PrismaService), false)
|
||||
).changes.every((row) => row.action === 'unchanged'),
|
||||
);
|
||||
assert.deepEqual(
|
||||
await db.worksheet.findUnique({ where: { id: parent.id } }),
|
||||
parent,
|
||||
);
|
||||
for (const preset of PAPER_SHEET_PRESETS) {
|
||||
const draft = await db.worksheet.findUniqueOrThrow({
|
||||
where: { id: preset.id },
|
||||
});
|
||||
assert.equal(draft.status, 'draft');
|
||||
assert.equal(draft.firstPublishedAt, null);
|
||||
assert.equal(draft.downloads, 0n);
|
||||
assert.equal(draft.likes, 0n);
|
||||
assert.equal(
|
||||
(await request(`/worksheets/${preset.id}`)).status,
|
||||
404,
|
||||
);
|
||||
}
|
||||
const input = {
|
||||
id: 'paper-mi',
|
||||
title: '米字格',
|
||||
subtitle: '',
|
||||
categoryId,
|
||||
path: `${PAPER_SHEET_PATH}?id=paper-mi`,
|
||||
ageMin: 3,
|
||||
ageMax: 12,
|
||||
difficulty: 1,
|
||||
previewAssetId: previewId,
|
||||
tags: ['米字格'],
|
||||
status: 'active',
|
||||
};
|
||||
assert.equal(
|
||||
(
|
||||
await request(
|
||||
'/admin/worksheets/publish',
|
||||
tokens.admin,
|
||||
'POST',
|
||||
{
|
||||
...input,
|
||||
path: `${PAPER_SHEET_PATH}?id=paper-tian`,
|
||||
},
|
||||
)
|
||||
).status,
|
||||
400,
|
||||
);
|
||||
assert.equal(
|
||||
(
|
||||
await request(
|
||||
'/admin/worksheets/publish',
|
||||
tokens.admin,
|
||||
'POST',
|
||||
input,
|
||||
)
|
||||
).status,
|
||||
201,
|
||||
);
|
||||
const detail = (await request('/worksheets/paper-mi')).body
|
||||
.data;
|
||||
assert.deepEqual(detail.rendering, {
|
||||
rendererKey: 'paper-sheet',
|
||||
paperType: 'mi',
|
||||
});
|
||||
assert.equal(detail.renderConfig, undefined);
|
||||
assert.equal(
|
||||
(await request('/me/favorites/paper-mi', tokens.b, 'PUT'))
|
||||
.status,
|
||||
200,
|
||||
);
|
||||
assert.equal(
|
||||
(
|
||||
await request(
|
||||
'/me/favorites/paper-sheet',
|
||||
tokens.b,
|
||||
'PUT',
|
||||
)
|
||||
).status,
|
||||
200,
|
||||
);
|
||||
const download = await request(
|
||||
'/me/downloads',
|
||||
tokens.b,
|
||||
'POST',
|
||||
{ worksheetId: 'paper-mi', exportId: randomUUID() },
|
||||
);
|
||||
assert.equal(download.status, 201);
|
||||
const saved = await db.worksheet.findUniqueOrThrow({
|
||||
where: { id: 'paper-mi' },
|
||||
});
|
||||
assert.equal(saved.downloads, 1n);
|
||||
assert.equal(saved.likes, 1n);
|
||||
const old = await db.worksheet.findUniqueOrThrow({
|
||||
where: { id: parent.id },
|
||||
});
|
||||
assert.equal(old.downloads, 123n);
|
||||
assert.equal(old.likes, 10n);
|
||||
assert.ok(
|
||||
await db.favorite.findFirst({
|
||||
where: { userId: ids.b, worksheetId: parent.id },
|
||||
}),
|
||||
);
|
||||
},
|
||||
);
|
||||
await context.test(
|
||||
'注销删除本人明细、撤销旧 JWT,其余用户不受影响',
|
||||
async () => {
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
import assert from 'node:assert/strict';
|
||||
import { test } from 'node:test';
|
||||
import {
|
||||
PAPER_SHEET_PATH,
|
||||
PAPER_SHEET_PRESETS,
|
||||
paperSheetPreset,
|
||||
publicPaperSheetRendering,
|
||||
} from '../src/worksheets/paper-sheet-presets';
|
||||
import { parseWorksheetExport } from '../src/imports/worksheet-import';
|
||||
import { worksheetFixture } from './worksheet-import.fixture';
|
||||
|
||||
test('独立纸张:固定注册、路由归属、导入配置和公开参数一致', () => {
|
||||
assert.equal(
|
||||
new Set(PAPER_SHEET_PRESETS.map((entry) => entry.id)).size,
|
||||
10,
|
||||
);
|
||||
for (const entry of PAPER_SHEET_PRESETS) {
|
||||
const path = `${PAPER_SHEET_PATH}?id=${entry.id}`;
|
||||
const config = paperSheetPreset(entry.id, path)!;
|
||||
const row = parseWorksheetExport(
|
||||
JSON.stringify([{ ...worksheetFixture, _id: entry.id, path }]),
|
||||
).rows[0]!.data;
|
||||
assert.equal(row.rendererKey, 'paper-sheet');
|
||||
assert.deepEqual(row.renderConfig, { paperType: entry.paperType });
|
||||
assert.deepEqual(
|
||||
publicPaperSheetRendering({
|
||||
id: entry.id,
|
||||
path,
|
||||
...config,
|
||||
renderConfig: {
|
||||
...config.renderConfig,
|
||||
privateKey: 'must-not-leak',
|
||||
},
|
||||
}),
|
||||
{ rendererKey: 'paper-sheet', paperType: entry.paperType },
|
||||
);
|
||||
assert.throws(() =>
|
||||
paperSheetPreset(entry.id, `${PAPER_SHEET_PATH}?id=paper-sheet`),
|
||||
);
|
||||
assert.equal(
|
||||
publicPaperSheetRendering({
|
||||
id: entry.id,
|
||||
path,
|
||||
...config,
|
||||
renderConfig: { paperType: 'unknown' },
|
||||
}),
|
||||
undefined,
|
||||
);
|
||||
assert.equal(
|
||||
publicPaperSheetRendering({
|
||||
id: entry.id,
|
||||
path,
|
||||
...config,
|
||||
rendererKey: 'unknown',
|
||||
}),
|
||||
undefined,
|
||||
);
|
||||
}
|
||||
assert.equal(
|
||||
paperSheetPreset('paper-sheet', `${PAPER_SHEET_PATH}?id=paper-sheet`),
|
||||
undefined,
|
||||
);
|
||||
assert.equal(
|
||||
paperSheetPreset('paper-unregistered', '/arbitrary'),
|
||||
undefined,
|
||||
);
|
||||
});
|
||||
Reference in New Issue
Block a user