This repository has no description
0

Configure Feed

Select the types of activity you want to include in your feed.

core / appview / models / blobs_test.go
3.1 kB 112 lines
1package models 2 3import ( 4 "encoding/json" 5 "testing" 6 7 "github.com/ipfs/go-cid" 8 9 lexutil "github.com/bluesky-social/indigo/lex/util" 10) 11 12// two distinct, valid CIDv1 strings for use as blob refs 13const ( 14 cidA = "bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdi" 15 cidB = "bafybeihdwdcefgh4dqkjv67uzcmw7ojee6xedzdetojuzjevtenxquvyku" 16) 17 18func blobJSON(t *testing.T, cidStr, mime string) string { 19 t.Helper() 20 c, err := cid.Decode(cidStr) 21 if err != nil { 22 t.Fatalf("decode cid: %v", err) 23 } 24 b := lexutil.LexBlob{Ref: lexutil.LexLink(c), MimeType: mime, Size: 1234} 25 raw, err := json.Marshal(b) 26 if err != nil { 27 t.Fatalf("marshal blob: %v", err) 28 } 29 return string(raw) 30} 31 32func cids(blobs []*lexutil.LexBlob) []string { 33 out := make([]string, len(blobs)) 34 for i, b := range blobs { 35 out[i] = b.Ref.String() 36 } 37 return out 38} 39 40func TestParseBlobs(t *testing.T) { 41 ja := blobJSON(t, cidA, "image/png") 42 jb := blobJSON(t, cidB, "image/jpeg") 43 body := "look: ![a](blob+at://did:plc:abc/" + cidA + ") and nothing else" 44 45 t.Run("keeps referenced, drops unreferenced", func(t *testing.T) { 46 got := ParseBlobs([]string{ja, jb}, body) 47 if len(got) != 1 || got[0].Ref.String() != cidA { 48 t.Fatalf("got %v, want [%s]", cids(got), cidA) 49 } 50 }) 51 52 t.Run("dedups repeated cid", func(t *testing.T) { 53 got := ParseBlobs([]string{ja, ja}, body) 54 if len(got) != 1 { 55 t.Fatalf("got %d blobs, want 1", len(got)) 56 } 57 }) 58 59 t.Run("ignores malformed json", func(t *testing.T) { 60 got := ParseBlobs([]string{"not json", ja}, body) 61 if len(got) != 1 { 62 t.Fatalf("got %d blobs, want 1", len(got)) 63 } 64 }) 65 66 t.Run("empty input", func(t *testing.T) { 67 if got := ParseBlobs(nil, body); got != nil { 68 t.Fatalf("got %v, want nil", cids(got)) 69 } 70 }) 71} 72 73func TestMergeBlobs(t *testing.T) { 74 ja := blobJSON(t, cidA, "image/png") 75 jb := blobJSON(t, cidB, "image/jpeg") 76 77 ca, _ := cid.Decode(cidA) 78 existing := []*lexutil.LexBlob{{Ref: lexutil.LexLink(ca), MimeType: "image/png", Size: 1234}} 79 80 // body references both A (existing) and B (new upload) 81 body := "![a](blob+at://did:plc:abc/" + cidA + ") ![b](blob+at://did:plc:abc/" + cidB + ")" 82 83 t.Run("union of existing and new, both referenced", func(t *testing.T) { 84 got := ParseBlobsSet(MergeBlobs(existing, []string{jb}, body)) 85 if !got[cidA] || !got[cidB] || len(got) != 2 { 86 t.Fatalf("got %v, want {%s,%s}", got, cidA, cidB) 87 } 88 }) 89 90 t.Run("drops existing no longer in body", func(t *testing.T) { 91 bodyOnlyB := "![b](blob+at://did:plc:abc/" + cidB + ")" 92 got := MergeBlobs(existing, []string{jb}, bodyOnlyB) 93 if len(got) != 1 || got[0].Ref.String() != cidB { 94 t.Fatalf("got %v, want [%s]", cids(got), cidB) 95 } 96 }) 97 98 t.Run("no double-count when new equals existing", func(t *testing.T) { 99 got := MergeBlobs(existing, []string{ja}, body) 100 if len(got) != 1 || got[0].Ref.String() != cidA { 101 t.Fatalf("got %v, want [%s]", cids(got), cidA) 102 } 103 }) 104} 105 106func ParseBlobsSet(blobs []*lexutil.LexBlob) map[string]bool { 107 m := make(map[string]bool, len(blobs)) 108 for _, b := range blobs { 109 m[b.Ref.String()] = true 110 } 111 return m 112}