github.com/ablease/cli@v6.37.1-0.20180613014814-3adbb7d7fb19+incompatible/command/v2/auth_command_test.go (about)

     1  package v2_test
     2  
     3  import (
     4  	"errors"
     5  
     6  	"code.cloudfoundry.org/cli/api/uaa"
     7  	"code.cloudfoundry.org/cli/api/uaa/constant"
     8  	"code.cloudfoundry.org/cli/command/commandfakes"
     9  	"code.cloudfoundry.org/cli/command/translatableerror"
    10  	. "code.cloudfoundry.org/cli/command/v2"
    11  	"code.cloudfoundry.org/cli/command/v2/v2fakes"
    12  	"code.cloudfoundry.org/cli/util/ui"
    13  	. "github.com/onsi/ginkgo"
    14  	. "github.com/onsi/gomega"
    15  	. "github.com/onsi/gomega/gbytes"
    16  )
    17  
    18  var _ = Describe("auth Command", func() {
    19  	var (
    20  		cmd        AuthCommand
    21  		testUI     *ui.UI
    22  		fakeActor  *v2fakes.FakeAuthActor
    23  		fakeConfig *commandfakes.FakeConfig
    24  		binaryName string
    25  		err        error
    26  	)
    27  
    28  	BeforeEach(func() {
    29  		testUI = ui.NewTestUI(nil, NewBuffer(), NewBuffer())
    30  		fakeActor = new(v2fakes.FakeAuthActor)
    31  		fakeConfig = new(commandfakes.FakeConfig)
    32  
    33  		cmd = AuthCommand{
    34  			UI:     testUI,
    35  			Config: fakeConfig,
    36  			Actor:  fakeActor,
    37  		}
    38  
    39  		binaryName = "faceman"
    40  		fakeConfig.BinaryNameReturns(binaryName)
    41  	})
    42  
    43  	JustBeforeEach(func() {
    44  		err = cmd.Execute(nil)
    45  	})
    46  
    47  	Context("when there are no errors", func() {
    48  		var (
    49  			testID     string
    50  			testSecret string
    51  		)
    52  
    53  		BeforeEach(func() {
    54  			testID = "hello"
    55  			testSecret = "goodbye"
    56  
    57  			fakeConfig.TargetReturns("some-api-target")
    58  		})
    59  
    60  		Context("when --client-credentials is set", func() {
    61  			BeforeEach(func() {
    62  				cmd.ClientCredentials = true
    63  				cmd.RequiredArgs.Username = testID
    64  				cmd.RequiredArgs.Password = testSecret
    65  			})
    66  
    67  			It("outputs API target information and clears the targeted org and space", func() {
    68  				Expect(err).ToNot(HaveOccurred())
    69  
    70  				Expect(testUI.Out).To(Say("API endpoint: %s", fakeConfig.Target()))
    71  				Expect(testUI.Out).To(Say("Authenticating\\.\\.\\."))
    72  				Expect(testUI.Out).To(Say("OK"))
    73  				Expect(testUI.Out).To(Say("Use '%s target' to view or set your target org and space", binaryName))
    74  
    75  				Expect(fakeActor.AuthenticateCallCount()).To(Equal(1))
    76  				ID, secret, grantType := fakeActor.AuthenticateArgsForCall(0)
    77  				Expect(ID).To(Equal(testID))
    78  				Expect(secret).To(Equal(testSecret))
    79  				Expect(grantType).To(Equal(constant.GrantTypeClientCredentials))
    80  			})
    81  		})
    82  
    83  		Context("when --client-credentials is not set", func() {
    84  			Context("when username and password are only provided as arguments", func() {
    85  				BeforeEach(func() {
    86  					cmd.RequiredArgs.Username = testID
    87  					cmd.RequiredArgs.Password = testSecret
    88  				})
    89  
    90  				It("outputs API target information and clears the targeted org and space", func() {
    91  					Expect(err).ToNot(HaveOccurred())
    92  
    93  					Expect(testUI.Out).To(Say("API endpoint: %s", fakeConfig.Target()))
    94  					Expect(testUI.Out).To(Say("Authenticating\\.\\.\\."))
    95  					Expect(testUI.Out).To(Say("OK"))
    96  					Expect(testUI.Out).To(Say("Use '%s target' to view or set your target org and space", binaryName))
    97  
    98  					Expect(fakeActor.AuthenticateCallCount()).To(Equal(1))
    99  					username, password, grantType := fakeActor.AuthenticateArgsForCall(0)
   100  					Expect(username).To(Equal(testID))
   101  					Expect(password).To(Equal(testSecret))
   102  					Expect(grantType).To(Equal(constant.GrantTypePassword))
   103  				})
   104  			})
   105  
   106  			Context("when the username and password are provided in env variables", func() {
   107  				var (
   108  					envUsername string
   109  					envPassword string
   110  				)
   111  
   112  				BeforeEach(func() {
   113  					envUsername = "banana"
   114  					envPassword = "potato"
   115  					fakeConfig.CFUsernameReturns(envUsername)
   116  					fakeConfig.CFPasswordReturns(envPassword)
   117  				})
   118  
   119  				Context("when username and password are not also provided as arguments", func() {
   120  					It("authenticates with the values in the env variables", func() {
   121  						Expect(err).ToNot(HaveOccurred())
   122  
   123  						Expect(fakeActor.AuthenticateCallCount()).To(Equal(1))
   124  						username, password, _ := fakeActor.AuthenticateArgsForCall(0)
   125  						Expect(username).To(Equal(envUsername))
   126  						Expect(password).To(Equal(envPassword))
   127  					})
   128  				})
   129  
   130  				Context("when username and password are also provided as arguments", func() {
   131  					BeforeEach(func() {
   132  						cmd.RequiredArgs.Username = testID
   133  						cmd.RequiredArgs.Password = testSecret
   134  					})
   135  
   136  					It("authenticates with the values from the command line args", func() {
   137  						Expect(err).ToNot(HaveOccurred())
   138  
   139  						Expect(fakeActor.AuthenticateCallCount()).To(Equal(1))
   140  						username, password, _ := fakeActor.AuthenticateArgsForCall(0)
   141  						Expect(username).To(Equal(testID))
   142  						Expect(password).To(Equal(testSecret))
   143  					})
   144  				})
   145  			})
   146  		})
   147  	})
   148  
   149  	Context("when credentials are missing", func() {
   150  		Context("when username and password are both missing", func() {
   151  			It("raises an error", func() {
   152  				Expect(err).To(MatchError(translatableerror.MissingCredentialsError{
   153  					MissingUsername: true,
   154  					MissingPassword: true,
   155  				}))
   156  			})
   157  		})
   158  
   159  		Context("when username is missing", func() {
   160  			BeforeEach(func() {
   161  				cmd.RequiredArgs.Password = "mypassword"
   162  			})
   163  
   164  			It("raises an error", func() {
   165  				Expect(err).To(MatchError(translatableerror.MissingCredentialsError{
   166  					MissingUsername: true,
   167  				}))
   168  			})
   169  		})
   170  
   171  		Context("when password is missing", func() {
   172  			BeforeEach(func() {
   173  				cmd.RequiredArgs.Username = "myuser"
   174  			})
   175  
   176  			It("raises an error", func() {
   177  				Expect(err).To(MatchError(translatableerror.MissingCredentialsError{
   178  					MissingPassword: true,
   179  				}))
   180  			})
   181  		})
   182  	})
   183  
   184  	Context("when there is an auth error", func() {
   185  		BeforeEach(func() {
   186  			cmd.RequiredArgs.Username = "foo"
   187  			cmd.RequiredArgs.Password = "bar"
   188  
   189  			fakeConfig.TargetReturns("some-api-target")
   190  			fakeActor.AuthenticateReturns(uaa.BadCredentialsError{Message: "some message"})
   191  		})
   192  
   193  		It("returns a BadCredentialsError", func() {
   194  			Expect(err).To(MatchError(uaa.BadCredentialsError{Message: "some message"}))
   195  		})
   196  	})
   197  
   198  	Context("when there is a non-auth error", func() {
   199  		var expectedError error
   200  
   201  		BeforeEach(func() {
   202  			cmd.RequiredArgs.Username = "foo"
   203  			cmd.RequiredArgs.Password = "bar"
   204  
   205  			fakeConfig.TargetReturns("some-api-target")
   206  			expectedError = errors.New("my humps")
   207  
   208  			fakeActor.AuthenticateReturns(expectedError)
   209  		})
   210  
   211  		It("returns the error", func() {
   212  			Expect(err).To(MatchError(expectedError))
   213  		})
   214  	})
   215  
   216  	Describe("it checks the CLI version", func() {
   217  		var (
   218  			apiVersion    string
   219  			minCLIVersion string
   220  			binaryVersion string
   221  		)
   222  
   223  		BeforeEach(func() {
   224  			apiVersion = "1.2.3"
   225  			fakeConfig.APIVersionReturns(apiVersion)
   226  			minCLIVersion = "1.0.0"
   227  			fakeConfig.MinCLIVersionReturns(minCLIVersion)
   228  
   229  			cmd.RequiredArgs.Username = "user"
   230  			cmd.RequiredArgs.Password = "password"
   231  		})
   232  
   233  		Context("the CLI version is older than the minimum version required by the API", func() {
   234  			BeforeEach(func() {
   235  				binaryVersion = "0.0.0"
   236  				fakeConfig.BinaryVersionReturns(binaryVersion)
   237  			})
   238  
   239  			It("displays a recommendation to update the CLI version", func() {
   240  				Expect(err).ToNot(HaveOccurred())
   241  				Expect(testUI.Err).To(Say("Cloud Foundry API version %s requires CLI version %s. You are currently on version %s. To upgrade your CLI, please visit: https://github.com/cloudfoundry/cli#downloads", apiVersion, minCLIVersion, binaryVersion))
   242  			})
   243  		})
   244  
   245  		Context("the CLI version satisfies the API's minimum version requirements", func() {
   246  			BeforeEach(func() {
   247  				binaryVersion = "1.0.0"
   248  				fakeConfig.BinaryVersionReturns(binaryVersion)
   249  			})
   250  
   251  			It("does not display a recommendation to update the CLI version", func() {
   252  				Expect(err).ToNot(HaveOccurred())
   253  				Expect(testUI.Err).ToNot(Say("Cloud Foundry API version %s requires CLI version %s. You are currently on version %s. To upgrade your CLI, please visit: https://github.com/cloudfoundry/cli#downloads", apiVersion, minCLIVersion, binaryVersion))
   254  			})
   255  		})
   256  
   257  		Context("when the CLI version is invalid", func() {
   258  			BeforeEach(func() {
   259  				fakeConfig.BinaryVersionReturns("&#%")
   260  			})
   261  
   262  			It("returns an error", func() {
   263  				Expect(err).To(HaveOccurred())
   264  				Expect(err.Error()).To(Equal("No Major.Minor.Patch elements found"))
   265  			})
   266  		})
   267  	})
   268  })