|
@@ -154,15 +154,25 @@ test('新增账号与栏目幂等补齐,已有账户余额和目录名称保
|
|
|
const previous=context.fetch;let passwords=0;
|
|
const previous=context.fetch;let passwords=0;
|
|
|
context.Parse.Query=class{constructor(className){assert.equal(className,'Company');}async get(id){return{id,className:'Company'};}};
|
|
context.Parse.Query=class{constructor(className){assert.equal(className,'Company');}async get(id){return{id,className:'Company'};}};
|
|
|
context.Parse.Object={createWithoutData:()=>{throw Error('Production SDK does not support two-argument createWithoutData');}};
|
|
context.Parse.Object={createWithoutData:()=>{throw Error('Production SDK does not support two-argument createWithoutData');}};
|
|
|
- context.Parse.User=class{constructor(){this.fields={};}set(k,v){this.fields[k]=v;}setUsername(v){this.fields.username=v;}setPassword(v){assert.ok(v.length>60);passwords++;}async save(){this.id='new-user';const f=this.fields;assert.equal(f.identityType,'member');assert.equal(f.adminRoleKey,undefined);assert.equal(f.password,undefined);await sql('INSERT INTO "_User" ("objectId",company,username,"legacyUserId","legacyUserData") VALUES($1,$2,$3,$4,$5::jsonb)',['new-user',f.company.id,f.username,f.legacyUserId,JSON.stringify(f.legacyUserData)]);}};
|
|
|
|
|
|
|
+ context.Parse.User=class{constructor(){this.fields={};}set(k,v){this.fields[k]=v;}setUsername(v){this.fields.username=v;}setPassword(v){assert.equal(v,'12345678');passwords++;}async save(){this.id='new-user';const f=this.fields;assert.equal(f.identityType,'member');assert.equal(f.passwordResetRequired,false);assert.equal(f.adminRoleKey,undefined);assert.equal(f.password,undefined);await sql('INSERT INTO "_User" ("objectId",company,username,"legacyUserId","legacyUserData","_hashed_password") VALUES($1,$2,$3,$4,$5::jsonb,$6)',['new-user',f.company.id,f.username,f.legacyUserId,JSON.stringify(f.legacyUserData),'sdk-hashed-initial-password']);}};
|
|
|
context.fetch=async url=>{const action=new URL(url).searchParams.get('action');return {ok:true,json:async()=>({retcode:0,page:{pageCount:1},result:action==='user_list'?[{UserID:20,UserName:'existing',GroupID:1,Purse:1},{UserID:4000,UserName:'new-member',GroupID:1,Purse:10,Password:'ignored-hash'}]:[{NodeID:8,NodeName:'旧目录'},{NodeID:9,ParentID:8,NodeName:'新目录'}]})};};
|
|
context.fetch=async url=>{const action=new URL(url).searchParams.get('action');return {ok:true,json:async()=>({retcode:0,page:{pageCount:1},result:action==='user_list'?[{UserID:20,UserName:'existing',GroupID:1,Purse:1},{UserID:4000,UserName:'new-member',GroupID:1,Purse:10,Password:'ignored-hash'}]:[{NodeID:8,NodeName:'旧目录'},{NodeID:9,ParentID:8,NodeName:'新目录'}]})};};
|
|
|
try{let r=await call({action:'supplement'});assert.equal(r.success,true,r.message);assert.equal(r.data.accounts.created,1);assert.equal(r.data.nodes.created,1);
|
|
try{let r=await call({action:'supplement'});assert.equal(r.success,true,r.message);assert.equal(r.data.accounts.created,1);assert.equal(r.data.nodes.created,1);
|
|
|
|
|
+ assert.equal((await sql('SELECT "legacyPasswordMigrationAllowed" FROM "_User" WHERE "objectId"=\'new-user\''))[0].legacyPasswordMigrationAllowed,false);
|
|
|
|
|
+ await sql('UPDATE "_User" SET "_hashed_password"=$1 WHERE "objectId"=\'new-user\'',['admin-reset-password']);
|
|
|
r=await call({action:'supplement'});assert.equal(r.success,true,r.message);assert.equal(r.data.accounts.created,0);assert.equal(r.data.nodes.created,0);assert.equal(passwords,1);
|
|
r=await call({action:'supplement'});assert.equal(r.success,true,r.message);assert.equal(r.data.accounts.created,0);assert.equal(r.data.nodes.created,0);assert.equal(passwords,1);
|
|
|
|
|
+ assert.equal((await sql('SELECT "_hashed_password" FROM "_User" WHERE "objectId"=\'new-user\''))[0]._hashed_password,'admin-reset-password');
|
|
|
assert.equal((await sql('SELECT "legacyUserData" FROM "_User" WHERE "legacyUserId"=20'))[0].legacyUserData.Purse,99);
|
|
assert.equal((await sql('SELECT "legacyUserData" FROM "_User" WHERE "legacyUserId"=20'))[0].legacyUserData.Purse,99);
|
|
|
assert.equal((await sql('SELECT "nodeName" FROM "Node" WHERE "nodeId"=8'))[0].nodeName,'新系统目录');
|
|
assert.equal((await sql('SELECT "nodeName" FROM "Node" WHERE "nodeId"=8'))[0].nodeName,'新系统目录');
|
|
|
}finally{context.fetch=previous;}
|
|
}finally{context.fetch=previous;}
|
|
|
});
|
|
});
|
|
|
|
|
|
|
|
|
|
+test('新导入的老师和门店仍使用各自的一次性旧密码迁移,不设置学生初始密码',async()=>{
|
|
|
|
|
+ const previous=context.fetch;const passwords=new Map();
|
|
|
|
|
+ context.Parse.User=class{constructor(){this.fields={};}set(k,v){this.fields[k]=v;}setUsername(v){this.fields.username=v;}setPassword(v){this.password=v;}async save(){const f=this.fields;this.id='role-'+f.legacyUserId;passwords.set(f.legacyUserId,this.password);assert.ok(this.password.length>60);assert.equal(f.identityType,f.legacyGroupId===3?'coach':'store');await sql('INSERT INTO "_User" ("objectId",company,username,"legacyUserId","legacyUserData","_hashed_password") VALUES($1,$2,$3,$4,$5::jsonb,$6)',[this.id,f.company.id,f.username,f.legacyUserId,JSON.stringify(f.legacyUserData),'sdk-'+f.legacyUserId]);}};
|
|
|
|
|
+ context.fetch=async url=>({ok:true,json:async()=>({retcode:0,page:{pageCount:1},result:new URL(url).searchParams.get('action')==='user_list'?[{UserID:4001,UserName:'new-coach',GroupID:3},{UserID:4002,UserName:'new-store',GroupID:2}]:[]})});
|
|
|
|
|
+ try{const r=await call({action:'supplement'});assert.equal(r.success,true,r.message);assert.equal(r.data.accounts.created,2);assert.notEqual(passwords.get(4001),passwords.get(4002));assert.ok((await sql('SELECT "legacyPasswordMigrationAllowed" allowed FROM "_User" WHERE "legacyUserId" IN (4001,4002)')).every(r=>r.allowed===true));}finally{context.fetch=previous;}
|
|
|
|
|
+});
|
|
|
|
|
+
|
|
|
|
|
|
|
|
test('未取得服务器对账证据时不完成运行;已退出进程的目录锁可恢复',async()=>{
|
|
test('未取得服务器对账证据时不完成运行;已退出进程的目录锁可恢复',async()=>{
|
|
|
const root=await mkdtemp(join(tmpdir(),'direct-sync-negative-')),realFetch=globalThis.fetch;let finished=false;
|
|
const root=await mkdtemp(join(tmpdir(),'direct-sync-negative-')),realFetch=globalThis.fetch;let finished=false;
|