From 6c6be3f92c7a005af60785f3d44f5da7a7a154b5 Mon Sep 17 00:00:00 2001 From: Benjamin DENEUX Date: Thu, 29 Aug 2024 12:08:20 +0200 Subject: [PATCH] test(dataverse): add test for GetResourceGovAddr --- dataverse/client.go | 7 +- dataverse/client_test.go | 152 ++++++++++++++++++++++++++++++++++++++- dataverse/query.go | 56 ++++++++++----- 3 files changed, 190 insertions(+), 25 deletions(-) diff --git a/dataverse/client.go b/dataverse/client.go index fd72956..79cb08a 100644 --- a/dataverse/client.go +++ b/dataverse/client.go @@ -2,7 +2,6 @@ package dataverse import ( "context" - "encoding/json" "fmt" cgschema "github.com/axone-protocol/axone-contract-schema/go/cognitarium-schema/v5" @@ -21,7 +20,9 @@ type client struct { cognitariumAddr string } -func NewDataverseClient(ctx context.Context, dataverseClient dvschema.QueryClient, cognitariumClient cgschema.QueryClient) (Client, error) { +func NewDataverseClient(ctx context.Context, + dataverseClient dvschema.QueryClient, + cognitariumClient cgschema.QueryClient) (Client, error) { cognitariumAddr, err := getCognitariumAddr(ctx, dataverseClient) if err != nil { return nil, fmt.Errorf("failed to get cognitarium address: %w", err) @@ -62,8 +63,6 @@ func NewClient(ctx context.Context, func (c *client) GetResourceGovAddr(_ context.Context, resourceDID string) (string, error) { query := buildGetResourceGovAddrRequest(resourceDID) - queryB, _ := json.Marshal(query) - fmt.Printf("query : %s", queryB) response, err := c.cognitariumClient.Select(context.Background(), &cgschema.QueryMsg_Select{Query: query}) if err != nil { return "", err diff --git a/dataverse/client_test.go b/dataverse/client_test.go index 2ebf743..a91df7a 100644 --- a/dataverse/client_test.go +++ b/dataverse/client_test.go @@ -5,7 +5,8 @@ import ( "fmt" "testing" - schema "github.com/axone-protocol/axone-contract-schema/go/dataverse-schema/v5" + cgschema "github.com/axone-protocol/axone-contract-schema/go/cognitarium-schema/v5" + dvschema "github.com/axone-protocol/axone-contract-schema/go/dataverse-schema/v5" "github.com/axone-protocol/axone-sdk/dataverse" "github.com/axone-protocol/axone-sdk/testutil" . "github.com/smartystreets/goconvey/convey" @@ -43,8 +44,8 @@ func TestClient_NewDataverseClient(t *testing.T) { mockClient.EXPECT(). Dataverse(gomock.Any(), gomock.Any()). Return( - &schema.DataverseResponse{ - TriplestoreAddress: schema.Addr(test.wantAddr), + &dvschema.DataverseResponse{ + TriplestoreAddress: dvschema.Addr(test.wantAddr), }, test.returnedErr, ). @@ -68,3 +69,148 @@ func TestClient_NewDataverseClient(t *testing.T) { }) } } + +func toAddress[T any](v T) *T { + return &v +} + +func TestClient_GetResourceGovAddr(t *testing.T) { + tests := []struct { + name string + resourceDID string + response *cgschema.SelectResponse + responseError error + wantErr error + wantResult string + }{ + { + name: "ask for good did response", + resourceDID: "did:key:zQ3shuwMJWYXRi64qiGojsV9bPN6Dtugz5YFM2ESPtkaNxTZ5", + response: &cgschema.SelectResponse{ + Head: cgschema.Head{ + Vars: []string{"code"}, + }, + Results: cgschema.Results{ + Bindings: []map[string]cgschema.Value{ + { + "code": cgschema.Value{ + ValueType: cgschema.URI{ + Type: "uri", + Value: cgschema.IRI{Full: toAddress(cgschema.IRI_Full("foo"))}, + }, + }, + }, + }, + }, + }, + responseError: nil, + wantErr: nil, + wantResult: "foo", + }, + { + name: "grpc error", + resourceDID: "did:key:zQ3shuwMJWYXRi64qiGojsV9bPN6Dtugz5YFM2ESPtkaNxTZ5", + response: nil, + responseError: fmt.Errorf("gRPC: connection refused"), + wantErr: fmt.Errorf("gRPC: connection refused"), + wantResult: "", + }, + { + name: "invalid variable binding in response", + resourceDID: "did:key:zQ3shuwMJWYXRi64qiGojsV9bPN6Dtugz5YFM2ESPtkaNxTZ5", + response: &cgschema.SelectResponse{ + Head: cgschema.Head{ + Vars: []string{"code"}, + }, + Results: cgschema.Results{ + Bindings: []map[string]cgschema.Value{ + { + "invalid": cgschema.Value{}, + }, + }, + }, + }, + responseError: nil, + wantErr: fmt.Errorf("could not find governance code"), + wantResult: "", + }, + { + name: "no binding in response", + resourceDID: "did:key:zQ3shuwMJWYXRi64qiGojsV9bPN6Dtugz5YFM2ESPtkaNxTZ5", + response: &cgschema.SelectResponse{ + Head: cgschema.Head{ + Vars: []string{"code"}, + }, + Results: cgschema.Results{ + Bindings: []map[string]cgschema.Value{}, + }, + }, + responseError: nil, + wantErr: fmt.Errorf("could not find governance code"), + wantResult: "", + }, + { + name: "invalid value type in response", + resourceDID: "did:key:zQ3shuwMJWYXRi64qiGojsV9bPN6Dtugz5YFM2ESPtkaNxTZ5", + response: &cgschema.SelectResponse{ + Head: cgschema.Head{ + Vars: []string{"code"}, + }, + Results: cgschema.Results{ + Bindings: []map[string]cgschema.Value{ + { + "code": cgschema.Value{ + ValueType: cgschema.BlankNode{ + Type: "blank_node", + Value: "foo", + }, + }, + }, + }, + }, + }, + responseError: nil, + wantErr: fmt.Errorf("could not decode governance code"), + wantResult: "", + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + Convey("Given a mocked dataverse client", t, func() { + controller := gomock.NewController(t) + defer controller.Finish() + + mockDataverseClient := testutil.NewMockDataverseQueryClient(controller) + mockDataverseClient.EXPECT(). + Dataverse(gomock.Any(), gomock.Any()). + Return(&dvschema.DataverseResponse{TriplestoreAddress: "bar"}, nil). + Times(1) + + mockCognitarium := testutil.NewMockCognitariumQueryClient(controller) + mockCognitarium. + EXPECT(). + Select(gomock.Any(), gomock.Any()). + Return(test.response, test.responseError). + Times(1) + + client, err := dataverse.NewDataverseClient(context.Background(), mockDataverseClient, mockCognitarium) + So(err, ShouldBeNil) + + Convey("When GetResourceGovAddr is called", func() { + addr, err := client.GetResourceGovAddr(context.Background(), test.resourceDID) + + Convey("Then the resource governance address should be returned", func() { + if test.wantErr == nil { + So(err, ShouldBeNil) + So(addr, ShouldEqual, test.wantResult) + } else { + So(err.Error(), ShouldEqual, test.wantErr.Error()) + So(addr, ShouldEqual, "") + } + }) + }) + }) + }) + } +} diff --git a/dataverse/query.go b/dataverse/query.go index 4a0bd9f..69258f8 100644 --- a/dataverse/query.go +++ b/dataverse/query.go @@ -2,16 +2,18 @@ package dataverse import ( "fmt" + cgschema "github.com/axone-protocol/axone-contract-schema/go/cognitarium-schema/v5" ) const W3IDPrefix = "https://w3id.org/axone/ontology/v4" +//nolint:funlen func buildGetResourceGovAddrRequest(resource string) cgschema.SelectQuery { limit := 1 - selectVar := cgschema.SelectItem_Variable("code") + codeVar := cgschema.SelectItem_Variable("code") codeVarOrNodeOrLit := cgschema.VarOrNodeOrLiteral_Variable("code") - credId := cgschema.VarOrNode_Variable("credId") + credIDVar := cgschema.VarOrNode_Variable("credId") resourceIRI := cgschema.IRI_Full(resource) govType := cgschema.IRI_Prefixed("gov:GovernanceTextCredential") claimVar := cgschema.VarOrNode_Variable("claim") @@ -31,36 +33,54 @@ func buildGetResourceGovAddrRequest(resource string) cgschema.SelectQuery { }, Select: []cgschema.SelectItem{ { - Variable: &selectVar, + Variable: &codeVar, }, }, Where: cgschema.WhereClause{ Bgp: &cgschema.WhereClause_Bgp{ Patterns: []cgschema.TriplePattern{ { - Subject: cgschema.VarOrNode{Variable: &credId}, - Predicate: cgschema.VarOrNamedNode{NamedNode: &cgschema.VarOrNamedNode_NamedNode{Full: &VcBodySubject}}, - Object: cgschema.VarOrNodeOrLiteral{Node: &cgschema.VarOrNodeOrLiteral_Node{NamedNode: &cgschema.Node_NamedNode{Full: &resourceIRI}}}, + Subject: cgschema.VarOrNode{Variable: &credIDVar}, + Predicate: cgschema.VarOrNamedNode{ + NamedNode: &cgschema.VarOrNamedNode_NamedNode{Full: &VcBodySubject}, + }, + Object: cgschema.VarOrNodeOrLiteral{ + Node: &cgschema.VarOrNodeOrLiteral_Node{ + NamedNode: &cgschema.Node_NamedNode{Full: &resourceIRI}, + }, + }, }, { - Subject: cgschema.VarOrNode{Variable: &credId}, - Predicate: cgschema.VarOrNamedNode{NamedNode: &cgschema.VarOrNamedNode_NamedNode{Full: &VcBodyType}}, - Object: cgschema.VarOrNodeOrLiteral{Node: &cgschema.VarOrNodeOrLiteral_Node{NamedNode: &cgschema.Node_NamedNode{Prefixed: &govType}}}, + Subject: cgschema.VarOrNode{Variable: &credIDVar}, + Predicate: cgschema.VarOrNamedNode{ + NamedNode: &cgschema.VarOrNamedNode_NamedNode{Full: &VcBodyType}, + }, + Object: cgschema.VarOrNodeOrLiteral{ + Node: &cgschema.VarOrNodeOrLiteral_Node{ + NamedNode: &cgschema.Node_NamedNode{Prefixed: &govType}, + }, + }, }, { - Subject: cgschema.VarOrNode{Variable: &credId}, - Predicate: cgschema.VarOrNamedNode{NamedNode: &cgschema.VarOrNamedNode_NamedNode{Full: &VcBodyClaim}}, - Object: cgschema.VarOrNodeOrLiteral{Variable: &claimVarOrNode}, + Subject: cgschema.VarOrNode{Variable: &credIDVar}, + Predicate: cgschema.VarOrNamedNode{ + NamedNode: &cgschema.VarOrNamedNode_NamedNode{Full: &VcBodyClaim}, + }, + Object: cgschema.VarOrNodeOrLiteral{Variable: &claimVarOrNode}, }, { - Subject: cgschema.VarOrNode{Variable: &claimVar}, - Predicate: cgschema.VarOrNamedNode{NamedNode: &cgschema.VarOrNamedNode_NamedNode{Prefixed: &isGovernedBy}}, - Object: cgschema.VarOrNodeOrLiteral{Variable: &govVarOrNodeOrLit}, + Subject: cgschema.VarOrNode{Variable: &claimVar}, + Predicate: cgschema.VarOrNamedNode{ + NamedNode: &cgschema.VarOrNamedNode_NamedNode{Prefixed: &isGovernedBy}, + }, + Object: cgschema.VarOrNodeOrLiteral{Variable: &govVarOrNodeOrLit}, }, { - Subject: cgschema.VarOrNode{Variable: &govVar}, - Predicate: cgschema.VarOrNamedNode{NamedNode: &cgschema.VarOrNamedNode_NamedNode{Prefixed: &fromGovernance}}, - Object: cgschema.VarOrNodeOrLiteral{Variable: &codeVarOrNodeOrLit}, + Subject: cgschema.VarOrNode{Variable: &govVar}, + Predicate: cgschema.VarOrNamedNode{ + NamedNode: &cgschema.VarOrNamedNode_NamedNode{Prefixed: &fromGovernance}, + }, + Object: cgschema.VarOrNodeOrLiteral{Variable: &codeVarOrNodeOrLit}, }, }, },