|
@@ -25,9 +25,13 @@ before(async () => {
|
|
|
CREATE TABLE "CourseAppointment"("company" text,"id" int,"szyh" text,"pl" text,"dszt" text,"bxrq" text,"yysj" text,"isDeleted" boolean);
|
|
CREATE TABLE "CourseAppointment"("company" text,"id" int,"szyh" text,"pl" text,"dszt" text,"bxrq" text,"yysj" text,"isDeleted" boolean);
|
|
|
CREATE TABLE "CommonModel"("company" text,"modelId" int,"itemId" int,"status" int,"updatedAt" timestamptz,"isDeleted" boolean);
|
|
CREATE TABLE "CommonModel"("company" text,"modelId" int,"itemId" int,"status" int,"updatedAt" timestamptz,"isDeleted" boolean);
|
|
|
CREATE TABLE "DailyStudyRecord"("company" text,"id" int,"userId" numeric,"pl" text,"isDeleted" boolean);
|
|
CREATE TABLE "DailyStudyRecord"("company" text,"id" int,"userId" numeric,"pl" text,"isDeleted" boolean);
|
|
|
|
|
+ CREATE TABLE "MemoryPracticeRecord"("company" text,"id" numeric,"yhid" numeric,"plid" numeric,"fxzt" text,"kywrq" text,"kywsj" text,"isDeleted" boolean,"rewardDuplicate" boolean);
|
|
|
`);
|
|
`);
|
|
|
});
|
|
});
|
|
|
-beforeEach(() => db.exec('TRUNCATE "_User","CourseAppointment","CommonModel","DailyStudyRecord"'));
|
|
|
|
|
|
|
+beforeEach(async () => {
|
|
|
|
|
+ gateway.appOverviewToday = () => '2026-10-30';
|
|
|
|
|
+ await db.exec('TRUNCATE "_User","CourseAppointment","CommonModel","DailyStudyRecord","MemoryPracticeRecord"');
|
|
|
|
|
+});
|
|
|
after(() => db.close());
|
|
after(() => db.close());
|
|
|
|
|
|
|
|
async function user(id, { disabled = false, deleted = false, group = 1, company = 'co' } = {}) {
|
|
async function user(id, { disabled = false, deleted = false, group = 1, company = 'co' } = {}) {
|
|
@@ -39,7 +43,14 @@ async function appointment(id, student, { date = '2026-10-31', yysj = '', status
|
|
|
await db.query('INSERT INTO "CommonModel" VALUES($1,54,$2,$3,$4,$5)', [company, id, commonStatus, '2026-10-30T00:00:00Z', commonDeleted]);
|
|
await db.query('INSERT INTO "CommonModel" VALUES($1,54,$2,$3,$4,$5)', [company, id, commonStatus, '2026-10-30T00:00:00Z', commonDeleted]);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-test('没有授课记录时仅列出正常账号且仍有今天或未来排课的学员,先筛选再分页', async () => {
|
|
|
|
|
|
|
+async function review(id, student, { date = '2026-11-01', time = '', status = '0', commonStatus = 99, teacher = 300, company = 'co', deleted = false, commonDeleted = false, duplicate = false } = {}) {
|
|
|
|
|
+ await db.query('INSERT INTO "MemoryPracticeRecord" VALUES($1,$2,$3,$4,$5,$6,$7,$8,$9)',
|
|
|
|
|
+ [company, id, student, teacher, status, date, time, deleted, duplicate]);
|
|
|
|
|
+ await db.query('INSERT INTO "CommonModel" VALUES($1,60,$2,$3,$4,$5)',
|
|
|
|
|
+ [company, id, commonStatus, '2026-10-30T00:00:00Z', commonDeleted]);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+test('没有未结束复习时仅列出正常账号且仍有今天或未来排课的学员,先筛选再分页', async () => {
|
|
|
for (let id = 1; id <= 13; id++) await user(id, { disabled: id === 2, deleted: id === 3, group: id === 4 ? 3 : 1 });
|
|
for (let id = 1; id <= 13; id++) await user(id, { disabled: id === 2, deleted: id === 3, group: id === 4 ? 3 : 1 });
|
|
|
await appointment(1, 1);
|
|
await appointment(1, 1);
|
|
|
await appointment(2, 2);
|
|
await appointment(2, 2);
|
|
@@ -73,22 +84,55 @@ test('日期兼容紧凑日期、斜线日期及预约时间回退,空日期
|
|
|
assert.deepEqual(ids(await page()).sort((a, b) => a - b), [1, 2, 3]);
|
|
assert.deepEqual(ids(await page()).sort((a, b) => a - b), [1, 2, 3]);
|
|
|
});
|
|
});
|
|
|
|
|
|
|
|
-test('有授课记录的正常学员在最后一节课结束后仍可查看历史,过滤停用、删除、取消及其他老师记录', async () => {
|
|
|
|
|
- for (let id = 1; id <= 9; id++) {
|
|
|
|
|
|
|
+test('无后续排课时按未结束复习保留正常学员,过滤无效账号、任务及其他老师记录', async () => {
|
|
|
|
|
+ for (let id = 1; id <= 12; id++) {
|
|
|
await user(id, { disabled: id === 2, deleted: id === 3, group: id === 4 ? 3 : 1 });
|
|
await user(id, { disabled: id === 2, deleted: id === 3, group: id === 4 ? 3 : 1 });
|
|
|
await appointment(id, id, { date: '2026-10-29', status: '30' });
|
|
await appointment(id, id, { date: '2026-10-29', status: '30' });
|
|
|
- await db.query('INSERT INTO "DailyStudyRecord" VALUES($1,$2,$3,$4,$5)',
|
|
|
|
|
- [id === 5 ? 'other' : 'co', id, String(id), id === 6 ? '301' : '300', id === 7]);
|
|
|
|
|
- await db.query('INSERT INTO "CommonModel" VALUES($1,56,$2,$3,$4,$5)',
|
|
|
|
|
- [id === 5 ? 'other' : 'co', id, id === 8 ? -2 : 99, '2026-10-29T00:00:00Z', id === 9]);
|
|
|
|
|
|
|
+ await review(id, id, { company: id === 5 ? 'other' : 'co', teacher: id === 6 ? 301 : 300,
|
|
|
|
|
+ deleted: id === 7, commonStatus: id === 8 ? -2 : 99, commonDeleted: id === 9,
|
|
|
|
|
+ duplicate: id === 10, status: id === 11 ? '1' : '0', date: id === 12 ? '2026-10-29' : '2026-11-01' });
|
|
|
}
|
|
}
|
|
|
- await user(10); await appointment(10, 10); // Future lesson remains eligible before first study.
|
|
|
|
|
- await user(11); await appointment(11, 11, { date: '2026-10-29', status: '30' }); // No study record.
|
|
|
|
|
|
|
+ await user(20); await appointment(20, 20); // Upcoming lessons remain visible before any review is generated.
|
|
|
const first = await page({ selectedStudentId: 1, psize: 1 });
|
|
const first = await page({ selectedStudentId: 1, psize: 1 });
|
|
|
const second = await page({ selectedStudentId: 1, psize: 1, cpage: 2 });
|
|
const second = await page({ selectedStudentId: 1, psize: 1, cpage: 2 });
|
|
|
assert.equal(first.page.itemCount, 2);
|
|
assert.equal(first.page.itemCount, 2);
|
|
|
assert.deepEqual(ids(first), [1]);
|
|
assert.deepEqual(ids(first), [1]);
|
|
|
- assert.deepEqual(ids(second), [10]);
|
|
|
|
|
|
|
+ assert.deepEqual(ids(second), [20]);
|
|
|
|
|
+});
|
|
|
|
|
+
|
|
|
|
|
+test('最后复习当天仍显示,复习期结束后移出,历史授课记录不会永久保留学员', async () => {
|
|
|
|
|
+ await user(1); await appointment(1, 1, { date: '2026-10-01', status: '30' });
|
|
|
|
|
+ await db.query('INSERT INTO "DailyStudyRecord" VALUES($1,$2,$3,$4,$5)', ['co', 1, 1, '300', false]);
|
|
|
|
|
+ await db.query('INSERT INTO "CommonModel" VALUES($1,56,$2,99,$3,false)', ['co', 1, '2026-10-01T00:00:00Z']);
|
|
|
|
|
+ await review(1, 1, { date: '2026-10-30' });
|
|
|
|
|
+ await review(2, 1, { date: '2026-11-01' });
|
|
|
|
|
+ assert.deepEqual(ids(await page()), [1]);
|
|
|
|
|
+ gateway.appOverviewToday = () => '2026-10-31';
|
|
|
|
|
+ assert.deepEqual(ids(await page()), [1]);
|
|
|
|
|
+ gateway.appOverviewToday = () => '2026-11-01';
|
|
|
|
|
+ assert.deepEqual(ids(await page()), [1]);
|
|
|
|
|
+ gateway.appOverviewToday = () => '2026-11-02';
|
|
|
|
|
+ assert.deepEqual(ids(await page({ selectedStudentId: 1 })), []);
|
|
|
|
|
+});
|
|
|
|
|
+
|
|
|
|
|
+test('复习全部完成后移出,另一节课仍有未结束复习时继续显示', async () => {
|
|
|
|
|
+ await user(1); await appointment(1, 1, { date: '2026-10-01', status: '30' });
|
|
|
|
|
+ await review(1, 1, { date: '2026-11-05' });
|
|
|
|
|
+ await review(2, 1, { date: '2026-11-20', status: '1' });
|
|
|
|
|
+ assert.deepEqual(ids(await page()), [1]);
|
|
|
|
|
+ await db.query('UPDATE "MemoryPracticeRecord" SET fxzt=$1 WHERE id=$2', ['1', 1]);
|
|
|
|
|
+ assert.deepEqual(ids(await page()), []);
|
|
|
|
|
+ await review(3, 1, { date: '2026-11-21' });
|
|
|
|
|
+ assert.deepEqual(ids(await page()), [1]);
|
|
|
|
|
+});
|
|
|
|
|
+
|
|
|
|
|
+test('复习日期兼容紧凑日期、斜线日期和计划时间回退,无日期任务不能保留学员', async () => {
|
|
|
|
|
+ for (let id = 1; id <= 4; id++) { await user(id); await appointment(id, id, { date: '2026-10-01', status: '30' }); }
|
|
|
|
|
+ await review(1, 1, { date: '20261030' });
|
|
|
|
|
+ await review(2, 2, { date: '2026/10/31' });
|
|
|
|
|
+ await review(3, 3, { date: '', time: '2026-10-30 20:00' });
|
|
|
|
|
+ await review(4, 4, { date: '', time: '' });
|
|
|
|
|
+ assert.deepEqual(ids(await page()).sort((a,b) => a-b), [1,2,3]);
|
|
|
});
|
|
});
|
|
|
|
|
|
|
|
test('恢复有效学员时将其放在首屏,停用或无排课的旧选择不能绕过筛选', async () => {
|
|
test('恢复有效学员时将其放在首屏,停用或无排课的旧选择不能绕过筛选', async () => {
|