tinyrelayfile
tinyrelay/tinygit/metadata_external_test.go/

tinygit/metadata_external_test.go raw
1package tinygit_test
2
3import (
4 "reflect"
5 "strings"
6 "testing"
7
8 "github.com/FelineStateMachine/tinyrelay/tinygit"
9)
10
11func TestParseMetadataRejectsInvalidShapes(t *testing.T) {
12 oid := strings.Repeat("a", 40)
13 for name, tags := range map[string][][]string{
14 "missing identifier": {},
15 "unsafe identifier": {{"d", "../demo"}},
16 "invalid ref": {{"d", "demo"}, {"refs/heads/a..b", oid}},
17 "invalid oid": {{"d", "demo"}, {"refs/heads/main", "not-a-sha1"}},
18 "uppercase oid": {{"d", "demo"}, {"refs/heads/main", strings.Repeat("A", 40)}},
19 "zero oid": {{"d", "demo"}, {"refs/heads/main", strings.Repeat("0", 40)}},
20 "empty oid": {{"d", "demo"}, {"refs/heads/main", ""}},
21 "duplicate ref": {{"d", "demo"}, {"refs/heads/main", oid}, {"refs/heads/main", oid}},
22 "duplicate head": {{"d", "demo"}, {"HEAD", "ref: refs/heads/main"}, {"HEAD", "ref: refs/heads/main"}},
23 "short head": {{"d", "demo"}, {"HEAD"}},
24 "long head": {{"d", "demo"}, {"HEAD", "ref: refs/heads/main", "extra"}},
25 "detached head": {{"d", "demo"}, {"HEAD", oid}},
26 "nonbranch head": {{"d", "demo"}, {"HEAD", "ref: refs/nostr/topic"}},
27 "invalid head ref": {{"d", "demo"}, {"HEAD", "ref: refs/heads/bad..name"}},
28 } {
29 t.Run(name, func(t *testing.T) {
30 m, err := tinygit.ParseMetadata(tinygit.Event{Kind: 30618, Tags: tags})
31 if err == nil || !strings.HasPrefix(err.Error(), "invalid:") || !reflect.DeepEqual(m, tinygit.Metadata{}) {
32 t.Fatalf("invalid shape: metadata=%#v err=%v", m, err)
33 }
34 })
35 }
36 if _, err := tinygit.ParseMetadata(tinygit.Event{Kind: 1, Tags: [][]string{{"d", "demo"}}}); err == nil || !strings.HasPrefix(err.Error(), "unsupported:") {
37 t.Fatalf("unsupported kind: %v", err)
38 }
39}
40
41func TestParseMetadataPreservesAnnouncementClaims(t *testing.T) {
42 e := tinygit.Event{Kind: 30617, PubKey: "author", Tags: [][]string{
43 {}, {"d", "demo"}, {"d", "ignored-second-identifier"},
44 {"private", "true"}, {"clone", "https://one", "https://two"}, {"clone", "https://three"},
45 {"relays", "wss://one", "wss://two"}, {"maintainers", "claimed-key", "another-key"},
46 {"unknown"}, {"HEAD", "not-state"},
47 }}
48 m, err := tinygit.ParseMetadata(e)
49 if err != nil {
50 t.Fatal(err)
51 }
52 if !m.Private || m.Identifier != "demo" || m.Author != "author" || m.Head != "" || len(m.Refs) != 0 ||
53 !reflect.DeepEqual(m.Clone, []string{"https://one", "https://two", "https://three"}) ||
54 !reflect.DeepEqual(m.Relays, []string{"wss://one", "wss://two"}) ||
55 !reflect.DeepEqual(m.Maintainers, []string{"claimed-key", "another-key"}) {
56 t.Fatalf("announcement claims = %#v", m)
57 }
58 m.Clone[0], m.Relays[0], m.Maintainers[0] = "changed", "changed", "changed"
59 again, err := tinygit.ParseMetadata(e)
60 if err != nil || again.Clone[0] != "https://one" || again.Relays[0] != "wss://one" || again.Maintainers[0] != "claimed-key" {
61 t.Fatalf("metadata aliases input tags: %#v, %v", again, err)
62 }
63}
64
65func TestParseMetadataWithoutSignatureOrHost(t *testing.T) {
66 // Shape parsing is useful before signing. These are claims, not authority.
67 e := tinygit.Event{Kind: 30618, PubKey: "unsigned-author", ID: "unverified-id", Tags: [][]string{
68 {"d", "demo"}, {"HEAD", "ref: refs/heads/unborn"},
69 {"refs/heads/main", strings.Repeat("a", 40), "extension"},
70 {"refs/tags/v1", strings.Repeat("b", 40)}, {"unknown", "ignored"},
71 }}
72 m, err := tinygit.ParseMetadata(e)
73 if err != nil {
74 t.Fatal(err)
75 }
76 if m.Kind != e.Kind || m.Author != e.PubKey || m.EventID != e.ID || m.Identifier != "demo" || m.Head != "ref: refs/heads/unborn" {
77 t.Fatalf("metadata claims = %#v", m)
78 }
79 if !reflect.DeepEqual(m.Refs, map[string]string{"refs/heads/main": strings.Repeat("a", 40), "refs/tags/v1": strings.Repeat("b", 40)}) {
80 t.Fatalf("refs = %#v", m.Refs)
81 }
82}

About

ownerc01503e8035f
visibilitypublic
headd730679639bf

Maintainers

  • c01503e8035f owner
  • ba1b5beed5b5 agent hermes

Clone

  • https://012.run/npub1cq2s86qrtadf36eqq3epm38wmhdynrrcwxf84eldk3f94dkv7ttsrulrz5/tinyrelay.git

Refs