forked from wangziqi/gongxue-base
feat: add learning stats and review plans
This commit is contained in:
@@ -746,6 +746,69 @@ async function testCatalogAndLearning() {
|
||||
query: { status: 'all' },
|
||||
});
|
||||
assert.ok(wrong.items?.some(item => item.questionId === ids.question), 'wrong book should include smoke question');
|
||||
|
||||
const wrongReviewPlan = await request('/api/learning/wrong-questions/review-plan', {
|
||||
userId: false,
|
||||
headers: { authorization: `Bearer ${freeLogin.session.token}` },
|
||||
query: { limit: 10 },
|
||||
});
|
||||
assert.ok(wrongReviewPlan.items?.some(item => item.questionId === ids.question), 'wrong review plan should include unresolved wrong question');
|
||||
assert.equal(wrongReviewPlan.nextAction?.body?.mode, 'wrong_review', 'wrong review plan should guide backend session creation');
|
||||
|
||||
const wrongReviewSession = await request('/api/learning/practice-sessions', {
|
||||
userId: false,
|
||||
headers: { authorization: `Bearer ${freeLogin.session.token}` },
|
||||
method: 'POST',
|
||||
body: {
|
||||
mode: 'wrong_review',
|
||||
questionLimit: 5,
|
||||
},
|
||||
});
|
||||
assert.equal(wrongReviewSession.item?.mode, 'wrong_review', 'wrong review should create a dedicated practice session');
|
||||
assert.ok(wrongReviewSession.item?.questionIds?.includes(ids.question), 'wrong review session should be assembled by backend wrong book');
|
||||
|
||||
const history = await request('/api/learning/practice-sessions/history', {
|
||||
userId: TENANT_ADMIN_USER_ID,
|
||||
query: { mode: 'mock_exam', limit: 20 },
|
||||
});
|
||||
assert.ok(history.items?.some(item => item.id === mockSession.item.id && item.reportId === mockReport.item.id), 'practice history should include submitted mock session');
|
||||
|
||||
const learningStats = await request('/api/learning/stats', {
|
||||
userId: TENANT_ADMIN_USER_ID,
|
||||
query: { days: 30 },
|
||||
});
|
||||
assert.ok(learningStats.item?.answers?.totalAnswered >= 2, 'learning stats should count answer records');
|
||||
assert.ok(learningStats.item?.reports?.reportCount >= 1, 'learning stats should count reports');
|
||||
assert.ok(learningStats.item?.questionTypes?.some(item => item.questionType === 'choice'), 'learning stats should include question type distribution');
|
||||
|
||||
const learningTrend = await request('/api/learning/trend', {
|
||||
userId: TENANT_ADMIN_USER_ID,
|
||||
query: { days: 7 },
|
||||
});
|
||||
assert.ok(Array.isArray(learningTrend.items), 'learning trend should return daily buckets');
|
||||
assert.ok(learningTrend.items.length >= 1, 'learning trend should include at least one bucket');
|
||||
assert.ok(learningTrend.items.some(item => item.answeredCount >= 2), 'learning trend should include answer activity');
|
||||
|
||||
await request('/api/learning/favorites/questions', {
|
||||
userId: TENANT_ADMIN_USER_ID,
|
||||
method: 'POST',
|
||||
body: {
|
||||
userId: TENANT_ADMIN_USER_ID,
|
||||
questionId: ids.questionThree,
|
||||
favorite: true,
|
||||
},
|
||||
});
|
||||
const favoriteReviewSession = await request('/api/learning/practice-sessions', {
|
||||
userId: TENANT_ADMIN_USER_ID,
|
||||
method: 'POST',
|
||||
body: {
|
||||
userId: TENANT_ADMIN_USER_ID,
|
||||
mode: 'favorite_review',
|
||||
questionLimit: 5,
|
||||
},
|
||||
});
|
||||
assert.equal(favoriteReviewSession.item?.mode, 'favorite_review', 'favorite review should create a dedicated practice session');
|
||||
assert.ok(favoriteReviewSession.item?.questionIds?.includes(ids.questionThree), 'favorite review session should be assembled by backend favorites');
|
||||
}
|
||||
|
||||
async function testProfile() {
|
||||
|
||||
Reference in New Issue
Block a user