120 lines
3.9 KiB
TypeScript
120 lines
3.9 KiB
TypeScript
|
|
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('用户任务接口返回未开始/进行中/已结束任务(由前端分组)', async () => {
|
||
|
|
const { initDatabase, run } = 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 now = Date.now();
|
||
|
|
const userId = randomUUID();
|
||
|
|
const subjectId = randomUUID();
|
||
|
|
|
||
|
|
const historyTaskId = randomUUID();
|
||
|
|
const upcomingTaskId = randomUUID();
|
||
|
|
const activeTaskId = randomUUID();
|
||
|
|
|
||
|
|
await run(`INSERT INTO users (id, name, phone, password) VALUES (?, ?, ?, ?)`, [
|
||
|
|
userId,
|
||
|
|
'测试用户',
|
||
|
|
'13800138099',
|
||
|
|
'',
|
||
|
|
]);
|
||
|
|
|
||
|
|
await run(
|
||
|
|
`INSERT INTO exam_subjects (id, name, type_ratios, category_ratios, total_score, duration_minutes)
|
||
|
|
VALUES (?, ?, ?, ?, ?, ?)`,
|
||
|
|
[
|
||
|
|
subjectId,
|
||
|
|
'测试科目',
|
||
|
|
JSON.stringify({ single: 100 }),
|
||
|
|
JSON.stringify({ 通用: 100 }),
|
||
|
|
100,
|
||
|
|
60,
|
||
|
|
],
|
||
|
|
);
|
||
|
|
|
||
|
|
const historyStartAt = new Date(now - 3 * 24 * 60 * 60 * 1000).toISOString();
|
||
|
|
const historyEndAt = new Date(now - 2 * 24 * 60 * 60 * 1000).toISOString();
|
||
|
|
const upcomingStartAt = new Date(now + 2 * 24 * 60 * 60 * 1000).toISOString();
|
||
|
|
const upcomingEndAt = new Date(now + 3 * 24 * 60 * 60 * 1000).toISOString();
|
||
|
|
const activeStartAt = new Date(now - 1 * 24 * 60 * 60 * 1000).toISOString();
|
||
|
|
const activeEndAt = new Date(now + 1 * 24 * 60 * 60 * 1000).toISOString();
|
||
|
|
|
||
|
|
await run(
|
||
|
|
`INSERT INTO exam_tasks (id, name, subject_id, start_at, end_at, selection_config)
|
||
|
|
VALUES (?, ?, ?, ?, ?, ?)`,
|
||
|
|
[historyTaskId, '历史任务', subjectId, historyStartAt, historyEndAt, null],
|
||
|
|
);
|
||
|
|
await run(
|
||
|
|
`INSERT INTO exam_tasks (id, name, subject_id, start_at, end_at, selection_config)
|
||
|
|
VALUES (?, ?, ?, ?, ?, ?)`,
|
||
|
|
[upcomingTaskId, '未开始任务', subjectId, upcomingStartAt, upcomingEndAt, null],
|
||
|
|
);
|
||
|
|
await run(
|
||
|
|
`INSERT INTO exam_tasks (id, name, subject_id, start_at, end_at, selection_config)
|
||
|
|
VALUES (?, ?, ?, ?, ?, ?)`,
|
||
|
|
[activeTaskId, '进行中任务', subjectId, activeStartAt, activeEndAt, null],
|
||
|
|
);
|
||
|
|
|
||
|
|
const linkUserToTask = async (taskId: string) => {
|
||
|
|
await run(`INSERT INTO exam_task_users (id, task_id, user_id) VALUES (?, ?, ?)`, [
|
||
|
|
randomUUID(),
|
||
|
|
taskId,
|
||
|
|
userId,
|
||
|
|
]);
|
||
|
|
};
|
||
|
|
|
||
|
|
await linkUserToTask(historyTaskId);
|
||
|
|
await linkUserToTask(upcomingTaskId);
|
||
|
|
await linkUserToTask(activeTaskId);
|
||
|
|
|
||
|
|
const res = await jsonFetch(baseUrl, `/api/exam-tasks/user/${userId}`);
|
||
|
|
assert.equal(res.status, 200);
|
||
|
|
assert.equal(res.json?.success, true);
|
||
|
|
assert.ok(Array.isArray(res.json?.data));
|
||
|
|
|
||
|
|
const names = (res.json?.data as any[]).map((t) => t.name).sort();
|
||
|
|
assert.deepEqual(names, ['历史任务', '未开始任务', '进行中任务'].sort());
|
||
|
|
|
||
|
|
const upcoming = (res.json?.data as any[]).find((t) => t.name === '未开始任务');
|
||
|
|
assert.ok(upcoming);
|
||
|
|
assert.equal(typeof upcoming.startAt, 'string');
|
||
|
|
assert.equal(typeof upcoming.endAt, 'string');
|
||
|
|
} finally {
|
||
|
|
server.close();
|
||
|
|
}
|
||
|
|
});
|