Skip to content

Commit 6cec73f

Browse files
committed
Fix integration test and mock implementations
1 parent 6bae85d commit 6cec73f

File tree

4 files changed

+142
-30
lines changed

4 files changed

+142
-30
lines changed

integration_test.go

Lines changed: 68 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@ import (
88

99
"github.com/Jetlum/WalletAlertService/mock"
1010
"github.com/Jetlum/WalletAlertService/models"
11+
"github.com/ethereum/go-ethereum/common"
1112
"github.com/ethereum/go-ethereum/core/types"
13+
"github.com/ethereum/go-ethereum/crypto"
1214
"github.com/stretchr/testify/assert"
1315
)
1416

@@ -21,23 +23,6 @@ func TestIntegration(t *testing.T) {
2123
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
2224
defer cancel()
2325

24-
// Create test event
25-
event := &models.Event{
26-
TxHash: "0xtest",
27-
FromAddress: "0xfrom",
28-
ToAddress: "0xto",
29-
Value: "1000000000000000000", // 1 ETH
30-
EventType: "LARGE_TRANSFER",
31-
}
32-
33-
// Setup mocks
34-
mockEventRepo := &mock.MockEventRepository{
35-
CreateFunc: func(e *models.Event) error {
36-
assert.Equal(t, event.TxHash, e.TxHash)
37-
return nil
38-
},
39-
}
40-
4126
userPref := models.UserPreference{
4227
UserID: "test@example.com",
4328
WalletAddress: "0xto",
@@ -47,40 +32,98 @@ func TestIntegration(t *testing.T) {
4732

4833
mockUserPrefRepo := &mock.MockUserPreferenceRepository{
4934
GetMatchingPreferencesFunc: func(e *models.Event) ([]models.UserPreference, error) {
50-
assert.Equal(t, event.ToAddress, e.ToAddress)
5135
return []models.UserPreference{userPref}, nil
5236
},
5337
}
5438

55-
// Setup mock email notification
39+
// Create mock Ethereum client
40+
mockClient := mock.NewMockEthClient()
41+
42+
// Create and use fromAddress in assertions
43+
privateKey, err := crypto.GenerateKey()
44+
if err != nil {
45+
t.Fatalf("Failed to generate private key: %v", err)
46+
}
47+
fromAddress := crypto.PubkeyToAddress(privateKey.PublicKey)
48+
49+
mockEventRepo := &mock.MockEventRepository{
50+
CreateFunc: func(e *models.Event) error {
51+
assert.Equal(t, fromAddress.Hex(), e.FromAddress, "From address should match")
52+
return nil
53+
},
54+
}
55+
// Create mock transaction (unsigned)
56+
mockTx := types.NewTransaction(
57+
0,
58+
common.HexToAddress("0xto"),
59+
big.NewInt(2000000000000000000), // 2 ETH (above threshold)
60+
21000,
61+
big.NewInt(1),
62+
nil,
63+
)
64+
65+
// Sign the transaction
66+
chainID := big.NewInt(1) // Use the same chain ID in the mock client
67+
signer := types.LatestSignerForChainID(chainID)
68+
signedTx, err := types.SignTx(mockTx, signer, privateKey)
69+
if err != nil {
70+
t.Fatalf("Failed to sign transaction: %v", err)
71+
}
72+
73+
// Update NetworkIDFunc to return the correct chain ID
74+
mockClient.NetworkIDFunc = func(ctx context.Context) (*big.Int, error) {
75+
return chainID, nil
76+
}
77+
78+
// Fix block.WithBody call
79+
mockClient.BlockByHashFunc = func(ctx context.Context, hash common.Hash) (*types.Block, error) {
80+
header := &types.Header{
81+
Number: big.NewInt(1),
82+
ParentHash: common.HexToHash("0x123"),
83+
Time: uint64(time.Now().Unix()),
84+
}
85+
86+
block := types.NewBlockWithHeader(header)
87+
return block.WithBody(types.Body{
88+
Transactions: []*types.Transaction{signedTx},
89+
Uncles: []*types.Header{},
90+
}), nil
91+
}
92+
93+
// Use mock NFT detector
94+
mockNFTDetector := &mock.MockNFTDetector{
95+
IsNFTTransactionFunc: func(tx *types.Transaction) bool {
96+
return false
97+
},
98+
}
99+
56100
emailSent := false
57101
mockEmailNotification := &mock.MockEmailNotification{
58-
SendFunc: func(e *models.Event, up *models.UserPreference) error {
102+
SendFunc: func(event *models.Event, userPref *models.UserPreference) error {
59103
emailSent = true
104+
// Add assertions if needed
60105
return nil
61106
},
62107
}
63108

64-
// Create mock block and header
109+
// Create mock header
65110
mockHeader := &types.Header{
66111
Number: big.NewInt(1),
67112
}
68113

69-
// Test full workflow
70114
done := make(chan bool)
71115
go func() {
72116
processBlock(
73-
nil,
117+
mockClient,
74118
mockHeader,
75-
mock.NewMockNFTDetector(),
119+
mockNFTDetector,
76120
mockEmailNotification,
77121
mockEventRepo,
78122
mockUserPrefRepo,
79123
)
80124
done <- true
81125
}()
82126

83-
// Wait for completion or timeout
84127
select {
85128
case <-ctx.Done():
86129
t.Fatal("Test timed out")

main.go

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ func main() {
8787
}
8888

8989
func processBlock(
90-
client *ethclient.Client,
90+
client mock.EthClient,
9191
header *types.Header,
9292
nftDetector nfts.INFTDetector,
9393
emailNotification services.EmailNotifier,
@@ -124,14 +124,13 @@ func processBlock(
124124
}
125125
}
126126

127-
func createEvent(tx *types.Transaction, client *ethclient.Client) *models.Event {
127+
func createEvent(tx *types.Transaction, client mock.EthClient) *models.Event {
128128
chainID, err := client.NetworkID(context.Background())
129129
if err != nil {
130130
log.Fatalf("Failed to get network ID: %v", err)
131131
}
132132

133133
signer := types.NewEIP155Signer(chainID)
134-
135134
fromAddress, err := types.Sender(signer, tx)
136135
if err != nil {
137136
log.Fatalf("Failed to get sender address: %v", err)

mock/ethereum_mock.go

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
package mock
2+
3+
import (
4+
"context"
5+
"math/big"
6+
"time"
7+
8+
"github.com/ethereum/go-ethereum/common"
9+
"github.com/ethereum/go-ethereum/core/types"
10+
)
11+
12+
// EthClient defines the interface for Ethereum client operations
13+
type EthClient interface {
14+
BlockByHash(ctx context.Context, hash common.Hash) (*types.Block, error)
15+
BlockNumber(ctx context.Context) (uint64, error)
16+
HeaderByNumber(ctx context.Context, number *big.Int) (*types.Header, error)
17+
NetworkID(ctx context.Context) (*big.Int, error)
18+
}
19+
20+
type MockEthClient struct {
21+
BlockByHashFunc func(ctx context.Context, hash common.Hash) (*types.Block, error)
22+
BlockNumberFunc func(ctx context.Context) (uint64, error)
23+
HeaderByNumberFunc func(ctx context.Context, number *big.Int) (*types.Header, error)
24+
NetworkIDFunc func(ctx context.Context) (*big.Int, error)
25+
}
26+
27+
func NewMockEthClient() *MockEthClient {
28+
return &MockEthClient{
29+
BlockByHashFunc: func(ctx context.Context, hash common.Hash) (*types.Block, error) {
30+
header := &types.Header{
31+
Number: big.NewInt(1),
32+
ParentHash: common.HexToHash("0x123"),
33+
Time: uint64(time.Now().Unix()),
34+
}
35+
36+
block := types.NewBlockWithHeader(header)
37+
return block.WithBody(types.Body{
38+
Transactions: make([]*types.Transaction, 0),
39+
Uncles: make([]*types.Header, 0),
40+
}), nil
41+
},
42+
NetworkIDFunc: func(ctx context.Context) (*big.Int, error) {
43+
return big.NewInt(1), nil
44+
},
45+
}
46+
}
47+
48+
func (m *MockEthClient) BlockByHash(ctx context.Context, hash common.Hash) (*types.Block, error) {
49+
return m.BlockByHashFunc(ctx, hash)
50+
}
51+
52+
func (m *MockEthClient) BlockNumber(ctx context.Context) (uint64, error) {
53+
if m.BlockNumberFunc != nil {
54+
return m.BlockNumberFunc(ctx)
55+
}
56+
return 0, nil
57+
}
58+
59+
func (m *MockEthClient) HeaderByNumber(ctx context.Context, number *big.Int) (*types.Header, error) {
60+
if m.HeaderByNumberFunc != nil {
61+
return m.HeaderByNumberFunc(ctx, number)
62+
}
63+
return nil, nil
64+
}
65+
66+
func (m *MockEthClient) NetworkID(ctx context.Context) (*big.Int, error) {
67+
if m.NetworkIDFunc != nil {
68+
return m.NetworkIDFunc(ctx)
69+
}
70+
return big.NewInt(1), nil
71+
}

mock/nft_mock.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,14 @@
11
package mock
22

33
import (
4-
nfts "github.com/Jetlum/WalletAlertService/nft"
54
"github.com/ethereum/go-ethereum/core/types"
65
)
76

87
type MockNFTDetector struct {
98
IsNFTTransactionFunc func(tx *types.Transaction) bool
109
}
1110

12-
func NewMockNFTDetector() nfts.INFTDetector {
11+
func NewMockNFTDetector() *MockNFTDetector {
1312
return &MockNFTDetector{
1413
IsNFTTransactionFunc: func(tx *types.Transaction) bool {
1514
return false

0 commit comments

Comments
 (0)