Skip to content

Commit

Permalink
Merge branch 'master' into aleem/646-ecocredit-projects
Browse files Browse the repository at this point in the history
  • Loading branch information
aleem1314 committed Jan 3, 2022
2 parents 231a23a + a70bae8 commit a23d2eb
Show file tree
Hide file tree
Showing 11 changed files with 1,704 additions and 67 deletions.
128 changes: 93 additions & 35 deletions x/data/client/query.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,73 +6,131 @@ import (

"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/client/flags"
gocid "github.com/ipfs/go-cid"
"github.com/spf13/cobra"

"github.com/regen-network/regen-ledger/x/data"
)

// QueryCmd returns the parent command for all x/data CLI query commands
func QueryCmd(name string) *cobra.Command {
queryByCidCmd := QueryByCidCmd()
queryByIRICmd := QueryByIRICmd()

cmd := &cobra.Command{
Args: cobra.ExactArgs(1),
Use: fmt.Sprintf("%s [cid]", name),
Use: fmt.Sprintf("%s [iri]", name),
Short: "Querying commands for the data module",
Long: strings.TrimSpace(`Querying commands for the data module.
If a CID is passed as first argument, then this command will query timestamp, signers and content (if available) for the given CID. Otherwise, this command will run the given subcommand.
If an IRI is passed as first argument, then this command will query timestamp,
signers and content (if available) for the given IRI. Otherwise, this command
will run the given subcommand.
Example (the two following commands are equivalent):
$ regen query data bafzbeigai3eoy2ccc7ybwjfz5r3rdxqrinwi4rwytly24tdbh6yk7zslrm
$ regen query data by-cid bafzbeigai3eoy2ccc7ybwjfz5r3rdxqrinwi4rwytly24tdbh6yk7zslrm`),
$ regen query data regen:113gdjFKcVCt13Za6vN7TtbgMM6LMSjRnu89BMCxeuHdkJ1hWUmy.rdf
$ regen query data by-iri regen:113gdjFKcVCt13Za6vN7TtbgMM6LMSjRnu89BMCxeuHdkJ1hWUmy.rdf`),
DisableFlagParsing: true,
SuggestionsMinimumDistance: 2,
RunE: func(cmd *cobra.Command, args []string) error {
// If 1st arg is NOT a CID, parse subcommands as usual.
_, err := gocid.Decode(args[0])
if err != nil {
// If 1st arg is NOT an IRI, parse subcommands as usual.
if !strings.Contains(args[0], "regen:") {
return client.ValidateCmd(cmd, args)
}

// Or else, we call QueryByCidCmd.
return queryByCidCmd.RunE(cmd, args)
// Or else, we call QueryByIRICmd.
return queryByIRICmd.RunE(cmd, args)
},
}

cmd.AddCommand(
queryByCidCmd,
queryByIRICmd,
QueryBySignerCmd(),
QuerySignersCmd(),
)

flags.AddQueryFlagsToCmd(cmd)

return cmd
}

// QueryByCidCmd creates a CLI command for Query/Data.
func QueryByCidCmd() *cobra.Command {
// QueryByIRICmd creates a CLI command for Query/Data.
func QueryByIRICmd() *cobra.Command {
cmd := &cobra.Command{
Use: "by-iri [iri]",
Short: "Query for anchored data based on IRI",
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
c, ctx, err := mkQueryClient(cmd)
if err != nil {
return err
}

res, err := c.ByIRI(cmd.Context(), &data.QueryByIRIRequest{
Iri: args[0],
})

return print(ctx, res, err)
},
}

flags.AddQueryFlagsToCmd(cmd)

return cmd
}

// QueryBySignerCmd creates a CLI command for Query/Data.
func QueryBySignerCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "by-cid [cid]",
Short: "Query for CID timestamp, signers and content (if available)",
Use: "by-signer [signer]",
Short: "Query for anchored data based on signer",
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
return fmt.Errorf("not implemented")
//clientCtx, err := client.GetClientQueryContext(cmd)
//if err != nil {
// return err
//}
//
//cid, err := gocid.Decode(args[0])
//if err != nil {
// return err
//}
//
//queryClient := data.NewQueryClient(clientCtx)
//
//res, err := queryClient.ByCid(cmd.Context(), &data.QueryByCidRequest{Cid: cid.Bytes()})
//if err != nil {
// return err
//}
//
//return clientCtx.PrintProto(res)
c, ctx, err := mkQueryClient(cmd)
if err != nil {
return err
}

pagination, err := client.ReadPageRequest(cmd.Flags())
if err != nil {
return err
}

res, err := c.BySigner(cmd.Context(), &data.QueryBySignerRequest{
Signer: args[0],
Pagination: pagination,
})

return print(ctx, res, err)
},
}

flags.AddQueryFlagsToCmd(cmd)

return cmd
}

// QuerySignersCmd creates a CLI command for Query/Data.
func QuerySignersCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "signers [iri]",
Short: "Query for signers based on IRI",
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
c, ctx, err := mkQueryClient(cmd)
if err != nil {
return err
}

pagination, err := client.ReadPageRequest(cmd.Flags())
if err != nil {
return err
}

res, err := c.Signers(cmd.Context(), &data.QuerySignersRequest{
Iri: args[0],
Pagination: pagination,
})

return print(ctx, res, err)
},
}

Expand Down
193 changes: 193 additions & 0 deletions x/data/client/testsuite/query.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,193 @@
package testsuite

import (
"github.com/regen-network/regen-ledger/types/testutil/cli"
"github.com/regen-network/regen-ledger/x/data"
"github.com/regen-network/regen-ledger/x/data/client"
)

func (s *IntegrationTestSuite) TestZQueryByIRICmd() {
val := s.network.Validators[0]
clientCtx := val.ClientCtx
clientCtx.OutputFormat = "JSON"

validIri := "regen:13toVgf5aZqSVSeJQv562xkkeoe3rr3bJWa29PHVKVf77VAkVMcDvVd.rdf"

testCases := []struct {
name string
args []string
expErr bool
expErrMsg string
expIRI string
}{
{
name: "missing args",
args: []string{},
expErr: true,
expErrMsg: "Error: accepts 1 arg(s), received 0",
},
{
name: "too many args",
args: []string{
"foo", "bar",
},
expErr: true,
expErrMsg: "Error: accepts 1 arg(s), received 2",
},
{
name: "invalid iri",
args: []string{
"foo",
},
expErr: true,
expErrMsg: "key not found",
},
{
name: "valid",
args: []string{validIri},
expErr: false,
expIRI: validIri,
},
}

for _, tc := range testCases {
s.Run(tc.name, func() {
cmd := client.QueryByIRICmd()
out, err := cli.ExecTestCLICmd(clientCtx, cmd, tc.args)
if tc.expErr {
s.Require().Error(err)
s.Require().Contains(out.String(), tc.expErrMsg)
} else {
s.Require().NoError(err, out.String())

var res data.QueryByIRIResponse
s.Require().NoError(clientCtx.Codec.UnmarshalJSON(out.Bytes(), &res))

s.Require().Equal(tc.expIRI, res.Entry.Iri)
s.Require().NotNil(res.Entry.Hash)
s.Require().NotNil(res.Entry.Timestamp)
}
})
}
}

func (s *IntegrationTestSuite) TestZQueryBySignerCmd() {
val := s.network.Validators[0]
clientCtx := val.ClientCtx
clientCtx.OutputFormat = "JSON"

validIri := "regen:13toVgf5aZqSVSeJQv562xkkeoe3rr3bJWa29PHVKVf77VAkVMcDvVd.rdf"

testCases := []struct {
name string
args []string
expErr bool
expErrMsg string
expIRIs []string
}{
{
name: "missing args",
args: []string{},
expErr: true,
expErrMsg: "Error: accepts 1 arg(s), received 0",
},
{
name: "too many args",
args: []string{"foo", "bar"},
expErr: true,
expErrMsg: "Error: accepts 1 arg(s), received 2",
},
{
name: "invalid signer",
args: []string{"foo"},
expErr: true,
expErrMsg: "invalid bech32 string",
},
{
name: "valid",
args: []string{val.Address.String()},
expErr: false,
expIRIs: []string{validIri},
},
}

for _, tc := range testCases {
s.Run(tc.name, func() {
cmd := client.QueryBySignerCmd()
out, err := cli.ExecTestCLICmd(clientCtx, cmd, tc.args)
if tc.expErr {
s.Require().Error(err)
s.Require().Contains(out.String(), tc.expErrMsg)
} else {
s.Require().NoError(err, out.String())

var res data.QueryBySignerResponse
s.Require().NoError(clientCtx.Codec.UnmarshalJSON(out.Bytes(), &res))

for i, entry := range res.Entries {
s.Require().Equal(tc.expIRIs[i], entry.Iri)
s.Require().NotNil(entry.Hash)
s.Require().NotNil(entry.Timestamp)
}
}
})
}
}

func (s *IntegrationTestSuite) TestZQuerySignersCmd() {
val := s.network.Validators[0]
clientCtx := val.ClientCtx
clientCtx.OutputFormat = "JSON"

validIri := "regen:13toVgf5aZqSVSeJQv562xkkeoe3rr3bJWa29PHVKVf77VAkVMcDvVd.rdf"

testCases := []struct {
name string
args []string
expErr bool
expErrMsg string
expResp []string
}{
{
name: "missing args",
args: []string{},
expErr: true,
expErrMsg: "Error: accepts 1 arg(s), received 0",
},
{
name: "too many args",
args: []string{"foo", "bar"},
expErr: true,
expErrMsg: "Error: accepts 1 arg(s), received 2",
},
{
name: "invalid signer",
args: []string{"foo"},
expErr: true,
expErrMsg: "key not found",
},
{
name: "valid",
args: []string{validIri},
expErr: false,
expResp: []string{val.Address.String()},
},
}

for _, tc := range testCases {
s.Run(tc.name, func() {
cmd := client.QuerySignersCmd()
out, err := cli.ExecTestCLICmd(clientCtx, cmd, tc.args)
if tc.expErr {
s.Require().Error(err)
s.Require().Contains(out.String(), tc.expErrMsg)
} else {
s.Require().NoError(err, out.String())

var res data.QuerySignersResponse
s.Require().NoError(clientCtx.Codec.UnmarshalJSON(out.Bytes(), &res))
s.Require().Equal(tc.expResp, res.Signers)
}
})
}
}
25 changes: 25 additions & 0 deletions x/data/client/util.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package client

import (
"github.com/spf13/cobra"

sdkclient "github.com/cosmos/cosmos-sdk/client"
"github.com/gogo/protobuf/proto"

"github.com/regen-network/regen-ledger/x/data"
)

func print(cctx sdkclient.Context, res proto.Message, err error) error {
if err != nil {
return err
}
return cctx.PrintProto(res)
}

func mkQueryClient(cmd *cobra.Command) (data.QueryClient, sdkclient.Context, error) {
ctx, err := sdkclient.GetClientQueryContext(cmd)
if err != nil {
return nil, sdkclient.Context{}, err
}
return data.NewQueryClient(ctx), ctx, err
}
Loading

0 comments on commit a23d2eb

Please sign in to comment.