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 })