import {test} from 'node:test'; import assert from 'node:assert/strict'; import {readFileSync} from 'node:fs'; import vm from 'node:vm'; import {PGlite} from '@electric-sql/pglite'; const source=readFileSync(new URL('../cloud/mobile-teaching.js',import.meta.url),'utf8'); test('复习姓名跳过空白,保留真实姓名、昵称、旧姓名及历史任务姓名,无法确认时显示学员编号',async()=>{ const expression=vm.runInNewContext(source+';reviewStudentNameSql()'),db=new PGlite(); try{ for(const [real,nick,legacy,title,login,expected] of [ ['可爱同学','昵称','{}','历史名@21天抗遗忘','login','可爱同学'], ['', ' 小林 ', '{}','历史名@21天抗遗忘','login','小林'], [' ','','{"HoneyName":" 小陈 "}','历史名@21天抗遗忘','login','小陈'], [null,null,'{}','谢星星@21天抗遗忘@2024-09-17',null,'谢星星'], ['', '', '{}','课程名称','student-login','student-login'], ['', '', '{}','课程名称',null,'学员 213'], [null,null,'{}','@21天抗遗忘',null,'学员 213']]){ const r=await db.query(`SELECT ${expression} AS name FROM (SELECT $1::text "realName",$2::text nickname,$3::jsonb "legacyUserData",$5::text username) u CROSS JOIN (SELECT $4::text title) c CROSS JOIN (SELECT 213 AS yhid) m`,[real,nick,legacy,title,login]);assert.equal(r.rows[0].name,expected); } }finally{await db.close();} }); test('老师复习列表待复习、已复习及翻页均返回姓名,保持工资与老师范围',async()=>{ const db=new PGlite();try{ await db.exec(readFileSync(new URL('./fixtures/teacher-review-schema.sql',import.meta.url),'utf8')); await db.exec(`INSERT INTO "_User" VALUES('co',20,'','', 'login','{"HoneyName":"小陈"}'); UPDATE "CommonModel" SET title='历史学员@21天抗遗忘'; INSERT INTO "ReviewRewardIncome"(company,"taskId",amount,status) VALUES('co','r2',0.5,'earned');`); const query=async(s,a)=>(await db.query(s,a)).rows; const ctx=vm.createContext({Date,Promise,DEFAULT_COMPANY_ID:'co',number:(v,f=0)=>Number(v)||f,authorizeRequestedUser:async()=>30,appOverviewToday:()=> '2026-10-14',legacyAliases:r=>r,appLiveVersionSnapshot:async()=>({}),reviewIncomeTotal:async()=>0.5,Psql:{query,one:async(s,a)=>(await query(s,a))[0]}});vm.runInContext(source,ctx); for(const [status,page] of [['pending',1],['pending',2],['completed',1]]){ const result=await ctx.appReviewPage({status,page,pageSize:10},{get:()=>3});assert.ok(result.items.length);assert.ok(result.items.every(r=>r.honeyName==='小陈'&&Number(r.plid)===30));assert.equal(result.summary.income,status==='completed'?0.5:0); if(status==='completed'){assert.equal(result.items[0].money,0.5);assert.equal(result.items[0].rewardStatus,'earned');} } const monthly=await ctx.appReviewPage({status:'completed',month:'2026-10',pageSize:1},{get:()=>3}); assert.equal(monthly.summary.income,0.5); const emptyMonth=await ctx.appReviewPage({status:'completed',month:'2026-09'},{get:()=>3}); assert.equal(emptyMonth.summary.income,0);assert.equal(emptyMonth.page.itemCount,0); await db.exec('DELETE FROM "_User"'); const historical=await ctx.appReviewPage({status:'completed'},{get:()=>3});assert.equal(historical.items[0].honeyName,'历史学员'); }finally{await db.close();} }); test('无单词语法写作任务进入日历、今日统计和学员筛选,普通空记录仍隐藏',async()=>{ const db=new PGlite();try{ await db.exec(readFileSync(new URL('./fixtures/teacher-review-schema.sql',import.meta.url),'utf8')); await db.exec(`INSERT INTO "DailyStudyRecord"(company,id,learned,xxqs,dsid,"userId") VALUES('co',101,0,'[]','200',20); INSERT INTO "CommonModel"(company,"modelId","generalId","itemId",status) VALUES('co',56,100,101,99),('co',54,200,201,99); INSERT INTO "CourseAppointment" VALUES('co',201,'20','30','high_writing');`); const query=async(s,a)=>(await db.query(s,a)).rows; const ctx=vm.createContext({Date,Promise,DEFAULT_COMPANY_ID:'co',number:(v,f=0)=>Number(v)||f,authorizeRequestedUser:async()=>30,appOverviewToday:()=> '2026-10-14',legacyAliases:r=>r,appLiveVersionSnapshot:async()=>({}),Psql:{query,one:async(s,a)=>(await query(s,a))[0]}});vm.runInContext(source,ctx); const page=()=>ctx.appReviewPage({scope:'today',includeIncome:false},{get:()=>3}); const notes=await page();assert.equal(notes.items.length,2);assert.equal(notes.summary.todayTotal,2);assert.equal(notes.summary.todayPending,1);assert.equal(notes.summary.todayCompleted,1); assert.equal(notes.students.length,1);assert.equal(notes.students[0].id,'20');assert.ok(notes.dates.length>0); assert.ok(notes.items.every(r=>r.kc_title==='语法写作复习')); for(const update of [`UPDATE "CourseAppointment" SET "courseCategoryKey"='word'`,`UPDATE "CourseAppointment" SET "courseCategoryKey"='high_writing',szyh='21'`,`UPDATE "CourseAppointment" SET szyh='20',dszt='10'`]){ await db.exec(update);const hidden=await page();assert.equal(hidden.items.length,0);assert.equal(hidden.summary.todayTotal,0);assert.equal(hidden.students.length,0); } }finally{await db.close();} });