code.vegaprotocol.io/vega@v0.79.0/datanode/entities/entities_test.go (about) 1 // Copyright (C) 2023 Gobalsky Labs Limited 2 // 3 // This program is free software: you can redistribute it and/or modify 4 // it under the terms of the GNU Affero General Public License as 5 // published by the Free Software Foundation, either version 3 of the 6 // License, or (at your option) any later version. 7 // 8 // This program is distributed in the hope that it will be useful, 9 // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 // GNU Affero General Public License for more details. 12 // 13 // You should have received a copy of the GNU Affero General Public License 14 // along with this program. If not, see <http://www.gnu.org/licenses/>. 15 16 package entities_test 17 18 import ( 19 "crypto/sha256" 20 "encoding/hex" 21 "math/rand" 22 "strconv" 23 "testing" 24 "time" 25 26 "code.vegaprotocol.io/vega/datanode/entities" 27 v2 "code.vegaprotocol.io/vega/protos/data-node/api/v2" 28 29 "github.com/stretchr/testify/assert" 30 "github.com/stretchr/testify/require" 31 ) 32 33 func generateTxHash() entities.TxHash { 34 randomString := strconv.FormatInt(rand.Int63(), 10) 35 hash := sha256.Sum256([]byte(randomString)) 36 return entities.TxHash(hex.EncodeToString(hash[:])) 37 } 38 39 func TestPageEntities(t *testing.T) { 40 t.Run("Number of results is 2 more then the page limit", func(t *testing.T) { 41 t.Run("The results are returned in order and we have next and previous when we are moving forward", testPageEntitiesForwardHasNextAndPrevious) 42 t.Run("The results are returned in order and we have next and previous when we are moving backward", testPageEntitiesBackwardHasNextAndPrevious) 43 }) 44 45 t.Run("Number of results is 1 more than the page limit", func(t *testing.T) { 46 t.Run("When moving forward, we have a previous page, but no next page", testPagedEntitiesForwardHasPreviousButNoNext) 47 t.Run("When moving backward, we have a next page, but no previous page", testPagedEntitiesBackwardHasNextButNoPrevious) 48 }) 49 50 t.Run("Number of results is equal to the page limit", func(t *testing.T) { 51 t.Run("When moving forward, we have no previous or next page", testPagedEntitiesForwardNoNextOrPreviousEqualLimit) 52 t.Run("When moving backward, we have no previous or next page", testPagedEntitiesBackwardNoNextOrPreviousEqualLimit) 53 }) 54 55 t.Run("Number of results is less than the page limit", func(t *testing.T) { 56 t.Run("When moving forward, we have no previous or next page", testPagedEntitiesForwardNoNextOrPreviousLessThanLimit) 57 t.Run("When moving backward, we have no previous or next page", testPagedEntitiesBackwardNoNextOrPreviousLessThanLimit) 58 }) 59 } 60 61 func testPageEntitiesForwardHasNextAndPrevious(t *testing.T) { 62 trades := getTradesForward(t, 0, 0) // 0, 0 return all entries 63 first := int32(5) 64 afterTs := time.Unix(0, 1000000000000).UTC() 65 after := entities.NewCursor(entities.TradeCursor{ 66 SyntheticTime: afterTs, 67 }.String()).Encode() 68 newestFirst := false 69 cursor, err := entities.CursorPaginationFromProto( 70 &v2.Pagination{ 71 First: &first, 72 After: &after, 73 Last: nil, 74 Before: nil, 75 NewestFirst: &newestFirst, 76 }) 77 require.NoError(t, err) 78 gotPaged, gotInfo := entities.PageEntities[*v2.TradeEdge](trades, cursor) 79 80 startCursor := entities.NewCursor(entities.TradeCursor{ 81 SyntheticTime: time.Unix(0, 1000001000000).UTC(), 82 }.String()).Encode() 83 84 endCursor := entities.NewCursor(entities.TradeCursor{ 85 SyntheticTime: time.Unix(0, 1000005000000).UTC(), 86 }.String()).Encode() 87 88 wantPaged := trades[1:6] 89 wantInfo := entities.PageInfo{ 90 HasNextPage: true, 91 HasPreviousPage: true, 92 StartCursor: startCursor, 93 EndCursor: endCursor, 94 } 95 assert.Equal(t, wantPaged, gotPaged) 96 assert.Equal(t, wantInfo, gotInfo) 97 } 98 99 func testPageEntitiesBackwardHasNextAndPrevious(t *testing.T) { 100 trades := getTradesBackward(t, 0, 0) // 0, 0 return all entries 101 last := int32(5) 102 beforeTs := time.Unix(0, 1000006000000).UTC() 103 before := entities.NewCursor(entities.TradeCursor{ 104 SyntheticTime: beforeTs, 105 }.String()).Encode() 106 newestFirst := false 107 cursor, err := entities.CursorPaginationFromProto( 108 &v2.Pagination{ 109 First: nil, 110 After: nil, 111 Last: &last, 112 Before: &before, 113 NewestFirst: &newestFirst, 114 }) 115 require.NoError(t, err) 116 gotPaged, gotInfo := entities.PageEntities[*v2.TradeEdge](trades, cursor) 117 118 startCursor := entities.NewCursor(entities.TradeCursor{ 119 SyntheticTime: time.Unix(0, 1000001000000).UTC(), 120 }.String()).Encode() 121 122 endCursor := entities.NewCursor(entities.TradeCursor{ 123 SyntheticTime: time.Unix(0, 1000005000000).UTC(), 124 }.String()).Encode() 125 126 wantPaged := getTradesForward(t, 1, 6) 127 wantInfo := entities.PageInfo{ 128 HasNextPage: true, 129 HasPreviousPage: true, 130 StartCursor: startCursor, 131 EndCursor: endCursor, 132 } 133 assert.Equal(t, wantPaged, gotPaged) 134 assert.Equal(t, wantInfo, gotInfo) 135 } 136 137 func testPagedEntitiesForwardHasPreviousButNoNext(t *testing.T) { 138 trades := getTradesForward(t, 1, 0) // 0, 0 return all entries 139 first := int32(5) 140 afterTs := time.Unix(0, 1000001000000).UTC() 141 after := entities.NewCursor(entities.TradeCursor{ 142 SyntheticTime: afterTs, 143 }.String()).Encode() 144 newestFirst := false 145 cursor, err := entities.CursorPaginationFromProto( 146 &v2.Pagination{ 147 First: &first, 148 After: &after, 149 Last: nil, 150 Before: nil, 151 NewestFirst: &newestFirst, 152 }) 153 require.NoError(t, err) 154 gotPaged, gotInfo := entities.PageEntities[*v2.TradeEdge](trades, cursor) 155 156 startCursor := entities.NewCursor(entities.TradeCursor{ 157 SyntheticTime: time.Unix(0, 1000002000000).UTC(), 158 }.String()).Encode() 159 160 endCursor := entities.NewCursor(entities.TradeCursor{ 161 SyntheticTime: time.Unix(0, 1000006000000).UTC(), 162 }.String()).Encode() 163 164 wantPaged := trades[1:6] 165 wantInfo := entities.PageInfo{ 166 HasNextPage: false, 167 HasPreviousPage: true, 168 StartCursor: startCursor, 169 EndCursor: endCursor, 170 } 171 assert.Equal(t, wantPaged, gotPaged) 172 assert.Equal(t, wantInfo, gotInfo) 173 } 174 175 func testPagedEntitiesBackwardHasNextButNoPrevious(t *testing.T) { 176 trades := getTradesBackward(t, 1, 0) // 0, 0 return all entries 177 last := int32(5) 178 beforeTs := time.Unix(0, 1000005000000).UTC() 179 before := entities.NewCursor(entities.TradeCursor{ 180 SyntheticTime: beforeTs, 181 }.String()).Encode() 182 newestFirst := false 183 cursor, err := entities.CursorPaginationFromProto( 184 &v2.Pagination{ 185 First: nil, 186 After: nil, 187 Last: &last, 188 Before: &before, 189 NewestFirst: &newestFirst, 190 }) 191 require.NoError(t, err) 192 gotPaged, gotInfo := entities.PageEntities[*v2.TradeEdge](trades, cursor) 193 194 startCursor := entities.NewCursor(entities.TradeCursor{ 195 SyntheticTime: time.Unix(0, 1000000000000).UTC(), 196 }.String()).Encode() 197 198 endCursor := entities.NewCursor(entities.TradeCursor{ 199 SyntheticTime: time.Unix(0, 1000004000000).UTC(), 200 }.String()).Encode() 201 202 wantPaged := getTradesForward(t, 0, 5) 203 wantInfo := entities.PageInfo{ 204 HasNextPage: true, 205 HasPreviousPage: false, 206 StartCursor: startCursor, 207 EndCursor: endCursor, 208 } 209 assert.Equal(t, wantPaged, gotPaged) 210 assert.Equal(t, wantInfo, gotInfo) 211 } 212 213 func testPagedEntitiesForwardNoNextOrPreviousEqualLimit(t *testing.T) { 214 trades := getTradesForward(t, 0, 5) // 0, 0 return all entries 215 first := int32(5) 216 newestFirst := false 217 cursor, err := entities.CursorPaginationFromProto( 218 &v2.Pagination{ 219 First: &first, 220 After: nil, 221 Last: nil, 222 Before: nil, 223 NewestFirst: &newestFirst, 224 }) 225 require.NoError(t, err) 226 gotPaged, gotInfo := entities.PageEntities[*v2.TradeEdge](trades, cursor) 227 228 startCursor := entities.NewCursor(entities.TradeCursor{ 229 SyntheticTime: time.Unix(0, 1000000000000).UTC(), 230 }.String()).Encode() 231 232 endCursor := entities.NewCursor(entities.TradeCursor{ 233 SyntheticTime: time.Unix(0, 1000004000000).UTC(), 234 }.String()).Encode() 235 236 wantPaged := trades 237 wantInfo := entities.PageInfo{ 238 HasNextPage: false, 239 HasPreviousPage: false, 240 StartCursor: startCursor, 241 EndCursor: endCursor, 242 } 243 assert.Equal(t, wantPaged, gotPaged) 244 assert.Equal(t, wantInfo, gotInfo) 245 } 246 247 func testPagedEntitiesBackwardNoNextOrPreviousEqualLimit(t *testing.T) { 248 trades := getTradesBackward(t, 0, 5) // 0, 0 return all entries 249 last := int32(5) 250 newestFirst := false 251 cursor, err := entities.CursorPaginationFromProto( 252 &v2.Pagination{ 253 First: nil, 254 After: nil, 255 Last: &last, 256 Before: nil, 257 NewestFirst: &newestFirst, 258 }) 259 require.NoError(t, err) 260 gotPaged, gotInfo := entities.PageEntities[*v2.TradeEdge](trades, cursor) 261 262 startCursor := entities.NewCursor(entities.TradeCursor{ 263 SyntheticTime: time.Unix(0, 1000002000000).UTC(), 264 }.String()).Encode() 265 266 endCursor := entities.NewCursor(entities.TradeCursor{ 267 SyntheticTime: time.Unix(0, 1000006000000).UTC(), 268 }.String()).Encode() 269 270 wantPaged := getTradesForward(t, 2, 0) 271 wantInfo := entities.PageInfo{ 272 HasNextPage: false, 273 HasPreviousPage: false, 274 StartCursor: startCursor, 275 EndCursor: endCursor, 276 } 277 assert.Equal(t, wantPaged, gotPaged) 278 assert.Equal(t, wantInfo, gotInfo) 279 } 280 281 func testPagedEntitiesForwardNoNextOrPreviousLessThanLimit(t *testing.T) { 282 trades := getTradesForward(t, 0, 3) // 0, 0 return all entries 283 first := int32(5) 284 newestFirst := false 285 cursor, err := entities.CursorPaginationFromProto( 286 &v2.Pagination{ 287 First: &first, 288 After: nil, 289 Last: nil, 290 Before: nil, 291 NewestFirst: &newestFirst, 292 }) 293 require.NoError(t, err) 294 gotPaged, gotInfo := entities.PageEntities[*v2.TradeEdge](trades, cursor) 295 296 startCursor := entities.NewCursor(entities.TradeCursor{ 297 SyntheticTime: time.Unix(0, 1000000000000).UTC(), 298 }.String()).Encode() 299 300 endCursor := entities.NewCursor(entities.TradeCursor{ 301 SyntheticTime: time.Unix(0, 1000002000000).UTC(), 302 }.String()).Encode() 303 304 wantPaged := trades 305 wantInfo := entities.PageInfo{ 306 HasNextPage: false, 307 HasPreviousPage: false, 308 StartCursor: startCursor, 309 EndCursor: endCursor, 310 } 311 assert.Equal(t, wantPaged, gotPaged) 312 assert.Equal(t, wantInfo, gotInfo) 313 } 314 315 func testPagedEntitiesBackwardNoNextOrPreviousLessThanLimit(t *testing.T) { 316 trades := getTradesBackward(t, 0, 3) // 0, 0 return all entries 317 last := int32(5) 318 newestFirst := false 319 cursor, err := entities.CursorPaginationFromProto( 320 &v2.Pagination{ 321 First: nil, 322 After: nil, 323 Last: &last, 324 Before: nil, 325 NewestFirst: &newestFirst, 326 }) 327 require.NoError(t, err) 328 gotPaged, gotInfo := entities.PageEntities[*v2.TradeEdge](trades, cursor) 329 330 startCursor := entities.NewCursor(entities.TradeCursor{ 331 SyntheticTime: time.Unix(0, 1000004000000).UTC(), 332 }.String()).Encode() 333 334 endCursor := entities.NewCursor(entities.TradeCursor{ 335 SyntheticTime: time.Unix(0, 1000006000000).UTC(), 336 }.String()).Encode() 337 338 wantPaged := getTradesForward(t, 4, 0) 339 wantInfo := entities.PageInfo{ 340 HasNextPage: false, 341 HasPreviousPage: false, 342 StartCursor: startCursor, 343 EndCursor: endCursor, 344 } 345 assert.Equal(t, wantPaged, gotPaged) 346 assert.Equal(t, wantInfo, gotInfo) 347 } 348 349 func getTradesForward(t *testing.T, start, end int) []entities.Trade { 350 t.Helper() 351 trades := []entities.Trade{ 352 { 353 SyntheticTime: time.Unix(0, 1000000000000).UTC(), 354 }, 355 { 356 SyntheticTime: time.Unix(0, 1000001000000).UTC(), 357 }, 358 { 359 SyntheticTime: time.Unix(0, 1000002000000).UTC(), 360 }, 361 { 362 SyntheticTime: time.Unix(0, 1000003000000).UTC(), 363 }, 364 { 365 SyntheticTime: time.Unix(0, 1000004000000).UTC(), 366 }, 367 { 368 SyntheticTime: time.Unix(0, 1000005000000).UTC(), 369 }, 370 { 371 SyntheticTime: time.Unix(0, 1000006000000).UTC(), 372 }, 373 } 374 375 if end == 0 { 376 end = len(trades) 377 } 378 379 if end < start { 380 end = start 381 } 382 383 return trades[start:end] 384 } 385 386 func getTradesBackward(t *testing.T, start, end int) []entities.Trade { 387 t.Helper() 388 trades := []entities.Trade{ 389 { 390 SyntheticTime: time.Unix(0, 1000006000000).UTC(), 391 }, 392 { 393 SyntheticTime: time.Unix(0, 1000005000000).UTC(), 394 }, 395 { 396 SyntheticTime: time.Unix(0, 1000004000000).UTC(), 397 }, 398 { 399 SyntheticTime: time.Unix(0, 1000003000000).UTC(), 400 }, 401 { 402 SyntheticTime: time.Unix(0, 1000002000000).UTC(), 403 }, 404 { 405 SyntheticTime: time.Unix(0, 1000001000000).UTC(), 406 }, 407 { 408 SyntheticTime: time.Unix(0, 1000000000000).UTC(), 409 }, 410 } 411 412 if end == 0 { 413 end = len(trades) 414 } 415 416 if end < start { 417 end = start 418 } 419 420 return trades[start:end] 421 }