Verify successful image generation and upscale task delivery
This commit is contained in:
@@ -2,6 +2,7 @@ import assert from 'node:assert/strict';
|
||||
import {randomUUID} from 'node:crypto';
|
||||
import {db} from '../src/lib/db';
|
||||
import {newToken,tokenDigest,ACCOUNT_COOKIE} from '../src/lib/account-crypto';
|
||||
import type {CanvasDocument} from '../src/lib/canvas-document';
|
||||
export async function verifyCanvasWorkspace(base:string){
|
||||
const identities=await Promise.all([0,1].map(async()=>{const id=randomUUID(),token=newToken();await db().query("INSERT INTO account_users(id,email,password_hash,verified_at) VALUES($1,$2,'test',now())",[id,id+'@example.com']);await db().query("INSERT INTO account_tokens(digest,user_id,kind,expires_at) VALUES($1,$2,'session',now()+interval '1 hour')",[tokenDigest(token),id]);return {[`cookie`]:ACCOUNT_COOKIE+'='+token}}));
|
||||
const origin=process.env.ACCOUNT_PUBLIC_ORIGIN||base;
|
||||
@@ -39,6 +40,39 @@ export async function verifyCanvasWorkspace(base:string){
|
||||
assert.equal((await call(root+'/tasks/'+second,'PATCH',result,agent)).status,200,'Identical completion is idempotent');
|
||||
assert.equal((await call(root+'/tasks/'+second,'PATCH',{status:'succeeded',result:{text:'覆盖'}},agent)).status,409);
|
||||
const final=await (await call(root,'GET',undefined,identities[0])).json();assert.equal(final.revision,4);assert.equal(final.document.cards.find((n:{id:string})=>n.id==='script').text,'第一镜:城市醒来。');assert.deepEqual(final.document.links,doc.links);
|
||||
const png='data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mP8/x8AAwMCAO+ip1sAAAAASUVORK5CYII=';
|
||||
const imageDocument:CanvasDocument={version:1,cards:[
|
||||
{id:'source',kind:'image',title:'参考图',text:'保留原图',image:png,x:0,y:0},
|
||||
{id:'generated',kind:'image',title:'图生图',text:'',instruction:'保留构图,改为雪夜',operation:'generate',x:500,y:0},
|
||||
{id:'upscaled',kind:'image',title:'图片高清',text:'',operation:'upscale',x:1000,y:0},
|
||||
],links:[['source','generated'],['generated','upscaled']]};
|
||||
const imageCreate=await call('','POST',{document:imageDocument},identities[0]);assert.equal(imageCreate.status,201);
|
||||
const imageCanvas=await imageCreate.json(),imageRoot='/'+imageCanvas.id;
|
||||
const imageLink=await call(imageRoot+'/link','POST',{},identities[0]);assert.equal(imageLink.status,201);
|
||||
const imageAgent={authorization:'Bearer '+(await imageLink.json()).token};
|
||||
for(const [index,targetId] of ['generated','upscaled'].entries()){
|
||||
const queued=await call(imageRoot+'/tasks','POST',{revision:index+1,targetId},identities[0]);assert.equal(queued.status,201,await queued.clone().text());
|
||||
const taskId=(await queued.json()).id,taskPath=imageRoot+'/tasks/'+taskId;
|
||||
const snapshotResponse=await call(taskPath,'GET',undefined,imageAgent);assert.equal(snapshotResponse.status,200);
|
||||
const snapshot=await snapshotResponse.json();assert.equal(snapshot.request.operation,index===0?'generate':'upscale');
|
||||
assert.equal(snapshot.request.references[0].id,index===0?'source':'generated');
|
||||
assert.equal(snapshot.request.references[0].image,png,'Image tasks carry the referenced image bytes');
|
||||
assert.deepEqual(snapshot.request.result.allowedFields,['image','text']);
|
||||
assert.equal((await call(taskPath,'PATCH',{status:'running'},imageAgent)).status,200);
|
||||
const completion={status:'succeeded',result:{image:png,text:index===0?'雪夜图片结果':'高清图片结果'}};
|
||||
const completed=await call(taskPath,'PATCH',completion,imageAgent);assert.equal(completed.status,200,await completed.clone().text());
|
||||
assert.equal((await call(taskPath,'PATCH',completion,imageAgent)).status,200,'Image completion retries are idempotent');
|
||||
const stateResponse=await call(imageRoot,'GET',undefined,identities[0]);assert.equal(stateResponse.status,200);
|
||||
const state=await stateResponse.json();assert.equal(state.revision,index+2);
|
||||
const cards=(state.document as CanvasDocument).cards;
|
||||
assert.equal(cards.find(n=>n.id===targetId)?.image,png);assert.equal(cards.find(n=>n.id===targetId)?.text,completion.result.text);
|
||||
assert.deepEqual(cards.find(n=>n.id==='source'),imageDocument.cards[0],'Generation preserves the reference node');
|
||||
assert.deepEqual(state.document.links,imageDocument.links,'Image results preserve the reference graph');
|
||||
if(index===0)assert.deepEqual(cards.find(n=>n.id==='upscaled'),imageDocument.cards[2],'Generation only updates its target');
|
||||
else assert.equal(cards.find(n=>n.id==='generated')?.text,'雪夜图片结果','Upscaling preserves the previous generated image');
|
||||
}
|
||||
assert.equal((await call(imageRoot+'/link','DELETE',{},identities[0])).status,200);
|
||||
assert.equal((await call(imageRoot,'GET',undefined,imageAgent)).status,404);
|
||||
assert.equal((await call(root+'/link','POST',{},agent)).status,403,'A delegated agent cannot mint links');
|
||||
assert.equal((await call(root+'/link','DELETE',{},identities[0])).status,200);
|
||||
assert.equal((await call(root,'GET',undefined,agent)).status,404,'Revocation takes effect on the next request');
|
||||
|
||||
Reference in New Issue
Block a user