d
This commit is contained in:
parent
c3a6f5ff37
commit
4c4e767ec6
73 changed files with 3502 additions and 741 deletions
|
|
@ -8,9 +8,10 @@ const {root,starterPuzzle}=require('./helpers/app-source');
|
|||
const {connectRealtime}=require('./helpers/realtime-client');
|
||||
|
||||
const port=19000+Math.floor(Math.random()*10000);
|
||||
const dataDir=fs.mkdtempSync(path.join(os.tmpdir(),'bend-field-shared-world-'));
|
||||
const dataDir=fs.mkdtempSync(path.join(os.tmpdir(),'link-field-shared-world-'));
|
||||
const worldDir=path.join(dataDir,'world');
|
||||
const child=spawn(process.execPath,[path.join(root,'server.js')],{
|
||||
env:{...process.env,PORT:String(port),HOST:'127.0.0.1',BEND_FIELD_DATA_DIR:dataDir},stdio:['ignore','pipe','pipe']
|
||||
env:{...process.env,PORT:String(port),HOST:'127.0.0.1',LINK_FIELD_TEST_DATA_ROOT:dataDir},stdio:['ignore','pipe','pipe']
|
||||
});
|
||||
let stderr='';child.stderr.on('data',chunk=>stderr+=chunk);
|
||||
const base=`http://127.0.0.1:${port}`;
|
||||
|
|
@ -27,8 +28,11 @@ function solvedState(puzzle){return{paths:puzzle.solution.map(route=>({startGate
|
|||
(async()=>{
|
||||
for(let i=0;i<60;i++){try{const {response}=await request('/api/cloud/status');if(response.ok)break}catch(_){}await sleep(50)}
|
||||
const status=await request('/api/cloud/status');assert.equal(status.response.status,200);assert.equal(status.body.sharedWorld,true);
|
||||
const mountedStatus=await request('/~333/link-field/api/cloud/status');assert.equal(mountedStatus.response.status,200);assert.equal(mountedStatus.body.sharedWorld,true);
|
||||
const page=await requestText('/');assert.equal(page.response.status,200);assert(page.body.indexOf('build-meta.js')<page.body.indexOf('puzzle-core.js')&&page.body.indexOf('app-logic.js')>page.body.indexOf('puzzle-core.js')&&page.body.indexOf('app-logic.js')<page.body.indexOf('app.js'));
|
||||
const mountedPage=await requestText('/~333/link-field/');assert.equal(mountedPage.response.status,200);assert.match(mountedPage.body,/LinkField/);
|
||||
const runtimeConfig=await requestText('/runtime-config.js');assert.equal(runtimeConfig.response.status,200);assert.match(runtimeConfig.body,/cloudApi:true/);
|
||||
const mountedRuntimeConfig=await requestText('/~333/link-field/runtime-config.js');assert.equal(mountedRuntimeConfig.response.status,200);assert.match(mountedRuntimeConfig.body,/cloudApi:true/);
|
||||
const logicAsset=await requestText('/app-logic.js');assert.equal(logicAsset.response.status,200);assert.match(logicAsset.body,/BendAppLogic/);
|
||||
|
||||
const alice=(await request('/api/cloud/session',{method:'POST',headers:{'content-type':'application/json'},body:JSON.stringify({name:'Alice'})})).body;
|
||||
|
|
@ -37,12 +41,12 @@ function solvedState(puzzle){return{paths:puzzle.solution.map(route=>({startGate
|
|||
assert.equal(alice.name,'Alice');assert.equal(bob.name,'Bob');
|
||||
|
||||
const starter=starterPuzzle(),b0=boardMeta('B0',0,123456,starter);
|
||||
const bootstrap={baseRevision:0,global:{schema:31,appVersion:'47.70',generatorVersion:5,worldGeneration:'v47-field-reset-20260728-interaction-fix',nextId:1,score:999,cursorStyle:'do-not-share',cloudProfile:{token:'do-not-store'}},metas:[b0],states:[{id:'B0',value:{paths:[],solved:false,rev:1,revAuthor:'alice'}}],deleted:[]};
|
||||
const bootstrap={baseRevision:0,global:{schema:31,appVersion:'47.70',generatorVersion:5,worldGeneration:'linkfield-single-world-20260801',nextId:1,score:999,cursorStyle:'do-not-share',cloudProfile:{token:'do-not-store'}},metas:[b0],states:[{id:'B0',value:{paths:[],solved:false,rev:1,revAuthor:'alice'}}],deleted:[]};
|
||||
const pushed=await request('/api/cloud/push',{method:'POST',headers:auth(alice),body:JSON.stringify(bootstrap)});assert.equal(pushed.response.status,200);assert.equal(pushed.body.revision,1);assert.deepEqual(pushed.body.clearEvents,[]);
|
||||
|
||||
const bobInitial=await request('/api/cloud/pull?since=0&eventsSince=0',{headers:auth(bob)});assert.equal(bobInitial.response.status,200);assert.equal(bobInitial.body.changed,true);assert.equal(bobInitial.body.fullSnapshot,true);assert.equal(bobInitial.body.page.metas.B0.seed,123456);assert.equal(bobInitial.body.page.states.B0.solved,false);assert(bobInitial.body.page.metas.B0.rev>1_000_000_000_000);assert(bobInitial.body.page.states.B0.rev>1_000_000_000_000);assert.equal(bobInitial.body.page.global.score,undefined);assert.equal(bobInitial.body.page.global.cursorStyle,undefined);assert.equal(bobInitial.body.page.global.cloudProfile,null);assert.equal(bobInitial.body.player.name,'Bob');
|
||||
|
||||
aliceRealtime=await connectRealtime(base,alice);aliceRealtime.send({type:'viewport',minX:-10,minY:-10,maxX:10,maxY:10});await aliceRealtime.waitFor('snapshot');aliceRealtime.send({type:'claim',requestId:'server-smoke-claim',boardId:'B0'});const claimResult=await aliceRealtime.waitFor(message=>message.type==='claim-result'&&message.requestId==='server-smoke-claim');assert.equal(claimResult.ok,true);
|
||||
aliceRealtime=await connectRealtime(base+'/~333/link-field',alice);aliceRealtime.send({type:'viewport',minX:-10,minY:-10,maxX:10,maxY:10});await aliceRealtime.waitFor('snapshot');aliceRealtime.send({type:'claim',requestId:'server-smoke-claim',boardId:'B0'});const claimResult=await aliceRealtime.waitFor(message=>message.type==='claim-result'&&message.requestId==='server-smoke-claim');assert.equal(claimResult.ok,true);
|
||||
const clearPayload={baseRevision:1,global:{nextId:1,lastSolveAt:Date.now()},metas:[],states:[{id:'B0',value:solvedState(starter)}],deleted:[]};
|
||||
const cleared=await request('/api/cloud/push',{method:'POST',headers:auth(alice),body:JSON.stringify(clearPayload)});assert.equal(cleared.response.status,200);assert.equal(cleared.body.revision,2);assert.equal(cleared.body.clearEvents.length,1);assert.equal(cleared.body.clearEvents[0].playerName,'Alice');assert.equal(cleared.body.clearEvents[0].id,'B0');assert.equal(cleared.body.clearEvents[0].level,1);
|
||||
|
||||
|
|
@ -63,8 +67,8 @@ function solvedState(puzzle){return{paths:puzzle.solution.map(route=>({startGate
|
|||
const overlap=await request('/api/cloud/push',{method:'POST',headers:auth(alice),body:JSON.stringify({baseRevision:4,global:{},metas:[boardMeta('B2',1,222,starter)],states:[],deleted:[]})});assert.equal(overlap.response.status,400);
|
||||
|
||||
|
||||
const aliceRecord=JSON.parse(fs.readFileSync(path.join(dataDir,`${alice.playerId}.json`),'utf8'));assert.equal(aliceRecord.name,'Alice');assert.notEqual(aliceRecord.tokenHash,alice.token);assert.equal(aliceRecord.boardVersions,undefined);assert.equal(aliceRecord.global,undefined);
|
||||
const world=JSON.parse(fs.readFileSync(path.join(dataDir,'shared-world.json'),'utf8'));assert.equal(world.revision,4);assert.equal(world.global.score,undefined);assert.equal(world.global.cursorStyle,undefined);assert.equal(world.boardVersions.B0,3);assert.equal(world.boardVersions.B1,4);assert.equal(world.clearEvents[0].playerName,'Alice');
|
||||
const b0Shard=JSON.parse(fs.readFileSync(path.join(dataDir,'shared-world.boards','B0.3.json'),'utf8'));assert.equal(b0Shard.state.solvedBy,'Alice');assert.equal(b0Shard.state.paths.length,starter.solution.length);
|
||||
const aliceRecord=JSON.parse(fs.readFileSync(path.join(worldDir,`${alice.playerId}.json`),'utf8'));assert.equal(aliceRecord.name,'Alice');assert.notEqual(aliceRecord.tokenHash,alice.token);assert.equal(aliceRecord.boardVersions,undefined);assert.equal(aliceRecord.global,undefined);
|
||||
const world=JSON.parse(fs.readFileSync(path.join(worldDir,'shared-world.json'),'utf8'));assert.equal(world.revision,4);assert.equal(world.global.score,undefined);assert.equal(world.global.cursorStyle,undefined);assert.equal(world.boardVersions.B0,3);assert.equal(world.boardVersions.B1,4);assert.equal(world.clearEvents[0].playerName,'Alice');
|
||||
const b0Shard=JSON.parse(fs.readFileSync(path.join(worldDir,'shared-world.boards','B0.3.json'),'utf8'));assert.equal(b0Shard.state.solvedBy,'Alice');assert.equal(b0Shard.state.paths.length,starter.solution.length);
|
||||
console.log('BEND FIELD shared-world phase 2 server smoke test passed');
|
||||
})().catch(error=>{console.error(error);if(stderr)console.error(stderr);process.exitCode=1}).finally(()=>{aliceRealtime?.close();child.kill('SIGTERM');fs.rmSync(dataDir,{recursive:true,force:true})});
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue