github.com/authzed/spicedb@v1.32.1-0.20240520085336-ebda56537386/internal/namespace/util_test.go (about) 1 package namespace_test 2 3 import ( 4 "context" 5 "sort" 6 "testing" 7 8 "github.com/stretchr/testify/require" 9 10 "github.com/authzed/spicedb/internal/datastore/memdb" 11 "github.com/authzed/spicedb/internal/namespace" 12 "github.com/authzed/spicedb/internal/testfixtures" 13 ns "github.com/authzed/spicedb/pkg/namespace" 14 core "github.com/authzed/spicedb/pkg/proto/core/v1" 15 ) 16 17 func TestListReferencedNamespaces(t *testing.T) { 18 testCases := []struct { 19 name string 20 toCheck []*core.NamespaceDefinition 21 expectedNames []string 22 }{ 23 { 24 "basic namespace", 25 []*core.NamespaceDefinition{ 26 ns.Namespace( 27 "document", 28 ns.MustRelation("owner", nil), 29 ), 30 }, 31 []string{"document"}, 32 }, 33 { 34 "basic namespaces", 35 []*core.NamespaceDefinition{ 36 ns.Namespace( 37 "document", 38 ns.MustRelation("viewer", nil, ns.AllowedRelation("user", "...")), 39 ), 40 ns.Namespace("user"), 41 }, 42 []string{"document", "user"}, 43 }, 44 { 45 "basic namespaces with references", 46 []*core.NamespaceDefinition{ 47 ns.Namespace( 48 "document", 49 ns.MustRelation("viewer", nil, 50 ns.AllowedRelation("group", "member"), 51 ns.AllowedRelation("group", "manager"), 52 ns.AllowedRelation("team", "member")), 53 ), 54 ns.Namespace("user"), 55 }, 56 []string{"document", "user", "group", "team"}, 57 }, 58 } 59 60 for _, tc := range testCases { 61 tc := tc 62 t.Run(tc.name, func(t *testing.T) { 63 require := require.New(t) 64 65 found := namespace.ListReferencedNamespaces(tc.toCheck) 66 sort.Strings(found) 67 sort.Strings(tc.expectedNames) 68 69 require.Equal(tc.expectedNames, found) 70 }) 71 } 72 } 73 74 func TestCheckNamespaceAndRelations(t *testing.T) { 75 tcs := []struct { 76 name string 77 schema string 78 checks []namespace.TypeAndRelationToCheck 79 expectedError string 80 }{ 81 { 82 "missing namespace", 83 `definition user {}`, 84 []namespace.TypeAndRelationToCheck{ 85 { 86 NamespaceName: "user", 87 RelationName: "...", 88 AllowEllipsis: true, 89 }, 90 { 91 NamespaceName: "resource", 92 RelationName: "viewer", 93 AllowEllipsis: false, 94 }, 95 }, 96 "object definition `resource` not found", 97 }, 98 { 99 "missing relation", 100 `definition resource {}`, 101 []namespace.TypeAndRelationToCheck{ 102 { 103 NamespaceName: "resource", 104 RelationName: "viewer", 105 AllowEllipsis: false, 106 }, 107 }, 108 "relation/permission `viewer` not found", 109 }, 110 { 111 "valid", 112 `definition user {} 113 114 definition resource { 115 relation viewer: user 116 } 117 `, 118 []namespace.TypeAndRelationToCheck{ 119 { 120 NamespaceName: "user", 121 RelationName: "...", 122 AllowEllipsis: true, 123 }, 124 { 125 NamespaceName: "resource", 126 RelationName: "viewer", 127 AllowEllipsis: false, 128 }, 129 }, 130 "", 131 }, 132 { 133 "ellipsis not allowed", 134 `definition user {}`, 135 []namespace.TypeAndRelationToCheck{ 136 { 137 NamespaceName: "user", 138 RelationName: "...", 139 AllowEllipsis: false, 140 }, 141 }, 142 "relation/permission `...` not found", 143 }, 144 { 145 "another missing namespace", 146 `definition user {}`, 147 []namespace.TypeAndRelationToCheck{ 148 { 149 NamespaceName: "resource", 150 RelationName: "viewer", 151 AllowEllipsis: false, 152 }, 153 { 154 NamespaceName: "user", 155 RelationName: "...", 156 AllowEllipsis: true, 157 }, 158 }, 159 "object definition `resource` not found", 160 }, 161 } 162 for _, tc := range tcs { 163 t.Run(tc.name, func(t *testing.T) { 164 req := require.New(t) 165 rawDS, err := memdb.NewMemdbDatastore(0, 0, memdb.DisableGC) 166 req.NoError(err) 167 168 ds, _ := testfixtures.DatastoreFromSchemaAndTestRelationships(rawDS, tc.schema, nil, req) 169 170 rev, err := ds.HeadRevision(context.Background()) 171 require.NoError(t, err) 172 173 reader := ds.SnapshotReader(rev) 174 175 err = namespace.CheckNamespaceAndRelations(context.Background(), tc.checks, reader) 176 if tc.expectedError == "" { 177 require.Nil(t, err) 178 } else { 179 require.ErrorContains(t, err, tc.expectedError) 180 } 181 }) 182 } 183 }