🌳
pt0/deployF/testsF/ipfsRoundtripTestAI.mts
1import { createHash } from 'crypto'
5import type { SuiteRunner } from './runTestsCoreAI.mts'
7export const genTestPng = (label: string): Buffer => {
8 const seed = `ipfs-roundtrip-${label}-${Date.now()}`
9 const hash = createHash('sha256').update(seed).digest()
10 const canvas = createCanvas(100, 100)
11 const ctx = canvas.getContext('2d')
12 ctx.fillStyle = `rgb(${hash[0]}, ${hash[1]}, ${hash[2]})`
13 ctx.fillRect(0, 0, 100, 100)
14 ctx.fillStyle = 'white'
15 ctx.font = '14px sans-serif'
16 ctx.fillText(seed.slice(0, 12), 5, 55)
17 return canvas.toBuffer('image/png')
20export const runIpfsRoundtripSuite: SuiteRunner = async ({baseUrl, singleTestName}) => {
21 const {tests, test} = createTestCollector()
23 test('ipfsUploadAndProxyFetch', async () => {
24 const buf = genTestPng('e2e')
26 let cid: string
27 try { cid = await uploadToIpfs(buf) }
28 catch (err) { return {passed: false, msg: `uploadToIpfs failed: ${(err as Error).message}`} }
30 const resp = await fetch(`${baseUrl}/ipfs/${cid}.bin`)
31 if (!resp.ok) return {passed: false, msg: `proxy GET ${resp.status}: ${await resp.text().catch(() => '')}`}
33 const contentType = resp.headers.get('content-type') || ''
34 if (!contentType.includes('image')) return {passed: false, msg: `expected image content-type, got: ${contentType}`}
36 const fetched = Buffer.from(await resp.arrayBuffer())
37 if (!buf.equals(fetched)) return {passed: false, msg: `bytes mismatch: sent ${buf.length}B, got ${fetched.length}B`}
39 const cacheCtrl = resp.headers.get('cache-control') || ''
40 if (!cacheCtrl.includes('immutable')) return {passed: false, msg: `missing immutable cache-control, got: ${cacheCtrl}`}
42 return {passed: true, msg: `cid=${cid.slice(0, 12)}... ${buf.length}B png roundtrip ok`}
43 })
45 return runTestsWithProgress({tests, suiteName: 'ipfs', singleTestName})