github.com/authzed/spicedb@v1.32.1-0.20240520085336-ebda56537386/pkg/validationfile/fileformat_test.go (about) 1 package validationfile 2 3 import ( 4 "testing" 5 6 "github.com/stretchr/testify/require" 7 8 "github.com/authzed/spicedb/pkg/spiceerrors" 9 ) 10 11 func TestDecodeValidationFile(t *testing.T) { 12 tests := []struct { 13 name string 14 contents string 15 expectedError string 16 expectedRelCount int 17 expectedAssertTrueCount int 18 expectedAssertFalseCount int 19 expectedValidationCount int 20 }{ 21 { 22 name: "empty", 23 contents: "", 24 expectedError: "", 25 expectedRelCount: 0, 26 expectedAssertTrueCount: 0, 27 expectedAssertFalseCount: 0, 28 expectedValidationCount: 0, 29 }, 30 { 31 name: "invalid schema", 32 contents: `schema: 33 foo: 34 - asdasd`, 35 expectedError: "yaml: line 3: found character that cannot start any token", 36 expectedRelCount: 0, 37 expectedAssertTrueCount: 0, 38 expectedAssertFalseCount: 0, 39 expectedValidationCount: 0, 40 }, 41 { 42 name: "valid", 43 contents: ` 44 schema: >- 45 definition user {} 46 definition document { 47 relation writer: user 48 relation reader: user 49 permission edit = writer 50 permission view = reader + edit 51 } 52 53 relationships: >- 54 document:firstdoc#writer@user:tom 55 56 document:firstdoc#reader@user:fred 57 58 document:seconddoc#reader@user:tom 59 60 assertions: 61 assertTrue: 62 - document:firstdoc#view@user:tom 63 - document:firstdoc#view@user:fred 64 - document:seconddoc#view@user:tom 65 assertFalse: 66 - document:seconddoc#view@user:fred 67 68 validation: 69 document:firstdoc#view: 70 - "[user:tom] is <document:firstdoc#writer>" 71 - "[user:fred] is <document:firstdoc#reader>" 72 document:seconddoc#view: 73 - "[user:tom] is <document:seconddoc#reader>" 74 `, 75 expectedError: "", 76 expectedRelCount: 3, 77 expectedAssertTrueCount: 3, 78 expectedAssertFalseCount: 1, 79 expectedValidationCount: 2, 80 }, 81 } 82 83 for _, tt := range tests { 84 tt := tt 85 t.Run(tt.name, func(t *testing.T) { 86 decoded, err := DecodeValidationFile([]byte(tt.contents)) 87 if tt.expectedError != "" { 88 require.NotNil(t, err) 89 require.Equal(t, err.Error(), tt.expectedError) 90 } else { 91 require.Nil(t, err) 92 93 require.NotNil(t, decoded) 94 require.Equal(t, len(decoded.Relationships.Relationships), tt.expectedRelCount) 95 96 require.Equal(t, len(decoded.Assertions.AssertTrue), tt.expectedAssertTrueCount) 97 require.Equal(t, len(decoded.Assertions.AssertFalse), tt.expectedAssertFalseCount) 98 require.Equal(t, len(decoded.ExpectedRelations.ValidationMap), tt.expectedValidationCount) 99 } 100 }) 101 } 102 } 103 104 func TestDecodeRelationshipsErrorLineNumber(t *testing.T) { 105 _, err := DecodeValidationFile([]byte(`schema: >- 106 definition user {} 107 108 relationships: >- 109 document:firstdocwriter@user:tom 110 111 document:firstdoc#reader#user:fred 112 `)) 113 114 errWithSource, ok := spiceerrors.AsErrorWithSource(err) 115 require.True(t, ok) 116 117 require.Equal(t, err.Error(), "error parsing relationship `document:firstdocwriter@user:tom`") 118 require.Equal(t, uint64(5), errWithSource.LineNumber) 119 } 120 121 func TestDecodeRelationshipsErrorLineNumberLater(t *testing.T) { 122 _, err := DecodeValidationFile([]byte(`schema: >- 123 definition user {} 124 125 relationships: >- 126 document:firstdoc#writer@user:tom 127 128 document:firstdoc#readeruser:fred 129 `)) 130 131 errWithSource, ok := spiceerrors.AsErrorWithSource(err) 132 require.True(t, ok) 133 134 require.Equal(t, err.Error(), "error parsing relationship `document:firstdoc#readeruser:fred`") 135 require.Equal(t, uint64(7), errWithSource.LineNumber) 136 } 137 138 func TestDecodeRelationshipsErrorLineNumberEventLater(t *testing.T) { 139 _, err := DecodeValidationFile([]byte(`schema: >- 140 definition user {} 141 142 relationships: >- 143 document:firstdoc#writer@user:tom1 144 145 document:firstdoc#writer@user:tom2 146 147 document:firstdoc#writer@user:tom3 148 149 document:firstdoc#writer@user:tom4 150 151 document:firstdoc#readeruser:fred 152 `)) 153 154 errWithSource, ok := spiceerrors.AsErrorWithSource(err) 155 require.True(t, ok) 156 157 require.Equal(t, err.Error(), "error parsing relationship `document:firstdoc#readeruser:fred`") 158 require.Equal(t, uint64(13), errWithSource.LineNumber) 159 } 160 161 func TestDecodeAssertionsErrorLineNumber(t *testing.T) { 162 _, err := DecodeValidationFile([]byte(` 163 schema: >- 164 definition user {} 165 166 relationships: >- 167 document:firstdoc#writer@user:tom 168 169 assertions: 170 assertTrue: asdkjhasd 171 - document:firstdoc#view@user:tom 172 - document:firstdoc#view@user:fred 173 - document:seconddoc#view@user:tom 174 assertFalse: 175 - document:seconddoc#view@user:fred 176 `)) 177 178 errWithSource, ok := spiceerrors.AsErrorWithSource(err) 179 require.True(t, ok) 180 181 require.Equal(t, err.Error(), "unexpected value `asdkjha`") 182 require.Equal(t, uint64(9), errWithSource.LineNumber) 183 } 184 185 func TestDecodeAssertionsErrorLineNumberSmallerToken(t *testing.T) { 186 _, err := DecodeValidationFile([]byte(` 187 schema: >- 188 definition user {} 189 190 relationships: >- 191 document:firstdoc#writer@user:tom 192 193 assertions: 194 assertTrue: asdk 195 - document:firstdoc#view@user:tom 196 - document:firstdoc#view@user:fred 197 - document:seconddoc#view@user:tom 198 assertFalse: 199 - document:seconddoc#view@user:fred 200 `)) 201 202 errWithSource, ok := spiceerrors.AsErrorWithSource(err) 203 require.True(t, ok) 204 205 require.Equal(t, err.Error(), "unexpected value `asdk`") 206 require.Equal(t, uint64(9), errWithSource.LineNumber) 207 }