Skip to content Search Apps Documentation Source Content File Folder Download Copy Actions State String Boolean Number Struct Map Slice Pointer Function Closure Reference Nil Package Type Interface Unknown

Community realm. Read the code first. Community realm, deployed by its author. Read the code before you interact or send coins.

write_test.gno

4.13 Kb · 108 lines
  1package blog
  2
  3import (
  4	"strings"
  5	"testing"
  6
  7	"gno.land/p/nt/testutils/v0"
  8	"gno.land/p/nt/uassert/v0"
  9)
 10
 11var stranger = testutils.TestAddress("stranger")
 12
 13// Everything here goes through the real crossing functions rather than seed(),
 14// because the author check, the re-key on a date change and the panic messages
 15// only exist on that path and are exactly what a typo would break on a
 16// permanent path.
 17
 18func TestSetPublishesAndRenders(cur realm, t *testing.T) {
 19	reset()
 20	testing.SetRealm(testing.NewUserRealm(author))
 21	Set(cross(cur), "hello", "Hello", "2026-09-23", "Gno, tooling", "The body.")
 22
 23	uassert.Equal(t, 1, Count(), "one post")
 24	uassert.Equal(t, "The body.", Get("hello"), "the body round-trips")
 25	uassert.True(t, strings.Contains(Render("hello"), "# Hello"), "it renders")
 26	// Tags are normalized on write, not on read, so the hash the tool computed
 27	// locally is the hash the manifest reports.
 28	uassert.True(t, strings.Contains(Manifest(), "\t"+hashOf(record("Hello", "2026-09-23", "gno,tooling", "The body."))),
 29		"the manifest hashes the normalized record")
 30}
 31
 32func TestOnlyTheAuthorMayWrite(cur realm, t *testing.T) {
 33	reset()
 34	testing.SetRealm(testing.NewUserRealm(stranger))
 35	// AbortsWithMessage, not PanicsWithMessage: a panic that crosses a realm
 36	// boundary becomes an abort, which recover() cannot catch, so asserting it
 37	// as a panic does not fail the assertion, it kills the whole test binary.
 38	uassert.AbortsWithMessage(t, cur, "restricted to the author", func() {
 39		Set(cross(cur), "nope", "Nope", "2026-09-23", "", "Body.")
 40	})
 41	uassert.AbortsWithMessage(t, cur, "restricted to the author", func() {
 42		SetIntro(cross(cur), "mine now")
 43	})
 44	uassert.Equal(t, 0, Count(), "nothing was written")
 45}
 46
 47// The one case a second tree can get wrong: re-dating a post must MOVE its
 48// index entry, not leave a ghost at the old key rendering the post twice.
 49func TestSetRedatingMovesTheIndexEntry(cur realm, t *testing.T) {
 50	reset()
 51	testing.SetRealm(testing.NewUserRealm(author))
 52	Set(cross(cur), "a", "A", "2026-01-01", "", "Body A.")
 53	Set(cross(cur), "a", "A", "2026-12-31", "", "Body A.")
 54
 55	uassert.Equal(t, 1, Count(), "still one post")
 56	out := Render("")
 57	uassert.Equal(t, 1, strings.Count(out, "](/r/nym-moultest123/blog:a)"), "listed exactly once")
 58	uassert.True(t, strings.Contains(out, "2026-12-31"), "under the new date")
 59	uassert.False(t, strings.Contains(out, "2026-01-01"), "and not the old one")
 60}
 61
 62func TestSetRejectsWhatTheToolRejects(cur realm, t *testing.T) {
 63	reset()
 64	testing.SetRealm(testing.NewUserRealm(author))
 65	uassert.AbortsContains(t, cur, "invalid slug", func() {
 66		Set(cross(cur), "Caps", "T", "2026-09-23", "", "Body.")
 67	})
 68	uassert.AbortsContains(t, cur, "reserved slug", func() {
 69		Set(cross(cur), introSlug, "T", "2026-09-23", "", "Body.")
 70	})
 71	uassert.AbortsContains(t, cur, "invalid date", func() {
 72		Set(cross(cur), "ok", "T", "23-09-2026", "", "Body.")
 73	})
 74	uassert.AbortsContains(t, cur, "a post needs a title", func() {
 75		Set(cross(cur), "ok", "  ", "2026-09-23", "", "Body.")
 76	})
 77	uassert.Equal(t, 0, Count(), "none of them was written")
 78}
 79
 80func TestAppendAndDelete(cur realm, t *testing.T) {
 81	reset()
 82	testing.SetRealm(testing.NewUserRealm(author))
 83	Set(cross(cur), "long", "Long", "2026-09-23", "", "First half.")
 84	Append(cross(cur), "long", " Second half.")
 85	uassert.Equal(t, "First half. Second half.", Get("long"), "append concatenates, it does not replace")
 86
 87	uassert.AbortsWithMessage(t, cur, `no such post: "ghost"`, func() {
 88		Append(cross(cur), "ghost", "x")
 89	})
 90
 91	Delete(cross(cur), "long")
 92	uassert.Equal(t, 0, Count(), "deleted")
 93	uassert.True(t, strings.Contains(Render(""), "Nothing published yet."), "and gone from the index")
 94	uassert.AbortsWithMessage(t, cur, `no such post: "long"`, func() {
 95		Delete(cross(cur), "long")
 96	})
 97}
 98
 99func TestRevisionMovesOnEveryWrite(cur realm, t *testing.T) {
100	reset()
101	testing.SetRealm(testing.NewUserRealm(author))
102	uassert.Equal(t, 0, Revision(), "a fresh realm is at zero")
103	Set(cross(cur), "a", "A", "2026-09-23", "", "Body.")
104	Append(cross(cur), "a", "!")
105	SetIntro(cross(cur), "# Header")
106	Delete(cross(cur), "a")
107	uassert.Equal(t, 4, Revision(), "one per mutation, so a client can tell nothing moved")
108}