Artifact 62bb688381ac6f83a4518d654c2a2131c0e80272771276ef32a656f6e2600ac6:
- File
internal/index/forum_test.go
— part of check-in
[debc1f4c9f]
at
2026-08-21 19:23:18
on branch quarry-forum
— forum anchors: threads mentioning a check-in backlink from its page
Extracted at fold (hex refs with a digit), resolved only at render — the page's own hash is the honesty gate. schemaVersion 3→4 (rebuild). (user: dmestas, size: 3454) [annotate] [blame] [check-ins using] [more...]
package index import ( "testing" "craftdesign.group/quarry/internal/artifact" ) func foldForum(t *testing.T, ix *Index, hash, root, parent, title, date string) { t.Helper() if err := ix.FoldNow([]Parsed{{Hash: hash, Art: &artifact.Artifact{ Type: artifact.Forum, ThreadRoot: root, InReplyTo: parent, ThreadTitle: title, Date: date, User: "dan", Body: []byte("hi"), }}}); err != nil { t.Fatal(err) } } // Votes are keyed on full post hashes while pages link with prefixes; // the resolver bridges the two and also answers which thread a post // belongs to, so a vote row can carry its thread without trusting the // form data. func TestForumPostThreadResolvesPrefix(t *testing.T) { ix := openIndex(t) foldForum(t, ix, "aaaa1111", "", "", "hello", "2026-01-01T10:00:00") foldForum(t, ix, "bbbb2222", "aaaa1111", "aaaa1111", "", "2026-01-02T10:00:00") post, thread, ok, err := ix.ForumPostThread("bbbb") if err != nil || !ok { t.Fatalf("resolve reply: ok=%v err=%v", ok, err) } if post != "bbbb2222" || thread != "aaaa1111" { t.Fatalf("reply resolved to post=%q thread=%q", post, thread) } // An opener roots its own thread. if _, thread, _, _ := ix.ForumPostThread("aaaa"); thread != "aaaa1111" { t.Fatalf("opener thread = %q, want itself", thread) } if _, _, ok, err := ix.ForumPostThread("ffff"); ok || err != nil { t.Fatalf("absent prefix: ok=%v err=%v, want false nil", ok, err) } } func foldForumBody(t *testing.T, ix *Index, hash, root, title, date, body string) { t.Helper() if err := ix.FoldNow([]Parsed{{Hash: hash, Art: &artifact.Artifact{ Type: artifact.Forum, ThreadRoot: root, ThreadTitle: title, Date: date, User: "dan", Body: []byte(body), }}}); err != nil { t.Fatal(err) } } // Anchors extract at fold and resolve only at query: the backlink query // asks by the page's own full hash, so a stored ref surfaces exactly on // the pages it prefixes — the honesty gate is structural. func TestThreadsMentioning(t *testing.T) { ix := openIndex(t) const target = "4bd6301f22bd6301f22bd6301f22bd63" foldForumBody(t, ix, "aaaa1111", "", "Broken build", "2026-01-01T10:00:00", "bisected to [4bd6301f22] which landed yesterday") foldForumBody(t, ix, "bbbb2222", "", "Naming decade debate", "2026-01-02T10:00:00", "a decade of efface and facade — hexy words, no digits") foldForumBody(t, ix, "cccc3333", "aaaa1111", "", "2026-01-03T10:00:00", "also see deadbeef99 maybe") threads, err := ix.ThreadsMentioning(target) if err != nil { t.Fatal(err) } if len(threads) != 1 || threads[0].Root != "aaaa1111" { t.Fatalf("mentions of %s = %+v, want thread aaaa1111", target, threads) } if threads[0].Title != "Broken build" || threads[0].Posts != 2 { t.Fatalf("backlink row = %+v", threads[0]) } // Hex-spelling English never anchors: no digits, no ref. if got, _ := ix.ThreadsMentioning("decade00decade00decade00"); len(got) != 0 { t.Fatalf("digit-free word anchored: %+v", got) } // A ref that prefixes nothing on this page stays silent. if got, _ := ix.ThreadsMentioning("ffffffffffffffff"); len(got) != 0 { t.Fatalf("unrelated hash has mentions: %+v", got) } // Re-folding the same post must not duplicate its anchors. foldForumBody(t, ix, "aaaa1111", "", "Broken build", "2026-01-01T10:00:00", "bisected to [4bd6301f22] which landed yesterday") if got, _ := ix.ThreadsMentioning(target); len(got) != 1 { t.Fatalf("re-fold duplicated anchors: %+v", got) } }