diff --git a/go.mod b/go.mod index 6c1410e..ddd56f9 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,7 @@ module github.com/project-kessel/relations-api go 1.22.7 + require ( buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.34.2-20240920164238-5a7b106cbb87.2 github.com/MicahParks/keyfunc/v3 v3.3.5 @@ -75,6 +76,7 @@ require ( github.com/samber/lo v1.47.0 // indirect github.com/sirupsen/logrus v1.9.3 // indirect github.com/stoewer/go-strcase v1.3.0 // indirect + github.com/stretchr/objx v0.5.2 // indirect github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect github.com/xeipuuv/gojsonschema v1.2.0 // indirect diff --git a/go.sum b/go.sum index 684f7f0..99ed31b 100644 --- a/go.sum +++ b/go.sum @@ -182,6 +182,8 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= +github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= diff --git a/internal/data/LocalSpiceDbContainer.go b/internal/data/LocalSpiceDbContainer.go index 7b74b5a..b0dc9b1 100644 --- a/internal/data/LocalSpiceDbContainer.go +++ b/internal/data/LocalSpiceDbContainer.go @@ -28,7 +28,7 @@ const ( // SpicedbImage is the image used for containerized spiceDB in tests SpicedbImage = "authzed/spicedb" // SpicedbVersion is the image version used for containerized spiceDB in tests - SpicedbVersion = "v1.22.2" + SpicedbVersion = "v1.37.0" // SpicedbSchemaBootstrapFile specifies an optional bootstrap schema file to be used for testing SpicedbSchemaBootstrapFile = "spicedb-test-data/basic_schema.zed" // SpicedbRelationsBootstrapFile specifies an optional bootstrap file containing relations to be used for testing diff --git a/internal/data/spicedb_test.go b/internal/data/spicedb_test.go index 11cfb48..a73772b 100644 --- a/internal/data/spicedb_test.go +++ b/internal/data/spicedb_test.go @@ -3,6 +3,9 @@ package data import ( "context" "fmt" + "github.com/stretchr/testify/mock" + "google.golang.org/grpc/metadata" + "io" "os" "testing" @@ -180,6 +183,80 @@ func TestSecondCreateRelationshipSucceedsWithTouchTrue(t *testing.T) { assert.True(t, exists) } +type MockgRPCClientStream struct { + mock.Mock +} + +func (m *MockgRPCClientStream) SetHeader(md metadata.MD) error { + panic("implement me") +} + +func (m *MockgRPCClientStream) SendHeader(md metadata.MD) error { + panic("implement me") +} + +func (m *MockgRPCClientStream) SetTrailer(md metadata.MD) { + panic("implement me") +} + +func (m *MockgRPCClientStream) Context() context.Context { + panic("implement me") +} + +func (m *MockgRPCClientStream) SendMsg(_ any) error { + panic("implement me") +} + +func (m *MockgRPCClientStream) RecvMsg(_ any) error { + panic("implement me") +} + +func (m *MockgRPCClientStream) Recv() (*apiV1beta1.ImportBulkTuplesRequest, error) { + args := m.Called() + if req, ok := args.Get(0).(*apiV1beta1.ImportBulkTuplesRequest); ok { + return req, args.Error(1) + } + return nil, args.Error(1) +} + +// SendAndClose simulates sending a response and closing the stream +func (m *MockgRPCClientStream) SendAndClose(resp *apiV1beta1.ImportBulkTuplesResponse) error { + args := m.Called(resp) + return args.Error(0) +} + +func (m *MockgRPCClientStream) CloseAndRecv() (*apiV1beta1.ImportBulkTuplesResponse, error) { + args := m.Called() + if res, ok := args.Get(0).(*apiV1beta1.ImportBulkTuplesResponse); ok { + return res, args.Error(1) + } + return nil, args.Error(1) +} + +func TestImportBulkTuples(t *testing.T) { + rels := []*apiV1beta1.Relationship{ + createRelationship("rbac", "group", "bob_club", "t_member", "rbac", "user", "bob5", ""), + createRelationship("rbac", "group", "bob_club", "t_member", "rbac", "user", "bob3", ""), + createRelationship("rbac", "group", "bob_club", "t_member", "rbac", "user", "bob6", ""), + createRelationship("rbac", "group", "bob_club", "t_member", "rbac", "user", "bob9", ""), + } + + mockgRPCClientStream := new(MockgRPCClientStream) + mockgRPCClientStream.On("Recv").Return(&apiV1beta1.ImportBulkTuplesRequest{Tuples: rels}, nil).Once() + mockgRPCClientStream.On("Recv").Return(nil, io.EOF).Once() + mockgRPCClientStream.On("SendAndClose", &apiV1beta1.ImportBulkTuplesResponse{NumImported: uint64(len(rels))}).Return(nil) + + spiceDbRepo, err := container.CreateSpiceDbRepository() + assert.NoError(t, err) + + err = spiceDbRepo.ImportBulkTuples(mockgRPCClientStream) + assert.NoError(t, err) + container.WaitForQuantizationInterval() + + exists := CheckForRelationship(spiceDbRepo, "bob5", "rbac", "user", "", "t_member", "rbac", "group", "bob_club") + assert.True(t, exists) +} + func TestIsBackendAvailable(t *testing.T) { t.Parallel()