github.com/authzed/spicedb@v1.32.1-0.20240520085336-ebda56537386/pkg/cursor/cursor_test.go (about)

     1  package cursor
     2  
     3  import (
     4  	"fmt"
     5  	"testing"
     6  
     7  	v1 "github.com/authzed/authzed-go/proto/authzed/api/v1"
     8  	"github.com/stretchr/testify/require"
     9  
    10  	"github.com/authzed/spicedb/internal/datastore/revisions"
    11  	"github.com/authzed/spicedb/pkg/datastore"
    12  	dispatch "github.com/authzed/spicedb/pkg/proto/dispatch/v1"
    13  )
    14  
    15  var (
    16  	revision1 = revisions.NewForTransactionID(1)
    17  	revision2 = revisions.NewForTransactionID(2)
    18  )
    19  
    20  func TestEncodeDecode(t *testing.T) {
    21  	for _, tc := range []struct {
    22  		name     string
    23  		revision datastore.Revision
    24  		sections []string
    25  		hash     string
    26  	}{
    27  		{
    28  			"empty",
    29  			revision1,
    30  			nil,
    31  			"somehash",
    32  		},
    33  		{
    34  			"basic",
    35  			revision1,
    36  			[]string{"a", "b", "c"},
    37  			"another",
    38  		},
    39  		{
    40  			"basic with different revision",
    41  			revision2,
    42  			[]string{"a", "b", "c"},
    43  			"another",
    44  		},
    45  	} {
    46  		tc := tc
    47  		t.Run(tc.name, func(t *testing.T) {
    48  			require := require.New(t)
    49  			encoded, err := EncodeFromDispatchCursor(&dispatch.Cursor{
    50  				Sections: tc.sections,
    51  			}, tc.hash, tc.revision)
    52  			require.NoError(err)
    53  			require.NotNil(encoded)
    54  
    55  			decoded, err := DecodeToDispatchCursor(encoded, tc.hash)
    56  			require.NoError(err)
    57  			require.NotNil(decoded)
    58  
    59  			require.Equal(tc.sections, decoded.Sections)
    60  
    61  			decodedRev, err := DecodeToDispatchRevision(encoded, revisions.CommonDecoder{
    62  				Kind: revisions.TransactionID,
    63  			})
    64  			require.NoError(err)
    65  			require.NotNil(decodedRev)
    66  			require.Equal(tc.revision, decodedRev)
    67  		})
    68  	}
    69  }
    70  
    71  func TestDecode(t *testing.T) {
    72  	for _, testCase := range []struct {
    73  		name             string
    74  		token            string
    75  		expectedRevision datastore.Revision
    76  		expectedSections []string
    77  		expectedHash     string
    78  		expectError      bool
    79  	}{
    80  		{
    81  			name:             "invalid",
    82  			token:            "abc",
    83  			expectedRevision: datastore.NoRevision,
    84  			expectedSections: []string{},
    85  			expectedHash:     "",
    86  			expectError:      true,
    87  		},
    88  		{
    89  			name:             "empty",
    90  			token:            "Cg0KATEaCHNvbWVoYXNo",
    91  			expectedRevision: revision1,
    92  			expectedSections: nil,
    93  			expectedHash:     "somehash",
    94  			expectError:      false,
    95  		},
    96  		{
    97  			name:             "basic",
    98  			token:            "ChUKATESAWESAWISAWMaB2Fub3RoZXI=",
    99  			expectedRevision: revision1,
   100  			expectedSections: []string{"a", "b", "c"},
   101  			expectedHash:     "another",
   102  			expectError:      false,
   103  		},
   104  		{
   105  			name:             "basic with wrong hash",
   106  			token:            "ChUKATESAWESAWISAWMaB2Fub3RoZXI=",
   107  			expectedRevision: revision1,
   108  			expectedSections: []string{"a", "b", "c"},
   109  			expectedHash:     "wrong",
   110  			expectError:      true,
   111  		},
   112  		{
   113  			name:             "basic with different revision",
   114  			token:            "ChUKATISAWESAWISAWMaB2Fub3RoZXI=",
   115  			expectedRevision: revision2,
   116  			expectedSections: []string{"a", "b", "c"},
   117  			expectedHash:     "another",
   118  			expectError:      false,
   119  		},
   120  	} {
   121  		testCase := testCase
   122  		testName := fmt.Sprintf("%s(%s)=>%s", testCase.name, testCase.token, testCase.expectedRevision)
   123  		t.Run(testName, func(t *testing.T) {
   124  			require := require.New(t)
   125  
   126  			decoded, err := DecodeToDispatchCursor(&v1.Cursor{
   127  				Token: testCase.token,
   128  			}, testCase.expectedHash)
   129  
   130  			if testCase.expectError {
   131  				require.Error(err)
   132  				return
   133  			}
   134  
   135  			require.NoError(err)
   136  			require.NotNil(decoded)
   137  			require.Equal(testCase.expectedSections, decoded.Sections)
   138  
   139  			decodedRev, err := DecodeToDispatchRevision(&v1.Cursor{
   140  				Token: testCase.token,
   141  			}, revisions.CommonDecoder{
   142  				Kind: revisions.TransactionID,
   143  			})
   144  
   145  			require.NoError(err)
   146  			require.True(
   147  				testCase.expectedRevision.Equal(decodedRev),
   148  				"%s != %s",
   149  				testCase.expectedRevision,
   150  				decodedRev,
   151  			)
   152  		})
   153  	}
   154  }