github.com/mattyw/juju@v0.0.0-20140610034352-732aecd63861/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 main 5 6 import ( 7 "errors" 8 "fmt" 9 "io/ioutil" 10 "path/filepath" 11 12 jc "github.com/juju/testing/checkers" 13 gc "launchpad.net/gocheck" 14 "launchpad.net/goyaml" 15 16 "github.com/juju/juju/cmd" 17 "github.com/juju/juju/cmd/envcmd" 18 "github.com/juju/juju/environs/configstore" 19 "github.com/juju/juju/testing" 20 ) 21 22 // All of the functionality of the AddUser api call is contained elsewhere. 23 // This suite provides basic tests for the "user add" command 24 type UserAddCommandSuite struct { 25 testing.FakeJujuHomeSuite 26 mockAPI *mockAddUserAPI 27 } 28 29 var _ = gc.Suite(&UserAddCommandSuite{}) 30 31 func (s *UserAddCommandSuite) SetUpTest(c *gc.C) { 32 s.FakeJujuHomeSuite.SetUpTest(c) 33 s.mockAPI = &mockAddUserAPI{} 34 s.PatchValue(&getAddUserAPI, func(c *UserAddCommand) (addUserAPI, error) { 35 return s.mockAPI, nil 36 }) 37 } 38 39 func newUserAddCommand() cmd.Command { 40 return envcmd.Wrap(&UserAddCommand{}) 41 } 42 43 func (s *UserAddCommandSuite) TestAddUserJustUsername(c *gc.C) { 44 context, err := testing.RunCommand(c, newUserAddCommand(), "foobar") 45 c.Assert(err, gc.IsNil) 46 c.Assert(s.mockAPI.username, gc.Equals, "foobar") 47 c.Assert(s.mockAPI.displayname, gc.Equals, "") 48 // Password is generated 49 c.Assert(s.mockAPI.password, gc.Not(gc.Equals), "") 50 expected := fmt.Sprintf(`user "foobar" added with password %q`, s.mockAPI.password) 51 c.Assert(testing.Stdout(context), gc.Equals, expected+"\n") 52 } 53 54 func (s *UserAddCommandSuite) TestAddUserUsernameAndDisplayname(c *gc.C) { 55 context, err := testing.RunCommand(c, newUserAddCommand(), "foobar", "Foo Bar") 56 c.Assert(err, gc.IsNil) 57 c.Assert(s.mockAPI.username, gc.Equals, "foobar") 58 c.Assert(s.mockAPI.displayname, gc.Equals, "Foo Bar") 59 // Password is generated 60 c.Assert(s.mockAPI.password, gc.Not(gc.Equals), "") 61 expected := fmt.Sprintf(`user "Foo Bar (foobar)" added with password %q`, s.mockAPI.password) 62 c.Assert(testing.Stdout(context), gc.Equals, expected+"\n") 63 } 64 65 func (s *UserAddCommandSuite) TestAddUserUsernameAndDisplaynameWithPassword(c *gc.C) { 66 context, err := testing.RunCommand(c, newUserAddCommand(), "foobar", "Foo Bar", "--password", "password") 67 c.Assert(err, gc.IsNil) 68 c.Assert(s.mockAPI.username, gc.Equals, "foobar") 69 c.Assert(s.mockAPI.displayname, gc.Equals, "Foo Bar") 70 c.Assert(s.mockAPI.password, gc.Equals, "password") 71 expected := `user "Foo Bar (foobar)" added with password "password"` 72 c.Assert(testing.Stdout(context), gc.Equals, expected+"\n") 73 } 74 75 func (s *UserAddCommandSuite) TestAddUserErrorResponse(c *gc.C) { 76 s.mockAPI.failMessage = "failed to create user, chaos ensues" 77 context, err := testing.RunCommand(c, newUserAddCommand(), "foobar") 78 c.Assert(err, gc.ErrorMatches, "failed to create user, chaos ensues") 79 c.Assert(s.mockAPI.username, gc.Equals, "foobar") 80 c.Assert(s.mockAPI.displayname, gc.Equals, "") 81 c.Assert(testing.Stdout(context), gc.Equals, "") 82 } 83 84 func (s *UserAddCommandSuite) TestInit(c *gc.C) { 85 for i, test := range []struct { 86 args []string 87 user string 88 displayname string 89 password string 90 outPath string 91 errorString string 92 }{ 93 { 94 errorString: "no username supplied", 95 }, { 96 args: []string{"foobar"}, 97 user: "foobar", 98 }, { 99 args: []string{"foobar", "Foo Bar"}, 100 user: "foobar", 101 displayname: "Foo Bar", 102 }, { 103 args: []string{"foobar", "Foo Bar", "extra"}, 104 errorString: `unrecognized args: \["extra"\]`, 105 }, { 106 args: []string{"foobar", "--password", "password"}, 107 user: "foobar", 108 password: "password", 109 }, { 110 args: []string{"foobar", "--output", "somefile"}, 111 user: "foobar", 112 outPath: "somefile", 113 }, { 114 args: []string{"foobar", "-o", "somefile"}, 115 user: "foobar", 116 outPath: "somefile", 117 }, 118 } { 119 c.Logf("test %d", i) 120 addUserCmd := &UserAddCommand{} 121 err := testing.InitCommand(addUserCmd, test.args) 122 if test.errorString == "" { 123 c.Check(addUserCmd.User, gc.Equals, test.user) 124 c.Check(addUserCmd.DisplayName, gc.Equals, test.displayname) 125 c.Check(addUserCmd.Password, gc.Equals, test.password) 126 c.Check(addUserCmd.OutPath, gc.Equals, test.outPath) 127 } else { 128 c.Check(err, gc.ErrorMatches, test.errorString) 129 } 130 } 131 } 132 133 func fakeBootstrapEnvironment(c *gc.C, envName string) { 134 store, err := configstore.Default() 135 c.Assert(err, gc.IsNil) 136 envInfo, err := store.CreateInfo(envName) 137 c.Assert(err, gc.IsNil) 138 envInfo.SetBootstrapConfig(map[string]interface{}{"random": "extra data"}) 139 envInfo.SetAPIEndpoint(configstore.APIEndpoint{ 140 Addresses: []string{"localhost:12345"}, 141 CACert: testing.CACert, 142 }) 143 envInfo.SetAPICredentials(configstore.APICredentials{ 144 User: "admin", 145 Password: "password", 146 }) 147 err = envInfo.Write() 148 c.Assert(err, gc.IsNil) 149 } 150 151 func (s *UserAddCommandSuite) TestJenvOutput(c *gc.C) { 152 fakeBootstrapEnvironment(c, "erewhemos") 153 outputName := filepath.Join(c.MkDir(), "output") 154 ctx, err := testing.RunCommand(c, newUserAddCommand(), 155 "foobar", "--password", "password", "--output", outputName) 156 c.Assert(err, gc.IsNil) 157 158 expected := fmt.Sprintf(`user "foobar" added with password %q`, s.mockAPI.password) 159 expected = fmt.Sprintf("%s\nenvironment file written to %s.jenv\n", expected, outputName) 160 c.Assert(testing.Stdout(ctx), gc.Equals, expected) 161 162 raw, err := ioutil.ReadFile(outputName + ".jenv") 163 c.Assert(err, gc.IsNil) 164 d := map[string]interface{}{} 165 err = goyaml.Unmarshal(raw, &d) 166 c.Assert(err, gc.IsNil) 167 c.Assert(d["user"], gc.Equals, "foobar") 168 c.Assert(d["password"], gc.Equals, "password") 169 c.Assert(d["state-servers"], gc.DeepEquals, []interface{}{"localhost:12345"}) 170 c.Assert(d["ca-cert"], gc.DeepEquals, testing.CACert) 171 _, found := d["bootstrap-config"] 172 c.Assert(found, jc.IsFalse) 173 } 174 175 type mockAddUserAPI struct { 176 failMessage string 177 username string 178 displayname string 179 password string 180 } 181 182 func (m *mockAddUserAPI) AddUser(username, displayname, password string) error { 183 m.username = username 184 m.displayname = displayname 185 m.password = password 186 if m.failMessage == "" { 187 return nil 188 } 189 return errors.New(m.failMessage) 190 } 191 192 func (*mockAddUserAPI) Close() error { 193 return nil 194 }