code.vegaprotocol.io/vega@v0.79.0/datanode/sqlstore/delegations_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 sqlstore_test
    17  
    18  import (
    19  	"context"
    20  	"testing"
    21  	"time"
    22  
    23  	"code.vegaprotocol.io/vega/datanode/entities"
    24  	"code.vegaprotocol.io/vega/datanode/sqlstore"
    25  
    26  	"github.com/google/go-cmp/cmp"
    27  	"github.com/google/go-cmp/cmp/cmpopts"
    28  	"github.com/shopspring/decimal"
    29  	"github.com/stretchr/testify/assert"
    30  	"github.com/stretchr/testify/require"
    31  )
    32  
    33  func addTestDelegation(t *testing.T, ctx context.Context, ds *sqlstore.Delegations,
    34  	party entities.Party,
    35  	node entities.Node,
    36  	epochID int64,
    37  	block entities.Block, seqNum uint64,
    38  ) entities.Delegation {
    39  	t.Helper()
    40  	r := entities.Delegation{
    41  		PartyID:  party.ID,
    42  		NodeID:   node.ID,
    43  		EpochID:  epochID,
    44  		Amount:   decimal.NewFromInt(100),
    45  		VegaTime: block.VegaTime,
    46  		SeqNum:   seqNum,
    47  		TxHash:   generateTxHash(),
    48  	}
    49  	err := ds.Add(ctx, r)
    50  	require.NoError(t, err)
    51  	return r
    52  }
    53  
    54  func delegationLessThan(x, y entities.Delegation) bool {
    55  	if x.EpochID != y.EpochID {
    56  		return x.EpochID < y.EpochID
    57  	}
    58  	if x.PartyID.String() != y.PartyID.String() {
    59  		return x.PartyID.String() < y.PartyID.String()
    60  	}
    61  	if x.NodeID.String() != y.NodeID.String() {
    62  		return x.NodeID.String() < y.NodeID.String()
    63  	}
    64  	return x.Amount.LessThan(y.Amount)
    65  }
    66  
    67  func assertDelegationsMatch(t *testing.T, expected, actual []entities.Delegation) {
    68  	t.Helper()
    69  	assert.Empty(t, cmp.Diff(expected, actual, cmpopts.SortSlices(delegationLessThan)))
    70  }
    71  
    72  func TestDelegations(t *testing.T) {
    73  	ctx := tempTransaction(t)
    74  
    75  	ps := sqlstore.NewParties(connectionSource)
    76  	ds := sqlstore.NewDelegations(connectionSource)
    77  	bs := sqlstore.NewBlocks(connectionSource)
    78  	ns := sqlstore.NewNode(connectionSource)
    79  	block := addTestBlock(t, ctx, bs)
    80  
    81  	node1 := addTestNode(t, ctx, ns, block, GenerateID())
    82  	node2 := addTestNode(t, ctx, ns, block, GenerateID())
    83  
    84  	node1ID := node1.ID.String()
    85  	node2ID := node2.ID.String()
    86  
    87  	party1 := addTestParty(t, ctx, ps, block)
    88  	party2 := addTestParty(t, ctx, ps, block)
    89  
    90  	party1ID := party1.ID.String()
    91  	party2ID := party2.ID.String()
    92  
    93  	delegation1 := addTestDelegation(t, ctx, ds, party1, node1, 1, block, 0)
    94  	delegation2 := addTestDelegation(t, ctx, ds, party1, node2, 2, block, 1)
    95  	delegation3 := addTestDelegation(t, ctx, ds, party2, node1, 3, block, 2)
    96  	delegation4 := addTestDelegation(t, ctx, ds, party2, node2, 4, block, 3)
    97  	delegation5 := addTestDelegation(t, ctx, ds, party2, node2, 5, block, 4)
    98  
    99  	t.Run("GetAll", func(t *testing.T) {
   100  		expected := []entities.Delegation{delegation1, delegation2, delegation3, delegation4, delegation5}
   101  		actual, err := ds.GetAll(ctx)
   102  		require.NoError(t, err)
   103  		assertDelegationsMatch(t, expected, actual)
   104  	})
   105  
   106  	t.Run("GetByTxHash", func(t *testing.T) {
   107  		expected := []entities.Delegation{delegation1}
   108  		actual, err := ds.GetByTxHash(ctx, delegation1.TxHash)
   109  		require.NoError(t, err)
   110  		assertDelegationsMatch(t, expected, actual)
   111  
   112  		expected = []entities.Delegation{delegation2}
   113  		actual, err = ds.GetByTxHash(ctx, delegation2.TxHash)
   114  		require.NoError(t, err)
   115  		assertDelegationsMatch(t, expected, actual)
   116  	})
   117  
   118  	t.Run("GetByParty", func(t *testing.T) {
   119  		expected := []entities.Delegation{delegation1, delegation2}
   120  		actual, _, err := ds.Get(ctx, &party1ID, nil, nil, nil)
   121  		require.NoError(t, err)
   122  		assertDelegationsMatch(t, expected, actual)
   123  	})
   124  
   125  	t.Run("GetByNode", func(t *testing.T) {
   126  		expected := []entities.Delegation{delegation1, delegation3}
   127  		actual, _, err := ds.Get(ctx, nil, &node1ID, nil, nil)
   128  		require.NoError(t, err)
   129  		assertDelegationsMatch(t, expected, actual)
   130  	})
   131  
   132  	t.Run("GetByEpoch", func(t *testing.T) {
   133  		expected := []entities.Delegation{delegation4}
   134  		four := int64(4)
   135  		actual, _, err := ds.Get(ctx, nil, nil, &four, nil)
   136  		require.NoError(t, err)
   137  		assertDelegationsMatch(t, expected, actual)
   138  	})
   139  
   140  	t.Run("GetByPartyAndNode", func(t *testing.T) {
   141  		expected := []entities.Delegation{delegation4, delegation5}
   142  		actual, _, err := ds.Get(ctx, &party2ID, &node2ID, nil, nil)
   143  		require.NoError(t, err)
   144  		assertDelegationsMatch(t, expected, actual)
   145  	})
   146  
   147  	t.Run("GetByPartyAndNodeAndEpoch", func(t *testing.T) {
   148  		expected := []entities.Delegation{delegation4}
   149  		four := int64(4)
   150  		actual, _, err := ds.Get(ctx, &party2ID, &node2ID, &four, nil)
   151  		require.NoError(t, err)
   152  		assertDelegationsMatch(t, expected, actual)
   153  	})
   154  }
   155  
   156  func TestDelegationPagination(t *testing.T) {
   157  	t.Run("Should return all delegations if no filter or pagination is provided", testDelegationPaginationNoFilterNoPagination)
   158  	t.Run("Should return the first page if no filter but first is provided", testDelegationPaginationNoFilterFirstPage)
   159  	t.Run("Should return the request page if no filter but first after is provided", testDelegationPaginationNoFilterFirstAfterPage)
   160  	t.Run("Should return the last page if no filter but last is provided", testDelegationPaginationNoFilterLastPage)
   161  	t.Run("Should return the request page if no filter but last before is provided", testDelegationPaginationNoFilterLastBeforePage)
   162  
   163  	t.Run("Should return all delegations if no filter or pagination is provided - newest first", testDelegationPaginationNoFilterNoPaginationNewestFirst)
   164  	t.Run("Should return the first page if no filter but first is provided - newest first", testDelegationPaginationNoFilterFirstPageNewestFirst)
   165  	t.Run("Should return the request page if no filter but first after is provided - newest first", testDelegationPaginationNoFilterFirstAfterPageNewestFirst)
   166  	t.Run("Should return the last page if no filter but last is provided - newest first", testDelegationPaginationNoFilterLastPageNewestFirst)
   167  	t.Run("Should return the request page if no filter but last before is provided - newest first", testDelegationPaginationNoFilterLastBeforePageNewestFirst)
   168  
   169  	t.Run("Should return all delegations if party filter is provided and pagination not provided", testDelegationPaginationPartyFilterNoPagination)
   170  	t.Run("Should return the first page if party filter and first is provided", testDelegationPaginationPartyFilterFirstPage)
   171  	t.Run("Should return the request page if party filter and first after is provided", testDelegationPaginationPartyFilterFirstAfterPage)
   172  	t.Run("Should return the last page if party filter and last is provided", testDelegationPaginationPartyFilterLastPage)
   173  	t.Run("Should return the request page if party filter and last before is provided", testDelegationPaginationPartyFilterLastBeforePage)
   174  
   175  	t.Run("Should return all delegations if party/node filter is provided and pagination not provided", testDelegationPaginationPartyNodeFilterNoPagination)
   176  	t.Run("Should return the first page if party/node filter and first is provided", testDelegationPaginationPartyNodeFilterFirstPage)
   177  	t.Run("Should return the request page if party/node filter and first after is provided", testDelegationPaginationPartyNodeFilterFirstAfterPage)
   178  	t.Run("Should return the last page if party/node filter and last is provided", testDelegationPaginationPartyNodeFilterLastPage)
   179  	t.Run("Should return the request page if party/node filter and last before is provided", testDelegationPaginationPartyNodeFilterLastBeforePage)
   180  }
   181  
   182  func testDelegationPaginationNoFilterNoPagination(t *testing.T) {
   183  	ctx := tempTransaction(t)
   184  
   185  	ds, delegations, _, _ := setupPaginatedDelegationsTests(t, ctx)
   186  	pagination, err := entities.NewCursorPagination(nil, nil, nil, nil, false)
   187  	require.NoError(t, err)
   188  
   189  	got, pageInfo, err := ds.Get(ctx, nil, nil, nil, pagination)
   190  	require.NoError(t, err)
   191  
   192  	want := delegations[:]
   193  	assert.Equal(t, want, got)
   194  	assert.Equal(t, entities.PageInfo{
   195  		HasNextPage:     false,
   196  		HasPreviousPage: false,
   197  		StartCursor:     delegations[0].Cursor().Encode(),
   198  		EndCursor:       delegations[19].Cursor().Encode(),
   199  	}, pageInfo)
   200  }
   201  
   202  func testDelegationPaginationNoFilterFirstPage(t *testing.T) {
   203  	ctx := tempTransaction(t)
   204  
   205  	ds, delegations, _, _ := setupPaginatedDelegationsTests(t, ctx)
   206  	first := int32(3)
   207  	pagination, err := entities.NewCursorPagination(&first, nil, nil, nil, false)
   208  	require.NoError(t, err)
   209  
   210  	got, pageInfo, err := ds.Get(ctx, nil, nil, nil, pagination)
   211  	require.NoError(t, err)
   212  
   213  	want := delegations[:3]
   214  	assert.Equal(t, want, got)
   215  	assert.Equal(t, entities.PageInfo{
   216  		HasNextPage:     true,
   217  		HasPreviousPage: false,
   218  		StartCursor:     delegations[0].Cursor().Encode(),
   219  		EndCursor:       delegations[2].Cursor().Encode(),
   220  	}, pageInfo)
   221  }
   222  
   223  func testDelegationPaginationNoFilterFirstAfterPage(t *testing.T) {
   224  	ctx := tempTransaction(t)
   225  
   226  	ds, delegations, _, _ := setupPaginatedDelegationsTests(t, ctx)
   227  	first := int32(3)
   228  	after := delegations[2].Cursor().Encode()
   229  	pagination, err := entities.NewCursorPagination(&first, &after, nil, nil, false)
   230  	require.NoError(t, err)
   231  
   232  	got, pageInfo, err := ds.Get(ctx, nil, nil, nil, pagination)
   233  	require.NoError(t, err)
   234  
   235  	want := delegations[3:6]
   236  	assert.Equal(t, want, got)
   237  	assert.Equal(t, entities.PageInfo{
   238  		HasNextPage:     true,
   239  		HasPreviousPage: true,
   240  		StartCursor:     delegations[3].Cursor().Encode(),
   241  		EndCursor:       delegations[5].Cursor().Encode(),
   242  	}, pageInfo)
   243  }
   244  
   245  func testDelegationPaginationNoFilterLastPage(t *testing.T) {
   246  	ctx := tempTransaction(t)
   247  
   248  	ds, delegations, _, _ := setupPaginatedDelegationsTests(t, ctx)
   249  	last := int32(3)
   250  	pagination, err := entities.NewCursorPagination(nil, nil, &last, nil, false)
   251  	require.NoError(t, err)
   252  
   253  	got, pageInfo, err := ds.Get(ctx, nil, nil, nil, pagination)
   254  	require.NoError(t, err)
   255  
   256  	want := delegations[17:]
   257  	assert.Equal(t, want, got)
   258  	assert.Equal(t, entities.PageInfo{
   259  		HasNextPage:     false,
   260  		HasPreviousPage: true,
   261  		StartCursor:     delegations[17].Cursor().Encode(),
   262  		EndCursor:       delegations[19].Cursor().Encode(),
   263  	}, pageInfo)
   264  }
   265  
   266  func testDelegationPaginationNoFilterLastBeforePage(t *testing.T) {
   267  	ctx := tempTransaction(t)
   268  
   269  	ds, delegations, _, _ := setupPaginatedDelegationsTests(t, ctx)
   270  	last := int32(3)
   271  	before := delegations[17].Cursor().Encode()
   272  	pagination, err := entities.NewCursorPagination(nil, nil, &last, &before, false)
   273  	require.NoError(t, err)
   274  
   275  	got, pageInfo, err := ds.Get(ctx, nil, nil, nil, pagination)
   276  	require.NoError(t, err)
   277  
   278  	want := delegations[14:17]
   279  	assert.Equal(t, want, got)
   280  	assert.Equal(t, entities.PageInfo{
   281  		HasNextPage:     true,
   282  		HasPreviousPage: true,
   283  		StartCursor:     delegations[14].Cursor().Encode(),
   284  		EndCursor:       delegations[16].Cursor().Encode(),
   285  	}, pageInfo)
   286  }
   287  
   288  func testDelegationPaginationNoFilterNoPaginationNewestFirst(t *testing.T) {
   289  	ctx := tempTransaction(t)
   290  
   291  	ds, delegations, _, _ := setupPaginatedDelegationsTests(t, ctx)
   292  	pagination, err := entities.NewCursorPagination(nil, nil, nil, nil, true)
   293  	require.NoError(t, err)
   294  
   295  	got, pageInfo, err := ds.Get(ctx, nil, nil, nil, pagination)
   296  	require.NoError(t, err)
   297  
   298  	delegations = entities.ReverseSlice(delegations)
   299  	want := delegations[:]
   300  	assert.Equal(t, want, got)
   301  	assert.Equal(t, entities.PageInfo{
   302  		HasNextPage:     false,
   303  		HasPreviousPage: false,
   304  		StartCursor:     delegations[0].Cursor().Encode(),
   305  		EndCursor:       delegations[19].Cursor().Encode(),
   306  	}, pageInfo)
   307  }
   308  
   309  func testDelegationPaginationNoFilterFirstPageNewestFirst(t *testing.T) {
   310  	ctx := tempTransaction(t)
   311  
   312  	ds, delegations, _, _ := setupPaginatedDelegationsTests(t, ctx)
   313  	delegations = entities.ReverseSlice(delegations)
   314  	first := int32(3)
   315  	pagination, err := entities.NewCursorPagination(&first, nil, nil, nil, true)
   316  	require.NoError(t, err)
   317  
   318  	got, pageInfo, err := ds.Get(ctx, nil, nil, nil, pagination)
   319  	require.NoError(t, err)
   320  
   321  	want := delegations[:3]
   322  	assert.Equal(t, want, got)
   323  	assert.Equal(t, entities.PageInfo{
   324  		HasNextPage:     true,
   325  		HasPreviousPage: false,
   326  		StartCursor:     delegations[0].Cursor().Encode(),
   327  		EndCursor:       delegations[2].Cursor().Encode(),
   328  	}, pageInfo)
   329  }
   330  
   331  func testDelegationPaginationNoFilterFirstAfterPageNewestFirst(t *testing.T) {
   332  	ctx := tempTransaction(t)
   333  
   334  	ds, delegations, _, _ := setupPaginatedDelegationsTests(t, ctx)
   335  	delegations = entities.ReverseSlice(delegations)
   336  	first := int32(3)
   337  	after := delegations[2].Cursor().Encode()
   338  	pagination, err := entities.NewCursorPagination(&first, &after, nil, nil, true)
   339  	require.NoError(t, err)
   340  
   341  	got, pageInfo, err := ds.Get(ctx, nil, nil, nil, pagination)
   342  	require.NoError(t, err)
   343  
   344  	want := delegations[3:6]
   345  	assert.Equal(t, want, got)
   346  	assert.Equal(t, entities.PageInfo{
   347  		HasNextPage:     true,
   348  		HasPreviousPage: true,
   349  		StartCursor:     delegations[3].Cursor().Encode(),
   350  		EndCursor:       delegations[5].Cursor().Encode(),
   351  	}, pageInfo)
   352  }
   353  
   354  func testDelegationPaginationNoFilterLastPageNewestFirst(t *testing.T) {
   355  	ctx := tempTransaction(t)
   356  
   357  	ds, delegations, _, _ := setupPaginatedDelegationsTests(t, ctx)
   358  	delegations = entities.ReverseSlice(delegations)
   359  	last := int32(3)
   360  	pagination, err := entities.NewCursorPagination(nil, nil, &last, nil, true)
   361  	require.NoError(t, err)
   362  
   363  	got, pageInfo, err := ds.Get(ctx, nil, nil, nil, pagination)
   364  	require.NoError(t, err)
   365  
   366  	want := delegations[17:]
   367  	assert.Equal(t, want, got)
   368  	assert.Equal(t, entities.PageInfo{
   369  		HasNextPage:     false,
   370  		HasPreviousPage: true,
   371  		StartCursor:     delegations[17].Cursor().Encode(),
   372  		EndCursor:       delegations[19].Cursor().Encode(),
   373  	}, pageInfo)
   374  }
   375  
   376  func testDelegationPaginationNoFilterLastBeforePageNewestFirst(t *testing.T) {
   377  	ctx := tempTransaction(t)
   378  
   379  	ds, delegations, _, _ := setupPaginatedDelegationsTests(t, ctx)
   380  	delegations = entities.ReverseSlice(delegations)
   381  	last := int32(3)
   382  	before := delegations[17].Cursor().Encode()
   383  	pagination, err := entities.NewCursorPagination(nil, nil, &last, &before, true)
   384  	require.NoError(t, err)
   385  
   386  	got, pageInfo, err := ds.Get(ctx, nil, nil, nil, pagination)
   387  	require.NoError(t, err)
   388  
   389  	want := delegations[14:17]
   390  	assert.Equal(t, want, got)
   391  	assert.Equal(t, entities.PageInfo{
   392  		HasNextPage:     true,
   393  		HasPreviousPage: true,
   394  		StartCursor:     delegations[14].Cursor().Encode(),
   395  		EndCursor:       delegations[16].Cursor().Encode(),
   396  	}, pageInfo)
   397  }
   398  
   399  func testDelegationPaginationPartyFilterNoPagination(t *testing.T) {
   400  	ctx := tempTransaction(t)
   401  
   402  	ds, delegations, parties, _ := setupPaginatedDelegationsTests(t, ctx)
   403  	pagination, err := entities.NewCursorPagination(nil, nil, nil, nil, false)
   404  	require.NoError(t, err)
   405  	partyID := parties[0].ID.String()
   406  	got, pageInfo, err := ds.Get(ctx, &partyID, nil, nil, pagination)
   407  	require.NoError(t, err)
   408  
   409  	want := delegations[0:10]
   410  	assert.Equal(t, want, got)
   411  	assert.Equal(t, entities.PageInfo{
   412  		HasNextPage:     false,
   413  		HasPreviousPage: false,
   414  		StartCursor:     delegations[0].Cursor().Encode(),
   415  		EndCursor:       delegations[9].Cursor().Encode(),
   416  	}, pageInfo)
   417  }
   418  
   419  func testDelegationPaginationPartyFilterFirstPage(t *testing.T) {
   420  	ctx := tempTransaction(t)
   421  
   422  	ds, delegations, parties, _ := setupPaginatedDelegationsTests(t, ctx)
   423  	first := int32(3)
   424  	pagination, err := entities.NewCursorPagination(&first, nil, nil, nil, false)
   425  	require.NoError(t, err)
   426  	partyID := parties[0].ID.String()
   427  	got, pageInfo, err := ds.Get(ctx, &partyID, nil, nil, pagination)
   428  	require.NoError(t, err)
   429  
   430  	want := delegations[0:3]
   431  	assert.Equal(t, want, got)
   432  	assert.Equal(t, entities.PageInfo{
   433  		HasNextPage:     true,
   434  		HasPreviousPage: false,
   435  		StartCursor:     delegations[0].Cursor().Encode(),
   436  		EndCursor:       delegations[2].Cursor().Encode(),
   437  	}, pageInfo)
   438  }
   439  
   440  func testDelegationPaginationPartyFilterFirstAfterPage(t *testing.T) {
   441  	ctx := tempTransaction(t)
   442  
   443  	ds, delegations, parties, _ := setupPaginatedDelegationsTests(t, ctx)
   444  	first := int32(3)
   445  	after := delegations[2].Cursor().Encode()
   446  	pagination, err := entities.NewCursorPagination(&first, &after, nil, nil, false)
   447  	require.NoError(t, err)
   448  	partyID := parties[0].ID.String()
   449  	got, pageInfo, err := ds.Get(ctx, &partyID, nil, nil, pagination)
   450  	require.NoError(t, err)
   451  
   452  	want := delegations[3:6]
   453  	assert.Equal(t, want, got)
   454  	assert.Equal(t, entities.PageInfo{
   455  		HasNextPage:     true,
   456  		HasPreviousPage: true,
   457  		StartCursor:     delegations[3].Cursor().Encode(),
   458  		EndCursor:       delegations[5].Cursor().Encode(),
   459  	}, pageInfo)
   460  }
   461  
   462  func testDelegationPaginationPartyFilterLastPage(t *testing.T) {
   463  	ctx := tempTransaction(t)
   464  
   465  	ds, delegations, parties, _ := setupPaginatedDelegationsTests(t, ctx)
   466  	last := int32(3)
   467  	pagination, err := entities.NewCursorPagination(nil, nil, &last, nil, false)
   468  	require.NoError(t, err)
   469  	partyID := parties[0].ID.String()
   470  	got, pageInfo, err := ds.Get(ctx, &partyID, nil, nil, pagination)
   471  	require.NoError(t, err)
   472  
   473  	want := delegations[7:10]
   474  	assert.Equal(t, want, got)
   475  	assert.Equal(t, entities.PageInfo{
   476  		HasNextPage:     false,
   477  		HasPreviousPage: true,
   478  		StartCursor:     delegations[7].Cursor().Encode(),
   479  		EndCursor:       delegations[9].Cursor().Encode(),
   480  	}, pageInfo)
   481  }
   482  
   483  func testDelegationPaginationPartyFilterLastBeforePage(t *testing.T) {
   484  	ctx := tempTransaction(t)
   485  
   486  	ds, delegations, parties, _ := setupPaginatedDelegationsTests(t, ctx)
   487  	last := int32(3)
   488  	before := delegations[7].Cursor().Encode()
   489  	pagination, err := entities.NewCursorPagination(nil, nil, &last, &before, false)
   490  	require.NoError(t, err)
   491  	partyID := parties[0].ID.String()
   492  	got, pageInfo, err := ds.Get(ctx, &partyID, nil, nil, pagination)
   493  	require.NoError(t, err)
   494  
   495  	want := delegations[4:7]
   496  	assert.Equal(t, want, got)
   497  	assert.Equal(t, entities.PageInfo{
   498  		HasNextPage:     true,
   499  		HasPreviousPage: true,
   500  		StartCursor:     delegations[4].Cursor().Encode(),
   501  		EndCursor:       delegations[6].Cursor().Encode(),
   502  	}, pageInfo)
   503  }
   504  
   505  func testDelegationPaginationPartyNodeFilterNoPagination(t *testing.T) {
   506  	ctx := tempTransaction(t)
   507  
   508  	ds, delegations, parties, nodes := setupPaginatedDelegationsTests(t, ctx)
   509  	pagination, err := entities.NewCursorPagination(nil, nil, nil, nil, false)
   510  	require.NoError(t, err)
   511  	partyID := parties[1].ID.String()
   512  	nodeID := nodes[1].ID.String()
   513  	got, pageInfo, err := ds.Get(ctx, &partyID, &nodeID, nil, pagination)
   514  	require.NoError(t, err)
   515  
   516  	want := delegations[10:]
   517  	assert.Equal(t, want, got)
   518  	assert.Equal(t, entities.PageInfo{
   519  		HasNextPage:     false,
   520  		HasPreviousPage: false,
   521  		StartCursor:     delegations[10].Cursor().Encode(),
   522  		EndCursor:       delegations[19].Cursor().Encode(),
   523  	}, pageInfo)
   524  }
   525  
   526  func testDelegationPaginationPartyNodeFilterFirstPage(t *testing.T) {
   527  	ctx := tempTransaction(t)
   528  
   529  	ds, delegations, parties, nodes := setupPaginatedDelegationsTests(t, ctx)
   530  	first := int32(3)
   531  	pagination, err := entities.NewCursorPagination(&first, nil, nil, nil, false)
   532  	require.NoError(t, err)
   533  	partyID := parties[1].ID.String()
   534  	nodeID := nodes[1].ID.String()
   535  	got, pageInfo, err := ds.Get(ctx, &partyID, &nodeID, nil, pagination)
   536  	require.NoError(t, err)
   537  
   538  	want := delegations[10:13]
   539  	assert.Equal(t, want, got)
   540  	assert.Equal(t, entities.PageInfo{
   541  		HasNextPage:     true,
   542  		HasPreviousPage: false,
   543  		StartCursor:     delegations[10].Cursor().Encode(),
   544  		EndCursor:       delegations[12].Cursor().Encode(),
   545  	}, pageInfo)
   546  }
   547  
   548  func testDelegationPaginationPartyNodeFilterFirstAfterPage(t *testing.T) {
   549  	ctx := tempTransaction(t)
   550  
   551  	ds, delegations, parties, nodes := setupPaginatedDelegationsTests(t, ctx)
   552  	first := int32(3)
   553  	after := delegations[12].Cursor().Encode()
   554  	pagination, err := entities.NewCursorPagination(&first, &after, nil, nil, false)
   555  	require.NoError(t, err)
   556  	partyID := parties[1].ID.String()
   557  	nodeID := nodes[1].ID.String()
   558  	got, pageInfo, err := ds.Get(ctx, &partyID, &nodeID, nil, pagination)
   559  	require.NoError(t, err)
   560  
   561  	want := delegations[13:16]
   562  	assert.Equal(t, want, got)
   563  	assert.Equal(t, entities.PageInfo{
   564  		HasNextPage:     true,
   565  		HasPreviousPage: true,
   566  		StartCursor:     delegations[13].Cursor().Encode(),
   567  		EndCursor:       delegations[15].Cursor().Encode(),
   568  	}, pageInfo)
   569  }
   570  
   571  func testDelegationPaginationPartyNodeFilterLastPage(t *testing.T) {
   572  	ctx := tempTransaction(t)
   573  
   574  	ds, delegations, parties, nodes := setupPaginatedDelegationsTests(t, ctx)
   575  	last := int32(3)
   576  	pagination, err := entities.NewCursorPagination(nil, nil, &last, nil, false)
   577  	require.NoError(t, err)
   578  	partyID := parties[1].ID.String()
   579  	nodeID := nodes[1].ID.String()
   580  	got, pageInfo, err := ds.Get(ctx, &partyID, &nodeID, nil, pagination)
   581  	require.NoError(t, err)
   582  
   583  	want := delegations[17:]
   584  	assert.Equal(t, want, got)
   585  	assert.Equal(t, entities.PageInfo{
   586  		HasNextPage:     false,
   587  		HasPreviousPage: true,
   588  		StartCursor:     delegations[17].Cursor().Encode(),
   589  		EndCursor:       delegations[19].Cursor().Encode(),
   590  	}, pageInfo)
   591  }
   592  
   593  func testDelegationPaginationPartyNodeFilterLastBeforePage(t *testing.T) {
   594  	ctx := tempTransaction(t)
   595  
   596  	ds, delegations, parties, nodes := setupPaginatedDelegationsTests(t, ctx)
   597  	last := int32(3)
   598  	before := delegations[17].Cursor().Encode()
   599  	pagination, err := entities.NewCursorPagination(nil, nil, &last, &before, false)
   600  	require.NoError(t, err)
   601  	partyID := parties[1].ID.String()
   602  	nodeID := nodes[1].ID.String()
   603  	got, pageInfo, err := ds.Get(ctx, &partyID, &nodeID, nil, pagination)
   604  	require.NoError(t, err)
   605  
   606  	want := delegations[14:17]
   607  	assert.Equal(t, want, got)
   608  	assert.Equal(t, entities.PageInfo{
   609  		HasNextPage:     true,
   610  		HasPreviousPage: true,
   611  		StartCursor:     delegations[14].Cursor().Encode(),
   612  		EndCursor:       delegations[16].Cursor().Encode(),
   613  	}, pageInfo)
   614  }
   615  
   616  func setupPaginatedDelegationsTests(t *testing.T, ctx context.Context) (*sqlstore.Delegations,
   617  	[]entities.Delegation, []entities.Party, []entities.Node,
   618  ) {
   619  	t.Helper()
   620  	ps := sqlstore.NewParties(connectionSource)
   621  	ns := sqlstore.NewNode(connectionSource)
   622  	bs := sqlstore.NewBlocks(connectionSource)
   623  	ds := sqlstore.NewDelegations(connectionSource)
   624  
   625  	delegations := make([]entities.Delegation, 0)
   626  
   627  	blockTime := time.Date(2022, 7, 15, 8, 0, 0, 0, time.Local)
   628  	block := addTestBlockForTime(t, ctx, bs, blockTime)
   629  
   630  	nodes := []entities.Node{
   631  		addTestNode(t, ctx, ns, block, GenerateID()),
   632  		addTestNode(t, ctx, ns, block, GenerateID()),
   633  	}
   634  
   635  	parties := []entities.Party{
   636  		addTestParty(t, ctx, ps, block),
   637  		addTestParty(t, ctx, ps, block),
   638  	}
   639  
   640  	for i := 0; i < 2; i++ {
   641  		for j := 0; j < 10; j++ {
   642  			blockTime = blockTime.Add(time.Minute)
   643  			block = addTestBlockForTime(t, ctx, bs, blockTime)
   644  			delegations = append(delegations, addTestDelegation(t, ctx, ds, parties[i], nodes[i], int64((i*10)+j), block, 0))
   645  		}
   646  	}
   647  
   648  	return ds, delegations, parties, nodes
   649  }