13 const {baseUrl, singleTestName} = ctx 16 test('ipfs_cid: upload file via token', async () => { 21 query: createDonaOrderGql, 22 variables: {input: {donaRefKind: 'ipfs_cid', amountUsd: 1, charityId: 'mockedfund', expectedUploadSizeMb: 1}}, 24 if (orderResp.errors) return {passed: false, msg: `Order failed: ${orderResp.errors[0]?.message}`} 25 const orderId = orderResp.data.gmCreateDonaOrder.id 29 const entry = await db('dona_entries').where({id: orderId}).first() 30 if (!entry.upload_token) return {passed: false, msg: 'upload_token not generated'} 31 const uploadToken = entry.upload_token 35 const formData = new FormData() 36 formData.append('file', new Blob([pngBuffer], {type: 'image/png'}), 'test.png') 37 formData.append('entryId', orderId) 38 formData.append('uploadToken', uploadToken) 41 if (uploadResp.status !== 200) { 42 const err = await uploadResp.json() 43 return {passed: false, msg: `Upload failed (${uploadResp.status}): ${err.error}`} 46 const result = await uploadResp.json() 47 if (!result.cid) return {passed: false, msg: 'No CID returned'} 49 const entryAfter = await db('dona_entries').where({id: orderId}).first() 50 if (!entryAfter.ipfs_cid) return {passed: false, msg: 'ipfs_cid not set after upload'} 51 if (entryAfter.ipfs_cid !== result.cid) return {passed: false, msg: `CID mismatch: ${entryAfter.ipfs_cid} vs ${result.cid}`} 52 if (entryAfter.upload_token) return {passed: false, msg: 'upload_token should be cleared after upload'} 56 query: `query($id: ID!) { gqDonaEntryById(id: $id) { pendingUpload ipfsCid } }`, 57 variables: {id: orderId}, 59 const gqlEntry = entryResp.data?.gqDonaEntryById 60 if (gqlEntry?.pendingUpload) return {passed: false, msg: 'pendingUpload still true after upload'} 62 return {passed: true, msg: `CID=${result.cid.slice(0, 12)}...`} 68export const donateIpfsSuiteConfig: SuiteConfig = {name: 'ipfs', runner: runDonateIpfsSuite, deps: ['db']}