github.com/nats-io/nsc/v2@v2.8.7-0.20240307184528-efd7023c6896/cmd/editaccount_test.go (about)

     1  /*
     2   * Copyright 2018-2024 The NATS Authors
     3   * Licensed under the Apache License, Version 2.0 (the "License");
     4   * you may not use this file except in compliance with the License.
     5   * You may obtain a copy of the License at
     6   *
     7   * http://www.apache.org/licenses/LICENSE-2.0
     8   *
     9   * Unless required by applicable law or agreed to in writing, software
    10   * distributed under the License is distributed on an "AS IS" BASIS,
    11   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12   * See the License for the specific language governing permissions and
    13   * limitations under the License.
    14   */
    15  
    16  package cmd
    17  
    18  import (
    19  	"fmt"
    20  	"github.com/nats-io/jwt/v2"
    21  	"testing"
    22  	"time"
    23  
    24  	"github.com/nats-io/nkeys"
    25  	"github.com/stretchr/testify/require"
    26  )
    27  
    28  func Test_EditAccount(t *testing.T) {
    29  	ts := NewTestStore(t, "edit account")
    30  	defer ts.Done(t)
    31  
    32  	ts.AddAccount(t, "A")
    33  	ts.AddAccount(t, "B")
    34  
    35  	tests := CmdTests{
    36  		{createEditAccount(), []string{"edit", "account"}, nil, []string{"specify an edit option"}, true},
    37  		{createEditAccount(), []string{"edit", "account", "--info-url", "http://foo/bar"}, nil, []string{"changed info url to"}, false},
    38  		{createEditAccount(), []string{"edit", "account", "--description", "my account is about this"}, nil, []string{"changed description to"}, false},
    39  		{createEditAccount(), []string{"edit", "account", "--tag", "A", "--name", "A"}, nil, []string{"edited account \"A\""}, false},
    40  	}
    41  
    42  	tests.Run(t, "root", "edit")
    43  }
    44  
    45  func Test_EditAccountRequired(t *testing.T) {
    46  	ts := NewTestStore(t, "edit account")
    47  	defer ts.Done(t)
    48  
    49  	ts.AddAccount(t, "A")
    50  	ts.AddAccount(t, "B")
    51  	require.NoError(t, GetConfig().SetAccount(""))
    52  	_, _, err := ExecuteCmd(createEditAccount(), "--tag", "A")
    53  	require.Error(t, err)
    54  	require.Contains(t, "an account is required", err.Error())
    55  }
    56  
    57  func Test_EditAccount_Tag(t *testing.T) {
    58  	ts := NewTestStore(t, "edit account")
    59  	defer ts.Done(t)
    60  
    61  	ts.AddAccount(t, "A")
    62  	_, _, err := ExecuteCmd(createEditAccount(), "--tag", "A,B,C")
    63  	require.NoError(t, err)
    64  
    65  	ac, err := ts.Store.ReadAccountClaim("A")
    66  	require.NoError(t, err)
    67  
    68  	require.Len(t, ac.Tags, 3)
    69  	require.ElementsMatch(t, ac.Tags, []string{"a", "b", "c"})
    70  }
    71  
    72  func Test_EditAccount_RmTag(t *testing.T) {
    73  	ts := NewTestStore(t, "edit account")
    74  	defer ts.Done(t)
    75  
    76  	ts.AddAccount(t, "A")
    77  	_, _, err := ExecuteCmd(createEditAccount(), "--tag", "A,B,C")
    78  	require.NoError(t, err)
    79  
    80  	_, _, err = ExecuteCmd(createEditAccount(), "--rm-tag", "A,B")
    81  	require.NoError(t, err)
    82  
    83  	ac, err := ts.Store.ReadAccountClaim("A")
    84  	require.NoError(t, err)
    85  
    86  	require.Len(t, ac.Tags, 1)
    87  	require.ElementsMatch(t, ac.Tags, []string{"c"})
    88  }
    89  
    90  func Test_EditAccount_Times(t *testing.T) {
    91  	ts := NewTestStore(t, "edit account")
    92  	defer ts.Done(t)
    93  
    94  	ts.AddAccount(t, "A")
    95  
    96  	_, _, err := ExecuteCmd(createEditAccount(), "--start", "2018-01-01", "--expiry", "2050-01-01")
    97  	require.NoError(t, err)
    98  
    99  	start, err := ParseExpiry("2018-01-01")
   100  	require.NoError(t, err)
   101  
   102  	expiry, err := ParseExpiry("2050-01-01")
   103  	require.NoError(t, err)
   104  
   105  	ac, err := ts.Store.ReadAccountClaim("A")
   106  	require.NoError(t, err)
   107  	require.Equal(t, start, ac.NotBefore)
   108  	require.Equal(t, expiry, ac.Expires)
   109  }
   110  
   111  func Test_EditAccountLimits(t *testing.T) {
   112  	ts := NewTestStore(t, "edit account")
   113  	defer ts.Done(t)
   114  
   115  	ts.AddAccount(t, "A")
   116  	_, _, err := ExecuteCmd(createEditAccount(), "--conns", "5", "--data", "10mib", "--exports", "15",
   117  		"--imports", "20", "--payload", "1Kib", "--subscriptions", "30", "--leaf-conns", "31",
   118  		"--js-streams", "5", "--js-consumer", "6", "--js-disk-storage", "7", "--js-mem-storage", "8",
   119  		"--js-max-disk-stream", "9mib", "--js-max-mem-stream", "10", "--js-max-ack-pending", "11", "--js-max-bytes-required")
   120  	require.NoError(t, err)
   121  
   122  	ac, err := ts.Store.ReadAccountClaim("A")
   123  	require.NoError(t, err)
   124  	require.Equal(t, int64(5), ac.Limits.Conn)
   125  	require.Equal(t, int64(31), ac.Limits.LeafNodeConn)
   126  	require.Equal(t, int64(1024*1024*10), ac.Limits.Data)
   127  	require.Equal(t, int64(15), ac.Limits.Exports)
   128  	require.Equal(t, int64(20), ac.Limits.Imports)
   129  	require.Equal(t, int64(1024), ac.Limits.Payload)
   130  	require.Equal(t, int64(30), ac.Limits.Subs)
   131  	require.Equal(t, int64(5), ac.Limits.Streams)
   132  	require.Equal(t, int64(6), ac.Limits.Consumer)
   133  	require.Equal(t, int64(7), ac.Limits.DiskStorage)
   134  	require.Equal(t, int64(8), ac.Limits.MemoryStorage)
   135  	require.Equal(t, int64(1024*1024*9), ac.Limits.DiskMaxStreamBytes)
   136  	require.Equal(t, int64(10), ac.Limits.MemoryMaxStreamBytes)
   137  	require.Equal(t, int64(11), ac.Limits.MaxAckPending)
   138  	require.True(t, ac.Limits.MaxBytesRequired)
   139  }
   140  
   141  func Test_EditJsOptionsOnTierDelete(t *testing.T) {
   142  	ts := NewTestStore(t, "edit account")
   143  	defer ts.Done(t)
   144  
   145  	ts.AddAccount(t, "A")
   146  	_, _, err := ExecuteCmd(createEditAccount(),
   147  		"--js-streams", "5", "--js-consumer", "6", "--js-disk-storage", "7")
   148  	require.NoError(t, err)
   149  
   150  	ac, err := ts.Store.ReadAccountClaim("A")
   151  	require.NoError(t, err)
   152  	require.Equal(t, int64(5), ac.Limits.Streams)
   153  	require.Equal(t, int64(6), ac.Limits.Consumer)
   154  	require.Equal(t, int64(7), ac.Limits.DiskStorage)
   155  
   156  	_, _, err = ExecuteCmd(createEditAccount(),
   157  		"--js-streams", "1", "--rm-js-tier", "0")
   158  	require.Error(t, err)
   159  	require.Equal(t, "rm-js-tier is exclusive of all other js options", err.Error())
   160  
   161  	_, _, err = ExecuteCmd(createEditAccount(),
   162  		"--rm-js-tier", "0")
   163  	require.NoError(t, err)
   164  	ac, err = ts.Store.ReadAccountClaim("A")
   165  	require.NoError(t, err)
   166  	require.Equal(t, int64(0), ac.Limits.Streams)
   167  	require.Equal(t, int64(0), ac.Limits.Consumer)
   168  	require.Equal(t, int64(0), ac.Limits.DiskStorage)
   169  }
   170  
   171  func Test_GlobalPreventsTiered(t *testing.T) {
   172  	ts := NewTestStore(t, "edit account")
   173  	defer ts.Done(t)
   174  
   175  	ts.AddAccount(t, "A")
   176  	_, _, err := ExecuteCmd(createEditAccount(),
   177  		"--js-streams", "5", "--js-disk-storage", "10")
   178  	require.NoError(t, err)
   179  
   180  	ac, err := ts.Store.ReadAccountClaim("A")
   181  	require.NoError(t, err)
   182  	require.Equal(t, int64(5), ac.Limits.Streams)
   183  
   184  	_, _, err = ExecuteCmd(createEditAccount(),
   185  		"--js-tier", "1", "--js-disk-storage", "10")
   186  	require.Error(t, err)
   187  	require.Equal(t, "cannot set a jetstream tier limit when a configuration has a global limit", err.Error())
   188  }
   189  
   190  func Test_TieredPreventsGlobal(t *testing.T) {
   191  	ts := NewTestStore(t, "edit account")
   192  	defer ts.Done(t)
   193  
   194  	ts.AddAccount(t, "A")
   195  	_, _, err := ExecuteCmd(createEditAccount(),
   196  		"--js-tier", "2", "--js-streams", "5", "--js-disk-storage", "10")
   197  	require.NoError(t, err)
   198  
   199  	ac, err := ts.Store.ReadAccountClaim("A")
   200  	require.NoError(t, err)
   201  	require.Equal(t, int64(5), ac.Limits.JetStreamTieredLimits["R2"].Streams)
   202  
   203  	_, _, err = ExecuteCmd(createEditAccount(),
   204  		"--js-disk-storage", "10")
   205  	require.Error(t, err)
   206  	require.Equal(t, "cannot set a jetstream global limit when a configuration has tiered limits 'R2'", err.Error())
   207  }
   208  
   209  func Test_TieredDoesntPreventOtherClaims(t *testing.T) {
   210  	ts := NewTestStore(t, "edit account")
   211  	defer ts.Done(t)
   212  
   213  	ts.AddAccount(t, "A")
   214  	_, _, err := ExecuteCmd(createEditAccount(),
   215  		"--js-tier", "2", "--js-streams", "5", "--js-disk-storage", "10")
   216  	require.NoError(t, err)
   217  
   218  	ac, err := ts.Store.ReadAccountClaim("A")
   219  	require.NoError(t, err)
   220  	require.Equal(t, int64(5), ac.Limits.JetStreamTieredLimits["R2"].Streams)
   221  
   222  	_, _, err = ExecuteCmd(createEditAccount(),
   223  		"--sk", "generate")
   224  	require.NoError(t, err)
   225  }
   226  
   227  func Test_EditAccountSigningKeys(t *testing.T) {
   228  	ts := NewTestStore(t, "edit account")
   229  	defer ts.Done(t)
   230  
   231  	ts.AddAccount(t, "A")
   232  	_, pk, _ := CreateAccountKey(t)
   233  	_, pk2, _ := CreateAccountKey(t)
   234  
   235  	_, _, err := ExecuteCmd(createEditAccount(), "--sk", pk, "--sk", pk2)
   236  	require.NoError(t, err)
   237  
   238  	ac, err := ts.Store.ReadAccountClaim("A")
   239  	require.NoError(t, err)
   240  	require.Contains(t, ac.SigningKeys, pk)
   241  	require.Contains(t, ac.SigningKeys, pk2)
   242  
   243  	_, _, err = ExecuteCmd(createEditAccount(), "--rm-sk", pk)
   244  	require.NoError(t, err)
   245  
   246  	ac, err = ts.Store.ReadAccountClaim("A")
   247  	require.NoError(t, err)
   248  	require.NotContains(t, ac.SigningKeys, pk)
   249  }
   250  
   251  func Test_EditAccount_Pubs(t *testing.T) {
   252  	ts := NewTestStore(t, "edit user")
   253  	defer ts.Done(t)
   254  
   255  	ts.AddAccount(t, "A")
   256  
   257  	_, _, err := ExecuteCmd(createEditAccount(), "--allow-pub", "a,b", "--allow-pubsub", "c", "--deny-pub", "foo", "--deny-pubsub", "bar")
   258  	require.NoError(t, err)
   259  
   260  	cc, err := ts.Store.ReadAccountClaim("A")
   261  	require.NoError(t, err)
   262  	require.NotNil(t, cc)
   263  	require.ElementsMatch(t, cc.DefaultPermissions.Pub.Allow, []string{"a", "b", "c"})
   264  	require.ElementsMatch(t, cc.DefaultPermissions.Sub.Allow, []string{"c"})
   265  	require.ElementsMatch(t, cc.DefaultPermissions.Pub.Deny, []string{"foo", "bar"})
   266  	require.ElementsMatch(t, cc.DefaultPermissions.Sub.Deny, []string{"bar"})
   267  
   268  	_, _, err = ExecuteCmd(createEditAccount(), "--rm", "c,bar")
   269  	require.NoError(t, err)
   270  	cc, err = ts.Store.ReadAccountClaim("A")
   271  	require.NoError(t, err)
   272  	require.NotNil(t, cc)
   273  
   274  	require.ElementsMatch(t, cc.DefaultPermissions.Pub.Allow, []string{"a", "b"})
   275  	require.Len(t, cc.DefaultPermissions.Sub.Allow, 0)
   276  	require.ElementsMatch(t, cc.DefaultPermissions.Pub.Deny, []string{"foo"})
   277  	require.Len(t, cc.DefaultPermissions.Sub.Deny, 0)
   278  }
   279  
   280  func Test_EditAccountResponsePermissions(t *testing.T) {
   281  	ts := NewTestStore(t, "O")
   282  	defer ts.Done(t)
   283  	ts.AddAccount(t, "A")
   284  
   285  	_, _, err := ExecuteCmd(createEditAccount(), "--max-responses", "1000", "--response-ttl", "4ms")
   286  	require.NoError(t, err)
   287  
   288  	uc, err := ts.Store.ReadAccountClaim("A")
   289  	require.NoError(t, err)
   290  	require.NotNil(t, uc.DefaultPermissions.Resp)
   291  	require.Equal(t, 1000, uc.DefaultPermissions.Resp.MaxMsgs)
   292  	d, _ := time.ParseDuration("4ms")
   293  	require.Equal(t, d, uc.DefaultPermissions.Resp.Expires)
   294  
   295  	_, _, err = ExecuteCmd(createEditAccount(), "--rm-response-perms")
   296  	require.NoError(t, err)
   297  
   298  	uc, err = ts.Store.ReadAccountClaim("A")
   299  	require.NoError(t, err)
   300  	require.Nil(t, uc.DefaultPermissions.Resp)
   301  }
   302  
   303  func Test_EditAccountSk(t *testing.T) {
   304  	ts := NewTestStore(t, "O")
   305  	defer ts.Done(t)
   306  
   307  	sk, err := nkeys.CreateOperator()
   308  	require.NoError(t, err)
   309  	_, err = ts.KeyStore.Store(sk)
   310  	require.NoError(t, err)
   311  	pSk, err := sk.PublicKey()
   312  	require.NoError(t, err)
   313  
   314  	_, _, err = ExecuteCmd(createEditOperatorCmd(), "--sk", pSk)
   315  	require.NoError(t, err)
   316  
   317  	ts.AddAccountWithSigner(t, "A", sk)
   318  	ac, err := ts.Store.ReadAccountClaim("A")
   319  	require.NoError(t, err)
   320  	require.Equal(t, ac.Issuer, pSk)
   321  
   322  	_, _, err = ExecuteCmd(createEditAccount(), "--tag", "foo")
   323  	require.NoError(t, err)
   324  	ac, err = ts.Store.ReadAccountClaim("A")
   325  	require.NoError(t, err)
   326  	require.Equal(t, ac.Issuer, pSk)
   327  }
   328  
   329  func Test_EditOperatorDisallowBearerToken(t *testing.T) {
   330  	ts := NewTestStore(t, "O")
   331  	defer ts.Done(t)
   332  	ts.AddAccount(t, "A")
   333  	ts.AddUser(t, "A", "U")
   334  
   335  	_, _, err := ExecuteCmd(createEditUserCmd(), "--name", "U", "--bearer")
   336  	require.NoError(t, err)
   337  
   338  	_, _, err = ExecuteCmd(createEditAccount(), "--name", "A", "--disallow-bearer")
   339  	require.Error(t, err)
   340  	require.Equal(t, err.Error(), `user "U" in account "A" uses bearer token (needs to be deleted/changed first)`)
   341  
   342  	// delete offending user
   343  	_, _, err = ExecuteCmd(createDeleteUserCmd(), "--account", "A", "--name", "U")
   344  	require.NoError(t, err)
   345  	// set option
   346  	_, _, err = ExecuteCmd(createEditAccount(), "--name", "A", "--disallow-bearer")
   347  	require.NoError(t, err)
   348  	// test user creation
   349  	_, _, err = ExecuteCmd(CreateAddUserCmd(), "--account", "A", "--name", "U", "--bearer")
   350  	require.Error(t, err)
   351  	require.Equal(t, err.Error(), `account "A" forbids the use of bearer token`)
   352  	_, _, err = ExecuteCmd(CreateAddUserCmd(), "--account", "A", "--name", "U")
   353  	require.NoError(t, err)
   354  	_, _, err = ExecuteCmd(createEditUserCmd(), "--account", "A", "--name", "U", "--bearer")
   355  	require.Error(t, err)
   356  	require.Equal(t, err.Error(), "account disallows bearer token")
   357  }
   358  
   359  func Test_EditSysAccount(t *testing.T) {
   360  	ts := NewTestStore(t, "O")
   361  	defer ts.Done(t)
   362  	ts.AddAccount(t, "SYS")
   363  	_, _, err := ExecuteCmd(createEditOperatorCmd(), "--system-account", "SYS")
   364  	require.NoError(t, err)
   365  
   366  	// test setting any flag will generate an error and the flag is reported
   367  	jsOptions := []string{
   368  		"js-max-bytes-required",
   369  		"js-tier",
   370  		"js-mem-storage",
   371  		"js-disk-storage",
   372  		"js-streams",
   373  		"js-consumer",
   374  		"js-max-mem-stream",
   375  		"js-max-disk-stream",
   376  		"js-max-ack-pending",
   377  	}
   378  	// setting any JS flags, will fail the edit
   379  	for idx, n := range jsOptions {
   380  		flag := fmt.Sprintf("--%s", n)
   381  		if idx > 0 {
   382  			_, _, err = ExecuteCmd(createEditAccount(), "SYS", "--tag", "A", flag, "1")
   383  			require.Error(t, err)
   384  			require.Contains(t, err.Error(), flag)
   385  		} else {
   386  			_, _, err = ExecuteCmd(createEditAccount(), "SYS", "--tag", "A", flag)
   387  			require.Error(t, err)
   388  			require.Contains(t, err.Error(), flag)
   389  		}
   390  	}
   391  	// defaults are removed automatically
   392  	_, _, err = ExecuteCmd(createEditAccount(), "SYS", "--tag", "A")
   393  	require.NoError(t, err)
   394  }
   395  
   396  func Test_TierRmAndDisabled(t *testing.T) {
   397  	ts := NewTestStore(t, "O")
   398  	defer ts.Done(t)
   399  	ts.AddAccount(t, "A")
   400  
   401  	_, _, err := ExecuteCmd(createEditAccount(), "A", "--rm-js-tier", "1", "--js-disable")
   402  	require.Error(t, err)
   403  	require.Equal(t, err.Error(), "js-disable is exclusive of all other js options")
   404  }
   405  
   406  func Test_TracingSampling(t *testing.T) {
   407  	ts := NewTestStore(t, "O")
   408  	defer ts.Done(t)
   409  	ts.AddAccount(t, "A")
   410  
   411  	// cannot set sampling if no subject
   412  	_, _, err := ExecuteCmd(createEditAccount(), "A", "--trace-context-sampling", "50")
   413  	require.Error(t, err)
   414  	require.Equal(t, "trace-context-sampling requires a subject", err.Error())
   415  
   416  	// set a subject
   417  	_, _, err = ExecuteCmd(createEditAccount(), "A", "--trace-context-subject", "traces")
   418  	require.NoError(t, err)
   419  
   420  	// range checks
   421  	_, _, err = ExecuteCmd(createEditAccount(), "A", "--trace-context-sampling", "101")
   422  	require.Error(t, err)
   423  	require.Equal(t, "tracing sampling rate must be between 1-100", err.Error())
   424  
   425  	_, _, err = ExecuteCmd(createEditAccount(), "A", "--trace-context-sampling", "-1")
   426  	require.Error(t, err)
   427  	require.Equal(t, "tracing sampling rate must be between 1-100", err.Error())
   428  
   429  	// disable and set
   430  	_, _, err = ExecuteCmd(createEditAccount(), "A", "--trace-context-sampling", "50", "--trace-context-subject", "")
   431  	require.Error(t, err)
   432  	require.Equal(t, "cannot set context sampling rate when disabling the trace context", err.Error())
   433  }
   434  
   435  func Test_TracingSubject(t *testing.T) {
   436  	ts := NewTestStore(t, "O")
   437  	defer ts.Done(t)
   438  	ts.AddAccount(t, "A")
   439  
   440  	ac, err := ts.Store.ReadAccountClaim("A")
   441  	require.NoError(t, err)
   442  	require.Nil(t, ac.Trace)
   443  
   444  	// no op
   445  	_, _, err = ExecuteCmd(createEditAccount(), "A", "--trace-context-subject", "")
   446  	require.NoError(t, err)
   447  
   448  	// bad subjects are checked by jwt lib, just making sure we are catching
   449  	_, _, err = ExecuteCmd(createEditAccount(), "A", "--trace-context-subject", "traces.*")
   450  	require.Error(t, err)
   451  	require.Equal(t, "tracing subjects cannot contain wildcards: \"traces.*\"", err.Error())
   452  
   453  	_, _, err = ExecuteCmd(createEditAccount(), "A", "--trace-context-subject", "traces.here")
   454  	require.NoError(t, err)
   455  
   456  	ac, err = ts.Store.ReadAccountClaim("A")
   457  	require.NoError(t, err)
   458  	require.NotNil(t, ac.Trace)
   459  	require.Equal(t, jwt.Subject("traces.here"), ac.Trace.Destination)
   460  	require.Equal(t, 0, ac.Trace.Sampling)
   461  
   462  	// we have a subject, so set the sampling
   463  	_, _, err = ExecuteCmd(createEditAccount(), "A", "--trace-context-sampling", "75")
   464  	require.NoError(t, err)
   465  
   466  	ac, err = ts.Store.ReadAccountClaim("A")
   467  	require.NoError(t, err)
   468  	require.NotNil(t, ac.Trace)
   469  	require.Equal(t, jwt.Subject("traces.here"), ac.Trace.Destination)
   470  	require.Equal(t, 75, ac.Trace.Sampling)
   471  
   472  	_, _, err = ExecuteCmd(createEditAccount(), "A", "--trace-context-subject", "")
   473  	require.NoError(t, err)
   474  	ac, err = ts.Store.ReadAccountClaim("A")
   475  	require.NoError(t, err)
   476  	require.Nil(t, ac.Trace)
   477  }
   478  
   479  func Test_EnableTier(t *testing.T) {
   480  	ts := NewTestStore(t, "O")
   481  	defer ts.Done(t)
   482  	ts.AddAccount(t, "A")
   483  
   484  	ac, err := ts.Store.ReadAccountClaim("A")
   485  	require.NoError(t, err)
   486  	require.Equal(t, ac.Limits.JetStreamLimits, jwt.JetStreamLimits{})
   487  
   488  	_, _, err = ExecuteCmd(createEditAccount(), "A", "--js-enable", "0")
   489  	require.NoError(t, err)
   490  
   491  	ac, err = ts.Store.ReadAccountClaim("A")
   492  	require.NoError(t, err)
   493  	require.Equal(t, ac.Limits.JetStreamLimits, jwt.JetStreamLimits{DiskStorage: -1, MemoryStorage: -1})
   494  }
   495  
   496  func Test_EnableTierDoesntClobber(t *testing.T) {
   497  	ts := NewTestStore(t, "O")
   498  	defer ts.Done(t)
   499  	ts.AddAccount(t, "A")
   500  
   501  	ac, err := ts.Store.ReadAccountClaim("A")
   502  	require.NoError(t, err)
   503  	require.Equal(t, ac.Limits.JetStreamLimits, jwt.JetStreamLimits{})
   504  
   505  	_, _, err = ExecuteCmd(createEditAccount(), "A", "--js-enable", "0")
   506  	require.NoError(t, err)
   507  
   508  	_, _, err = ExecuteCmd(createEditAccount(), "A", "--js-enable", "0")
   509  	require.Error(t, err)
   510  	require.Equal(t, "jetstream tier global is already enabled", err.Error())
   511  }
   512  
   513  func Test_EnableTierNoOtherFlag(t *testing.T) {
   514  	ts := NewTestStore(t, "O")
   515  	defer ts.Done(t)
   516  	ts.AddAccount(t, "A")
   517  
   518  	ac, err := ts.Store.ReadAccountClaim("A")
   519  	require.NoError(t, err)
   520  	require.Equal(t, ac.Limits.JetStreamLimits, jwt.JetStreamLimits{})
   521  
   522  	_, _, err = ExecuteCmd(createEditAccount(), "A", "--js-enable", "0", "--rm-js-tier", "0")
   523  	require.Error(t, err)
   524  	require.Equal(t, "rm-js-tier is exclusive of all other js options", err.Error())
   525  }