Skip to content

Commit 828bddf

Browse files
feat(tokenfactory-cli): add CLI commands for set denom functions (#2372)
* test(tokenfactory-cli): impl CLI tests * chore: changelog * fix: include template functinoality in tokenfactory cli
1 parent ef98682 commit 828bddf

File tree

5 files changed

+378
-19
lines changed

5 files changed

+378
-19
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ See https://github.com/dangoslen/changelog-enforcer.
4848

4949
- [#2353](https://github.com/NibiruChain/nibiru/pull/2353) - refactor(oracle): remove dead code from asset registry
5050
- [#2371](https://github.com/NibiruChain/nibiru/pull/2371) - feat(evm): fix UnmarshalJSON to accept ASCII hex strings
51+
- [#2372](https://github.com/NibiruChain/nibiru/pull/2372) - feat(tokenfactory-cli): add CLI commands for set denom functions
5152

5253
### Dependencies
5354
- Bump `base-x` from 3.0.10 to 3.0.11 ([#2355](https://github.com/NibiruChain/nibiru/pull/2355))

cmd/nibid/cmd/base64.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ func GetBuildWasmMsg() *cobra.Command {
1414
cmd := &cobra.Command{
1515
Use: "build-stargate-wasm [message data]",
1616
Short: "Build wasm Stargate message in Base64",
17-
Long: `This message is used to build a Cosmos SDK,
18-
in the format used to be sent as a Stargate message in a CosmWasm transaction.`,
17+
Long: `This message is used to build an sdk.Msg as a protobuf Any
18+
type for use as a Stargate message in a CosmWasm transaction.`,
1919
Args: cobra.ExactArgs(1),
2020
RunE: func(cmd *cobra.Command, args []string) error {
2121
clientCtx := client.GetClientContextFromCmd(cmd)

x/evm/cli/cli_setup_test.go

Lines changed: 10 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -23,28 +23,15 @@ import (
2323
type Suite struct {
2424
suite.Suite
2525

26-
keyring keyring.Keyring
27-
encCfg testutilmod.TestEncodingConfig
28-
baseCtx sdkclient.Context
29-
clientCtx sdkclient.Context
26+
keyring keyring.Keyring
27+
encCfg testutilmod.TestEncodingConfig
3028

3129
testAcc sdktestutil.TestAccount
3230
}
3331

3432
func (s *Suite) SetupSuite() {
3533
s.encCfg = testutilmod.MakeTestEncodingConfig(evmmodule.AppModuleBasic{})
3634
s.keyring = keyring.NewInMemory(s.encCfg.Codec)
37-
s.baseCtx = sdkclient.Context{}.
38-
WithKeyring(s.keyring).
39-
WithTxConfig(s.encCfg.TxConfig).
40-
WithCodec(s.encCfg.Codec).
41-
WithClient(sdktestutilcli.MockTendermintRPC{Client: rpcclientmock.Client{}}).
42-
WithAccountRetriever(sdkclient.MockAccountRetriever{}).
43-
WithOutput(io.Discard).
44-
WithChainID("test-chain")
45-
46-
s.clientCtx = s.baseCtx
47-
4835
testAccs := sdktestutil.CreateKeyringAccounts(s.T(), s.keyring, 1)
4936
s.testAcc = testAccs[0]
5037
}
@@ -71,7 +58,14 @@ type TestCase struct {
7158
}
7259

7360
func (tc TestCase) NewCtx(s *Suite) sdkclient.Context {
74-
return s.baseCtx
61+
return sdkclient.Context{}.
62+
WithKeyring(s.keyring).
63+
WithTxConfig(s.encCfg.TxConfig).
64+
WithCodec(s.encCfg.Codec).
65+
WithClient(sdktestutilcli.MockTendermintRPC{Client: rpcclientmock.Client{}}).
66+
WithAccountRetriever(sdkclient.MockAccountRetriever{}).
67+
WithOutput(io.Discard).
68+
WithChainID("test-chain")
7569
}
7670

7771
func (tc TestCase) RunTxCmd(s *Suite) {

x/tokenfactory/cli/cli_test.go

Lines changed: 199 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,14 @@
11
package cli_test
22

33
import (
4+
"bytes"
5+
"context"
46
"fmt"
7+
"io"
8+
"os"
59
"testing"
610

11+
"github.com/spf13/cobra"
712
"github.com/stretchr/testify/suite"
813

914
"github.com/NibiruChain/nibiru/v2/app"
@@ -14,6 +19,14 @@ import (
1419
"github.com/NibiruChain/nibiru/v2/x/tokenfactory/types"
1520

1621
sdk "github.com/cosmos/cosmos-sdk/types"
22+
23+
rpcclientmock "github.com/cometbft/cometbft/rpc/client/mock"
24+
sdkclient "github.com/cosmos/cosmos-sdk/client"
25+
"github.com/cosmos/cosmos-sdk/crypto/keyring"
26+
svrcmd "github.com/cosmos/cosmos-sdk/server/cmd"
27+
sdktestutil "github.com/cosmos/cosmos-sdk/testutil"
28+
sdktestutilcli "github.com/cosmos/cosmos-sdk/testutil/cli"
29+
testutilmod "github.com/cosmos/cosmos-sdk/types/module/testutil"
1730
)
1831

1932
var (
@@ -30,6 +43,8 @@ type TestSuite struct {
3043
}
3144

3245
func TestIntegrationTestSuite(t *testing.T) {
46+
suite.Run(t, new(CmdSuiteLite))
47+
3348
testutil.RetrySuiteRunIfDbClosed(t, func() {
3449
suite.Run(t, new(TestSuite))
3550
}, 2)
@@ -196,3 +211,187 @@ func (s *TestSuite) TearDownSuite() {
196211
s.T().Log("tearing down integration test suite")
197212
s.network.Cleanup()
198213
}
214+
215+
type CmdTestCase struct {
216+
name string
217+
args []string
218+
extraArgs []string
219+
wantErr string
220+
}
221+
222+
// Flags for broadcasting transactions
223+
func (s *CmdSuiteLite) commonTxArgs() []string {
224+
return []string{
225+
"--yes=true", // skip confirmation
226+
"--broadcast-mode=sync",
227+
"--fees=1unibi",
228+
"--chain-id=test-chain",
229+
}
230+
}
231+
232+
type CmdSuiteLite struct {
233+
suite.Suite
234+
235+
keyring keyring.Keyring
236+
testEncCfg testutilmod.TestEncodingConfig
237+
238+
testAcc sdktestutil.TestAccount
239+
}
240+
241+
func (s *CmdSuiteLite) SetupSuite() {
242+
s.testEncCfg = testutilmod.TestEncodingConfig(app.MakeEncodingConfig())
243+
s.keyring = keyring.NewInMemory(s.testEncCfg.Codec)
244+
245+
testAccs := sdktestutil.CreateKeyringAccounts(s.T(), s.keyring, 1)
246+
s.testAcc = testAccs[0]
247+
}
248+
249+
func (s *CmdSuiteLite) TestCmdSetDenomMetadata() {
250+
s.T().Log(`Create a valid metadata file as "metadata.json"`)
251+
tempDir := s.T().TempDir()
252+
metadataFile, err := os.CreateTemp(tempDir, "metadata.json")
253+
s.Require().NoError(err)
254+
defer metadataFile.Close()
255+
256+
_, err = metadataFile.Write([]byte(`
257+
{
258+
"description": "A short description of the token",
259+
"denom_units": [
260+
{
261+
"denom": "testdenom"
262+
},
263+
{
264+
"denom": "TEST",
265+
"exponent": 6
266+
}
267+
],
268+
"base": "testdenom",
269+
"display": "TEST",
270+
"name": "Test Token",
271+
"symbol": "TEST"
272+
}`),
273+
)
274+
s.Require().NoError(err)
275+
276+
metadatFilePath := metadataFile.Name()
277+
278+
testCases := []CmdTestCase{
279+
{
280+
name: "happy: set-denom-metadata",
281+
args: []string{
282+
"set-denom-metadata",
283+
metadatFilePath,
284+
},
285+
extraArgs: []string{fmt.Sprintf("--from=%s", s.testAcc.Address)},
286+
wantErr: "",
287+
},
288+
{
289+
name: "happy: sudo-set-denom-metadata",
290+
args: []string{
291+
"sudo-set-denom-metadata",
292+
metadatFilePath,
293+
},
294+
extraArgs: []string{fmt.Sprintf("--from=%s", s.testAcc.Address)},
295+
wantErr: "",
296+
},
297+
{
298+
name: "happy: template flag",
299+
args: []string{
300+
"set-denom-metadata",
301+
"args.json",
302+
"--template",
303+
},
304+
extraArgs: []string{},
305+
wantErr: "",
306+
},
307+
{
308+
name: "happy: template flag sudo",
309+
args: []string{
310+
"sudo-set-denom-metadata",
311+
"args.json",
312+
"--template",
313+
},
314+
extraArgs: []string{},
315+
wantErr: "",
316+
},
317+
{
318+
name: "sad: no FILE given",
319+
args: []string{
320+
"set-denom-metadata",
321+
},
322+
extraArgs: []string{fmt.Sprintf("--from=%s", s.testAcc.Address)},
323+
wantErr: "accepts 1 arg(s), received 0",
324+
},
325+
{
326+
name: "sad: file does not exist",
327+
args: []string{
328+
"set-denom-metadata",
329+
"not-a-file.json",
330+
},
331+
extraArgs: []string{fmt.Sprintf("--from=%s", s.testAcc.Address)},
332+
wantErr: "no such file or directory",
333+
},
334+
}
335+
336+
for _, tc := range testCases {
337+
testOutput := new(bytes.Buffer)
338+
tc.RunTxCmd(
339+
s,
340+
cli.NewTxCmd(),
341+
testOutput,
342+
)
343+
}
344+
}
345+
346+
func (tc CmdTestCase) NewCtx(s *CmdSuiteLite) sdkclient.Context {
347+
return sdkclient.Context{}.
348+
WithKeyring(s.keyring).
349+
WithTxConfig(s.testEncCfg.TxConfig).
350+
WithCodec(s.testEncCfg.Codec).
351+
WithClient(sdktestutilcli.MockTendermintRPC{Client: rpcclientmock.Client{}}).
352+
WithAccountRetriever(sdkclient.MockAccountRetriever{}).
353+
WithOutput(io.Discard).
354+
WithChainID("test-chain")
355+
}
356+
357+
func (tc CmdTestCase) RunTxCmd(s *CmdSuiteLite, txCmd *cobra.Command, output io.Writer) {
358+
s.Run(tc.name, func() {
359+
ctx := svrcmd.CreateExecuteContext(context.Background())
360+
361+
cmd := txCmd
362+
cmd.SetContext(ctx)
363+
cmd.SetOutput(output)
364+
args := append(tc.args, s.commonTxArgs()...)
365+
cmd.SetArgs(append(args, tc.extraArgs...))
366+
367+
s.Require().NoError(sdkclient.SetCmdClientContextHandler(tc.NewCtx(s), cmd))
368+
369+
err := cmd.Execute()
370+
if tc.wantErr != "" {
371+
s.Require().ErrorContains(err, tc.wantErr)
372+
return
373+
}
374+
s.Require().NoError(err)
375+
})
376+
}
377+
378+
func (tc CmdTestCase) RunQueryCmd(s *CmdSuiteLite, queryCmd *cobra.Command, output io.Writer) {
379+
s.Run(tc.name, func() {
380+
ctx := svrcmd.CreateExecuteContext(context.Background())
381+
382+
cmd := queryCmd
383+
cmd.SetContext(ctx)
384+
cmd.SetOutput(output)
385+
args := tc.args // don't append common tx args
386+
cmd.SetArgs(append(args, tc.extraArgs...))
387+
388+
s.Require().NoError(sdkclient.SetCmdClientContextHandler(tc.NewCtx(s), cmd))
389+
390+
err := cmd.Execute()
391+
if tc.wantErr != "" {
392+
s.Require().ErrorContains(err, tc.wantErr)
393+
return
394+
}
395+
s.Require().NoError(err)
396+
})
397+
}

0 commit comments

Comments
 (0)