~bigbes/sr-ht-spec

ref: 128d72963281e275bb1ec3be2bdb8653a2bb0c78 sr-ht-spec/service/archive_test.go -rw-r--r-- 4.1 KiB
128d7296 — Eugene Blikh ci: cache Go module and build dirs via cacher 13 days ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
package service

import (
	"context"
	"testing"
)

// The accessor every surface above this layer reads a space through: one call,
// the addressing rule applied, the bodies alongside, and the link graph filled
// in. web/ used to scan the git tree itself and mcpsrv/ used to convert this
// package's documents back into git ones; both are gone because this exists.
func TestArchiveReturnsDocumentsBodiesAndLinks(t *testing.T) {
	svc, root := newService(t)
	sp := newSpace(t, root, 1)
	ctx := context.Background()

	head := commitFiles(t, sp, sp.ApprovedBranch(), 1, map[string][]byte{
		"specs/0007-storage.md": mdDoc("SPEC-0007", "Storage model", "Supersedes [[SPEC-0003]]."),
		"specs/0003-old.md":     mdDoc("SPEC-0003", "Older sketch", "The first attempt."),
		"notes/plain.md":        []byte("# Just a note\n\nNo frontmatter at all.\n"),
	})

	arc, bodies, err := svc.Archive(ctx, sp, ApprovedRev)
	if err != nil {
		t.Fatalf("Archive: %v", err)
	}

	// The revision is resolved before anything is read, so the archive names
	// the commit it describes and a caller can pin to it.
	if arc.Rev != head.String() {
		t.Errorf("archive Rev = %s, want the resolved approved head %s", arc.Rev, head)
	}
	if arc.Space != sp.Ref {
		t.Errorf("archive space = %s, want %s", arc.Space, sp.Ref)
	}
	if len(arc.All()) != 3 || len(bodies) != 3 {
		t.Fatalf("archive holds %d documents and %d bodies, want 3 of each", len(arc.All()), len(bodies))
	}

	// The addressing rule: a well-formed unique id addresses the document, and
	// a document without one is addressed by its path.
	page, ok := arc.Page("SPEC-0007")
	if !ok || page.Path != "specs/0007-storage.md" {
		t.Fatalf("SPEC-0007 = %+v, ok=%v", page, ok)
	}
	if _, ok := arc.Page("notes/plain"); !ok {
		t.Error("a document with no frontmatter must be addressed by its path")
	}

	// Bodies are the whole document, keyed the way the archive keys pages.
	if body, ok := bodies[page.Path]; !ok || !contains(body, "Supersedes") {
		t.Errorf("body of %s = %q", page.Path, body)
	}

	// The link graph: filled here, so Backlinks answers rather than always
	// returning nothing.
	if len(page.Links) != 1 || page.Links[0] != "SPEC-0003" {
		t.Errorf("links of SPEC-0007 = %v, want [SPEC-0003]", page.Links)
	}
	if page.WordCount == 0 {
		t.Error("word count is filled by the same pass and must not be zero")
	}
	back := arc.Backlinks("SPEC-0003")
	if len(back) != 1 || back[0].ID != "SPEC-0007" {
		t.Fatalf("Backlinks(SPEC-0003) = %v, want SPEC-0007", back)
	}
}

// A pinned revision and the approved head are the same call with a different
// revision string, and the read contract still applies: a branch name is not a
// revision this method will serve.
func TestArchiveHonoursTheReadContract(t *testing.T) {
	svc, root := newService(t)
	sp := newSpace(t, root, 1)
	ctx := context.Background()

	first := commitFiles(t, sp, sp.ApprovedBranch(), 1, map[string][]byte{
		"specs/0007-storage.md": mdDoc("SPEC-0007", "Storage model", "first"),
	})
	commitFiles(t, sp, sp.ApprovedBranch(), 2, map[string][]byte{
		"specs/0007-storage.md": mdDoc("SPEC-0007", "Storage model", "second"),
	})

	_, bodies, err := svc.Archive(ctx, sp, first.String())
	if err != nil {
		t.Fatalf("pinned Archive: %v", err)
	}
	if !contains(bodies["specs/0007-storage.md"], "first") {
		t.Errorf("pinned archive returned %q, want the pinned revision", bodies["specs/0007-storage.md"])
	}

	cutBranch(t, sp, "proposals/1", sp.ApprovedBranch())
	if _, _, err := svc.Archive(ctx, sp, "proposals/1"); err == nil {
		t.Fatal("Archive served a branch name; the read plane takes object names only")
	}
}

// ArchiveFrom is the same construction over documents a caller already holds,
// and it refuses a document whose blob id is not an object name rather than
// keying the render cache on a zero hash.
func TestArchiveFromRefusesAMalformedBlobID(t *testing.T) {
	_, _, err := ArchiveFrom(fxSpace, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", []Document{
		{Path: "specs/0007-storage.md", Blob: "not-a-sha", Data: mdDoc("SPEC-0007", "Storage model", "body")},
	})
	if err == nil {
		t.Fatal("ArchiveFrom accepted a malformed blob id")
	}
}