Skip to content

Commit 9c95b7c

Browse files
committed
Added token unit tests
Signed-off-by: Effi-S <effi.szt@gmail.com>
1 parent 4fa8965 commit 9c95b7c

1 file changed

Lines changed: 123 additions & 0 deletions

File tree

token/services/tokens/tokens_test.go

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import (
1212

1313
"github.com/LFDT-Panurus/panurus/token"
1414
"github.com/LFDT-Panurus/panurus/token/driver"
15+
"github.com/LFDT-Panurus/panurus/token/services/storage/tokendb"
1516
"github.com/LFDT-Panurus/panurus/token/services/tokens"
1617
"github.com/LFDT-Panurus/panurus/token/services/tokens/mock"
1718
token2 "github.com/LFDT-Panurus/panurus/token/token"
@@ -157,6 +158,128 @@ func TestParse(t *testing.T) {
157158
assert.Equal(t, output2.Type, store[1].Tok.Type)
158159
}
159160

161+
// TestAppendValid_SkipsWhenNoRequestOrMetadata verifies that AppendValid is a no-op
162+
// (returns nil without touching storage or the cache) when there is nothing to apply:
163+
// either the request itself or its metadata is absent.
164+
func TestAppendValid_SkipsWhenNoRequestOrMetadata(t *testing.T) {
165+
ctx := context.Background()
166+
167+
t.Run("nil request", func(t *testing.T) {
168+
cache := &mock.FakeCache{}
169+
ts := &tokens.Service{Storage: &tokens.DBStorage{}, RequestsCache: cache}
170+
171+
require.NoError(t, ts.AppendValid(ctx, nil, "tx1", nil))
172+
// getActions was never reached, so the cache was neither consulted nor invalidated.
173+
assert.Equal(t, 0, cache.GetCallCount())
174+
assert.Equal(t, 0, cache.DeleteCallCount())
175+
})
176+
177+
t.Run("nil metadata", func(t *testing.T) {
178+
cache := &mock.FakeCache{}
179+
ts := &tokens.Service{Storage: &tokens.DBStorage{}, RequestsCache: cache}
180+
181+
req := &token.Request{Anchor: "tx1", Metadata: nil}
182+
require.NoError(t, ts.AppendValid(ctx, nil, "tx1", req))
183+
assert.Equal(t, 0, cache.GetCallCount())
184+
assert.Equal(t, 0, cache.DeleteCallCount())
185+
})
186+
}
187+
188+
// TestAppendValid_SkipsWhenTransactionExists verifies that a transaction already recorded
189+
// in local storage is not processed a second time: AppendValid returns without extracting
190+
// actions from the request or invalidating its cache entry.
191+
func TestAppendValid_SkipsWhenTransactionExists(t *testing.T) {
192+
ctx := context.Background()
193+
194+
mockDB := &mock.FakeTokenStore{}
195+
mockDB.TransactionExistsReturns(true, nil)
196+
cache := &mock.FakeCache{}
197+
storage := &tokens.DBStorage{TokenDB: &tokendb.StoreService{TokenStore: mockDB}}
198+
ts := &tokens.Service{Storage: storage, RequestsCache: cache}
199+
200+
req := &token.Request{Anchor: "tx1", Metadata: &driver.TokenRequestMetadata{}}
201+
require.NoError(t, ts.AppendValid(ctx, nil, "tx1", req))
202+
203+
assert.Equal(t, 1, mockDB.TransactionExistsCallCount())
204+
// getActions must not run for an already-known transaction.
205+
assert.Equal(t, 0, cache.GetCallCount())
206+
assert.Equal(t, 0, cache.DeleteCallCount())
207+
}
208+
209+
// TestAppendValid_TransactionExistsError verifies that a storage failure while checking
210+
// for an existing transaction is propagated to the caller rather than swallowed.
211+
func TestAppendValid_TransactionExistsError(t *testing.T) {
212+
ctx := context.Background()
213+
214+
mockDB := &mock.FakeTokenStore{}
215+
mockDB.TransactionExistsReturns(false, assert.AnError)
216+
storage := &tokens.DBStorage{TokenDB: &tokendb.StoreService{TokenStore: mockDB}}
217+
ts := &tokens.Service{Storage: storage, RequestsCache: &mock.FakeCache{}}
218+
219+
req := &token.Request{Anchor: "tx1", Metadata: &driver.TokenRequestMetadata{}}
220+
err := ts.AppendValid(ctx, nil, "tx1", req)
221+
assert.ErrorIs(t, err, assert.AnError)
222+
}
223+
224+
// TestGetCachedTokenRequest verifies that a cached request is returned together with its
225+
// serialized message on a hit, and that a miss yields two nil values.
226+
func TestGetCachedTokenRequest(t *testing.T) {
227+
cache := &mock.FakeCache{}
228+
ts := &tokens.Service{RequestsCache: cache}
229+
230+
// miss: nothing cached under this key
231+
cache.GetReturns(nil, false)
232+
req, msg := ts.GetCachedTokenRequest("missing")
233+
assert.Nil(t, req)
234+
assert.Nil(t, msg)
235+
236+
// hit: the stored request and its message-to-sign are returned
237+
want := &token.Request{Anchor: "tx1"}
238+
cache.GetReturns(&tokens.CacheEntry{Request: want, MsgToSign: []byte("sig")}, true)
239+
req, msg = ts.GetCachedTokenRequest("tx1")
240+
assert.Same(t, want, req)
241+
assert.Equal(t, []byte("sig"), msg)
242+
}
243+
244+
// TestSetSpendableFlag verifies that SetSpendableFlag commits the transaction on success and
245+
// rolls it back (propagating the error) when the underlying store rejects the update.
246+
func TestSetSpendableFlag(t *testing.T) {
247+
ctx := context.Background()
248+
tmsID := token.TMSID{Network: "net", Channel: "ch", Namespace: "ns"}
249+
250+
t.Run("commits when the store succeeds", func(t *testing.T) {
251+
mockTx := &mock.FakeTokenStoreTransaction{}
252+
mockDB := &mock.FakeTokenStore{}
253+
mockDB.NewTokenDBTransactionReturns(mockTx, nil)
254+
storage := &tokens.DBStorage{TokenDB: &tokendb.StoreService{TokenStore: mockDB}, TMSID: tmsID}
255+
ts := &tokens.Service{Storage: storage}
256+
257+
id := &token2.ID{TxId: "tx1", Index: 0}
258+
require.NoError(t, ts.SetSpendableFlag(ctx, true, id))
259+
260+
require.Equal(t, 1, mockTx.SetSpendableCallCount())
261+
assert.Equal(t, 1, mockTx.CommitCallCount())
262+
assert.Equal(t, 0, mockTx.RollbackCallCount())
263+
_, gotID, gotVal := mockTx.SetSpendableArgsForCall(0)
264+
assert.Equal(t, *id, gotID)
265+
assert.True(t, gotVal)
266+
})
267+
268+
t.Run("rolls back when the store fails", func(t *testing.T) {
269+
mockTx := &mock.FakeTokenStoreTransaction{}
270+
mockTx.SetSpendableReturns(assert.AnError)
271+
mockDB := &mock.FakeTokenStore{}
272+
mockDB.NewTokenDBTransactionReturns(mockTx, nil)
273+
storage := &tokens.DBStorage{TokenDB: &tokendb.StoreService{TokenStore: mockDB}, TMSID: tmsID}
274+
ts := &tokens.Service{Storage: storage}
275+
276+
err := ts.SetSpendableFlag(ctx, true, &token2.ID{TxId: "tx1", Index: 0})
277+
require.Error(t, err)
278+
assert.Equal(t, 1, mockTx.RollbackCallCount())
279+
assert.Equal(t, 0, mockTx.CommitCallCount())
280+
})
281+
}
282+
160283
// TestParseRedeem verifies that a redeem output (empty owner) is stored as a redeemed token
161284
// when its issuer is known to this node, and skipped otherwise.
162285
func TestParseRedeem(t *testing.T) {

0 commit comments

Comments
 (0)