Search Apps Documentation Source Content File Folder Download Copy Actions Download

store_test.gno

6.95 Kb ยท 226 lines
  1package users
  2
  3import (
  4	"chain"
  5	"testing"
  6
  7	"gno.land/p/nt/avl"
  8	"gno.land/p/nt/testutils"
  9	"gno.land/p/nt/uassert"
 10	"gno.land/p/nt/urequire"
 11)
 12
 13var (
 14	alice     = "alice"
 15	aliceAddr = testutils.TestAddress(alice)
 16	bob       = "bob"
 17	bobAddr   = testutils.TestAddress(bob)
 18
 19	whitelistedCallerAddr = chain.PackageAddress(gUsersV1Path)
 20)
 21
 22func TestRegister(t *testing.T) {
 23	testing.SetRealm(testing.NewCodeRealm(gUsersV1Path))
 24
 25	t.Run("valid_registration", func(t *testing.T) {
 26		urequire.NoError(t, RegisterUser(cross, alice, aliceAddr))
 27
 28		res, isLatest := ResolveName(alice)
 29		uassert.Equal(t, aliceAddr, res.Addr())
 30		uassert.True(t, isLatest)
 31
 32		res = ResolveAddress(aliceAddr)
 33		uassert.Equal(t, alice, res.Name())
 34	})
 35
 36	t.Run("invalid_inputs", func(t *testing.T) {
 37		cleanStore(t)
 38
 39		uassert.ErrorContains(t, RegisterUser(cross, "", aliceAddr), ErrEmptyUsername.Error())
 40		uassert.ErrorContains(t, RegisterUser(cross, alice, ""), ErrInvalidAddress.Error())
 41		uassert.ErrorContains(t, RegisterUser(cross, alice, "invalidaddress"), ErrInvalidAddress.Error())
 42
 43		uassert.ErrorContains(t, RegisterUser(cross, "username with a space", aliceAddr), ErrInvalidUsername.Error())
 44		uassert.ErrorContains(t,
 45			RegisterUser(cross, "verylongusernameverylongusernameverylongusernameverylongusername1", aliceAddr),
 46			ErrInvalidUsername.Error())
 47		uassert.ErrorContains(t, RegisterUser(cross, "namewith^&()", aliceAddr), ErrInvalidUsername.Error())
 48	})
 49
 50	t.Run("addr_already_registered", func(t *testing.T) {
 51		cleanStore(t)
 52
 53		urequire.NoError(t, RegisterUser(cross, alice, aliceAddr))
 54
 55		// Try registering again
 56		uassert.ErrorContains(t, RegisterUser(cross, "othername", aliceAddr), ErrAlreadyHasName.Error())
 57	})
 58
 59	t.Run("name_taken", func(t *testing.T) {
 60		cleanStore(t)
 61
 62		urequire.NoError(t, RegisterUser(cross, alice, aliceAddr))
 63
 64		// Try registering alice's name with bob's address
 65		uassert.ErrorContains(t, RegisterUser(cross, alice, bobAddr), ErrNameTaken.Error())
 66	})
 67
 68	t.Run("user_deleted", func(t *testing.T) {
 69		cleanStore(t)
 70
 71		urequire.NoError(t, RegisterUser(cross, alice, aliceAddr))
 72		data := ResolveAddress(aliceAddr)
 73		urequire.NoError(t, data.Delete())
 74
 75		// Try re-registering after deletion
 76		uassert.ErrorContains(t, RegisterUser(cross, "newname", aliceAddr), ErrDeletedUser.Error())
 77	})
 78
 79	t.Run("address_lookalike", func(t *testing.T) {
 80		cleanStore(t)
 81
 82		// Address as username
 83		uassert.ErrorContains(t, RegisterUser(cross, "g1jg8mtutu9khhfwc4nxmuhcpftf0pajdhfvsqf5", aliceAddr), ErrNameLikeAddress.Error())
 84		// Beginning of address as username
 85		uassert.ErrorContains(t, RegisterUser(cross, "g1jg8mtutu9khhfwc4nxmu", aliceAddr), ErrNameLikeAddress.Error())
 86		uassert.NoError(t, RegisterUser(cross, "g1jg8mtutu9khhfwc4nxmuhcpftf0pajdhfvsqf5longerthananaddress", aliceAddr))
 87	})
 88}
 89
 90func TestUpdateName(t *testing.T) {
 91	testing.SetRealm(testing.NewCodeRealm(gUsersV1Path))
 92
 93	t.Run("valid_direct_alias", func(t *testing.T) {
 94		cleanStore(t)
 95
 96		urequire.NoError(t, RegisterUser(cross, alice, aliceAddr))
 97		data := ResolveAddress(aliceAddr)
 98		{
 99			testing.SetOriginCaller(whitelistedCallerAddr)
100			uassert.NoError(t, data.UpdateName("alice1"))
101			testing.SetRealm(testing.NewCodeRealm("gno.land/r/sys/users"))
102		}
103	})
104
105	t.Run("valid_double_alias", func(t *testing.T) {
106		cleanStore(t)
107
108		urequire.NoError(t, RegisterUser(cross, alice, aliceAddr))
109		data := ResolveAddress(aliceAddr)
110		{
111			testing.SetOriginCaller(whitelistedCallerAddr)
112			uassert.NoError(t, data.UpdateName("alice2"))
113			uassert.NoError(t, data.UpdateName("alice3"))
114			testing.SetRealm(testing.NewCodeRealm("gno.land/r/sys/users"))
115		}
116		uassert.Equal(t, ResolveAddress(aliceAddr).username, "alice3")
117	})
118
119	t.Run("name_taken", func(t *testing.T) {
120		cleanStore(t)
121
122		urequire.NoError(t, RegisterUser(cross, alice, aliceAddr))
123
124		data := ResolveAddress(aliceAddr)
125		uassert.Error(t, data.UpdateName(alice), ErrNameTaken.Error())
126	})
127
128	t.Run("alias_before_name", func(t *testing.T) {
129		cleanStore(t)
130		data := ResolveAddress(aliceAddr) // not registered
131
132		uassert.ErrorContains(t, data.UpdateName(alice), ErrUserNotExistOrDeleted.Error())
133	})
134
135	t.Run("alias_after_delete", func(t *testing.T) {
136		cleanStore(t)
137
138		urequire.NoError(t, RegisterUser(cross, alice, aliceAddr))
139		data := ResolveAddress(aliceAddr)
140		{
141			urequire.NoError(t, data.Delete())
142			testing.SetRealm(testing.NewCodeRealm("gno.land/r/sys/users"))
143		}
144
145		data = ResolveAddress(aliceAddr)
146		{
147			uassert.ErrorContains(t, data.UpdateName("newalice"), ErrUserNotExistOrDeleted.Error())
148			testing.SetRealm(testing.NewCodeRealm("gno.land/r/sys/users"))
149		}
150	})
151
152	t.Run("invalid_inputs", func(t *testing.T) {
153		cleanStore(t)
154
155		urequire.NoError(t, RegisterUser(cross, alice, aliceAddr))
156		data := ResolveAddress(aliceAddr)
157		{
158			testing.SetOriginCaller(whitelistedCallerAddr)
159			uassert.ErrorContains(t, data.UpdateName(""), ErrEmptyUsername.Error())
160			uassert.ErrorContains(t, data.UpdateName("username with a space"), ErrInvalidUsername.Error())
161			uassert.ErrorContains(t,
162				data.UpdateName("verylongusernameverylongusernameverylongusernameverylongusername1"),
163				ErrInvalidUsername.Error())
164			uassert.ErrorContains(t, data.UpdateName("namewith^&()"), ErrInvalidUsername.Error())
165			testing.SetRealm(testing.NewCodeRealm("gno.land/r/sys/users"))
166		}
167	})
168
169	t.Run("address_lookalike", func(t *testing.T) {
170		cleanStore(t)
171
172		urequire.NoError(t, RegisterUser(cross, alice, aliceAddr))
173		data := ResolveAddress(aliceAddr)
174
175		{
176			// Address as username
177			uassert.ErrorContains(t, data.UpdateName("g1jg8mtutu9khhfwc4nxmuhcpftf0pajdhfvsqf5"), ErrNameLikeAddress.Error())
178			// Beginning of address as username
179			uassert.ErrorContains(t, data.UpdateName("g1jg8mtutu9khhfwc4nxmu"), ErrNameLikeAddress.Error())
180			uassert.NoError(t, data.UpdateName("g1jg8mtutu9khhfwc4nxmuhcpftf0pajdhfvsqf5longerthananaddress"))
181			testing.SetRealm(testing.NewCodeRealm("gno.land/r/sys/users"))
182		}
183	})
184}
185
186func TestDelete(t *testing.T) {
187	testing.SetRealm(testing.NewCodeRealm(gUsersV1Path))
188
189	t.Run("non_existent_user", func(t *testing.T) {
190		cleanStore(t)
191
192		data := ResolveAddress(testutils.TestAddress("unregistered"))
193		uassert.ErrorContains(t, data.Delete(), ErrUserNotExistOrDeleted.Error())
194	})
195
196	t.Run("double_delete", func(t *testing.T) {
197		cleanStore(t)
198
199		urequire.NoError(t, RegisterUser(cross, alice, aliceAddr))
200		data := ResolveAddress(aliceAddr)
201		urequire.NoError(t, data.Delete())
202		data = ResolveAddress(aliceAddr)
203		uassert.ErrorContains(t, data.Delete(), ErrUserNotExistOrDeleted.Error())
204	})
205
206	t.Run("valid_delete", func(t *testing.T) {
207		cleanStore(t)
208
209		urequire.NoError(t, RegisterUser(cross, alice, aliceAddr))
210		data := ResolveAddress(aliceAddr)
211		uassert.NoError(t, data.Delete())
212
213		resolved1, _ := ResolveName(alice)
214		uassert.Equal(t, nil, resolved1)
215		uassert.Equal(t, nil, ResolveAddress(aliceAddr))
216	})
217}
218
219// cleanStore should not be needed, as vm store should be reset after each test.
220// Reference: https://github.com/gnolang/gno/issues/1982
221func cleanStore(t *testing.T) {
222	t.Helper()
223
224	nameStore = avl.NewTree()
225	addressStore = avl.NewTree()
226}