| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364 |
- 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('../deploy-admin-functions.mjs',import.meta.url),'utf8');
- const gateway=source.match(/const appGatewayCode = String.raw`([\s\S]*?)\n`;/)[1];
- async function setup(t){
- const db=new PGlite();t.after(()=>db.close());
- await db.exec(`
- CREATE TABLE "Node" (company text,"nodeId" int,"parentId" int);
- CREATE TABLE "CommonModel" (company text,"modelId" int,"generalId" int,"itemId" int,"nodeId" int,"orderId" int,title text);
- CREATE TABLE "VocabularyWord" (company text,id int,sy text);
- CREATE TABLE "PracticeRecord" (company text,yhid text,scid text,xxcs text,jrscb text);
- INSERT INTO "Node" VALUES ('7pIbDBJmKx',100,0),('7pIbDBJmKx',110,100),('7pIbDBJmKx',120,100),('other',130,100);
- INSERT INTO "CommonModel" VALUES
- ('7pIbDBJmKx',52,1,1,110,1,'one'),('7pIbDBJmKx',52,2,2,110,2,'two'),
- ('7pIbDBJmKx',52,3,3,110,3,'three'),('7pIbDBJmKx',52,4,4,110,4,'four'),
- ('7pIbDBJmKx',52,5,5,120,5,'other-unit'),('other',52,6,6,130,6,'foreign');
- INSERT INTO "VocabularyWord" VALUES ('7pIbDBJmKx',2,'第二个词');
- INSERT INTO "PracticeRecord" VALUES
- ('7pIbDBJmKx','42','2','1','0'),('7pIbDBJmKx','42','2','0','0'),
- ('7pIbDBJmKx','42','3','2.0','0'),('7pIbDBJmKx','42','4','7','0'),
- ('7pIbDBJmKx','99','1','3','0'),('other','42','1','3','0');
- `);
- const context=vm.createContext({Psql:{one:async(s,a)=>(await db.query(s,a)).rows[0],query:async(s,a)=>(await db.query(s,a)).rows}});
- vm.runInContext(gateway,context);
- context.authorizeRequestedUser=async(_,uid)=>{if(uid!==42)throw Error('无权访问');return uid;};
- return {db,read:input=>context.courseWordPage({uid:42,nids:'110',pnid:100,...input},{})};
- }
- test('四栏按最大有效学习次数分类,旧记录超过三遍归入第三遍,不重复计算',async t=>{
- const {read}=await setup(t);
- for(let pass=0;pass<4;pass++){
- const result=await read({learningPass:pass,psize:1});
- assert.equal(result.rows.length,1);assert.equal(result.rows[0].w_learned,pass);
- assert.equal(result.rows[0].GeneralID,pass+1);
- assert.deepEqual(Array.from(result.page.passCounts),[1,1,1,1]);
- assert.deepEqual(Array.from(result.page.bookPassCounts),[2,1,1,1]);
- assert.equal(result.page.firstPassProgress,60);
- }
- const result=await read({learningPass:1});assert.equal(result.rows[0].detail.sy,'第二个词');
- });
- test('分页后仍保留整本计数,其他单元未学完不会被误判为首遍完成',async t=>{
- const {read,db}=await setup(t);
- await db.exec(`UPDATE "PracticeRecord" SET xxcs='1' WHERE company='7pIbDBJmKx' AND yhid='42';INSERT INTO "PracticeRecord" VALUES('7pIbDBJmKx','42','1','1','0');`);
- const selected=await read({learningPass:1,psize:2,cpage:2});
- assert.equal(selected.rows.length,2);assert.equal(selected.page.itemCount,4);
- assert.deepEqual(Array.from(selected.page.bookPassCounts),[1,4,0,0]);assert.equal(selected.page.firstPassProgress,80);
- const empty=await read({learningPass:1,psize:2,cpage:3});assert.equal(empty.rows.length,0);assert.equal(empty.page.itemCount,4);
- });
- test('首遍全完成后进度始终100%,第二第三遍不重置;兼容旧客户端混合列表',async t=>{
- const {read,db}=await setup(t);
- await db.exec(`INSERT INTO "PracticeRecord" VALUES ('7pIbDBJmKx','42','1','1','0'),('7pIbDBJmKx','42','5','1','0');`);
- assert.equal((await read({})).page.firstPassProgress,100);
- await db.exec(`UPDATE "PracticeRecord" SET xxcs='2' WHERE company='7pIbDBJmKx' AND yhid='42';`);
- assert.equal((await read({})).page.firstPassProgress,100);
- await db.exec(`UPDATE "PracticeRecord" SET xxcs='3' WHERE company='7pIbDBJmKx' AND yhid='42';`);
- const done=await read({});assert.equal(done.page.firstPassProgress,100);assert.equal(done.rows.length,4);assert.equal(done.page.passCounts[3],4);
- });
- test('拒绝无效遍数和越权访问',async t=>{
- const {read}=await setup(t);
- for(const learningPass of [-1,4,1.5,'bad'])await assert.rejects(read({learningPass}),/学习遍数无效/);
- await assert.rejects(read({uid:99}),/无权访问/);
- });
|