/** * 旧画布附件上传助手和显示 URL 转换测试。请求为替身,检查 FormData、错误和资源地址,不是真实上传或图像解码。 * 这里的上传重试属于 canvas-assets helper,不可等同于 headless ledger 的持久冻结请求恢复。 */ import test from 'node:test'; import assert from 'node:assert/strict'; import { uploadCanvasImage } from '../src/lib/canvas-assets.ts'; import { managedImageSource } from '../src/lib/canvas-v2.ts'; // 固定 data URL 仅用来构造与对比二进制前缀,并非完整 PNG 解码样本。 const source='data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAB'; // 固定资产身份;返回值必须是项目管理的地址,任意外域响应不被当作受管上传结果。 const id='77777777-7777-4777-8777-777777777777'; const asset={id,url:`https://api.foundry.entroia.com/projects/endoleap/workspaces/w/assets/${id}`,width:1,height:1,bytes:24,mime_type:'image/png'}; // 首例直接比对 FormData.image 原字节、上传路径、POST 和幂等键形状,返回值保留服务资产元数据。 // 键的正则只检查 36 位字符集合,不完整校验 UUID 分段;替身返回固定元数据,不证明服务器实际解码成功。 test('attachment upload sends the original file bytes',async()=>{ const bytes=Buffer.from(source.split(',')[1],'base64');let calls=0; const result=await uploadCanvasImage(async(path,options)=>{ calls++;assert.equal(path,'workspaces/w/assets');assert.match(options.headers['Idempotency-Key'],/^[a-f0-9-]{36}$/);assert.equal(options.method,'POST'); assert.deepEqual(Buffer.from(await options.body.get('image').arrayBuffer()),bytes);return asset; },'w',new Blob([bytes],{type:'image/png'}),'image.png'); assert.equal(calls,1);assert.deepEqual(result,asset); }); // 权限拒绝直接传播;格式类似但地址不受管理的成功响应也要拒绝,不能把任意 URL 写成上传结果。 test('attachment upload propagates permission failures and rejects unmanaged response URLs',async()=>{ const file=new Blob(['test'],{type:'image/png'}); await assert.rejects(uploadCanvasImage(async()=>{throw new Error('forbidden');},'w',file,'test.png'),/forbidden/); await assert.rejects(uploadCanvasImage(async()=>({...asset,url:'https://invalid.example/a.png'}),'w',file,'test.png'),/invalid_asset_response/); }); // 模拟第一次连接丢失、第二次成功;此例直接断言两次调用与相同幂等键,文件字节传递由首例单独检查。 test('uncertain upload retries the exact bytes with the same idempotency key',async()=>{ let calls=0,key; await uploadCanvasImage(async(_path,options)=>{calls++;if(!key)key=options.headers['Idempotency-Key'];assert.equal(options.headers['Idempotency-Key'],key);if(calls===1)throw new TypeError('connection lost');return asset;},'w',new Blob(['test'],{type:'image/png'}),'test.png');assert.equal(calls,2); }); // 受管原始 URL 转同源认证代理,preview 仅加显示变体参数;普通外部图片地址保持原样。 // 这里仅比对字符串,不请求代理,也不验证登录鉴权或预览图片内容。 test('preview URLs are renderer-only and do not replace original managed references',()=>{ assert.equal(managedImageSource(asset.url),`/api/foundry/workspaces/w/assets/${id}`);assert.equal(managedImageSource(asset.url,true),`/api/foundry/workspaces/w/assets/${id}?variant=preview`); assert.equal(managedImageSource('https://example.com/photo.png',true),'https://example.com/photo.png'); });