From 3560c30c65999f7edcb6091c5ad304cc60240e37 Mon Sep 17 00:00:00 2001 From: Julien Robert Date: Sat, 15 Jul 2023 09:22:53 +0200 Subject: [PATCH 1/4] feat(group): autocli query support --- tests/e2e/group/query.go | 113 ------ tests/e2e/group/suite.go | 38 +- x/group/client/cli/query.go | 556 ------------------------------ x/group/client/cli/query_test.go | 513 --------------------------- x/group/client/cli/util_test.go | 2 +- x/group/keeper/grpc_query_test.go | 2 + x/group/module/autocli.go | 130 +++++++ x/group/module/module.go | 5 - 8 files changed, 154 insertions(+), 1205 deletions(-) delete mode 100644 tests/e2e/group/query.go delete mode 100644 x/group/client/cli/query.go delete mode 100644 x/group/client/cli/query_test.go create mode 100644 x/group/module/autocli.go diff --git a/tests/e2e/group/query.go b/tests/e2e/group/query.go deleted file mode 100644 index 293b8f046d1..00000000000 --- a/tests/e2e/group/query.go +++ /dev/null @@ -1,113 +0,0 @@ -package group - -import ( - "fmt" - - "github.com/cosmos/cosmos-sdk/client/flags" - clitestutil "github.com/cosmos/cosmos-sdk/testutil/cli" - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/x/group" - client "github.com/cosmos/cosmos-sdk/x/group/client/cli" -) - -func (s *E2ETestSuite) TestTallyResult() { - val := s.network.Validators[0] - clientCtx := val.ClientCtx - - member := s.voter - - // create a proposal - out, err := clitestutil.ExecTestCLICmd(val.ClientCtx, client.MsgSubmitProposalCmd(), - append( - []string{ - s.createCLIProposal( - s.groupPolicies[0].Address, val.Address.String(), - s.groupPolicies[0].Address, val.Address.String(), - "", "title", "summary"), - }, - s.commonFlags..., - ), - ) - s.Require().NoError(err, out.String()) - - var txResp sdk.TxResponse - s.Require().NoError(val.ClientCtx.Codec.UnmarshalJSON(out.Bytes(), &txResp), out.String()) - txResp, err = clitestutil.GetTxResponse(s.network, clientCtx, txResp.TxHash) - s.Require().NoError(err) - s.Require().Equal(txResp.Code, uint32(0), out.String()) - - proposalID := s.getProposalIDFromTxResponse(txResp) - - testCases := []struct { - name string - args []string - expectErr bool - expTallyResult group.TallyResult - expectErrMsg string - }{ - { - "not found", - []string{ - "12345", - fmt.Sprintf("--%s=json", flags.FlagOutput), - }, - true, - group.TallyResult{}, - "not found", - }, - { - "invalid proposal id", - []string{ - "", - fmt.Sprintf("--%s=json", flags.FlagOutput), - }, - true, - group.TallyResult{}, - "strconv.ParseUint: parsing \"\": invalid syntax", - }, - { - "valid proposal id with no votes", - []string{ - proposalID, - fmt.Sprintf("--%s=json", flags.FlagOutput), - }, - false, - group.DefaultTallyResult(), - "", - }, - { - "valid proposal id", - []string{ - "1", - fmt.Sprintf("--%s=json", flags.FlagOutput), - }, - false, - group.TallyResult{ - YesCount: member.Weight, - AbstainCount: "0", - NoCount: "0", - NoWithVetoCount: "0", - }, - "", - }, - } - - for _, tc := range testCases { - tc := tc - - s.Run(tc.name, func() { - cmd := client.QueryTallyResultCmd() - - out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args) - if tc.expectErr { - s.Require().Contains(out.String(), tc.expectErrMsg) - } else { - s.Require().NoError(err, out.String()) - var tallyResultRes group.QueryTallyResultResponse - s.Require().NoError(clientCtx.Codec.UnmarshalJSON(out.Bytes(), &tallyResultRes)) - s.Require().NotNil(tallyResultRes) - s.Require().Equal(tc.expTallyResult, tallyResultRes.Tally) - } - }) - } -} diff --git a/tests/e2e/group/suite.go b/tests/e2e/group/suite.go index 60d924733bd..a0efde25cbc 100644 --- a/tests/e2e/group/suite.go +++ b/tests/e2e/group/suite.go @@ -120,9 +120,13 @@ func (s *E2ETestSuite) SetupSuite() { } s.createGroupThresholdPolicyWithBalance(val.Address.String(), "1", threshold, 1000) - out, err = clitestutil.ExecTestCLICmd(val.ClientCtx, client.QueryGroupPoliciesByGroupCmd(), []string{"1", fmt.Sprintf("--%s=json", flags.FlagOutput)}) - s.Require().NoError(err, out.String()) s.Require().NoError(s.network.WaitForNextBlock()) + resp, err := testutil.GetRequest(fmt.Sprintf("%s/cosmos/group/v1/group_policies_by_group/1", val.APIAddress)) + s.Require().NoError(err) + + var groupPoliciesResp group.QueryGroupPoliciesByGroupResponse + s.Require().NoError(val.ClientCtx.Codec.UnmarshalJSON(resp, &groupPoliciesResp)) + s.Require().Len(groupPoliciesResp.GroupPolicies, i+1) } // create group policy with percentage decision policy out, err = clitestutil.ExecTestCLICmd(val.ClientCtx, client.MsgCreateGroupPolicyCmd(), @@ -140,13 +144,13 @@ func (s *E2ETestSuite) SetupSuite() { s.Require().NoError(val.ClientCtx.Codec.UnmarshalJSON(out.Bytes(), &txResp), out.String()) s.Require().NoError(clitestutil.CheckTxCode(s.network, val.ClientCtx, txResp.TxHash, 0)) - out, err = clitestutil.ExecTestCLICmd(val.ClientCtx, client.QueryGroupPoliciesByGroupCmd(), []string{"1", fmt.Sprintf("--%s=json", flags.FlagOutput)}) - s.Require().NoError(err, out.String()) + resp, err := testutil.GetRequest(fmt.Sprintf("%s/cosmos/group/v1/group_policies_by_group/1", val.APIAddress)) + s.Require().NoError(err) - var res group.QueryGroupPoliciesByGroupResponse - s.Require().NoError(val.ClientCtx.Codec.UnmarshalJSON(out.Bytes(), &res)) - s.Require().Equal(len(res.GroupPolicies), 6) - s.groupPolicies = res.GroupPolicies + var groupPoliciesResp group.QueryGroupPoliciesByGroupResponse + s.Require().NoError(val.ClientCtx.Codec.UnmarshalJSON(resp, &groupPoliciesResp)) + s.Require().Equal(len(groupPoliciesResp.GroupPolicies), 6) + s.groupPolicies = groupPoliciesResp.GroupPolicies // create a proposal out, err = clitestutil.ExecTestCLICmd(val.ClientCtx, client.MsgSubmitProposalCmd(), @@ -180,18 +184,18 @@ func (s *E2ETestSuite) SetupSuite() { s.Require().NoError(val.ClientCtx.Codec.UnmarshalJSON(out.Bytes(), &txResp), out.String()) s.Require().NoError(clitestutil.CheckTxCode(s.network, val.ClientCtx, txResp.TxHash, 0)) - out, err = clitestutil.ExecTestCLICmd(val.ClientCtx, client.QueryProposalCmd(), []string{"1", fmt.Sprintf("--%s=json", flags.FlagOutput)}) - s.Require().NoError(err, out.String()) + resp, err = testutil.GetRequest(fmt.Sprintf("%s/cosmos/group/v1/proposal/1", val.APIAddress)) + s.Require().NoError(err) var proposalRes group.QueryProposalResponse - s.Require().NoError(val.ClientCtx.Codec.UnmarshalJSON(out.Bytes(), &proposalRes)) + s.Require().NoError(val.ClientCtx.Codec.UnmarshalJSON(resp, &proposalRes)) s.proposal = proposalRes.Proposal - out, err = clitestutil.ExecTestCLICmd(val.ClientCtx, client.QueryVoteByProposalVoterCmd(), []string{"1", val.Address.String(), fmt.Sprintf("--%s=json", flags.FlagOutput)}) - s.Require().NoError(err, out.String()) + resp, err = testutil.GetRequest(fmt.Sprintf("%s/cosmos/group/v1/vote_by_proposal_voter/1/%s", val.APIAddress, val.Address.String())) + s.Require().NoError(err) var voteRes group.QueryVoteByProposalVoterResponse - s.Require().NoError(val.ClientCtx.Codec.UnmarshalJSON(out.Bytes(), &voteRes)) + s.Require().NoError(val.ClientCtx.Codec.UnmarshalJSON(resp, &voteRes)) s.vote = voteRes.Vote s.voter = &group.Member{ @@ -272,11 +276,11 @@ func (s *E2ETestSuite) createGroupThresholdPolicyWithBalance(adminAddress, group s.Require().NoError(val.ClientCtx.Codec.UnmarshalJSON(out.Bytes(), &txResp), out.String()) s.Require().NoError(clitestutil.CheckTxCode(s.network, val.ClientCtx, txResp.TxHash, 0)) - out, err = clitestutil.ExecTestCLICmd(val.ClientCtx, client.QueryGroupPoliciesByGroupCmd(), []string{groupID, fmt.Sprintf("--%s=json", flags.FlagOutput)}) - s.Require().NoError(err, out.String()) + resp, err := testutil.GetRequest(fmt.Sprintf("%s/cosmos/group/v1/group_policies_by_group/%s", val.APIAddress, groupID)) + s.Require().NoError(err) var res group.QueryGroupPoliciesByGroupResponse - s.Require().NoError(val.ClientCtx.Codec.UnmarshalJSON(out.Bytes(), &res)) + s.Require().NoError(val.ClientCtx.Codec.UnmarshalJSON(resp, &res)) groupPolicyAddress := res.GroupPolicies[0].Address addr, err := sdk.AccAddressFromBech32(groupPolicyAddress) diff --git a/x/group/client/cli/query.go b/x/group/client/cli/query.go deleted file mode 100644 index 88d2582473e..00000000000 --- a/x/group/client/cli/query.go +++ /dev/null @@ -1,556 +0,0 @@ -package cli - -import ( - "strconv" - - "github.com/spf13/cobra" - - "github.com/cosmos/cosmos-sdk/client" - "github.com/cosmos/cosmos-sdk/client/flags" - "github.com/cosmos/cosmos-sdk/x/group" -) - -// QueryCmd returns the cli query commands for the group module. -func QueryCmd(name string) *cobra.Command { - queryCmd := &cobra.Command{ - Use: name, - Short: "Querying commands for the group module", - DisableFlagParsing: true, - SuggestionsMinimumDistance: 2, - RunE: client.ValidateCmd, - } - - queryCmd.AddCommand( - QueryGroupInfoCmd(), - QueryGroupPolicyInfoCmd(), - QueryGroupMembersCmd(), - QueryGroupsByAdminCmd(), - QueryGroupPoliciesByGroupCmd(), - QueryGroupPoliciesByAdminCmd(), - QueryProposalCmd(), - QueryProposalsByGroupPolicyCmd(), - QueryVoteByProposalVoterCmd(), - QueryVotesByProposalCmd(), - QueryVotesByVoterCmd(), - QueryGroupsByMemberCmd(), - QueryTallyResultCmd(), - QueryGroupsCmd(), - ) - - return queryCmd -} - -// QueryGroupsByMemberCmd creates a CLI command for Query/GroupsByMember. -func QueryGroupsByMemberCmd() *cobra.Command { - cmd := &cobra.Command{ - Use: "groups-by-member [address]", - Short: "Query for groups by member address with pagination flags", - Args: cobra.ExactArgs(1), - RunE: func(cmd *cobra.Command, args []string) error { - clientCtx, err := client.GetClientQueryContext(cmd) - if err != nil { - return err - } - - pageReq, err := client.ReadPageRequest(cmd.Flags()) - if err != nil { - return err - } - - queryClient := group.NewQueryClient(clientCtx) - res, err := queryClient.GroupsByMember(cmd.Context(), &group.QueryGroupsByMemberRequest{ - Address: args[0], - Pagination: pageReq, - }) - if err != nil { - return err - } - - return clientCtx.PrintProto(res) - }, - } - - flags.AddQueryFlagsToCmd(cmd) - flags.AddPaginationFlagsToCmd(cmd, "groups-by-members") - return cmd -} - -// QueryGroupInfoCmd creates a CLI command for Query/GroupInfo. -func QueryGroupInfoCmd() *cobra.Command { - cmd := &cobra.Command{ - Use: "group-info [id]", - Short: "Query for group info by group id", - Args: cobra.ExactArgs(1), - RunE: func(cmd *cobra.Command, args []string) error { - clientCtx, err := client.GetClientQueryContext(cmd) - if err != nil { - return err - } - - groupID, err := strconv.ParseUint(args[0], 10, 64) - if err != nil { - return err - } - - queryClient := group.NewQueryClient(clientCtx) - - res, err := queryClient.GroupInfo(cmd.Context(), &group.QueryGroupInfoRequest{ - GroupId: groupID, - }) - if err != nil { - return err - } - - return clientCtx.PrintProto(res.Info) - }, - } - - flags.AddQueryFlagsToCmd(cmd) - - return cmd -} - -// QueryGroupPolicyInfoCmd creates a CLI command for Query/GroupPolicyInfo. -func QueryGroupPolicyInfoCmd() *cobra.Command { - cmd := &cobra.Command{ - Use: "group-policy-info [group-policy-account]", - Short: "Query for group policy info by account address of group policy", - Args: cobra.ExactArgs(1), - RunE: func(cmd *cobra.Command, args []string) error { - clientCtx, err := client.GetClientQueryContext(cmd) - if err != nil { - return err - } - - queryClient := group.NewQueryClient(clientCtx) - - res, err := queryClient.GroupPolicyInfo(cmd.Context(), &group.QueryGroupPolicyInfoRequest{ - Address: args[0], - }) - if err != nil { - return err - } - - return clientCtx.PrintProto(res.Info) - }, - } - - flags.AddQueryFlagsToCmd(cmd) - - return cmd -} - -// QueryGroupMembersCmd creates a CLI command for Query/GroupMembers. -func QueryGroupMembersCmd() *cobra.Command { - cmd := &cobra.Command{ - Use: "group-members [id]", - Short: "Query for group members by group id with pagination flags", - Args: cobra.ExactArgs(1), - RunE: func(cmd *cobra.Command, args []string) error { - clientCtx, err := client.GetClientQueryContext(cmd) - if err != nil { - return err - } - - groupID, err := strconv.ParseUint(args[0], 10, 64) - if err != nil { - return err - } - - pageReq, err := client.ReadPageRequest(cmd.Flags()) - if err != nil { - return err - } - - queryClient := group.NewQueryClient(clientCtx) - - res, err := queryClient.GroupMembers(cmd.Context(), &group.QueryGroupMembersRequest{ - GroupId: groupID, - Pagination: pageReq, - }) - if err != nil { - return err - } - - return clientCtx.PrintProto(res) - }, - } - - flags.AddQueryFlagsToCmd(cmd) - flags.AddPaginationFlagsToCmd(cmd, "group-members") - - return cmd -} - -// QueryGroupsByAdminCmd creates a CLI command for Query/GroupsByAdmin. -func QueryGroupsByAdminCmd() *cobra.Command { - cmd := &cobra.Command{ - Use: "groups-by-admin [admin]", - Short: "Query for groups by admin account address with pagination flags", - Args: cobra.ExactArgs(1), - RunE: func(cmd *cobra.Command, args []string) error { - clientCtx, err := client.GetClientQueryContext(cmd) - if err != nil { - return err - } - - pageReq, err := client.ReadPageRequest(cmd.Flags()) - if err != nil { - return err - } - - queryClient := group.NewQueryClient(clientCtx) - - res, err := queryClient.GroupsByAdmin(cmd.Context(), &group.QueryGroupsByAdminRequest{ - Admin: args[0], - Pagination: pageReq, - }) - if err != nil { - return err - } - - return clientCtx.PrintProto(res) - }, - } - - flags.AddQueryFlagsToCmd(cmd) - flags.AddPaginationFlagsToCmd(cmd, "groups-by-admin") - - return cmd -} - -// QueryGroupPoliciesByGroupCmd creates a CLI command for Query/GroupPoliciesByGroup. -func QueryGroupPoliciesByGroupCmd() *cobra.Command { - cmd := &cobra.Command{ - Use: "group-policies-by-group [group-id]", - Short: "Query for group policies by group id with pagination flags", - Args: cobra.ExactArgs(1), - RunE: func(cmd *cobra.Command, args []string) error { - clientCtx, err := client.GetClientQueryContext(cmd) - if err != nil { - return err - } - - groupID, err := strconv.ParseUint(args[0], 10, 64) - if err != nil { - return err - } - - pageReq, err := client.ReadPageRequest(cmd.Flags()) - if err != nil { - return err - } - - queryClient := group.NewQueryClient(clientCtx) - - res, err := queryClient.GroupPoliciesByGroup(cmd.Context(), &group.QueryGroupPoliciesByGroupRequest{ - GroupId: groupID, - Pagination: pageReq, - }) - if err != nil { - return err - } - - return clientCtx.PrintProto(res) - }, - } - - flags.AddQueryFlagsToCmd(cmd) - flags.AddPaginationFlagsToCmd(cmd, "groups-policies-by-group") - - return cmd -} - -// QueryGroupPoliciesByAdminCmd creates a CLI command for Query/GroupPoliciesByAdmin. -func QueryGroupPoliciesByAdminCmd() *cobra.Command { - cmd := &cobra.Command{ - Use: "group-policies-by-admin [admin]", - Short: "Query for group policies by admin account address with pagination flags", - Args: cobra.ExactArgs(1), - RunE: func(cmd *cobra.Command, args []string) error { - clientCtx, err := client.GetClientQueryContext(cmd) - if err != nil { - return err - } - - pageReq, err := client.ReadPageRequest(cmd.Flags()) - if err != nil { - return err - } - - queryClient := group.NewQueryClient(clientCtx) - - res, err := queryClient.GroupPoliciesByAdmin(cmd.Context(), &group.QueryGroupPoliciesByAdminRequest{ - Admin: args[0], - Pagination: pageReq, - }) - if err != nil { - return err - } - - return clientCtx.PrintProto(res) - }, - } - - flags.AddQueryFlagsToCmd(cmd) - flags.AddPaginationFlagsToCmd(cmd, "group-policies-by-admin") - - return cmd -} - -// QueryProposalCmd creates a CLI command for Query/Proposal. -func QueryProposalCmd() *cobra.Command { - cmd := &cobra.Command{ - Use: "proposal [id]", - Short: "Query for proposal by id", - Args: cobra.ExactArgs(1), - RunE: func(cmd *cobra.Command, args []string) error { - clientCtx, err := client.GetClientQueryContext(cmd) - if err != nil { - return err - } - - proposalID, err := strconv.ParseUint(args[0], 10, 64) - if err != nil { - return err - } - - queryClient := group.NewQueryClient(clientCtx) - - res, err := queryClient.Proposal(cmd.Context(), &group.QueryProposalRequest{ - ProposalId: proposalID, - }) - if err != nil { - return err - } - - return clientCtx.PrintProto(res) - }, - } - - flags.AddQueryFlagsToCmd(cmd) - - return cmd -} - -// QueryProposalsByGroupPolicyCmd creates a CLI command for Query/ProposalsByGroupPolicy. -func QueryProposalsByGroupPolicyCmd() *cobra.Command { - cmd := &cobra.Command{ - Use: "proposals-by-group-policy [group-policy-account]", - Short: "Query for proposals by account address of group policy with pagination flags", - Args: cobra.ExactArgs(1), - RunE: func(cmd *cobra.Command, args []string) error { - clientCtx, err := client.GetClientQueryContext(cmd) - if err != nil { - return err - } - - pageReq, err := client.ReadPageRequest(cmd.Flags()) - if err != nil { - return err - } - - queryClient := group.NewQueryClient(clientCtx) - - res, err := queryClient.ProposalsByGroupPolicy(cmd.Context(), &group.QueryProposalsByGroupPolicyRequest{ - Address: args[0], - Pagination: pageReq, - }) - if err != nil { - return err - } - - return clientCtx.PrintProto(res) - }, - } - - flags.AddQueryFlagsToCmd(cmd) - flags.AddPaginationFlagsToCmd(cmd, "proposals-by-group-policy") - - return cmd -} - -// QueryVoteByProposalVoterCmd creates a CLI command for Query/VoteByProposalVoter. -func QueryVoteByProposalVoterCmd() *cobra.Command { - cmd := &cobra.Command{ - Use: "vote [proposal-id] [voter]", - Short: "Query for vote by proposal id and voter account address", - Args: cobra.ExactArgs(2), - RunE: func(cmd *cobra.Command, args []string) error { - clientCtx, err := client.GetClientQueryContext(cmd) - if err != nil { - return err - } - - proposalID, err := strconv.ParseUint(args[0], 10, 64) - if err != nil { - return err - } - - queryClient := group.NewQueryClient(clientCtx) - - res, err := queryClient.VoteByProposalVoter(cmd.Context(), &group.QueryVoteByProposalVoterRequest{ - ProposalId: proposalID, - Voter: args[1], - }) - if err != nil { - return err - } - - return clientCtx.PrintProto(res) - }, - } - - flags.AddQueryFlagsToCmd(cmd) - - return cmd -} - -// QueryVotesByProposalCmd creates a CLI command for Query/VotesByProposal. -func QueryVotesByProposalCmd() *cobra.Command { - cmd := &cobra.Command{ - Use: "votes-by-proposal [proposal-id]", - Short: "Query for votes by proposal id with pagination flags", - Args: cobra.ExactArgs(1), - RunE: func(cmd *cobra.Command, args []string) error { - clientCtx, err := client.GetClientQueryContext(cmd) - if err != nil { - return err - } - - proposalID, err := strconv.ParseUint(args[0], 10, 64) - if err != nil { - return err - } - - pageReq, err := client.ReadPageRequest(cmd.Flags()) - if err != nil { - return err - } - - queryClient := group.NewQueryClient(clientCtx) - - res, err := queryClient.VotesByProposal(cmd.Context(), &group.QueryVotesByProposalRequest{ - ProposalId: proposalID, - Pagination: pageReq, - }) - if err != nil { - return err - } - - return clientCtx.PrintProto(res) - }, - } - - flags.AddQueryFlagsToCmd(cmd) - flags.AddPaginationFlagsToCmd(cmd, "votes-by-proposal") - - return cmd -} - -// QueryTallyResultCmd creates a CLI command for Query/TallyResult. -func QueryTallyResultCmd() *cobra.Command { - cmd := &cobra.Command{ - Use: "tally-result [proposal-id]", - Short: "Query tally result of proposal", - Args: cobra.ExactArgs(1), - RunE: func(cmd *cobra.Command, args []string) error { - clientCtx, err := client.GetClientQueryContext(cmd) - if err != nil { - return err - } - - proposalID, err := strconv.ParseUint(args[0], 10, 64) - if err != nil { - return err - } - - queryClient := group.NewQueryClient(clientCtx) - - res, err := queryClient.TallyResult(cmd.Context(), &group.QueryTallyResultRequest{ - ProposalId: proposalID, - }) - if err != nil { - return err - } - - return clientCtx.PrintProto(res) - }, - } - - flags.AddQueryFlagsToCmd(cmd) - - return cmd -} - -// QueryVotesByVoterCmd creates a CLI command for Query/VotesByVoter. -func QueryVotesByVoterCmd() *cobra.Command { - cmd := &cobra.Command{ - Use: "votes-by-voter [voter]", - Short: "Query for votes by voter account address with pagination flags", - Args: cobra.ExactArgs(1), - RunE: func(cmd *cobra.Command, args []string) error { - clientCtx, err := client.GetClientQueryContext(cmd) - if err != nil { - return err - } - - pageReq, err := client.ReadPageRequest(cmd.Flags()) - if err != nil { - return err - } - - queryClient := group.NewQueryClient(clientCtx) - - res, err := queryClient.VotesByVoter(cmd.Context(), &group.QueryVotesByVoterRequest{ - Voter: args[0], - Pagination: pageReq, - }) - if err != nil { - return err - } - - return clientCtx.PrintProto(res) - }, - } - - flags.AddQueryFlagsToCmd(cmd) - flags.AddPaginationFlagsToCmd(cmd, "votes-by-voter") - - return cmd -} - -// QueryGroupsCmd creates a CLI command for Query/Groups. -func QueryGroupsCmd() *cobra.Command { - cmd := &cobra.Command{ - Use: "groups", - Short: "Query for groups present in the state", - RunE: func(cmd *cobra.Command, args []string) error { - clientCtx, err := client.GetClientQueryContext(cmd) - if err != nil { - return err - } - - pageReq, err := client.ReadPageRequest(cmd.Flags()) - if err != nil { - return err - } - - queryClient := group.NewQueryClient(clientCtx) - - res, err := queryClient.Groups(cmd.Context(), &group.QueryGroupsRequest{ - Pagination: pageReq, - }) - if err != nil { - return err - } - - return clientCtx.PrintProto(res) - }, - } - - flags.AddQueryFlagsToCmd(cmd) - flags.AddPaginationFlagsToCmd(cmd, "groups") - - return cmd -} diff --git a/x/group/client/cli/query_test.go b/x/group/client/cli/query_test.go deleted file mode 100644 index 5e9735ababc..00000000000 --- a/x/group/client/cli/query_test.go +++ /dev/null @@ -1,513 +0,0 @@ -package cli_test - -import ( - "context" - "fmt" - "io" - - "github.com/cosmos/cosmos-sdk/client" - "github.com/cosmos/cosmos-sdk/client/flags" - svrcmd "github.com/cosmos/cosmos-sdk/server/cmd" - "github.com/cosmos/cosmos-sdk/testutil" - "github.com/cosmos/cosmos-sdk/x/group/client/cli" -) - -func (s *CLITestSuite) TestQueryGroupInfo() { - testCases := []struct { - name string - args []string - expCmdOutput string - }{ - { - name: "invalid id", - args: []string{"invalid id"}, - expCmdOutput: `[invalid id]`, - }, - { - name: "json output", - args: []string{"1", fmt.Sprintf("--%s=json", flags.FlagOutput)}, - expCmdOutput: `[1 --output=json]`, - }, - { - name: "text output", - args: []string{"1", fmt.Sprintf("--%s=text", flags.FlagOutput)}, - expCmdOutput: `[1 --output=text]`, - }, - } - - for _, tc := range testCases { - s.Run(tc.name, func() { - cmd := cli.QueryGroupInfoCmd() - - ctx := svrcmd.CreateExecuteContext(context.Background()) - - cmd.SetOut(io.Discard) - s.Require().NotNil(cmd) - - cmd.SetContext(ctx) - cmd.SetArgs(tc.args) - s.Require().NoError(client.SetCmdClientContextHandler(s.baseCtx, cmd)) - - s.Require().Contains(fmt.Sprint(cmd), "group-info [id] [] [] Query for group info by group id") - s.Require().Contains(fmt.Sprint(cmd), tc.expCmdOutput) - }) - } -} - -func (s *CLITestSuite) TestQueryGroupPolicyInfo() { - accounts := testutil.CreateKeyringAccounts(s.T(), s.kr, 1) - - testCases := []struct { - name string - args []string - expCmdOutput string - }{ - { - name: "json output", - args: []string{accounts[0].Address.String(), fmt.Sprintf("--%s=json", flags.FlagOutput)}, - expCmdOutput: fmt.Sprintf("%s --output=json", accounts[0].Address.String()), - }, - { - name: "text output", - args: []string{accounts[0].Address.String(), fmt.Sprintf("--%s=text", flags.FlagOutput)}, - expCmdOutput: fmt.Sprintf("%s --output=text", accounts[0].Address.String()), - }, - } - - for _, tc := range testCases { - s.Run(tc.name, func() { - cmd := cli.QueryGroupPolicyInfoCmd() - - ctx := svrcmd.CreateExecuteContext(context.Background()) - - cmd.SetOut(io.Discard) - s.Require().NotNil(cmd) - - cmd.SetContext(ctx) - cmd.SetArgs(tc.args) - s.Require().NoError(client.SetCmdClientContextHandler(s.baseCtx, cmd)) - - s.Require().Contains(fmt.Sprint(cmd), "group-policy-info [group-policy-account] [] [] Query for group policy info by account address of group policy") - s.Require().Contains(fmt.Sprint(cmd), tc.expCmdOutput) - }) - } -} - -func (s *CLITestSuite) TestQueryGroupMembers() { - testCases := []struct { - name string - args []string - expCmdOutput string - }{ - { - name: "json output", - args: []string{"1", fmt.Sprintf("--%s=json", flags.FlagOutput)}, - expCmdOutput: "1 --output=json", - }, - { - name: "text output", - args: []string{"1", fmt.Sprintf("--%s=text", flags.FlagOutput)}, - expCmdOutput: "1 --output=text", - }, - } - - for _, tc := range testCases { - s.Run(tc.name, func() { - cmd := cli.QueryGroupMembersCmd() - - ctx := svrcmd.CreateExecuteContext(context.Background()) - - cmd.SetOut(io.Discard) - s.Require().NotNil(cmd) - - cmd.SetContext(ctx) - cmd.SetArgs(tc.args) - s.Require().NoError(client.SetCmdClientContextHandler(s.baseCtx, cmd)) - - s.Require().Contains(fmt.Sprint(cmd), "group-members [id] [] [] Query for group members by group id with pagination flags") - s.Require().Contains(fmt.Sprint(cmd), tc.expCmdOutput) - }) - } -} - -func (s *CLITestSuite) TestQueryGroupsByAdmin() { - accounts := testutil.CreateKeyringAccounts(s.T(), s.kr, 1) - - testCases := []struct { - name string - args []string - expCmdOutput string - }{ - { - name: "json output", - args: []string{accounts[0].Address.String(), fmt.Sprintf("--%s=json", flags.FlagOutput)}, - expCmdOutput: fmt.Sprintf("%s --output=json", accounts[0].Address.String()), - }, - { - name: "text output", - args: []string{accounts[0].Address.String(), fmt.Sprintf("--%s=text", flags.FlagOutput)}, - expCmdOutput: fmt.Sprintf("%s --output=text", accounts[0].Address.String()), - }, - } - - for _, tc := range testCases { - s.Run(tc.name, func() { - cmd := cli.QueryGroupsByAdminCmd() - - ctx := svrcmd.CreateExecuteContext(context.Background()) - - cmd.SetOut(io.Discard) - s.Require().NotNil(cmd) - - cmd.SetContext(ctx) - cmd.SetArgs(tc.args) - s.Require().NoError(client.SetCmdClientContextHandler(s.baseCtx, cmd)) - - s.Require().Contains(fmt.Sprint(cmd), "groups-by-admin [admin] [] [] Query for groups by admin account address with pagination flags") - s.Require().Contains(fmt.Sprint(cmd), tc.expCmdOutput) - }) - } -} - -func (s *CLITestSuite) TestQueryGroupPoliciesByGroup() { - testCases := []struct { - name string - args []string - expCmdOutput string - }{ - { - name: "json output", - args: []string{"1", fmt.Sprintf("--%s=json", flags.FlagOutput)}, - expCmdOutput: "1 --output=json", - }, - { - name: "text output", - args: []string{"1", fmt.Sprintf("--%s=text", flags.FlagOutput)}, - expCmdOutput: "1 --output=text", - }, - } - - for _, tc := range testCases { - s.Run(tc.name, func() { - cmd := cli.QueryGroupPoliciesByGroupCmd() - - ctx := svrcmd.CreateExecuteContext(context.Background()) - - cmd.SetOut(io.Discard) - s.Require().NotNil(cmd) - - cmd.SetContext(ctx) - cmd.SetArgs(tc.args) - s.Require().NoError(client.SetCmdClientContextHandler(s.baseCtx, cmd)) - - s.Require().Contains(fmt.Sprint(cmd), "group-policies-by-group [group-id] [] [] Query for group policies by group id with pagination flags") - s.Require().Contains(fmt.Sprint(cmd), tc.expCmdOutput) - }) - } -} - -func (s *CLITestSuite) TestQueryGroupPoliciesByAdmin() { - accounts := testutil.CreateKeyringAccounts(s.T(), s.kr, 1) - - testCases := []struct { - name string - args []string - expCmdOutput string - }{ - { - name: "json output", - args: []string{accounts[0].Address.String(), fmt.Sprintf("--%s=json", flags.FlagOutput)}, - expCmdOutput: fmt.Sprintf("%s --output=json", accounts[0].Address.String()), - }, - { - name: "text output", - args: []string{accounts[0].Address.String(), fmt.Sprintf("--%s=text", flags.FlagOutput)}, - expCmdOutput: fmt.Sprintf("%s --output=text", accounts[0].Address.String()), - }, - } - - for _, tc := range testCases { - s.Run(tc.name, func() { - cmd := cli.QueryGroupPoliciesByAdminCmd() - - ctx := svrcmd.CreateExecuteContext(context.Background()) - - cmd.SetOut(io.Discard) - s.Require().NotNil(cmd) - - cmd.SetContext(ctx) - cmd.SetArgs(tc.args) - s.Require().NoError(client.SetCmdClientContextHandler(s.baseCtx, cmd)) - - s.Require().Contains(fmt.Sprint(cmd), "group-policies-by-admin [admin] [] [] Query for group policies by admin account address with pagination flags") - s.Require().Contains(fmt.Sprint(cmd), tc.expCmdOutput) - }) - } -} - -func (s *CLITestSuite) TestQueryProposal() { - testCases := []struct { - name string - args []string - expCmdOutput string - }{ - { - name: "json output", - args: []string{"1", fmt.Sprintf("--%s=json", flags.FlagOutput)}, - expCmdOutput: "1 --output=json", - }, - { - name: "text output", - args: []string{"1", fmt.Sprintf("--%s=text", flags.FlagOutput)}, - expCmdOutput: "1 --output=text", - }, - } - - for _, tc := range testCases { - s.Run(tc.name, func() { - cmd := cli.QueryProposalCmd() - - ctx := svrcmd.CreateExecuteContext(context.Background()) - - cmd.SetOut(io.Discard) - s.Require().NotNil(cmd) - - cmd.SetContext(ctx) - cmd.SetArgs(tc.args) - s.Require().NoError(client.SetCmdClientContextHandler(s.baseCtx, cmd)) - - s.Require().Contains(fmt.Sprint(cmd), "proposal [id] [] [] Query for proposal by id") - s.Require().Contains(fmt.Sprint(cmd), tc.expCmdOutput) - }) - } -} - -func (s *CLITestSuite) TestQueryProposalsByGroupPolicy() { - accounts := testutil.CreateKeyringAccounts(s.T(), s.kr, 1) - - testCases := []struct { - name string - args []string - expCmdOutput string - }{ - { - name: "json output", - args: []string{accounts[0].Address.String(), fmt.Sprintf("--%s=json", flags.FlagOutput)}, - expCmdOutput: fmt.Sprintf("%s --output=json", accounts[0].Address.String()), - }, - { - name: "text output", - args: []string{accounts[0].Address.String(), fmt.Sprintf("--%s=text", flags.FlagOutput)}, - expCmdOutput: fmt.Sprintf("%s --output=text", accounts[0].Address.String()), - }, - } - - for _, tc := range testCases { - s.Run(tc.name, func() { - cmd := cli.QueryProposalsByGroupPolicyCmd() - - ctx := svrcmd.CreateExecuteContext(context.Background()) - - cmd.SetOut(io.Discard) - s.Require().NotNil(cmd) - - cmd.SetContext(ctx) - cmd.SetArgs(tc.args) - s.Require().NoError(client.SetCmdClientContextHandler(s.baseCtx, cmd)) - - s.Require().Contains(fmt.Sprint(cmd), "proposals-by-group-policy [group-policy-account] [] [] Query for proposals by account address of group policy with pagination flags") - s.Require().Contains(fmt.Sprint(cmd), tc.expCmdOutput) - }) - } -} - -func (s *CLITestSuite) TestQueryVoteByProposalVoter() { - accounts := testutil.CreateKeyringAccounts(s.T(), s.kr, 1) - - testCases := []struct { - name string - args []string - expCmdOutput string - }{ - { - name: "json output", - args: []string{"1", accounts[0].Address.String(), fmt.Sprintf("--%s=json", flags.FlagOutput)}, - expCmdOutput: fmt.Sprintf("1 %s --output=json", accounts[0].Address.String()), - }, - { - name: "text output", - args: []string{"1", accounts[0].Address.String(), fmt.Sprintf("--%s=text", flags.FlagOutput)}, - expCmdOutput: fmt.Sprintf("1 %s --output=text", accounts[0].Address.String()), - }, - } - - for _, tc := range testCases { - s.Run(tc.name, func() { - cmd := cli.QueryVoteByProposalVoterCmd() - - ctx := svrcmd.CreateExecuteContext(context.Background()) - - cmd.SetOut(io.Discard) - s.Require().NotNil(cmd) - - cmd.SetContext(ctx) - cmd.SetArgs(tc.args) - s.Require().NoError(client.SetCmdClientContextHandler(s.baseCtx, cmd)) - - s.Require().Contains(fmt.Sprint(cmd), "vote [proposal-id] [voter] [] [] Query for vote by proposal id and voter account address") - s.Require().Contains(fmt.Sprint(cmd), tc.expCmdOutput) - }) - } -} - -func (s *CLITestSuite) TestQueryVotesByProposal() { - testCases := []struct { - name string - args []string - expCmdOutput string - }{ - { - name: "json output", - args: []string{"1", fmt.Sprintf("--%s=json", flags.FlagOutput)}, - expCmdOutput: "1 --output=json", - }, - { - name: "text output", - args: []string{"1", fmt.Sprintf("--%s=text", flags.FlagOutput)}, - expCmdOutput: "1 --output=text", - }, - } - - for _, tc := range testCases { - s.Run(tc.name, func() { - cmd := cli.QueryVotesByProposalCmd() - - ctx := svrcmd.CreateExecuteContext(context.Background()) - - cmd.SetOut(io.Discard) - s.Require().NotNil(cmd) - - cmd.SetContext(ctx) - cmd.SetArgs(tc.args) - s.Require().NoError(client.SetCmdClientContextHandler(s.baseCtx, cmd)) - - s.Require().Contains(fmt.Sprint(cmd), "votes-by-proposal [proposal-id] [] [] Query for votes by proposal id with pagination flags") - s.Require().Contains(fmt.Sprint(cmd), tc.expCmdOutput) - }) - } -} - -func (s *CLITestSuite) TestQueryTallyResult() { - testCases := []struct { - name string - args []string - expCmdOutput string - }{ - { - name: "json output", - args: []string{"1", fmt.Sprintf("--%s=json", flags.FlagOutput)}, - expCmdOutput: "1 --output=json", - }, - { - name: "text output", - args: []string{"1", fmt.Sprintf("--%s=text", flags.FlagOutput)}, - expCmdOutput: "1 --output=text", - }, - } - - for _, tc := range testCases { - s.Run(tc.name, func() { - cmd := cli.QueryTallyResultCmd() - - ctx := svrcmd.CreateExecuteContext(context.Background()) - - cmd.SetOut(io.Discard) - s.Require().NotNil(cmd) - - cmd.SetContext(ctx) - cmd.SetArgs(tc.args) - s.Require().NoError(client.SetCmdClientContextHandler(s.baseCtx, cmd)) - - s.Require().Contains(fmt.Sprint(cmd), "tally-result [proposal-id] [] [] Query tally result of proposal") - s.Require().Contains(fmt.Sprint(cmd), tc.expCmdOutput) - }) - } -} - -func (s *CLITestSuite) TestQueryVotesByVoter() { - accounts := testutil.CreateKeyringAccounts(s.T(), s.kr, 1) - - testCases := []struct { - name string - args []string - expCmdOutput string - }{ - { - name: "json output", - args: []string{accounts[0].Address.String(), fmt.Sprintf("--%s=json", flags.FlagOutput)}, - expCmdOutput: fmt.Sprintf("%s --output=json", accounts[0].Address.String()), - }, - { - name: "text output", - args: []string{accounts[0].Address.String(), fmt.Sprintf("--%s=text", flags.FlagOutput)}, - expCmdOutput: fmt.Sprintf("%s --output=text", accounts[0].Address.String()), - }, - } - - for _, tc := range testCases { - s.Run(tc.name, func() { - cmd := cli.QueryVotesByVoterCmd() - - ctx := svrcmd.CreateExecuteContext(context.Background()) - - cmd.SetOut(io.Discard) - s.Require().NotNil(cmd) - - cmd.SetContext(ctx) - cmd.SetArgs(tc.args) - s.Require().NoError(client.SetCmdClientContextHandler(s.baseCtx, cmd)) - - s.Require().Contains(fmt.Sprint(cmd), "votes-by-voter [voter] [] [] Query for votes by voter account address with pagination flags") - s.Require().Contains(fmt.Sprint(cmd), tc.expCmdOutput) - }) - } -} - -func (s *CLITestSuite) TestQueryGroupsByMembers() { - accounts := testutil.CreateKeyringAccounts(s.T(), s.kr, 1) - - testCases := []struct { - name string - args []string - expCmdOutput string - }{ - { - name: "json output", - args: []string{accounts[0].Address.String(), fmt.Sprintf("--%s=json", flags.FlagOutput)}, - expCmdOutput: fmt.Sprintf("%s --output=json", accounts[0].Address.String()), - }, - { - name: "text output", - args: []string{accounts[0].Address.String(), fmt.Sprintf("--%s=text", flags.FlagOutput)}, - expCmdOutput: fmt.Sprintf("%s --output=text", accounts[0].Address.String()), - }, - } - - for _, tc := range testCases { - s.Run(tc.name, func() { - cmd := cli.QueryGroupsByMemberCmd() - - ctx := svrcmd.CreateExecuteContext(context.Background()) - - cmd.SetOut(io.Discard) - s.Require().NotNil(cmd) - - cmd.SetContext(ctx) - cmd.SetArgs(tc.args) - s.Require().NoError(client.SetCmdClientContextHandler(s.baseCtx, cmd)) - - s.Require().Contains(fmt.Sprint(cmd), "groups-by-member [address] [] [] Query for groups by member address with pagination flags") - s.Require().Contains(fmt.Sprint(cmd), tc.expCmdOutput) - }) - } -} diff --git a/x/group/client/cli/util_test.go b/x/group/client/cli/util_test.go index 67b90ef3d65..c883def2fa0 100644 --- a/x/group/client/cli/util_test.go +++ b/x/group/client/cli/util_test.go @@ -6,7 +6,7 @@ import ( "github.com/stretchr/testify/require" ) -func Test_ParseCLIProposal(t *testing.T) { +func TestParseCLIProposal(t *testing.T) { data := []byte(`{ "group_policy_address": "cosmos15r295x4994egvckteam9skazy9kvfvzpak4naf", "messages": [ diff --git a/x/group/keeper/grpc_query_test.go b/x/group/keeper/grpc_query_test.go index f73ab33e63c..0bf32601948 100644 --- a/x/group/keeper/grpc_query_test.go +++ b/x/group/keeper/grpc_query_test.go @@ -25,6 +25,8 @@ import ( grouptestutil "github.com/cosmos/cosmos-sdk/x/group/testutil" ) +// TODO add all missing tests + func initKeeper(t *testing.T) (types.Context, groupkeeper.Keeper, []types.AccAddress, group.QueryClient) { t.Helper() var ( diff --git a/x/group/module/autocli.go b/x/group/module/autocli.go new file mode 100644 index 00000000000..071e33b51b6 --- /dev/null +++ b/x/group/module/autocli.go @@ -0,0 +1,130 @@ +package module + +import ( + autocliv1 "cosmossdk.io/api/cosmos/autocli/v1" + groupv1 "cosmossdk.io/api/cosmos/group/v1" +) + +// AutoCLIOptions implements the autocli.HasAutoCLIConfig interface. +func (am AppModule) AutoCLIOptions() *autocliv1.ModuleOptions { + return &autocliv1.ModuleOptions{ + Query: &autocliv1.ServiceCommandDescriptor{ + Service: groupv1.Query_ServiceDesc.ServiceName, + RpcCommandOptions: []*autocliv1.RpcCommandOptions{ + { + RpcMethod: "GroupInfo", + Use: "group-info [group-id]", + Short: "Query for group info by group id", + PositionalArgs: []*autocliv1.PositionalArgDescriptor{ + {ProtoField: "group_id"}, + }, + }, + { + RpcMethod: "GroupPolicyInfo", + Use: "group-policy-info [group-policy-account]", + Short: "Query for group policy info by account address of group policy", + PositionalArgs: []*autocliv1.PositionalArgDescriptor{ + {ProtoField: "address"}, + }, + }, + { + RpcMethod: "GroupMembers", + Use: "group-members [group-id]", + Short: "Query for group members by group id", + PositionalArgs: []*autocliv1.PositionalArgDescriptor{ + {ProtoField: "group_id"}, + }, + }, + { + RpcMethod: "GroupsByAdmin", + Use: "groups-by-admin [admin]", + Short: "Query for groups by admin account address", + PositionalArgs: []*autocliv1.PositionalArgDescriptor{ + {ProtoField: "admin"}, + }, + }, + { + RpcMethod: "GroupPoliciesByGroup", + Use: "group-policies-by-group [group-id]", + Short: "Query for group policies by group id", + PositionalArgs: []*autocliv1.PositionalArgDescriptor{ + {ProtoField: "group_id"}, + }, + }, + { + RpcMethod: "GroupPoliciesByAdmin", + Use: "group-policies-by-admin [admin]", + Short: "Query for group policies by admin account address", + PositionalArgs: []*autocliv1.PositionalArgDescriptor{ + {ProtoField: "admin"}, + }, + }, + { + RpcMethod: "Proposal", + Use: "proposal [proposal-id]", + Short: "Query for proposal by id", + PositionalArgs: []*autocliv1.PositionalArgDescriptor{ + {ProtoField: "proposal_id"}, + }, + }, + { + RpcMethod: "ProposalsByGroupPolicy", + Use: "proposals-by-group-policy [group-policy-account]", + Short: "Query for proposals by account address of group policy", + PositionalArgs: []*autocliv1.PositionalArgDescriptor{ + {ProtoField: "address"}, + }, + }, + { + RpcMethod: "VoteByProposalVoter", + Use: "vote [proposal-id] [voter]", + Short: "Query for vote by proposal id and voter account address", + PositionalArgs: []*autocliv1.PositionalArgDescriptor{ + {ProtoField: "proposal_id"}, + {ProtoField: "voter"}, + }, + }, + { + RpcMethod: "VotesByProposal", + Use: "votes-by-proposal [proposal-id]", + Short: "Query for votes by proposal id", + PositionalArgs: []*autocliv1.PositionalArgDescriptor{ + {ProtoField: "proposal_id"}, + }, + }, + { + RpcMethod: "VotesByVoter", + Use: "votes-by-voter [voter]", + Short: "Query for votes by voter account address", + PositionalArgs: []*autocliv1.PositionalArgDescriptor{ + {ProtoField: "voter"}, + }, + }, + { + RpcMethod: "GroupsByMember", + Use: "groups-by-member [address]", + Short: "Query for groups by member address", + PositionalArgs: []*autocliv1.PositionalArgDescriptor{ + {ProtoField: "address"}, + }, + }, + { + RpcMethod: "TallyResult", + Use: "tally-result [proposal-id]", + Short: "Query tally result of proposal", + PositionalArgs: []*autocliv1.PositionalArgDescriptor{ + {ProtoField: "proposal_id"}, + }, + }, + { + RpcMethod: "Groups", + Use: "groups", + Short: "Query for all groups on chain", + }, + }, + }, + Tx: &autocliv1.ServiceCommandDescriptor{ + Service: groupv1.Query_ServiceDesc.ServiceName, + }, + } +} diff --git a/x/group/module/module.go b/x/group/module/module.go index b20bea5428e..f5151f2d670 100644 --- a/x/group/module/module.go +++ b/x/group/module/module.go @@ -91,11 +91,6 @@ func (AppModuleBasic) ValidateGenesis(cdc codec.JSONCodec, config sdkclient.TxEn return data.Validate() } -// GetQueryCmd returns the cli query commands for the group module -func (a AppModuleBasic) GetQueryCmd() *cobra.Command { - return cli.QueryCmd(a.Name()) -} - // GetTxCmd returns the transaction commands for the group module func (a AppModuleBasic) GetTxCmd() *cobra.Command { return cli.TxCmd(a.Name(), a.ac) From c9c6b91fb29078c2de0fede769de8a12a200e080 Mon Sep 17 00:00:00 2001 From: Julien Robert Date: Mon, 17 Jul 2023 11:14:27 +0200 Subject: [PATCH 2/4] add few tests --- x/group/keeper/grpc_query_test.go | 76 +++++++++++++++++++------------ 1 file changed, 48 insertions(+), 28 deletions(-) diff --git a/x/group/keeper/grpc_query_test.go b/x/group/keeper/grpc_query_test.go index 0bf32601948..58c73341c6e 100644 --- a/x/group/keeper/grpc_query_test.go +++ b/x/group/keeper/grpc_query_test.go @@ -3,6 +3,7 @@ package keeper_test import ( "context" "testing" + "time" "github.com/golang/mock/gomock" "github.com/stretchr/testify/require" @@ -25,8 +26,6 @@ import ( grouptestutil "github.com/cosmos/cosmos-sdk/x/group/testutil" ) -// TODO add all missing tests - func initKeeper(t *testing.T) (types.Context, groupkeeper.Keeper, []types.AccAddress, group.QueryClient) { t.Helper() var ( @@ -56,32 +55,65 @@ func initKeeper(t *testing.T) (types.Context, groupkeeper.Keeper, []types.AccAdd accountKeeper.EXPECT().AddressCodec().Return(address.NewBech32Codec("cosmos")).AnyTimes() groupKeeper = groupkeeper.NewKeeper(key, encCfg.Codec, bApp.MsgServiceRouter(), accountKeeper, group.DefaultConfig()) - queryHelper := baseapp.NewQueryServerTestHelper(ctx, interfaceRegistry) group.RegisterQueryServer(queryHelper, groupKeeper) queryClient := group.NewQueryClient(queryHelper) + msgGroupAndPolicy := &group.MsgCreateGroupWithPolicy{ + Admin: addrs[0].String(), + Members: []group.MemberRequest{ + {Address: addrs[1].String(), Weight: "1"}, + {Address: addrs[3].String(), Weight: "2"}, + }, + } + msgGroupAndPolicy.SetDecisionPolicy(group.NewThresholdDecisionPolicy("2", time.Second, 20)) + + _, err := groupKeeper.CreateGroupWithPolicy(ctx, msgGroupAndPolicy) + require.NoError(t, err) + return ctx, groupKeeper, addrs, queryClient } -func TestQueryGroupsByMember(t *testing.T) { - ctx, groupKeeper, addrs, queryClient := initKeeper(t) +func TestQueryGroupInfo(t *testing.T) { + ctx, _, _, queryClient := initKeeper(t) - // Initial group, group policy and balance setup - members := []group.MemberRequest{ - {Address: addrs[2].String(), Weight: "1"}, {Address: addrs[3].String(), Weight: "2"}, + testCases := []struct { + name string + groupID uint64 + expErrMsg string + }{ + { + name: "unknown id", + groupID: 20, + expErrMsg: "group: not found", + }, + { + name: "valid id", + groupID: 1, + expErrMsg: "", + }, } - _, err := groupKeeper.CreateGroup(ctx, &group.MsgCreateGroup{ - Admin: addrs[0].String(), - Members: members, - }) - require.NoError(t, err) + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + _, err := queryClient.GroupInfo(ctx, &group.QueryGroupInfoRequest{GroupId: tc.groupID}) + if tc.expErrMsg != "" { + require.Error(t, err) + require.Contains(t, err.Error(), tc.expErrMsg) + } else { + require.NoError(t, err) + } + }) + } +} + +func TestQueryGroupsByMember(t *testing.T) { + ctx, groupKeeper, addrs, queryClient := initKeeper(t) - members = []group.MemberRequest{ + members := []group.MemberRequest{ {Address: addrs[3].String(), Weight: "1"}, {Address: addrs[4].String(), Weight: "2"}, } - _, err = groupKeeper.CreateGroup(ctx, &group.MsgCreateGroup{ + _, err := groupKeeper.CreateGroup(ctx, &group.MsgCreateGroup{ Admin: addrs[1].String(), Members: members, }) @@ -112,22 +144,10 @@ func TestQueryGroupsByMember(t *testing.T) { func TestQueryGroups(t *testing.T) { ctx, groupKeeper, addrs, queryClient := initKeeper(t) - // Initial group, group policy and balance setup members := []group.MemberRequest{ - {Address: addrs[1].String(), Weight: "1"}, - {Address: addrs[3].String(), Weight: "2"}, - } - - _, err := groupKeeper.CreateGroup(ctx, &group.MsgCreateGroup{ - Admin: addrs[0].String(), - Members: members, - }) - require.NoError(t, err) - - members = []group.MemberRequest{ {Address: addrs[3].String(), Weight: "1"}, } - _, err = groupKeeper.CreateGroup(ctx, &group.MsgCreateGroup{ + _, err := groupKeeper.CreateGroup(ctx, &group.MsgCreateGroup{ Admin: addrs[2].String(), Members: members, }) From 339ba1bd64bbafff02221f103a85f25d2083ef83 Mon Sep 17 00:00:00 2001 From: Julien Robert Date: Mon, 17 Jul 2023 13:29:39 +0200 Subject: [PATCH 3/4] updates --- x/group/keeper/grpc_query.go | 5 + x/group/keeper/grpc_query_test.go | 284 +++++++++++++++++++++++++++--- 2 files changed, 265 insertions(+), 24 deletions(-) diff --git a/x/group/keeper/grpc_query.go b/x/group/keeper/grpc_query.go index eed68bc46af..2c036bdedf4 100644 --- a/x/group/keeper/grpc_query.go +++ b/x/group/keeper/grpc_query.go @@ -39,6 +39,11 @@ func (k Keeper) getGroupInfo(ctx sdk.Context, id uint64) (group.GroupInfo, error // GroupPolicyInfo queries info about a group policy. func (k Keeper) GroupPolicyInfo(goCtx context.Context, request *group.QueryGroupPolicyInfoRequest) (*group.QueryGroupPolicyInfoResponse, error) { + _, err := k.accKeeper.AddressCodec().StringToBytes(request.Address) + if err != nil { + return nil, err + } + ctx := sdk.UnwrapSDKContext(goCtx) groupPolicyInfo, err := k.getGroupPolicyInfo(ctx, request.Address) if err != nil { diff --git a/x/group/keeper/grpc_query_test.go b/x/group/keeper/grpc_query_test.go index 58c73341c6e..f71f86a84e6 100644 --- a/x/group/keeper/grpc_query_test.go +++ b/x/group/keeper/grpc_query_test.go @@ -26,7 +26,15 @@ import ( grouptestutil "github.com/cosmos/cosmos-sdk/x/group/testutil" ) -func initKeeper(t *testing.T) (types.Context, groupkeeper.Keeper, []types.AccAddress, group.QueryClient) { +type fixture struct { + ctx types.Context + keeper groupkeeper.Keeper + queryClient group.QueryClient + addrs []types.AccAddress + defaultGroup *group.MsgCreateGroupWithPolicyResponse +} + +func initKeeper(t *testing.T) *fixture { t.Helper() var ( groupKeeper groupkeeper.Keeper @@ -54,6 +62,11 @@ func initKeeper(t *testing.T) (types.Context, groupkeeper.Keeper, []types.AccAdd } accountKeeper.EXPECT().AddressCodec().Return(address.NewBech32Codec("cosmos")).AnyTimes() + // group policy expected calls + accountKeeper.EXPECT().GetAccount(gomock.Any(), gomock.Any()).Return(nil).AnyTimes() + accountKeeper.EXPECT().NewAccount(gomock.Any(), gomock.Any()).Return(nil).AnyTimes() + accountKeeper.EXPECT().SetAccount(gomock.Any(), gomock.Any()).AnyTimes() + groupKeeper = groupkeeper.NewKeeper(key, encCfg.Codec, bApp.MsgServiceRouter(), accountKeeper, group.DefaultConfig()) queryHelper := baseapp.NewQueryServerTestHelper(ctx, interfaceRegistry) group.RegisterQueryServer(queryHelper, groupKeeper) @@ -66,89 +79,312 @@ func initKeeper(t *testing.T) (types.Context, groupkeeper.Keeper, []types.AccAdd {Address: addrs[3].String(), Weight: "2"}, }, } - msgGroupAndPolicy.SetDecisionPolicy(group.NewThresholdDecisionPolicy("2", time.Second, 20)) + err := msgGroupAndPolicy.SetDecisionPolicy(group.NewThresholdDecisionPolicy("2", time.Second, 20)) + require.NoError(t, err) - _, err := groupKeeper.CreateGroupWithPolicy(ctx, msgGroupAndPolicy) + resp, err := groupKeeper.CreateGroupWithPolicy(ctx, msgGroupAndPolicy) require.NoError(t, err) - return ctx, groupKeeper, addrs, queryClient + return &fixture{ + ctx: ctx, + keeper: groupKeeper, + queryClient: queryClient, + addrs: addrs, + defaultGroup: resp, + } } func TestQueryGroupInfo(t *testing.T) { - ctx, _, _, queryClient := initKeeper(t) + fixture := initKeeper(t) testCases := []struct { name string - groupID uint64 + req group.QueryGroupInfoRequest expErrMsg string }{ + { + name: "invalid req", + expErrMsg: "group: not found", + }, { name: "unknown id", - groupID: 20, + req: group.QueryGroupInfoRequest{GroupId: 20}, expErrMsg: "group: not found", }, { name: "valid id", - groupID: 1, + req: group.QueryGroupInfoRequest{GroupId: 1}, + expErrMsg: "", + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + _, err := fixture.queryClient.GroupInfo(fixture.ctx, &tc.req) + if tc.expErrMsg != "" { + require.Error(t, err) + require.Contains(t, err.Error(), tc.expErrMsg) + } else { + require.NoError(t, err) + } + }) + } +} + +func TestQueryGroupPolicyInfo(t *testing.T) { + fixture := initKeeper(t) + + testCases := []struct { + name string + req group.QueryGroupPolicyInfoRequest + expErrMsg string + }{ + { + name: "valid address", + req: group.QueryGroupPolicyInfoRequest{Address: fixture.defaultGroup.GroupPolicyAddress}, + expErrMsg: "", + }, + { + name: "unexisting address", + req: group.QueryGroupPolicyInfoRequest{Address: fixture.addrs[5].String()}, + expErrMsg: "group policy: not found", + }, + { + name: "invalid address", + req: group.QueryGroupPolicyInfoRequest{Address: "invalid address"}, + expErrMsg: "decoding bech32 failed", + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + _, err := fixture.queryClient.GroupPolicyInfo(fixture.ctx, &tc.req) + if tc.expErrMsg != "" { + require.Error(t, err) + require.Contains(t, err.Error(), tc.expErrMsg) + } else { + require.NoError(t, err) + } + }) + } +} + +func TestQueryGroupMembers(t *testing.T) { + fixture := initKeeper(t) + + testCases := []struct { + name string + req group.QueryGroupMembersRequest + postRun func(resp *group.QueryGroupMembersResponse) + expErrMsg string + }{ + { + name: "valid group", + req: group.QueryGroupMembersRequest{GroupId: 1}, + postRun: func(resp *group.QueryGroupMembersResponse) { + require.Len(t, resp.Members, 2) + }, + expErrMsg: "", + }, + { + name: "unexisting group", + req: group.QueryGroupMembersRequest{GroupId: 20}, + postRun: func(resp *group.QueryGroupMembersResponse) { + require.Len(t, resp.Members, 0) + }, + expErrMsg: "", + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + resp, err := fixture.queryClient.GroupMembers(fixture.ctx, &tc.req) + if tc.expErrMsg != "" { + require.Error(t, err) + require.Contains(t, err.Error(), tc.expErrMsg) + } else { + require.NoError(t, err) + } + + if tc.postRun != nil { + tc.postRun(resp) + } + }) + } +} + +func TestQueryGroupsByAdmin(t *testing.T) { + fixture := initKeeper(t) + + testCases := []struct { + name string + req group.QueryGroupsByAdminRequest + postRun func(resp *group.QueryGroupsByAdminResponse) + expErrMsg string + }{ + { + name: "valid admin", + req: group.QueryGroupsByAdminRequest{Admin: fixture.addrs[0].String()}, + postRun: func(resp *group.QueryGroupsByAdminResponse) { require.Len(t, resp.Groups, 1) }, expErrMsg: "", }, + { + name: "unexisting address", + req: group.QueryGroupsByAdminRequest{Admin: fixture.addrs[5].String()}, + postRun: func(resp *group.QueryGroupsByAdminResponse) { require.Len(t, resp.Groups, 0) }, + expErrMsg: "", + }, + { + name: "invalid address", + req: group.QueryGroupsByAdminRequest{Admin: "invalid address"}, + expErrMsg: "decoding bech32 failed", + }, } for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { - _, err := queryClient.GroupInfo(ctx, &group.QueryGroupInfoRequest{GroupId: tc.groupID}) + resp, err := fixture.queryClient.GroupsByAdmin(fixture.ctx, &tc.req) if tc.expErrMsg != "" { require.Error(t, err) require.Contains(t, err.Error(), tc.expErrMsg) } else { require.NoError(t, err) } + + if tc.postRun != nil { + tc.postRun(resp) + } + }) + } +} + +func TestQueryGroupPoliciesByGroup(t *testing.T) { + fixture := initKeeper(t) + + testCases := []struct { + name string + req group.QueryGroupPoliciesByGroupRequest + postRun func(resp *group.QueryGroupPoliciesByGroupResponse) + expErrMsg string + }{ + { + name: "valid group", + req: group.QueryGroupPoliciesByGroupRequest{GroupId: 1}, + postRun: func(resp *group.QueryGroupPoliciesByGroupResponse) { require.Len(t, resp.GroupPolicies, 1) }, + expErrMsg: "", + }, + { + name: "unexisting group", + req: group.QueryGroupPoliciesByGroupRequest{GroupId: 20}, + postRun: func(resp *group.QueryGroupPoliciesByGroupResponse) { require.Len(t, resp.GroupPolicies, 0) }, + expErrMsg: "", + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + resp, err := fixture.keeper.GroupPoliciesByGroup(fixture.ctx, &tc.req) + if tc.expErrMsg != "" { + require.Error(t, err) + require.Contains(t, err.Error(), tc.expErrMsg) + } else { + require.NoError(t, err) + } + + if tc.postRun != nil { + tc.postRun(resp) + } + }) + } +} + +func TestQueryGroupPoliciesByAdmin(t *testing.T) { + fixture := initKeeper(t) + + testCases := []struct { + name string + req group.QueryGroupPoliciesByAdminRequest + postRun func(resp *group.QueryGroupPoliciesByAdminResponse) + expErrMsg string + }{ + { + name: "valid admin", + req: group.QueryGroupPoliciesByAdminRequest{Admin: fixture.addrs[0].String()}, + postRun: func(resp *group.QueryGroupPoliciesByAdminResponse) { require.Len(t, resp.GroupPolicies, 1) }, + expErrMsg: "", + }, + { + name: "unexisting address", + req: group.QueryGroupPoliciesByAdminRequest{Admin: fixture.addrs[5].String()}, + postRun: func(resp *group.QueryGroupPoliciesByAdminResponse) { require.Len(t, resp.GroupPolicies, 0) }, + expErrMsg: "", + }, + { + name: "invalid address", + req: group.QueryGroupPoliciesByAdminRequest{Admin: "invalid address"}, + expErrMsg: "decoding bech32 failed", + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + resp, err := fixture.keeper.GroupPoliciesByAdmin(fixture.ctx, &tc.req) + if tc.expErrMsg != "" { + require.Error(t, err) + require.Contains(t, err.Error(), tc.expErrMsg) + } else { + require.NoError(t, err) + } + + if tc.postRun != nil { + tc.postRun(resp) + } }) } } func TestQueryGroupsByMember(t *testing.T) { - ctx, groupKeeper, addrs, queryClient := initKeeper(t) + fixture := initKeeper(t) members := []group.MemberRequest{ - {Address: addrs[3].String(), Weight: "1"}, {Address: addrs[4].String(), Weight: "2"}, + {Address: fixture.addrs[3].String(), Weight: "1"}, {Address: fixture.addrs[4].String(), Weight: "2"}, } - _, err := groupKeeper.CreateGroup(ctx, &group.MsgCreateGroup{ - Admin: addrs[1].String(), + _, err := fixture.keeper.CreateGroup(fixture.ctx, &group.MsgCreateGroup{ + Admin: fixture.addrs[1].String(), Members: members, }) require.NoError(t, err) // not part of any group - resp, err := queryClient.GroupsByMember(context.Background(), &group.QueryGroupsByMemberRequest{ - Address: addrs[5].String(), + resp, err := fixture.queryClient.GroupsByMember(context.Background(), &group.QueryGroupsByMemberRequest{ + Address: fixture.addrs[5].String(), }) require.NoError(t, err) require.Len(t, resp.Groups, 0) // expect one group - resp, err = queryClient.GroupsByMember(context.Background(), &group.QueryGroupsByMemberRequest{ - Address: addrs[4].String(), + resp, err = fixture.queryClient.GroupsByMember(context.Background(), &group.QueryGroupsByMemberRequest{ + Address: fixture.addrs[4].String(), }) require.NoError(t, err) require.Len(t, resp.Groups, 1) // expect two groups - resp, err = queryClient.GroupsByMember(context.Background(), &group.QueryGroupsByMemberRequest{ - Address: addrs[3].String(), + resp, err = fixture.queryClient.GroupsByMember(context.Background(), &group.QueryGroupsByMemberRequest{ + Address: fixture.addrs[3].String(), }) require.NoError(t, err) require.Len(t, resp.Groups, 2) } func TestQueryGroups(t *testing.T) { - ctx, groupKeeper, addrs, queryClient := initKeeper(t) + fixture := initKeeper(t) members := []group.MemberRequest{ - {Address: addrs[3].String(), Weight: "1"}, + {Address: fixture.addrs[3].String(), Weight: "1"}, } - _, err := groupKeeper.CreateGroup(ctx, &group.MsgCreateGroup{ - Admin: addrs[2].String(), + _, err := fixture.keeper.CreateGroup(fixture.ctx, &group.MsgCreateGroup{ + Admin: fixture.addrs[2].String(), Members: members, }) require.NoError(t, err) @@ -180,7 +416,7 @@ func TestQueryGroups(t *testing.T) { for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { - resp, err := queryClient.Groups(context.Background(), &group.QueryGroupsRequest{ + resp, err := fixture.queryClient.Groups(context.Background(), &group.QueryGroupsRequest{ Pagination: &query.PageRequest{ Limit: tc.itemsPerPage, }, From f629f1f5bd3a23e43bd7c427a99543036acab30f Mon Sep 17 00:00:00 2001 From: Julien Robert Date: Mon, 17 Jul 2023 13:46:50 +0200 Subject: [PATCH 4/4] remove unused --- tests/e2e/group/suite.go | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/tests/e2e/group/suite.go b/tests/e2e/group/suite.go index a0efde25cbc..6d1525e543a 100644 --- a/tests/e2e/group/suite.go +++ b/tests/e2e/group/suite.go @@ -4,7 +4,6 @@ import ( "encoding/base64" "encoding/json" "fmt" - "strings" "github.com/stretchr/testify/suite" @@ -210,21 +209,6 @@ func (s *E2ETestSuite) TearDownSuite() { s.network.Cleanup() } -func (s *E2ETestSuite) getProposalIDFromTxResponse(txResp sdk.TxResponse) string { - s.Require().Greater(len(txResp.Events), 0) - s.Require().NotNil(txResp.Events[0]) - events := txResp.Events - createProposalEvent, _ := sdk.TypedEventToEvent(&group.EventSubmitProposal{}) - - for _, e := range events { - if e.Type == createProposalEvent.Type { - return strings.ReplaceAll(e.Attributes[0].Value, "\"", "") - } - } - - return "" -} - // createCLIProposal writes a CLI proposal with a MsgSend to a file. Returns // the path to the JSON file. func (s *E2ETestSuite) createCLIProposal(groupPolicyAddress, proposer, sendFrom, sendTo, metadata, title, summary string) string {