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.

tipjar_test.gno

3.60 Kb · 137 lines
  1package tipjar
  2
  3import (
  4	"strings"
  5	"testing"
  6
  7	"chain"
  8	"chain/banker"
  9
 10	"gno.land/p/nt/avl/v0"
 11	"gno.land/p/nt/testutils/v0"
 12)
 13
 14var realmAddr = chain.PackageAddress("gno.land/r/nym-moultest123/x/daily/tipjar/v0")
 15
 16// reset clears package globals between tests, pinning owner to a known test
 17// address rather than whatever init() captured from the test harness.
 18func reset() {
 19	owner = testutils.TestAddress("owner")
 20	tippers = avl.Tree{}
 21	recent = nil
 22	totalReceived = 0
 23	withdrawn = 0
 24	tipCount = 0
 25}
 26
 27// fund simulates a tipper sending `amount` ugnot alongside the tx: the
 28// runtime deposits it at the realm's address first, then unsafe.OriginSend
 29// reports it to the crossing function. SetRealm is call-frame scoped (see
 30// build.md), so the caller must still SetRealm directly before crossing.
 31func fund(amount int64) {
 32	testing.IssueCoins(realmAddr, chain.Coins{{denom, amount}})
 33	testing.SetOriginSend(chain.Coins{{denom, amount}})
 34}
 35
 36func TestTipCreditsAndTracks(cur realm, t *testing.T) {
 37	reset()
 38	alice := testutils.TestAddress("alice")
 39
 40	fund(500)
 41	testing.SetRealm(testing.NewUserRealm(alice))
 42	Tip(cross(cur), "gm")
 43
 44	if got := Balance(); got != 500 {
 45		t.Fatalf("Balance() = %d, want 500", got)
 46	}
 47	if tipCount != 1 {
 48		t.Fatalf("tipCount = %d, want 1", tipCount)
 49	}
 50	ts := get(alice)
 51	if ts.total != 500 || ts.count != 1 || ts.lastMessage != "gm" {
 52		t.Fatalf("unexpected tipper stats: %+v", ts)
 53	}
 54
 55	fund(250)
 56	testing.SetRealm(testing.NewUserRealm(alice))
 57	Tip(cross(cur), "again")
 58	if got := get(alice).total; got != 750 {
 59		t.Fatalf("cumulative total = %d, want 750", got)
 60	}
 61	if got := Balance(); got != 750 {
 62		t.Fatalf("Balance() after second tip = %d, want 750", got)
 63	}
 64}
 65
 66func TestTipRejectsZeroAmount(cur realm, t *testing.T) {
 67	reset()
 68	alice := testutils.TestAddress("alice")
 69	testing.SetRealm(testing.NewUserRealm(alice))
 70
 71	rec := revive(func() { Tip(cross(cur), "freeloading") })
 72	if rec == nil {
 73		t.Fatal("expected panic when tipping with no ugnot sent")
 74	}
 75}
 76
 77func TestTipRejectsNonUserCall(cur realm, t *testing.T) {
 78	reset()
 79	testing.SetRealm(testing.NewCodeRealm("gno.land/r/g1attacker/relay"))
 80
 81	rec := revive(func() { Tip(cross(cur), "sneaky") })
 82	if rec == nil {
 83		t.Fatal("expected panic when the caller isn't an EOA via MsgCall")
 84	}
 85}
 86
 87func TestWithdrawOwnerOnly(cur realm, t *testing.T) {
 88	reset()
 89	alice := testutils.TestAddress("alice")
 90	mallory := testutils.TestAddress("mallory")
 91
 92	fund(1000)
 93	testing.SetRealm(testing.NewUserRealm(alice))
 94	Tip(cross(cur), "for the jar")
 95
 96	testing.SetRealm(testing.NewUserRealm(mallory))
 97	rec := revive(func() { Withdraw(cross(cur), 100) })
 98	if rec == nil {
 99		t.Fatal("expected panic when a non-owner withdraws")
100	}
101
102	testing.SetRealm(testing.NewUserRealm(owner))
103	Withdraw(cross(cur), 400)
104
105	if got := Balance(); got != 600 {
106		t.Fatalf("Balance() after withdraw = %d, want 600", got)
107	}
108	ro := banker.NewReadonlyBanker()
109	if got := ro.GetCoins(owner).AmountOf(denom); got != 400 {
110		t.Fatalf("owner received = %d, want 400", got)
111	}
112
113	rec = revive(func() { Withdraw(cross(cur), 10000) })
114	if rec == nil {
115		t.Fatal("expected panic when withdrawing more than the balance")
116	}
117}
118
119func TestRenderShowsLeaderboardAndFeed(cur realm, t *testing.T) {
120	reset()
121	if !strings.Contains(Render(""), "No tips yet") {
122		t.Fatal("expected empty-jar placeholder")
123	}
124
125	alice := testutils.TestAddress("alice")
126	fund(300)
127	testing.SetRealm(testing.NewUserRealm(alice))
128	Tip(cross(cur), "nice work")
129
130	out := Render("")
131	if !strings.Contains(out, "Leaderboard") {
132		t.Fatal("expected leaderboard section")
133	}
134	if !strings.Contains(out, "nice work") {
135		t.Fatal("expected the tip message in the recent-tips feed")
136	}
137}