Skip to content

Commit a93bbff

Browse files
jkawanJenita
authored andcommitted
test: added unit tests for chainsync filter plugin
Signed-off-by: Jenita <jkawan@blinklabs.io>
1 parent 92233db commit a93bbff

File tree

1 file changed

+265
-1
lines changed

1 file changed

+265
-1
lines changed

filter/chainsync/chainsync_test.go

Lines changed: 265 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,116 @@
1414

1515
package chainsync
1616

17-
import "testing"
17+
import (
18+
"encoding/hex"
19+
"testing"
20+
"time"
21+
22+
"github.com/blinklabs-io/adder/event"
23+
"github.com/blinklabs-io/adder/input/chainsync"
24+
"github.com/blinklabs-io/gouroboros/cbor"
25+
"github.com/blinklabs-io/gouroboros/ledger"
26+
"github.com/blinklabs-io/gouroboros/ledger/common"
27+
"github.com/stretchr/testify/assert"
28+
"github.com/utxorpc/go-codegen/utxorpc/v1alpha/cardano"
29+
)
1830

1931
// MockLogger is a mock implementation of the plugin.Logger interface
2032
type MockLogger struct{}
2133

34+
// MockAddress is a mock implementation of the ledger.Address interface
35+
type MockAddress struct {
36+
common.Address // Embed the common.Address struct
37+
}
38+
39+
func (m MockAddress) ByronAttr() common.ByronAddressAttributes {
40+
return common.ByronAddressAttributes{}
41+
}
42+
43+
func (m MockAddress) ByronType() uint64 {
44+
return 0
45+
}
46+
47+
func (m MockAddress) Bytes() []byte {
48+
return []byte("mockAddressBytes")
49+
}
50+
51+
func (m *MockAddress) MarshalCBOR() ([]byte, error) {
52+
return []byte{}, nil
53+
}
54+
55+
func (m MockAddress) MarshalJSON() ([]byte, error) {
56+
return []byte("{}"), nil
57+
}
58+
59+
func (m MockAddress) NetworkId() uint {
60+
return 1
61+
}
62+
63+
func (m MockAddress) PaymentAddress() *common.Address {
64+
return &common.Address{}
65+
}
66+
67+
func (m *MockAddress) PaymentKeyHash() common.Blake2b224 {
68+
return common.Blake2b224Hash([]byte("paymentKeyHash"))
69+
}
70+
71+
func (m MockAddress) StakeAddress() *common.Address {
72+
return &common.Address{}
73+
}
74+
75+
func (m *MockAddress) StakeKeyHash() common.Blake2b224 {
76+
return common.Blake2b224Hash([]byte("stakeKeyHash"))
77+
}
78+
79+
func (m MockAddress) String() string {
80+
return hex.EncodeToString(m.Bytes())
81+
}
82+
83+
func (m MockAddress) Type() uint8 {
84+
return 0
85+
}
86+
87+
func (m *MockAddress) UnmarshalCBOR(data []byte) error {
88+
return nil
89+
}
90+
91+
// MockOutput is a mock implementation of the TransactionOutput interface
92+
type MockOutput struct {
93+
address ledger.Address
94+
amount uint64
95+
assets *common.MultiAsset[common.MultiAssetTypeOutput]
96+
datum *cbor.LazyValue
97+
}
98+
99+
func (m MockOutput) Address() ledger.Address {
100+
return m.address
101+
}
102+
103+
func (m MockOutput) Amount() uint64 {
104+
return m.amount
105+
}
106+
107+
func (m MockOutput) Assets() *common.MultiAsset[common.MultiAssetTypeOutput] {
108+
return m.assets
109+
}
110+
111+
func (m MockOutput) Datum() *cbor.LazyValue {
112+
return m.datum
113+
}
114+
115+
func (m MockOutput) DatumHash() *common.Blake2b256 {
116+
return nil
117+
}
118+
119+
func (m MockOutput) Cbor() []byte {
120+
return []byte{}
121+
}
122+
123+
func (m MockOutput) Utxorpc() *cardano.TxOutput {
124+
return nil
125+
}
126+
22127
func (l *MockLogger) Info(msg string, args ...interface{}) {}
23128
func (l *MockLogger) Error(msg string, args ...interface{}) {}
24129
func (l *MockLogger) Debug(msg string, args ...interface{}) {}
@@ -85,3 +190,162 @@ func TestChainSync_OutputChan(t *testing.T) {
85190
t.Fatalf("expected non-nil outputChan")
86191
}
87192
}
193+
194+
func TestFilterByAddress(t *testing.T) {
195+
// Setup ChainSync with address filter
196+
cs := New(WithAddresses([]string{"addr_test1qqjwq357"}))
197+
198+
// Create a mock address using the methods
199+
mockAddr := common.Address{}
200+
201+
// Mock transaction event
202+
output := MockOutput{
203+
address: mockAddr,
204+
amount: 1000000,
205+
assets: nil,
206+
datum: nil,
207+
}
208+
evt := event.Event{
209+
Payload: chainsync.TransactionEvent{
210+
Outputs: []ledger.TransactionOutput{output},
211+
ResolvedInputs: []ledger.TransactionOutput{output},
212+
},
213+
}
214+
215+
// Start the filter
216+
err := cs.Start()
217+
assert.NoError(t, err, "ChainSync filter should start without error")
218+
defer cs.Stop()
219+
220+
// Send event to input channel
221+
cs.InputChan() <- evt
222+
223+
// Wait for the event to be processed
224+
select {
225+
case filteredEvt := <-cs.OutputChan():
226+
assert.Equal(t, evt, filteredEvt, "Filtered event should match the input event")
227+
case <-time.After(10 * time.Second):
228+
t.Fatal("Test timed out waiting for filtered event")
229+
}
230+
}
231+
232+
func TestFilterByPolicyId(t *testing.T) {
233+
// Setup ChainSync with policy ID filter
234+
filterPolicyId := "random_policy_id"
235+
policyIdHash := common.Blake2b224Hash([]byte(filterPolicyId))
236+
cs := New(WithPolicies([]string{policyIdHash.String()}))
237+
238+
// Mock transaction event
239+
policyId := policyIdHash // Use the same hash as the filter
240+
241+
// Create a new MultiAsset with pre-populated data
242+
assetsData := make(map[common.Blake2b224]map[cbor.ByteString]common.MultiAssetTypeOutput)
243+
assetName := cbor.NewByteString([]byte("asset1"))
244+
assetsData[policyId] = map[cbor.ByteString]common.MultiAssetTypeOutput{
245+
assetName: 1, // Add asset with quantity 1
246+
}
247+
assets := common.NewMultiAsset(assetsData)
248+
249+
output := MockOutput{
250+
address: ledger.Address{},
251+
amount: 1000000,
252+
assets: &assets,
253+
datum: nil,
254+
}
255+
evt := event.Event{
256+
Payload: chainsync.TransactionEvent{
257+
Outputs: []ledger.TransactionOutput{output},
258+
ResolvedInputs: []ledger.TransactionOutput{output},
259+
},
260+
}
261+
262+
// Start the filter
263+
err := cs.Start()
264+
assert.NoError(t, err, "ChainSync filter should start without error")
265+
defer cs.Stop()
266+
267+
// Send event to input channel
268+
cs.InputChan() <- evt
269+
270+
// Wait for the event to be processed
271+
select {
272+
case filteredEvt := <-cs.OutputChan():
273+
assert.Equal(t, evt, filteredEvt, "Filtered event should match the input event")
274+
case <-time.After(5 * time.Second):
275+
t.Fatal("Test timed out waiting for filtered event")
276+
}
277+
}
278+
279+
func TestFilterByAssetFingerprint(t *testing.T) {
280+
// Setup ChainSync with asset fingerprint filter
281+
filterAssetFingerprint := "asset1e58wmplshqdkkq97tz02chq980456wgt35tfjr"
282+
cs := New(WithAssetFingerprints([]string{filterAssetFingerprint}))
283+
284+
// Mock transaction event
285+
policyId := common.Blake2b224Hash([]byte("policy1"))
286+
287+
// Create a new MultiAsset with pre-populated data
288+
assetsData := make(map[common.Blake2b224]map[cbor.ByteString]common.MultiAssetTypeOutput)
289+
assetName := cbor.NewByteString([]byte("asset1"))
290+
assetsData[policyId] = map[cbor.ByteString]common.MultiAssetTypeOutput{
291+
assetName: 1, // Add asset with quantity 1
292+
}
293+
assets := common.NewMultiAsset(assetsData)
294+
295+
output := MockOutput{
296+
address: ledger.Address{},
297+
amount: 1000000,
298+
assets: &assets,
299+
datum: nil,
300+
}
301+
evt := event.Event{
302+
Payload: chainsync.TransactionEvent{
303+
Outputs: []ledger.TransactionOutput{output},
304+
ResolvedInputs: []ledger.TransactionOutput{output},
305+
},
306+
}
307+
308+
// Start the filter
309+
err := cs.Start()
310+
assert.NoError(t, err, "ChainSync filter should start without error")
311+
defer cs.Stop()
312+
313+
// Send event to input channel
314+
cs.InputChan() <- evt
315+
316+
// Wait for the event to be processed
317+
select {
318+
case filteredEvt := <-cs.OutputChan():
319+
assert.Equal(t, evt, filteredEvt, "Filtered event should match the input event")
320+
case <-time.After(5 * time.Second):
321+
t.Fatal("Test timed out waiting for filtered event")
322+
}
323+
}
324+
325+
func TestFilterByPoolId(t *testing.T) {
326+
// Setup ChainSync with pool ID filter
327+
cs := New(WithPoolIds([]string{"pool1"}))
328+
329+
// Mock block event
330+
evt := event.Event{
331+
Payload: chainsync.BlockEvent{
332+
IssuerVkey: "pool1", // Match the filterPoolIds
333+
},
334+
}
335+
336+
// Start the filter
337+
err := cs.Start()
338+
assert.NoError(t, err, "ChainSync filter should start without error")
339+
defer cs.Stop()
340+
341+
// Send event to input channel
342+
cs.InputChan() <- evt
343+
344+
// Wait for the event to be processed
345+
select {
346+
case filteredEvt := <-cs.OutputChan():
347+
assert.Equal(t, evt, filteredEvt, "Filtered event should match the input event")
348+
case <-time.After(5 * time.Second):
349+
t.Fatal("Test timed out waiting for filtered event")
350+
}
351+
}

0 commit comments

Comments
 (0)