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.

close_test.gno

5.51 Kb · 154 lines
  1package bolo
  2
  3import (
  4	"testing"
  5
  6	"gno.land/p/nt/testutils/v0"
  7)
  8
  9// TestClose walks each of Close's branches. Before each call, CanClose names the
 10// reason Close then records (API §4); the refusals are in txtar (organizer.txtar).
 11func TestClose(cur realm, t *testing.T) {
 12	closed := func(c *campaign, reason string, at int64) bool {
 13		s := c.state
 14		return s.status == statusClosed && s.closeReason == reason && s.closedAt == at && !active.Has(c.id.Binary()) &&
 15			!activeByCategory.Has(c.category+"/"+c.id.Binary())
 16	}
 17
 18	// The organizer closes an open campaign, now.
 19	c := testCampaign(9201, modeEscrow, 0)
 20	id, unstore := storeCampaign(c)
 21	defer unstore()
 22	if ok, why := CanClose(id, c.organizer); !ok || why != reasonOrganizer {
 23		t.Errorf("CanClose(organizer) = %t, %q", ok, why)
 24	}
 25	testing.SetRealm(testing.NewUserRealm(c.organizer))
 26	Close(cross(cur), id)
 27	if !closed(c, reasonOrganizer, now()) {
 28		t.Errorf("organizer: %v", *c.state)
 29	}
 30	if ok, why := CanClose(id, c.organizer); ok || why != statusClosed {
 31		t.Errorf("CanClose once closed = %t, %q", ok, why)
 32	}
 33
 34	// Past dormancy, anyone closes it for dormancy, its organizer too (Q7).
 35	d := testCampaign(9202, modeEscrow, 0)
 36	idD, unstoreD := storeCampaign(d)
 37	defer unstoreD()
 38	e := testCampaign(9203, modeEscrow, 0)
 39	idE, unstoreE := storeCampaign(e)
 40	defer unstoreE()
 41	testing.SkipHeights(90 * heightsPerDay)
 42	if ok, why := CanClose(idD, passerby); !ok || why != reasonDormant {
 43		t.Errorf("CanClose(passerby), dormant = %t, %q", ok, why)
 44	}
 45	testing.SetRealm(testing.NewUserRealm(passerby))
 46	Close(cross(cur), idD)
 47	if !closed(d, reasonDormant, now()) {
 48		t.Errorf("passerby, dormant: %v", *d.state)
 49	}
 50	if ok, why := CanClose(idE, e.organizer); !ok || why != reasonDormant {
 51		t.Errorf("CanClose(organizer), dormant = %t, %q", ok, why)
 52	}
 53	testing.SetRealm(testing.NewUserRealm(e.organizer))
 54	Close(cross(cur), idE)
 55	if !closed(e, reasonDormant, now()) {
 56		t.Errorf("organizer, dormant: %v", *e.state)
 57	}
 58
 59	// Past its deadline: closed at the deadline by whoever calls first; a second
 60	// call changes nothing, and fails nothing.
 61	f := testCampaign(9204, modeEscrow, now()+2*secondsPerDay)
 62	idF, unstoreF := storeCampaign(f)
 63	defer unstoreF()
 64	g := testCampaign(9205, modeEscrow, now()+2*secondsPerDay)
 65	idG, unstoreG := storeCampaign(g)
 66	defer unstoreG()
 67	testing.SetRealm(testing.NewUserRealm(g.organizer))
 68	Close(cross(cur), idG)
 69	closedG := now()
 70	testing.SkipHeights(3 * heightsPerDay)
 71	if ok, why := CanClose(idF, passerby); !ok || why != reasonDeadline {
 72		t.Errorf("CanClose(passerby), deadline = %t, %q", ok, why)
 73	}
 74	testing.SetRealm(testing.NewUserRealm(passerby))
 75	Close(cross(cur), idF)
 76	if !closed(f, reasonDeadline, f.deadline) {
 77		t.Errorf("passerby, deadline: %v", *f.state)
 78	}
 79	Close(cross(cur), idF)
 80	if !closed(f, reasonDeadline, f.deadline) {
 81		t.Errorf("a second close changed it: %v", *f.state)
 82	}
 83	// One the organizer closed before its deadline keeps its close after it.
 84	Close(cross(cur), idG)
 85	if !closed(g, reasonOrganizer, closedG) {
 86		t.Errorf("closed before its deadline, then housekept: %v", *g.state)
 87	}
 88}
 89
 90// TestDormancy: dormancy counts from the latest of creation, the last gift and the
 91// last update, so an update resets it (API §3.1).
 92func TestDormancy(cur realm, t *testing.T) {
 93	c := testCampaign(9206, modeEscrow, 0)
 94	id, unstore := storeCampaign(c)
 95	defer unstore()
 96	testing.SkipHeights(80 * heightsPerDay)
 97	testing.SetRealm(testing.NewUserRealm(c.organizer))
 98	PostUpdate(cross(cur), id, "Still here.")
 99	testing.SkipHeights(90*heightsPerDay - 1)
100	if ok, why := CanClose(id, passerby); ok || why != closeNotYet {
101		t.Errorf("a height before 90 days from the update: %t, %q", ok, why)
102	}
103	testing.SkipHeights(1)
104	if ok, why := CanClose(id, passerby); !ok || why != reasonDormant {
105		t.Errorf("90 days from the update: %t, %q", ok, why)
106	}
107	c.state.lastDonationAt = now()
108	if ok, why := CanClose(id, passerby); ok || why != closeNotYet {
109		t.Errorf("right after a gift: %t, %q", ok, why)
110	}
111}
112
113func TestCanClose(t *testing.T) {
114	organizer := testutils.TestAddress("organizer")
115	open := testCampaign(9211, modeEscrow, 0)
116	dormant := testCampaign(9212, modeEscrow, 0)
117	dormant.createdAt = now() - 90*secondsPerDay
118	passed := testCampaign(9213, modeEscrow, now()-1)
119	both := testCampaign(9214, modeEscrow, now()-1)
120	both.createdAt = now() - 91*secondsPerDay
121	recorded := testCampaign(9215, modeEscrow, now()-1)
122	recorded.state.status = statusClosed
123	shut := testCampaign(9216, modeEscrow, 0)
124	shut.state.status = statusClosed
125	settled := testCampaign(9217, modeEscrow, 0)
126	settled.state.status = statusSettled
127	for _, k := range []struct {
128		name   string
129		c      *campaign
130		caller address
131		ok     bool
132		why    string
133	}{
134		{"open, organizer", open, organizer, true, reasonOrganizer},
135		{"open, passerby", open, passerby, false, closeNotYet},
136		{"dormant, passerby", dormant, passerby, true, reasonDormant},
137		{"dormant, organizer", dormant, organizer, true, reasonDormant},
138		{"deadline passed, unrecorded", passed, passerby, true, reasonDeadline},
139		{"deadline passed and dormant", both, organizer, true, reasonDeadline},
140		{"deadline recorded", recorded, passerby, false, statusClosed},
141		{"closed", shut, organizer, false, statusClosed},
142		{"settled", settled, organizer, false, statusClosed},
143	} {
144		id, unstore := storeCampaign(k.c)
145		ok, why := CanClose(id, k.caller)
146		unstore()
147		if ok != k.ok || why != k.why {
148			t.Errorf("%s: CanClose = %t, %q, want %t, %q", k.name, ok, why, k.ok, k.why)
149		}
150	}
151	if !panicsWith(func() { CanClose("042", organizer) }, ErrNotFound) {
152		t.Errorf("CanClose(\"042\"): not ErrNotFound")
153	}
154}