11import test from 'ava'
2- import pRetry from 'p-retry'
32import { CID } from 'multiformats/cid'
43import * as Block from 'multiformats/block'
54import { sha256 , sha512 } from 'multiformats/hashes/sha2'
65import * as pb from '@ipld/dag-pb'
76import { CarWriter } from '@ipld/car'
87import { packToBlob } from 'ipfs-car/pack/blob'
8+ import { MultihashIndexSortedReader } from 'cardex'
99import { TreewalkCarSplitter } from 'carbites/treewalk'
10+ import { equals as uint8ArrayEquals } from 'uint8arrays/equals'
1011import { toString as uint8ArrayToString } from 'uint8arrays/to-string'
1112import { createClientWithUser , getRawClient } from './scripts/helpers.js'
1213import { createCar } from './scripts/car.js'
@@ -21,6 +22,7 @@ import {
2122import { File } from 'nft.storage/src/platform.js'
2223import crypto from 'node:crypto'
2324import { FormData } from 'undici'
25+ import { createCarCid } from '../src/utils/car.js'
2426
2527test . before ( async ( t ) => {
2628 const linkdexUrl = 'http://fake.api.net'
@@ -735,6 +737,75 @@ test.serial('should update a single file', async (t) => {
735737 t . is ( uploadData . name , name )
736738} )
737739
740+ test . serial ( 'should write satnav index' , async ( t ) => {
741+ const client = await createClientWithUser ( t )
742+ const config = getTestServiceConfig ( t )
743+ const mf = getMiniflareContext ( t )
744+ const { root, car : carBody } = await createCar ( 'satnav' )
745+ const carBytes = new Uint8Array ( await carBody . arrayBuffer ( ) )
746+ const carCid = await createCarCid ( carBytes )
747+
748+ const res = await mf . dispatchFetch ( 'http://miniflare.test/upload' , {
749+ method : 'POST' ,
750+ headers : {
751+ Authorization : `Bearer ${ client . token } ` ,
752+ 'Content-Type' : 'application/car' ,
753+ } ,
754+ body : carBody ,
755+ } )
756+
757+ const { ok, value } = await res . json ( )
758+ t . truthy ( ok , 'Server response payload has `ok` property' )
759+ t . is ( value . cid , root . toString ( ) , 'Server responded with expected CID' )
760+ t . is ( value . type , 'application/car' , 'type should match car mime-type' )
761+
762+ const r2Bucket = await mf . getR2Bucket ( 'SATNAV' )
763+ const r2Object = await r2Bucket . get ( `${ carCid } /${ carCid } .car.idx` )
764+ if ( ! r2Object ?. body ) {
765+ t . fail ( 'repsonse stream must exist' )
766+ }
767+ // @ts -expect-error
768+ const reader = MultihashIndexSortedReader . fromIterable ( r2Object ?. body )
769+ const entries = [ ]
770+ for await ( const entry of reader . entries ( ) ) {
771+ entries . push ( entry )
772+ }
773+
774+ t . is ( entries . length , 1 , 'Index contains a single entry' )
775+ t . true (
776+ uint8ArrayEquals ( entries [ 0 ] . digest , root . multihash . digest ) ,
777+ 'Index entry is for root data CID'
778+ )
779+ } )
780+
781+ test . serial ( 'should write dudewhere index' , async ( t ) => {
782+ const client = await createClientWithUser ( t )
783+ const config = getTestServiceConfig ( t )
784+ const mf = getMiniflareContext ( t )
785+ const { root, car : carBody } = await createCar ( 'dude' )
786+ const carBytes = new Uint8Array ( await carBody . arrayBuffer ( ) )
787+ const carCid = await createCarCid ( carBytes )
788+
789+ const res = await mf . dispatchFetch ( 'http://miniflare.test/upload' , {
790+ method : 'POST' ,
791+ headers : {
792+ Authorization : `Bearer ${ client . token } ` ,
793+ 'Content-Type' : 'application/car' ,
794+ } ,
795+ body : carBody ,
796+ } )
797+
798+ const { ok, value } = await res . json ( )
799+ t . truthy ( ok , 'Server response payload has `ok` property' )
800+ t . is ( value . cid , root . toString ( ) , 'Server responded with expected CID' )
801+ t . is ( value . type , 'application/car' , 'type should match car mime-type' )
802+
803+ const r2Bucket = await mf . getR2Bucket ( 'DUDEWHERE' )
804+ const r2Objects = await r2Bucket . list ( { prefix : `${ root } /` } )
805+ t . is ( r2Objects . objects . length , 1 )
806+ t . is ( r2Objects . objects [ 0 ] . key , `${ root } /${ carCid } ` )
807+ } )
808+
738809/**
739810 * @param {Uint8Array } data
740811 */
0 commit comments