1
// Copyright 2014 Canonical Ltd.
2
// Licensed under the AGPLv3, see LICENCE file for details.
10
"github.com/juju/errors"
11
jc "github.com/juju/testing/checkers"
12
gc "gopkg.in/check.v1"
13
"gopkg.in/juju/names.v2"
15
"github.com/juju/juju/api/base"
16
"github.com/juju/juju/apiserver/common"
17
"github.com/juju/juju/cmd/juju/user"
18
"github.com/juju/juju/testing"
21
// All of the functionality of the AddUser api call is contained elsewhere.
22
// This suite provides basic tests for the "add-user" command
23
type UserAddCommandSuite struct {
25
mockAPI *mockAddUserAPI
28
var _ = gc.Suite(&UserAddCommandSuite{})
30
func (s *UserAddCommandSuite) SetUpTest(c *gc.C) {
31
s.BaseSuite.SetUpTest(c)
32
s.mockAPI = &mockAddUserAPI{}
33
s.mockAPI.secretKey = []byte(strings.Repeat("X", 32))
36
func (s *UserAddCommandSuite) run(c *gc.C, args ...string) (*cmd.Context, error) {
37
addCommand, _ := user.NewAddCommandForTest(s.mockAPI, s.store, &mockModelApi{})
38
return testing.RunCommand(c, addCommand, args...)
41
func (s *UserAddCommandSuite) TestInit(c *gc.C) {
42
for i, test := range []struct {
51
errorString: "no username supplied",
53
args: []string{"foobar"},
56
args: []string{"foobar", "Foo Bar"},
58
displayname: "Foo Bar",
60
args: []string{"foobar", "Foo Bar", "extra"},
61
errorString: `unrecognized args: \["extra"\]`,
63
args: []string{"foobar", "--models", "foo,bar", "--acl=read"},
68
args: []string{"foobar", "--models", "baz", "--acl=write"},
73
c.Logf("test %d (%q)", i, test.args)
74
wrappedCommand, command := user.NewAddCommandForTest(s.mockAPI, s.store, &mockModelApi{})
75
err := testing.InitCommand(wrappedCommand, test.args)
76
if test.errorString == "" {
77
c.Check(err, jc.ErrorIsNil)
78
c.Check(command.User, gc.Equals, test.user)
79
c.Check(command.DisplayName, gc.Equals, test.displayname)
80
if len(test.models) > 0 {
81
c.Check(command.ModelNames, gc.Equals, test.models)
84
c.Check(command.ModelAccess, gc.Equals, test.acl)
87
c.Check(err, gc.ErrorMatches, test.errorString)
92
func (s *UserAddCommandSuite) TestAddUserWithUsername(c *gc.C) {
93
context, err := s.run(c, "foobar")
94
c.Assert(err, jc.ErrorIsNil)
95
c.Assert(s.mockAPI.username, gc.Equals, "foobar")
96
c.Assert(s.mockAPI.displayname, gc.Equals, "")
97
c.Assert(s.mockAPI.access, gc.Equals, "read")
98
c.Assert(s.mockAPI.models, gc.HasLen, 0)
101
Please send this command to foobar:
102
juju register MEYTBmZvb2JhcjAREw8xMjcuMC4wLjE6MTIzNDUEIFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYEwd0ZXN0aW5n
104
"foobar" has not been granted access to any models. You can use "juju grant" to grant access.
106
c.Assert(testing.Stdout(context), gc.Equals, expected)
107
c.Assert(testing.Stderr(context), gc.Equals, "")
110
func (s *UserAddCommandSuite) TestAddUserWithUsernameAndACL(c *gc.C) {
111
context, err := s.run(c, "--acl", "write", "foobar")
112
c.Assert(err, jc.ErrorIsNil)
113
c.Assert(s.mockAPI.username, gc.Equals, "foobar")
114
c.Assert(s.mockAPI.displayname, gc.Equals, "")
115
c.Assert(s.mockAPI.access, gc.Equals, "write")
116
c.Assert(s.mockAPI.models, gc.HasLen, 0)
119
Please send this command to foobar:
120
juju register MEYTBmZvb2JhcjAREw8xMjcuMC4wLjE6MTIzNDUEIFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYEwd0ZXN0aW5n
122
"foobar" has not been granted access to any models. You can use "juju grant" to grant access.
124
c.Assert(testing.Stdout(context), gc.Equals, expected)
125
c.Assert(testing.Stderr(context), gc.Equals, "")
128
func (s *UserAddCommandSuite) TestAddUserWithUsernameAndDisplayname(c *gc.C) {
129
context, err := s.run(c, "foobar", "Foo Bar")
130
c.Assert(err, jc.ErrorIsNil)
131
c.Assert(s.mockAPI.username, gc.Equals, "foobar")
132
c.Assert(s.mockAPI.displayname, gc.Equals, "Foo Bar")
133
c.Assert(s.mockAPI.access, gc.Equals, "read")
134
c.Assert(s.mockAPI.models, gc.HasLen, 0)
136
User "Foo Bar (foobar)" added
137
Please send this command to foobar:
138
juju register MEYTBmZvb2JhcjAREw8xMjcuMC4wLjE6MTIzNDUEIFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYEwd0ZXN0aW5n
140
"Foo Bar (foobar)" has not been granted access to any models. You can use "juju grant" to grant access.
142
c.Assert(testing.Stdout(context), gc.Equals, expected)
143
c.Assert(testing.Stderr(context), gc.Equals, "")
146
type mockModelApi struct{}
148
func (m *mockModelApi) ListModels(user string) ([]base.UserModel, error) {
149
return []base.UserModel{{Name: "model", UUID: "modeluuid", Owner: "current-user@local"}}, nil
152
func (m *mockModelApi) Close() error {
156
func (s *UserAddCommandSuite) TestAddUserWithModelAccess(c *gc.C) {
157
context, err := s.run(c, "foobar", "--models", "model")
158
c.Assert(err, jc.ErrorIsNil)
159
c.Assert(s.mockAPI.username, gc.Equals, "foobar")
160
c.Assert(s.mockAPI.displayname, gc.Equals, "")
161
c.Assert(s.mockAPI.access, gc.Equals, "read")
162
c.Assert(s.mockAPI.models, gc.DeepEquals, []string{"modeluuid"})
165
User "foobar" granted read access to model "model"
166
Please send this command to foobar:
167
juju register MEYTBmZvb2JhcjAREw8xMjcuMC4wLjE6MTIzNDUEIFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYEwd0ZXN0aW5n
169
c.Assert(testing.Stdout(context), gc.Equals, expected)
170
c.Assert(testing.Stderr(context), gc.Equals, "")
173
func (s *UserAddCommandSuite) TestBlockAddUser(c *gc.C) {
175
s.mockAPI.blocked = true
176
_, err := s.run(c, "foobar", "Foo Bar")
177
c.Assert(err, gc.ErrorMatches, cmd.ErrSilent.Error())
179
stripped := strings.Replace(c.GetTestLog(), "\n", "", -1)
180
c.Check(stripped, gc.Matches, ".*To unblock changes.*")
183
func (s *UserAddCommandSuite) TestAddUserErrorResponse(c *gc.C) {
184
s.mockAPI.failMessage = "failed to create user, chaos ensues"
185
_, err := s.run(c, "foobar")
186
c.Assert(err, gc.ErrorMatches, s.mockAPI.failMessage)
189
type mockAddUserAPI struct {
201
func (m *mockAddUserAPI) AddUser(username, displayname, password, access string, models ...string) (names.UserTag, []byte, error) {
203
return names.UserTag{}, nil, common.OperationBlockedError("the operation has been blocked")
205
m.username = username
206
m.displayname = displayname
207
m.password = password
210
if m.failMessage != "" {
211
return names.UserTag{}, nil, errors.New(m.failMessage)
213
return names.NewLocalUserTag(username), m.secretKey, nil
216
func (*mockAddUserAPI) Close() error {