Skip to content

Commit e9ea792

Browse files
committed
add: chainstore tests
1 parent f2ddb5d commit e9ea792

File tree

1 file changed

+207
-4
lines changed

1 file changed

+207
-4
lines changed

universalClient/chains/common/chain_store_test.go

Lines changed: 207 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
package common
22

33
import (
4+
"fmt"
45
"testing"
56

67
"github.com/stretchr/testify/assert"
78
"github.com/stretchr/testify/require"
89

10+
"github.com/pushchain/push-chain-node/universalClient/db"
911
storemodels "github.com/pushchain/push-chain-node/universalClient/store"
1012
)
1113

@@ -68,9 +70,210 @@ func TestChainStoreNilDatabase(t *testing.T) {
6870
})
6971
}
7072

71-
func TestChainStoreStruct(t *testing.T) {
72-
t.Run("struct has database field", func(t *testing.T) {
73-
store := &ChainStore{}
74-
assert.Nil(t, store.database)
73+
func newTestChainStore(t *testing.T) *ChainStore {
74+
t.Helper()
75+
testDB, err := db.OpenInMemoryDB(true)
76+
require.NoError(t, err)
77+
t.Cleanup(func() { testDB.Close() })
78+
return NewChainStore(testDB)
79+
}
80+
81+
func TestChainStore_GetChainHeight(t *testing.T) {
82+
cs := newTestChainStore(t)
83+
84+
t.Run("creates state on first call", func(t *testing.T) {
85+
height, err := cs.GetChainHeight()
86+
require.NoError(t, err)
87+
assert.Equal(t, uint64(0), height)
88+
})
89+
90+
t.Run("returns existing height", func(t *testing.T) {
91+
require.NoError(t, cs.UpdateChainHeight(100))
92+
height, err := cs.GetChainHeight()
93+
require.NoError(t, err)
94+
assert.Equal(t, uint64(100), height)
95+
})
96+
}
97+
98+
func TestChainStore_UpdateChainHeight(t *testing.T) {
99+
cs := newTestChainStore(t)
100+
101+
t.Run("creates and updates", func(t *testing.T) {
102+
require.NoError(t, cs.UpdateChainHeight(50))
103+
height, err := cs.GetChainHeight()
104+
require.NoError(t, err)
105+
assert.Equal(t, uint64(50), height)
106+
})
107+
108+
t.Run("only updates if higher", func(t *testing.T) {
109+
require.NoError(t, cs.UpdateChainHeight(100))
110+
require.NoError(t, cs.UpdateChainHeight(50)) // lower — ignored
111+
height, err := cs.GetChainHeight()
112+
require.NoError(t, err)
113+
assert.Equal(t, uint64(100), height)
114+
})
115+
}
116+
117+
func TestChainStore_InsertAndQuery(t *testing.T) {
118+
cs := newTestChainStore(t)
119+
120+
event := &storemodels.Event{
121+
EventID: "evt-1",
122+
BlockHeight: 10,
123+
Type: storemodels.EventTypeInbound,
124+
ConfirmationType: storemodels.ConfirmationStandard,
125+
Status: storemodels.StatusPending,
126+
}
127+
128+
t.Run("insert new event", func(t *testing.T) {
129+
inserted, err := cs.InsertEventIfNotExists(event)
130+
require.NoError(t, err)
131+
assert.True(t, inserted)
132+
})
133+
134+
t.Run("duplicate insert returns false", func(t *testing.T) {
135+
inserted, err := cs.InsertEventIfNotExists(event)
136+
require.NoError(t, err)
137+
assert.False(t, inserted)
138+
})
139+
140+
t.Run("get pending events", func(t *testing.T) {
141+
events, err := cs.GetPendingEvents(10)
142+
require.NoError(t, err)
143+
require.Len(t, events, 1)
144+
assert.Equal(t, "evt-1", events[0].EventID)
145+
})
146+
147+
t.Run("get confirmed events returns empty", func(t *testing.T) {
148+
events, err := cs.GetConfirmedEvents(10)
149+
require.NoError(t, err)
150+
assert.Empty(t, events)
151+
})
152+
}
153+
154+
func TestChainStore_UpdateEventStatus(t *testing.T) {
155+
cs := newTestChainStore(t)
156+
157+
event := &storemodels.Event{
158+
EventID: "evt-2",
159+
BlockHeight: 20,
160+
Type: storemodels.EventTypeInbound,
161+
ConfirmationType: storemodels.ConfirmationStandard,
162+
Status: storemodels.StatusPending,
163+
}
164+
_, err := cs.InsertEventIfNotExists(event)
165+
require.NoError(t, err)
166+
167+
t.Run("updates matching status", func(t *testing.T) {
168+
rows, err := cs.UpdateEventStatus("evt-2", storemodels.StatusPending, storemodels.StatusConfirmed)
169+
require.NoError(t, err)
170+
assert.Equal(t, int64(1), rows)
75171
})
172+
173+
t.Run("no-op if status mismatch", func(t *testing.T) {
174+
rows, err := cs.UpdateEventStatus("evt-2", storemodels.StatusPending, storemodels.StatusCompleted)
175+
require.NoError(t, err)
176+
assert.Equal(t, int64(0), rows)
177+
})
178+
179+
t.Run("confirmed events visible", func(t *testing.T) {
180+
events, err := cs.GetConfirmedEvents(10)
181+
require.NoError(t, err)
182+
require.Len(t, events, 1)
183+
assert.Equal(t, "evt-2", events[0].EventID)
184+
})
185+
}
186+
187+
func TestChainStore_UpdateStatusAndVoteTxHash(t *testing.T) {
188+
cs := newTestChainStore(t)
189+
190+
event := &storemodels.Event{
191+
EventID: "evt-3",
192+
BlockHeight: 30,
193+
Type: storemodels.EventTypeInbound,
194+
ConfirmationType: storemodels.ConfirmationStandard,
195+
Status: storemodels.StatusConfirmed,
196+
}
197+
_, err := cs.InsertEventIfNotExists(event)
198+
require.NoError(t, err)
199+
200+
rows, err := cs.UpdateStatusAndVoteTxHash("evt-3", storemodels.StatusConfirmed, storemodels.StatusCompleted, "0xvote123")
201+
require.NoError(t, err)
202+
assert.Equal(t, int64(1), rows)
203+
}
204+
205+
func TestChainStore_UpdateStatusAndEventData(t *testing.T) {
206+
cs := newTestChainStore(t)
207+
208+
event := &storemodels.Event{
209+
EventID: "evt-4",
210+
BlockHeight: 40,
211+
Type: storemodels.EventTypeInbound,
212+
ConfirmationType: storemodels.ConfirmationStandard,
213+
Status: storemodels.StatusPending,
214+
EventData: []byte(`{"old":"data"}`),
215+
}
216+
_, err := cs.InsertEventIfNotExists(event)
217+
require.NoError(t, err)
218+
219+
newData := []byte(`{"new":"data"}`)
220+
rows, err := cs.UpdateStatusAndEventData("evt-4", storemodels.StatusPending, storemodels.StatusConfirmed, newData)
221+
require.NoError(t, err)
222+
assert.Equal(t, int64(1), rows)
223+
}
224+
225+
func TestChainStore_UpdateVoteTxHash(t *testing.T) {
226+
cs := newTestChainStore(t)
227+
228+
event := &storemodels.Event{
229+
EventID: "evt-5",
230+
BlockHeight: 50,
231+
Type: storemodels.EventTypeOutbound,
232+
ConfirmationType: storemodels.ConfirmationStandard,
233+
Status: storemodels.StatusConfirmed,
234+
}
235+
_, err := cs.InsertEventIfNotExists(event)
236+
require.NoError(t, err)
237+
238+
err = cs.UpdateVoteTxHash("evt-5", "0xvotehash")
239+
require.NoError(t, err)
240+
}
241+
242+
func TestChainStore_DeleteTerminalEvents(t *testing.T) {
243+
cs := newTestChainStore(t)
244+
245+
// Insert events in terminal states
246+
for i, status := range []string{storemodels.StatusCompleted, storemodels.StatusReverted, storemodels.StatusReorged} {
247+
evt := &storemodels.Event{
248+
EventID: fmt.Sprintf("term-%d", i),
249+
BlockHeight: uint64(i),
250+
Type: storemodels.EventTypeInbound,
251+
ConfirmationType: storemodels.ConfirmationStandard,
252+
Status: status,
253+
}
254+
_, err := cs.InsertEventIfNotExists(evt)
255+
require.NoError(t, err)
256+
}
257+
258+
// Insert a non-terminal event
259+
active := &storemodels.Event{
260+
EventID: "active-1",
261+
BlockHeight: 100,
262+
Type: storemodels.EventTypeInbound,
263+
ConfirmationType: storemodels.ConfirmationStandard,
264+
Status: storemodels.StatusPending,
265+
}
266+
_, err := cs.InsertEventIfNotExists(active)
267+
require.NoError(t, err)
268+
269+
// Delete terminal events updated before far future
270+
deleted, err := cs.DeleteTerminalEvents("2099-01-01")
271+
require.NoError(t, err)
272+
assert.Equal(t, int64(3), deleted)
273+
274+
// Active event still exists
275+
events, err := cs.GetPendingEvents(10)
276+
require.NoError(t, err)
277+
assert.Len(t, events, 1)
278+
assert.Equal(t, "active-1", events[0].EventID)
76279
}

0 commit comments

Comments
 (0)