Artifact c0687a74b80b7975b66cf108228bd13949e472760d70494f6160a26fff2d1827:
- File
internal/index/attachment_test.go
— part of check-in
[0a228d956b]
at
2026-08-16 19:27:40
on branch trunk
— attachments: serve content, gated by the A card
A download route completes the previous slice. The bytes come from 'zit artifact --raw'; the index gates which hashes are servable, so this cannot become read-any-artifact-by-hash, and a deleted attachment stops being reachable by URL. An older revision of a live file still is — fossil keeps attachment history.
The route is hostile to its own payload: always a download, never an inline render, octet-stream regardless of what was stored, nosniff, and a deny-all CSP. Reads are capped at 32MiB and refused rather than truncated. (user: dmestas, size: 3809) [annotate] [blame] [check-ins using]
package index import ( "path/filepath" "testing" "craftdesign.group/quarry/internal/artifact" ) func openIndex(t *testing.T) *Index { t.Helper() ix, err := Open(filepath.Join(t.TempDir(), "index.db")) if err != nil { t.Fatal(err) } t.Cleanup(func() { ix.Close() }) return ix } func attach(hash, name, target, src, date string) Parsed { return Parsed{Hash: hash, Art: &artifact.Artifact{ Type: artifact.Attachment, Date: date, User: "dan", Attachment: &artifact.Attach{Name: name, Target: target, Source: src}, }} } // Fossil models attachments as a log, not a set: the latest A card per // filename wins, and one with no source is a deletion. Getting that // wrong resurrects deleted files. func TestAttachmentsResolveLikeFossil(t *testing.T) { ix := openIndex(t) tkt := "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" if err := ix.FoldNow([]Parsed{ attach("h1", "spec.pdf", tkt, "src1", "2026-01-01T00:00:00"), attach("h2", "spec.pdf", tkt, "src2", "2026-01-02T00:00:00"), // replaced attach("h3", "notes.txt", tkt, "src3", "2026-01-03T00:00:00"), attach("h4", "notes.txt", tkt, "", "2026-01-04T00:00:00"), // deleted attach("h5", "other.txt", "different-target", "src5", "2026-01-05T00:00:00"), }); err != nil { t.Fatal(err) } got, err := ix.AttachmentsFor(tkt) if err != nil { t.Fatal(err) } if len(got) != 1 { t.Fatalf("live attachments = %+v, want just the replaced spec.pdf", got) } if got[0].Name != "spec.pdf" || got[0].Src != "src2" { t.Fatalf("wrong revision won: %+v", got[0]) } // A deletion followed by a re-attach brings the file back. if err := ix.FoldNow([]Parsed{ attach("h6", "notes.txt", tkt, "src6", "2026-01-06T00:00:00"), }); err != nil { t.Fatal(err) } got, _ = ix.AttachmentsFor(tkt) if len(got) != 2 { t.Fatalf("re-attach did not restore the file: %+v", got) } // Every card is still counted — the census matches fossil's // attachment table, deletions included. n, err := ix.CountAttachments() if err != nil { t.Fatal(err) } if n != 6 { t.Fatalf("counted %d attachment artifacts, want 6", n) } } // Folds are idempotent: redelivery must not double-count. func TestAttachmentFoldIsIdempotent(t *testing.T) { ix := openIndex(t) batch := []Parsed{attach("h1", "a.txt", "tgt", "src", "2026-01-01T00:00:00")} if err := ix.FoldNow(batch); err != nil { t.Fatal(err) } if err := ix.FoldNow(batch); err != nil { t.Fatal(err) } n, _ := ix.CountAttachments() if n != 1 { t.Fatalf("redelivery produced %d rows", n) } } // AttachmentName is the gate on the download route: it must resolve only // blobs that are LIVE attachments. Anything looser turns the route into // a read-any-artifact-by-hash endpoint, and a deleted file must stop // being reachable by URL. func TestAttachmentNameGatesDownloads(t *testing.T) { ix := openIndex(t) if err := ix.FoldNow([]Parsed{ attach("h1", "spec.pdf", "tkt", "livesrc", "2026-01-01T00:00:00"), attach("h2", "gone.txt", "tkt", "deadsrc", "2026-01-02T00:00:00"), attach("h3", "gone.txt", "tkt", "", "2026-01-03T00:00:00"), // deletion }); err != nil { t.Fatal(err) } if name, ok, err := ix.AttachmentName("livesrc"); err != nil || !ok || name != "spec.pdf" { t.Fatalf("live attachment: name=%q ok=%v err=%v", name, ok, err) } // Deleted: the content artifact still exists in the store, but the // newest card for that filename is a deletion. if _, ok, err := ix.AttachmentName("deadsrc"); err != nil || ok { t.Fatalf("deleted attachment still downloadable: ok=%v err=%v", ok, err) } // An artifact that was never attached — a check-in manifest, a file // blob — must not be reachable. if _, ok, err := ix.AttachmentName("some-unrelated-artifact"); err != nil || ok { t.Fatalf("unattached artifact served: ok=%v err=%v", ok, err) } }