feat: 添加得分占比计算功能;优化时间格式化工具函数;更新考试记录和用户任务页面以显示得分占比;新增得分占比测试用例;修复时间解析逻辑
This commit is contained in:
111
test/score-percentage.test.ts
Normal file
111
test/score-percentage.test.ts
Normal file
@@ -0,0 +1,111 @@
|
||||
import test from 'node:test';
|
||||
import assert from 'node:assert/strict';
|
||||
import { randomUUID } from 'node:crypto';
|
||||
|
||||
process.env.NODE_ENV = 'test';
|
||||
process.env.DB_PATH = ':memory:';
|
||||
|
||||
const jsonFetch = async (
|
||||
baseUrl: string,
|
||||
path: string,
|
||||
options?: { method?: string; body?: unknown },
|
||||
) => {
|
||||
const res = await fetch(`${baseUrl}${path}`, {
|
||||
method: options?.method ?? 'GET',
|
||||
headers: options?.body ? { 'Content-Type': 'application/json' } : undefined,
|
||||
body: options?.body ? JSON.stringify(options.body) : undefined,
|
||||
});
|
||||
|
||||
const text = await res.text();
|
||||
let json: any = null;
|
||||
try {
|
||||
json = text ? JSON.parse(text) : null;
|
||||
} catch {
|
||||
json = null;
|
||||
}
|
||||
return { status: res.status, json, text };
|
||||
};
|
||||
|
||||
test('得分占比=总得分/试卷总分;40%应判定为不及格', async () => {
|
||||
const { initDatabase, run, get } = await import('../api/database');
|
||||
await initDatabase();
|
||||
|
||||
const { app } = await import('../api/server');
|
||||
const server = app.listen(0);
|
||||
|
||||
try {
|
||||
const addr = server.address();
|
||||
assert.ok(addr && typeof addr === 'object');
|
||||
const baseUrl = `http://127.0.0.1:${addr.port}`;
|
||||
|
||||
const userId = randomUUID();
|
||||
|
||||
await run(`INSERT INTO users (id, name, phone, password) VALUES (?, ?, ?, ?)`, [
|
||||
userId,
|
||||
'测试用户',
|
||||
'13900139001',
|
||||
'',
|
||||
]);
|
||||
|
||||
// 5道单选题,每题5分,总分25;答对2题得10分,得分占比=40%
|
||||
const questionIds: string[] = [];
|
||||
for (let i = 0; i < 5; i++) {
|
||||
const qid = randomUUID();
|
||||
questionIds.push(qid);
|
||||
await run(
|
||||
`INSERT INTO questions (id, content, type, options, answer, analysis, score, category)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?)`,
|
||||
[
|
||||
qid,
|
||||
`题目${i + 1}`,
|
||||
'single',
|
||||
JSON.stringify(['A', 'B', 'C', 'D']),
|
||||
'A',
|
||||
'',
|
||||
5,
|
||||
'通用',
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
const answers = questionIds.map((questionId, idx) => ({
|
||||
questionId,
|
||||
userAnswer: idx < 2 ? 'A' : 'B',
|
||||
score: 0,
|
||||
isCorrect: false,
|
||||
}));
|
||||
|
||||
const submitRes = await jsonFetch(baseUrl, '/api/quiz/submit', {
|
||||
method: 'POST',
|
||||
body: { userId, answers },
|
||||
});
|
||||
|
||||
assert.equal(submitRes.status, 200, submitRes.text);
|
||||
assert.equal(submitRes.json?.success, true);
|
||||
const recordId = submitRes.json?.data?.recordId;
|
||||
assert.ok(recordId);
|
||||
|
||||
const detailRes = await jsonFetch(baseUrl, `/api/quiz/records/detail/${recordId}`);
|
||||
assert.equal(detailRes.status, 200, detailRes.text);
|
||||
assert.equal(detailRes.json?.success, true);
|
||||
|
||||
const record = detailRes.json?.data?.record;
|
||||
assert.ok(record);
|
||||
assert.equal(record.totalScore, 10);
|
||||
assert.equal(record.correctCount, 2);
|
||||
assert.equal(record.totalCount, 5);
|
||||
|
||||
assert.ok(typeof record.scorePercentage === 'number');
|
||||
assert.ok(Math.abs(record.scorePercentage - 40) < 0.0001);
|
||||
assert.equal(record.status, '不及格');
|
||||
|
||||
// 数据库里也应写入合理的score_percentage(避免旧逻辑200%)
|
||||
const dbRow = await get(`SELECT score_percentage as scorePercentage, status FROM quiz_records WHERE id = ?`, [recordId]);
|
||||
assert.ok(dbRow);
|
||||
assert.ok(typeof dbRow.scorePercentage === 'number');
|
||||
assert.ok(Math.abs(dbRow.scorePercentage - 40) < 0.0001);
|
||||
assert.equal(dbRow.status, '不及格');
|
||||
} finally {
|
||||
server.close();
|
||||
}
|
||||
});
|
||||
Reference in New Issue
Block a user