github.com/authzed/spicedb@v1.32.1-0.20240520085336-ebda56537386/pkg/validationfile/blocks/assertions_test.go (about)

     1  package blocks
     2  
     3  import (
     4  	"testing"
     5  
     6  	"github.com/stretchr/testify/require"
     7  	yamlv3 "gopkg.in/yaml.v3"
     8  
     9  	"github.com/authzed/spicedb/pkg/spiceerrors"
    10  	"github.com/authzed/spicedb/pkg/tuple"
    11  )
    12  
    13  func TestParseAssertions(t *testing.T) {
    14  	type testCase struct {
    15  		name               string
    16  		contents           string
    17  		expectedError      string
    18  		expectedAssertions Assertions
    19  	}
    20  
    21  	tests := []testCase{
    22  		{
    23  			"empty",
    24  			"",
    25  			"",
    26  			Assertions{},
    27  		},
    28  		{
    29  			"with one assertion",
    30  			`assertTrue:
    31  - document:foo#view@user:someone`,
    32  			"",
    33  			Assertions{
    34  				AssertTrue: []Assertion{
    35  					{
    36  						"document:foo#view@user:someone",
    37  						tuple.MustToRelationship(tuple.MustParse("document:foo#view@user:someone")),
    38  						nil,
    39  						spiceerrors.SourcePosition{LineNumber: 2, ColumnPosition: 3},
    40  					},
    41  				},
    42  				SourcePosition: spiceerrors.SourcePosition{LineNumber: 1, ColumnPosition: 1},
    43  			},
    44  		},
    45  		{
    46  			"with one assertion per section",
    47  			`assertTrue:
    48  - document:foo#view@user:someone
    49  - document:bar#view@user:sometwo
    50  assertFalse:
    51  - document:foo#write@user:someone`,
    52  			"",
    53  			Assertions{
    54  				AssertTrue: []Assertion{
    55  					{
    56  						"document:foo#view@user:someone",
    57  						tuple.MustToRelationship(tuple.MustParse("document:foo#view@user:someone")),
    58  						nil,
    59  						spiceerrors.SourcePosition{LineNumber: 2, ColumnPosition: 3},
    60  					},
    61  					{
    62  						"document:bar#view@user:sometwo",
    63  						tuple.MustToRelationship(tuple.MustParse("document:bar#view@user:sometwo")),
    64  						nil,
    65  						spiceerrors.SourcePosition{LineNumber: 3, ColumnPosition: 3},
    66  					},
    67  				},
    68  				AssertFalse: []Assertion{
    69  					{
    70  						"document:foo#write@user:someone",
    71  						tuple.MustToRelationship(tuple.MustParse("document:foo#write@user:someone")),
    72  						nil,
    73  						spiceerrors.SourcePosition{LineNumber: 5, ColumnPosition: 3},
    74  					},
    75  				},
    76  				SourcePosition: spiceerrors.SourcePosition{LineNumber: 1, ColumnPosition: 1},
    77  			},
    78  		},
    79  		{
    80  			"with invalid yaml",
    81  			`assertTrue: somethinginvalid
    82  - document:foo#view@user:someone`,
    83  			"yaml: line 1: did not find expected key",
    84  			Assertions{},
    85  		},
    86  		{
    87  			"with garbage",
    88  			`assertTrue:
    89    - document:firstdoc#view@user:tom
    90    - document:firstdoc#view@user:fred
    91    - document:seconddoc#view@user:tom
    92  assertFalse: garbage
    93    - document:seconddoc#view@user:fred`,
    94  			"unexpected value `garbage`",
    95  			Assertions{},
    96  		},
    97  		{
    98  			"with one assertion with context",
    99  			`assertTrue:
   100  - 'document:foo#view@user:someone with {"foo": "bar"}'`,
   101  			"",
   102  			Assertions{
   103  				AssertTrue: []Assertion{
   104  					{
   105  						`document:foo#view@user:someone with {"foo": "bar"}`,
   106  						tuple.MustToRelationship(tuple.MustParse("document:foo#view@user:someone")),
   107  						map[string]any{
   108  							"foo": "bar",
   109  						},
   110  						spiceerrors.SourcePosition{LineNumber: 2, ColumnPosition: 3},
   111  					},
   112  				},
   113  				SourcePosition: spiceerrors.SourcePosition{LineNumber: 1, ColumnPosition: 1},
   114  			},
   115  		},
   116  		{
   117  			"with one assertion with invalid context",
   118  			`assertTrue:
   119  - 'document:foo#view@user:someone with {"foo: "bar"}'`,
   120  			"error parsing caveat context in assertion",
   121  			Assertions{},
   122  		},
   123  		{
   124  			"with one spaced assertion with context",
   125  			`assertTrue:
   126  - '   document:foo#view@user:someone   with   {"foo":     "bar"}   '`,
   127  			"",
   128  			Assertions{
   129  				AssertTrue: []Assertion{
   130  					{
   131  						`   document:foo#view@user:someone   with   {"foo":     "bar"}   `,
   132  						tuple.MustToRelationship(tuple.MustParse("document:foo#view@user:someone")),
   133  						map[string]any{
   134  							"foo": "bar",
   135  						},
   136  						spiceerrors.SourcePosition{LineNumber: 2, ColumnPosition: 3},
   137  					},
   138  				},
   139  				SourcePosition: spiceerrors.SourcePosition{LineNumber: 1, ColumnPosition: 1},
   140  			},
   141  		},
   142  	}
   143  
   144  	for _, tc := range tests {
   145  		tc := tc
   146  		t.Run(tc.name, func(t *testing.T) {
   147  			require := require.New(t)
   148  			a := Assertions{}
   149  			err := yamlv3.Unmarshal([]byte(tc.contents), &a)
   150  			if tc.expectedError != "" {
   151  				require.Contains(err.Error(), tc.expectedError)
   152  			} else {
   153  				require.NoError(err)
   154  				require.Equal(tc.expectedAssertions, a)
   155  			}
   156  		})
   157  	}
   158  }