github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/cmd/juju/user/add_test.go (about) 1 // Copyright 2014 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package user_test 5 6 import ( 7 "strings" 8 9 "github.com/juju/cmd" 10 "github.com/juju/cmd/cmdtesting" 11 "github.com/juju/errors" 12 jc "github.com/juju/testing/checkers" 13 gc "gopkg.in/check.v1" 14 "gopkg.in/juju/names.v2" 15 16 "github.com/juju/juju/api/base" 17 "github.com/juju/juju/apiserver/common" 18 "github.com/juju/juju/apiserver/params" 19 "github.com/juju/juju/cmd/juju/user" 20 "github.com/juju/juju/testing" 21 ) 22 23 // All of the functionality of the AddUser api call is contained elsewhere. 24 // This suite provides basic tests for the "add-user" command 25 type UserAddCommandSuite struct { 26 BaseSuite 27 mockAPI *mockAddUserAPI 28 } 29 30 var _ = gc.Suite(&UserAddCommandSuite{}) 31 32 func (s *UserAddCommandSuite) SetUpTest(c *gc.C) { 33 s.BaseSuite.SetUpTest(c) 34 s.mockAPI = &mockAddUserAPI{} 35 s.mockAPI.secretKey = []byte(strings.Repeat("X", 32)) 36 } 37 38 func (s *UserAddCommandSuite) run(c *gc.C, args ...string) (*cmd.Context, error) { 39 addCommand, _ := user.NewAddCommandForTest(s.mockAPI, s.store, &mockModelAPI{}) 40 return cmdtesting.RunCommand(c, addCommand, args...) 41 } 42 43 func (s *UserAddCommandSuite) TestInit(c *gc.C) { 44 for i, test := range []struct { 45 args []string 46 user string 47 displayname string 48 models string 49 acl string 50 outPath string 51 errorString string 52 }{{ 53 errorString: "no username supplied", 54 }, { 55 args: []string{"foobar"}, 56 user: "foobar", 57 }, { 58 args: []string{"foobar", "Foo Bar"}, 59 user: "foobar", 60 displayname: "Foo Bar", 61 }, { 62 args: []string{"foobar", "Foo Bar", "extra"}, 63 errorString: `unrecognized args: \["extra"\]`, 64 }, { 65 args: []string{"foobar"}, 66 user: "foobar", 67 }, { 68 args: []string{"foobar"}, 69 user: "foobar", 70 }} { 71 c.Logf("test %d (%q)", i, test.args) 72 wrappedCommand, command := user.NewAddCommandForTest(s.mockAPI, s.store, &mockModelAPI{}) 73 err := cmdtesting.InitCommand(wrappedCommand, test.args) 74 if test.errorString == "" { 75 c.Check(err, jc.ErrorIsNil) 76 c.Check(command.User, gc.Equals, test.user) 77 c.Check(command.DisplayName, gc.Equals, test.displayname) 78 } else { 79 c.Check(err, gc.ErrorMatches, test.errorString) 80 } 81 } 82 } 83 84 func (s *UserAddCommandSuite) TestAddUserWithUsername(c *gc.C) { 85 context, err := s.run(c, "foobar") 86 c.Assert(err, jc.ErrorIsNil) 87 c.Assert(s.mockAPI.username, gc.Equals, "foobar") 88 c.Assert(s.mockAPI.displayname, gc.Equals, "") 89 expected := ` 90 User "foobar" added 91 Please send this command to foobar: 92 juju register MEQTBmZvb2JhcjAPEw0wLjEuMi4zOjEyMzQ1BCBYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWBMHdGVzdGluZwAA 93 94 "foobar" has not been granted access to any models. You can use "juju grant" to grant access. 95 `[1:] 96 c.Assert(cmdtesting.Stdout(context), gc.Equals, expected) 97 c.Assert(cmdtesting.Stderr(context), gc.Equals, "") 98 } 99 100 func (s *UserAddCommandSuite) TestAddUserWithUsernameAndDisplayname(c *gc.C) { 101 context, err := s.run(c, "foobar", "Foo Bar") 102 c.Assert(err, jc.ErrorIsNil) 103 c.Assert(s.mockAPI.username, gc.Equals, "foobar") 104 c.Assert(s.mockAPI.displayname, gc.Equals, "Foo Bar") 105 expected := ` 106 User "Foo Bar (foobar)" added 107 Please send this command to foobar: 108 juju register MEQTBmZvb2JhcjAPEw0wLjEuMi4zOjEyMzQ1BCBYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWBMHdGVzdGluZwAA 109 110 "Foo Bar (foobar)" has not been granted access to any models. You can use "juju grant" to grant access. 111 `[1:] 112 c.Assert(cmdtesting.Stdout(context), gc.Equals, expected) 113 c.Assert(cmdtesting.Stderr(context), gc.Equals, "") 114 } 115 116 func (s *UserAddCommandSuite) TestUserRegistrationString(c *gc.C) { 117 // Ensure that the user registration string only contains alphanumerics. 118 for i := 0; i < 3; i++ { 119 s.mockAPI.secretKey = []byte(strings.Repeat("X", 32+i)) 120 context, err := s.run(c, "foobar", "Foo Bar") 121 c.Assert(err, jc.ErrorIsNil) 122 lines := strings.Split(cmdtesting.Stdout(context), "\n") 123 c.Assert(lines, gc.HasLen, 6) 124 c.Assert(lines[2], gc.Matches, `^\s+juju register [A-Za-z0-9]+$`) 125 } 126 } 127 128 type mockModelAPI struct{} 129 130 func (m *mockModelAPI) ListModels(user string) ([]base.UserModel, error) { 131 return []base.UserModel{{Name: "model", UUID: "modeluuid", Owner: "current-user"}}, nil 132 } 133 134 func (m *mockModelAPI) Close() error { 135 return nil 136 } 137 138 func (s *UserAddCommandSuite) TestBlockAddUser(c *gc.C) { 139 // Block operation 140 s.mockAPI.blocked = true 141 _, err := s.run(c, "foobar", "Foo Bar") 142 testing.AssertOperationWasBlocked(c, err, ".*To enable changes.*") 143 } 144 145 func (s *UserAddCommandSuite) TestAddUserErrorResponse(c *gc.C) { 146 s.mockAPI.failMessage = "failed to create user, chaos ensues" 147 _, err := s.run(c, "foobar") 148 c.Assert(err, gc.ErrorMatches, s.mockAPI.failMessage) 149 } 150 151 func (s *UserAddCommandSuite) TestAddUserUnauthorizedMentionsJujuGrant(c *gc.C) { 152 s.mockAPI.addError = ¶ms.Error{ 153 Message: "permission denied", 154 Code: params.CodeUnauthorized, 155 } 156 ctx, _ := s.run(c, "foobar") 157 errString := strings.Replace(cmdtesting.Stderr(ctx), "\n", " ", -1) 158 c.Assert(errString, gc.Matches, `.*juju grant.*`) 159 } 160 161 type mockAddUserAPI struct { 162 addError error 163 failMessage string 164 blocked bool 165 secretKey []byte 166 167 username string 168 displayname string 169 password string 170 } 171 172 func (m *mockAddUserAPI) AddUser(username, displayname, password string) (names.UserTag, []byte, error) { 173 if m.blocked { 174 return names.UserTag{}, nil, common.OperationBlockedError("the operation has been blocked") 175 } 176 if m.addError != nil { 177 return names.UserTag{}, nil, m.addError 178 } 179 m.username = username 180 m.displayname = displayname 181 m.password = password 182 if m.failMessage != "" { 183 return names.UserTag{}, nil, errors.New(m.failMessage) 184 } 185 return names.NewLocalUserTag(username), m.secretKey, nil 186 } 187 188 func (*mockAddUserAPI) Close() error { 189 return nil 190 }