write_test.gno
4.12 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/moul/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}