Something went wrong. Try again.
Monorepo for Tangled tangled.org
Something went wrong. Try again.
Go
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172package knotfeed
import ( "bytes" "encoding/hex" "slices" "strings" "testing"
"github.com/bluesky-social/indigo/atproto/syntax" cbg "github.com/whyrusleeping/cbor-gen")
const frozenPushedHex = "a4637368617828616261626162616261626162616261626162616261626162616261626162616261626162616261626524747970657273682e74616e676c65642e6769742e7265666d782d746e676c2d656469746f726e6469643a706c633a6c696d70657473782d746e676c2d707573682d6f7074696f6e738167736b69702d6369"
const frozenBareHex = "a2637368617840636463646364636463646364636463646364636463646364636463646364636463646364636463646364636463646364636463646364636463646364636463646524747970657273682e74616e676c65642e6769742e726566"
func TestFrozenRecordBytesDecodeAndEncodeBackAsThemselves(t *testing.T) { for _, tt := range []struct { name string hex string want RefRecord }{ {"pushed", frozenPushedHex, RefRecord{ Sha: sha(t, strings.Repeat("ab", 20)), Editor: "did:plc:limpet", PushOptions: []string{"skip-ci"}, }}, {"catch-up", frozenBareHex, RefRecord{Sha: sha(t, strings.Repeat("cd", 32))}}, } { t.Run(tt.name, func(t *testing.T) { data, err := hex.DecodeString(tt.hex) if err != nil { t.Fatalf("frozen hex: %v", err) } rec, err := DecodeRefRecord(data) if err != nil { t.Fatalf("DecodeRefRecord: %v", err) } if rec.Sha != tt.want.Sha || rec.Editor != tt.want.Editor || !slices.Equal(rec.PushOptions, tt.want.PushOptions) { t.Fatalf("record = %+v, want %+v", rec, tt.want) } again, err := encodeRefRecord(tt.want) if err != nil { t.Fatalf("encodeRefRecord: %v", err) } if !bytes.Equal(again, data) { t.Errorf("re-encoded record\n got %x\nwant %x", again, data) } }) }}
func shaRecord(t *testing.T, reported string) []byte { t.Helper() var out bytes.Buffer if err := cbg.CborWriteHeader(&out, cbg.MajMap, 1); err != nil { t.Fatalf("map header: %v", err) } writeText(&out, "sha") writeText(&out, reported) return out.Bytes()}
func TestDecodeRefRecordRefusesMalformedRecords(t *testing.T) { const overlongShaRun = "a2637368617840636463646364636463646364636463646364636463646364636463" + "64636463646364636463646364636463646364636463646364636463646364636463646364636463" + "646524747970657273682e74616e676c65642e6769742e726566"
overlong, err := hex.DecodeString(overlongShaRun) if err != nil { t.Fatalf("decoding overlong record: %v", err) } var hugeArray bytes.Buffer if err := cbg.CborWriteHeader(&hugeArray, cbg.MajMap, 1); err != nil { t.Fatalf("map header: %v", err) } writeText(&hugeArray, "x-tngl-push-options") if err := cbg.CborWriteHeader(&hugeArray, cbg.MajArray, 1<<32); err != nil { t.Fatalf("array header: %v", err) }
refused := [][]byte{{0xa1, 0x63, 'a', 'b', 0x00}, hugeArray.Bytes(), overlong} for _, reported := range []string{"", "def456", strings.Repeat("ab", 21), strings.Repeat("zz", 20)} { refused = append(refused, shaRecord(t, reported)) } for _, data := range refused { if _, err := DecodeRefRecord(data); err == nil { t.Errorf("DecodeRefRecord accepted % x", data) } }
for _, reported := range []string{strings.Repeat("ab", 20), strings.Repeat("AB", 32)} { if _, err := DecodeRefRecord(shaRecord(t, reported)); err != nil { t.Errorf("DecodeRefRecord(%q): %v", reported, err) } }}
func TestEncodeRefRecordRefusesWhatItsOwnDecoderWouldReject(t *testing.T) { present := sha(t, strings.Repeat("ab", 20)) huge := strings.Repeat("x", cbg.MaxLength+1) for _, tt := range []struct { name string rec RefRecord }{ {"no sha at all", RefRecord{}}, {"editor past the cbor limit", RefRecord{Sha: present, Editor: syntax.DID(huge)}}, {"push option past the cbor limit", RefRecord{Sha: present, PushOptions: []string{huge}}}, } { if _, err := encodeRefRecord(tt.rec); err == nil { t.Errorf("%s encoded anyway, and the record would fail its own decode", tt.name) } }}
func TestEscapeRefnameRulesTheRkey(t *testing.T) { for _, tt := range []struct { refname string want syntax.RecordKey wantOK bool }{ {"refs/heads/main", "refs~2fheads~2fmain", true}, {"refs/heads/~x", "refs~2fheads~2f~7ex", true}, {strings.Repeat("/", 79), syntax.RecordKey(strings.Repeat("~2f", 79)), true}, {strings.Repeat("/", 80), "", false}, } { rkey, ok := EscapeRefname(tt.refname) if ok != tt.wantOK || (ok && rkey != tt.want) { t.Fatalf("EscapeRefname(%q) = %q, %v", tt.refname, rkey, ok) } }}
func TestUnescapeRkeyRoundTripsPlainAndEscapedRefnames(t *testing.T) { for _, refname := range []string{ "refs/heads/main", "main", "refs/tags/v1.0.0+build", "refs/heads/feature/foo_bar-squid.conch", "refs/heads/~tilde", "refs/heads/ branch with spaces ", "refs/heads/日本語ブランチ", "refs/heads/emoji-🍀", } { rkey, ok := EscapeRefname(refname) if !ok { t.Fatalf("EscapeRefname refused %q", refname) } decoded, ok := UnescapeRkey(rkey) if !ok { t.Fatalf("UnescapeRkey refused %q", rkey) } if decoded != refname { t.Fatalf("round trip of %q answered %q", refname, decoded) } }}
func TestUnescapeRkeyRefusesMalformedKeys(t *testing.T) { for _, rkey := range []syntax.RecordKey{ "refs~2fheads~", "refs~2fheads~2", "refs~2fheads~zz", "refs~2fhea ds", "refs~ff", } { if decoded, ok := UnescapeRkey(rkey); ok { t.Fatalf("UnescapeRkey(%q) = %q, want refusal", rkey, decoded) } }}