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") } }