github.com/axw/juju@v0.0.0-20161005053422-4bd6544d08d4/cmd/juju/user/change_password_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/errors"
    11  	"github.com/juju/testing"
    12  	jc "github.com/juju/testing/checkers"
    13  	gc "gopkg.in/check.v1"
    14  
    15  	"github.com/juju/juju/api"
    16  	"github.com/juju/juju/cmd/juju/user"
    17  	"github.com/juju/juju/juju"
    18  	"github.com/juju/juju/jujuclient"
    19  	coretesting "github.com/juju/juju/testing"
    20  )
    21  
    22  type ChangePasswordCommandSuite struct {
    23  	BaseSuite
    24  	mockAPI *mockChangePasswordAPI
    25  	store   jujuclient.ClientStore
    26  }
    27  
    28  var _ = gc.Suite(&ChangePasswordCommandSuite{})
    29  
    30  func (s *ChangePasswordCommandSuite) SetUpTest(c *gc.C) {
    31  	s.BaseSuite.SetUpTest(c)
    32  	s.mockAPI = &mockChangePasswordAPI{}
    33  	s.store = s.BaseSuite.store
    34  }
    35  
    36  func (s *ChangePasswordCommandSuite) run(c *gc.C, args ...string) (*cmd.Context, *juju.NewAPIConnectionParams, error) {
    37  	var argsOut juju.NewAPIConnectionParams
    38  	newAPIConnection := func(args juju.NewAPIConnectionParams) (api.Connection, error) {
    39  		argsOut = args
    40  		return mockAPIConnection{}, nil
    41  	}
    42  	changePasswordCommand, _ := user.NewChangePasswordCommandForTest(
    43  		newAPIConnection, s.mockAPI, s.store,
    44  	)
    45  	ctx := coretesting.Context(c)
    46  	ctx.Stdin = strings.NewReader("sekrit\nsekrit\n")
    47  	err := coretesting.InitCommand(changePasswordCommand, args)
    48  	if err != nil {
    49  		return ctx, nil, err
    50  	}
    51  	return ctx, &argsOut, changePasswordCommand.Run(ctx)
    52  }
    53  
    54  func (s *ChangePasswordCommandSuite) TestInit(c *gc.C) {
    55  	for i, test := range []struct {
    56  		args        []string
    57  		user        string
    58  		errorString string
    59  	}{
    60  		{
    61  		// no args is fine
    62  		}, {
    63  			args: []string{"foobar"},
    64  			user: "foobar",
    65  		}, {
    66  			args:        []string{"--foobar"},
    67  			errorString: "flag provided but not defined: --foobar",
    68  		}, {
    69  			args:        []string{"foobar", "extra"},
    70  			errorString: `unrecognized args: \["extra"\]`,
    71  		},
    72  	} {
    73  		c.Logf("test %d", i)
    74  		wrappedCommand, command := user.NewChangePasswordCommandForTest(nil, nil, s.store)
    75  		err := coretesting.InitCommand(wrappedCommand, test.args)
    76  		if test.errorString == "" {
    77  			c.Check(command.User, gc.Equals, test.user)
    78  		} else {
    79  			c.Check(err, gc.ErrorMatches, test.errorString)
    80  		}
    81  	}
    82  }
    83  
    84  func (s *ChangePasswordCommandSuite) assertAPICalls(c *gc.C, user, pass string) {
    85  	s.mockAPI.CheckCall(c, 0, "SetPassword", user, pass)
    86  }
    87  
    88  func (s *ChangePasswordCommandSuite) TestChangePassword(c *gc.C) {
    89  	context, args, err := s.run(c)
    90  	c.Assert(err, jc.ErrorIsNil)
    91  	s.assertAPICalls(c, "current-user@local", "sekrit")
    92  	c.Assert(coretesting.Stdout(context), gc.Equals, "")
    93  	c.Assert(coretesting.Stderr(context), gc.Equals, `
    94  new password: 
    95  type new password again: 
    96  Your password has been updated.
    97  `[1:])
    98  	// The command should have logged in without a password to get a macaroon.
    99  	c.Assert(args.AccountDetails, jc.DeepEquals, &jujuclient.AccountDetails{
   100  		User: "current-user@local",
   101  	})
   102  }
   103  
   104  func (s *ChangePasswordCommandSuite) TestChangePasswordFail(c *gc.C) {
   105  	s.mockAPI.SetErrors(errors.New("failed to do something"))
   106  	_, _, err := s.run(c)
   107  	c.Assert(err, gc.ErrorMatches, "failed to do something")
   108  	s.assertAPICalls(c, "current-user@local", "sekrit")
   109  }
   110  
   111  func (s *ChangePasswordCommandSuite) TestChangeOthersPassword(c *gc.C) {
   112  	// The checks for user existence and admin rights are tested
   113  	// at the apiserver level.
   114  	_, _, err := s.run(c, "other")
   115  	c.Assert(err, jc.ErrorIsNil)
   116  	s.assertAPICalls(c, "other@local", "sekrit")
   117  }
   118  
   119  type mockChangePasswordAPI struct {
   120  	testing.Stub
   121  }
   122  
   123  func (m *mockChangePasswordAPI) SetPassword(username, password string) error {
   124  	m.MethodCall(m, "SetPassword", username, password)
   125  	return m.NextErr()
   126  }
   127  
   128  func (*mockChangePasswordAPI) Close() error {
   129  	return nil
   130  }
   131  
   132  type mockAPIConnection struct {
   133  	api.Connection
   134  }
   135  
   136  func (mockAPIConnection) Close() error {
   137  	return nil
   138  }