github.com/DaAlbrecht/cf-cli@v0.0.0-20231128151943-1fe19bb400b9/actor/v7action/service_app_binding_test.go (about) 1 package v7action_test 2 3 import ( 4 "errors" 5 6 "code.cloudfoundry.org/cli/actor/actionerror" 7 . "code.cloudfoundry.org/cli/actor/v7action" 8 "code.cloudfoundry.org/cli/actor/v7action/v7actionfakes" 9 "code.cloudfoundry.org/cli/api/cloudcontroller/ccerror" 10 "code.cloudfoundry.org/cli/api/cloudcontroller/ccv3" 11 "code.cloudfoundry.org/cli/api/cloudcontroller/ccv3/constant" 12 "code.cloudfoundry.org/cli/resources" 13 "code.cloudfoundry.org/cli/types" 14 . "github.com/onsi/ginkgo" 15 . "github.com/onsi/gomega" 16 ) 17 18 var _ = Describe("Service App Binding Action", func() { 19 var ( 20 actor *Actor 21 fakeCloudControllerClient *v7actionfakes.FakeCloudControllerClient 22 ) 23 24 BeforeEach(func() { 25 fakeCloudControllerClient = new(v7actionfakes.FakeCloudControllerClient) 26 actor = NewActor(fakeCloudControllerClient, nil, nil, nil, nil, nil) 27 }) 28 29 Describe("CreateServiceAppBinding", func() { 30 const ( 31 serviceInstanceName = "fake-service-instance-name" 32 serviceInstanceGUID = "fake-service-instance-guid" 33 appName = "fake-app-name" 34 appGUID = "fake-app-guid" 35 bindingName = "fake-binding-name" 36 spaceGUID = "fake-space-guid" 37 fakeJobURL = ccv3.JobURL("fake-job-url") 38 ) 39 40 var ( 41 params CreateServiceAppBindingParams 42 warnings Warnings 43 executionError error 44 stream chan PollJobEvent 45 ) 46 47 BeforeEach(func() { 48 fakeCloudControllerClient.GetServiceInstanceByNameAndSpaceReturns( 49 resources.ServiceInstance{ 50 Name: serviceInstanceName, 51 GUID: serviceInstanceGUID, 52 }, 53 ccv3.IncludedResources{}, 54 ccv3.Warnings{"get instance warning"}, 55 nil, 56 ) 57 58 fakeCloudControllerClient.GetApplicationByNameAndSpaceReturns( 59 resources.Application{ 60 GUID: appGUID, 61 Name: appName, 62 }, 63 ccv3.Warnings{"get app warning"}, 64 nil, 65 ) 66 67 fakeCloudControllerClient.CreateServiceCredentialBindingReturns( 68 fakeJobURL, 69 ccv3.Warnings{"create binding warning"}, 70 nil, 71 ) 72 73 fakeStream := make(chan ccv3.PollJobEvent) 74 fakeCloudControllerClient.PollJobToEventStreamReturns(fakeStream) 75 go func() { 76 fakeStream <- ccv3.PollJobEvent{ 77 State: constant.JobPolling, 78 Warnings: ccv3.Warnings{"poll warning"}, 79 } 80 }() 81 82 params = CreateServiceAppBindingParams{ 83 SpaceGUID: spaceGUID, 84 ServiceInstanceName: serviceInstanceName, 85 AppName: appName, 86 BindingName: bindingName, 87 Parameters: types.NewOptionalObject(map[string]interface{}{ 88 "foo": "bar", 89 }), 90 } 91 }) 92 93 JustBeforeEach(func() { 94 stream, warnings, executionError = actor.CreateServiceAppBinding(params) 95 }) 96 97 It("returns an event stream, warnings, and no errors", func() { 98 Expect(executionError).NotTo(HaveOccurred()) 99 100 Expect(warnings).To(ConsistOf(Warnings{ 101 "get instance warning", 102 "get app warning", 103 "create binding warning", 104 })) 105 106 Eventually(stream).Should(Receive(Equal(PollJobEvent{ 107 State: JobPolling, 108 Warnings: Warnings{"poll warning"}, 109 Err: nil, 110 }))) 111 }) 112 113 Describe("service instance lookup", func() { 114 It("makes the correct call", func() { 115 Expect(fakeCloudControllerClient.GetServiceInstanceByNameAndSpaceCallCount()).To(Equal(1)) 116 actualServiceInstanceName, actualSpaceGUID, actualQuery := fakeCloudControllerClient.GetServiceInstanceByNameAndSpaceArgsForCall(0) 117 Expect(actualServiceInstanceName).To(Equal(serviceInstanceName)) 118 Expect(actualSpaceGUID).To(Equal(spaceGUID)) 119 Expect(actualQuery).To(BeEmpty()) 120 }) 121 122 When("not found", func() { 123 BeforeEach(func() { 124 fakeCloudControllerClient.GetServiceInstanceByNameAndSpaceReturns( 125 resources.ServiceInstance{}, 126 ccv3.IncludedResources{}, 127 ccv3.Warnings{"get instance warning"}, 128 ccerror.ServiceInstanceNotFoundError{Name: serviceInstanceName}, 129 ) 130 }) 131 132 It("returns the error and warning", func() { 133 Expect(warnings).To(ContainElement("get instance warning")) 134 Expect(executionError).To(MatchError(actionerror.ServiceInstanceNotFoundError{Name: serviceInstanceName})) 135 }) 136 }) 137 138 When("fails", func() { 139 BeforeEach(func() { 140 fakeCloudControllerClient.GetServiceInstanceByNameAndSpaceReturns( 141 resources.ServiceInstance{}, 142 ccv3.IncludedResources{}, 143 ccv3.Warnings{"get instance warning"}, 144 errors.New("boof"), 145 ) 146 }) 147 148 It("returns the error and warning", func() { 149 Expect(warnings).To(ContainElement("get instance warning")) 150 Expect(executionError).To(MatchError("boof")) 151 }) 152 }) 153 }) 154 155 Describe("app lookup", func() { 156 It("makes the correct call", func() { 157 Expect(fakeCloudControllerClient.GetApplicationByNameAndSpaceCallCount()).To(Equal(1)) 158 actualAppName, actualSpaceGUID := fakeCloudControllerClient.GetApplicationByNameAndSpaceArgsForCall(0) 159 Expect(actualAppName).To(Equal(appName)) 160 Expect(actualSpaceGUID).To(Equal(spaceGUID)) 161 }) 162 163 When("not found", func() { 164 BeforeEach(func() { 165 fakeCloudControllerClient.GetApplicationByNameAndSpaceReturns( 166 resources.Application{}, 167 ccv3.Warnings{"get app warning"}, 168 ccerror.ApplicationNotFoundError{Name: appName}, 169 ) 170 }) 171 172 It("returns the error and warning", func() { 173 Expect(warnings).To(ContainElement("get app warning")) 174 Expect(executionError).To(MatchError(actionerror.ApplicationNotFoundError{Name: appName})) 175 }) 176 }) 177 178 When("fails", func() { 179 BeforeEach(func() { 180 fakeCloudControllerClient.GetApplicationByNameAndSpaceReturns( 181 resources.Application{}, 182 ccv3.Warnings{"get app warning"}, 183 errors.New("boom"), 184 ) 185 }) 186 187 It("returns the error and warning", func() { 188 Expect(warnings).To(ContainElement("get app warning")) 189 Expect(executionError).To(MatchError("boom")) 190 }) 191 }) 192 }) 193 194 Describe("initiating the create", func() { 195 It("makes the correct call", func() { 196 Expect(fakeCloudControllerClient.CreateServiceCredentialBindingCallCount()).To(Equal(1)) 197 Expect(fakeCloudControllerClient.CreateServiceCredentialBindingArgsForCall(0)).To(Equal(resources.ServiceCredentialBinding{ 198 Type: resources.AppBinding, 199 Name: bindingName, 200 ServiceInstanceGUID: serviceInstanceGUID, 201 AppGUID: appGUID, 202 Parameters: types.NewOptionalObject(map[string]interface{}{ 203 "foo": "bar", 204 }), 205 })) 206 }) 207 208 When("binding already exists", func() { 209 BeforeEach(func() { 210 fakeCloudControllerClient.CreateServiceCredentialBindingReturns( 211 "", 212 ccv3.Warnings{"create binding warning"}, 213 ccerror.ResourceAlreadyExistsError{ 214 Message: "The app is already bound to the service instance", 215 }, 216 ) 217 }) 218 219 It("returns an actionerror and warnings", func() { 220 Expect(warnings).To(ContainElement("create binding warning")) 221 Expect(executionError).To(MatchError(actionerror.ResourceAlreadyExistsError{ 222 Message: "The app is already bound to the service instance", 223 })) 224 }) 225 }) 226 227 When("fails", func() { 228 BeforeEach(func() { 229 fakeCloudControllerClient.CreateServiceCredentialBindingReturns( 230 "", 231 ccv3.Warnings{"create binding warning"}, 232 errors.New("boop"), 233 ) 234 }) 235 236 It("returns the error and warnings", func() { 237 Expect(warnings).To(ContainElement("create binding warning")) 238 Expect(executionError).To(MatchError("boop")) 239 }) 240 }) 241 }) 242 243 Describe("polling the job", func() { 244 It("polls the job", func() { 245 Expect(fakeCloudControllerClient.PollJobToEventStreamCallCount()).To(Equal(1)) 246 Expect(fakeCloudControllerClient.PollJobToEventStreamArgsForCall(0)).To(Equal(fakeJobURL)) 247 }) 248 }) 249 }) 250 251 Describe("DeleteServiceAppBinding", func() { 252 const ( 253 serviceInstanceName = "fake-service-instance-name" 254 serviceInstanceGUID = "fake-service-instance-guid" 255 appName = "fake-app-name" 256 appGUID = "fake-app-guid" 257 spaceGUID = "fake-space-guid" 258 bindingGUID = "fake-binding-guid" 259 fakeJobURL = ccv3.JobURL("fake-job-url") 260 ) 261 262 var ( 263 params DeleteServiceAppBindingParams 264 warnings Warnings 265 executionError error 266 stream chan PollJobEvent 267 ) 268 269 BeforeEach(func() { 270 fakeCloudControllerClient.GetServiceInstanceByNameAndSpaceReturns( 271 resources.ServiceInstance{ 272 Name: serviceInstanceName, 273 GUID: serviceInstanceGUID, 274 }, 275 ccv3.IncludedResources{}, 276 ccv3.Warnings{"get instance warning"}, 277 nil, 278 ) 279 280 fakeCloudControllerClient.GetApplicationByNameAndSpaceReturns( 281 resources.Application{ 282 GUID: appGUID, 283 Name: appName, 284 }, 285 ccv3.Warnings{"get app warning"}, 286 nil, 287 ) 288 289 fakeCloudControllerClient.GetServiceCredentialBindingsReturns( 290 []resources.ServiceCredentialBinding{ 291 {GUID: bindingGUID}, 292 }, 293 ccv3.Warnings{"get bindings warning"}, 294 nil, 295 ) 296 297 fakeCloudControllerClient.DeleteServiceCredentialBindingReturns( 298 fakeJobURL, 299 ccv3.Warnings{"delete binding warning"}, 300 nil, 301 ) 302 303 fakeStream := make(chan ccv3.PollJobEvent) 304 fakeCloudControllerClient.PollJobToEventStreamReturns(fakeStream) 305 go func() { 306 fakeStream <- ccv3.PollJobEvent{ 307 State: constant.JobPolling, 308 Warnings: ccv3.Warnings{"poll warning"}, 309 } 310 }() 311 312 params = DeleteServiceAppBindingParams{ 313 SpaceGUID: spaceGUID, 314 ServiceInstanceName: serviceInstanceName, 315 AppName: appName, 316 } 317 }) 318 319 JustBeforeEach(func() { 320 stream, warnings, executionError = actor.DeleteServiceAppBinding(params) 321 }) 322 323 It("returns an event stream, warnings, and no errors", func() { 324 Expect(executionError).NotTo(HaveOccurred()) 325 326 Expect(warnings).To(ConsistOf(Warnings{ 327 "get instance warning", 328 "get app warning", 329 "get bindings warning", 330 "delete binding warning", 331 })) 332 333 Eventually(stream).Should(Receive(Equal(PollJobEvent{ 334 State: JobPolling, 335 Warnings: Warnings{"poll warning"}, 336 Err: nil, 337 }))) 338 }) 339 340 Describe("service instance lookup", func() { 341 It("makes the correct call", func() { 342 Expect(fakeCloudControllerClient.GetServiceInstanceByNameAndSpaceCallCount()).To(Equal(1)) 343 actualServiceInstanceName, actualSpaceGUID, actualQuery := fakeCloudControllerClient.GetServiceInstanceByNameAndSpaceArgsForCall(0) 344 Expect(actualServiceInstanceName).To(Equal(serviceInstanceName)) 345 Expect(actualSpaceGUID).To(Equal(spaceGUID)) 346 Expect(actualQuery).To(BeEmpty()) 347 }) 348 349 When("not found", func() { 350 BeforeEach(func() { 351 fakeCloudControllerClient.GetServiceInstanceByNameAndSpaceReturns( 352 resources.ServiceInstance{}, 353 ccv3.IncludedResources{}, 354 ccv3.Warnings{"get instance warning"}, 355 ccerror.ServiceInstanceNotFoundError{Name: serviceInstanceName}, 356 ) 357 }) 358 359 It("returns the error and warning", func() { 360 Expect(warnings).To(ContainElement("get instance warning")) 361 Expect(executionError).To(MatchError(actionerror.ServiceInstanceNotFoundError{Name: serviceInstanceName})) 362 }) 363 }) 364 365 When("fails", func() { 366 BeforeEach(func() { 367 fakeCloudControllerClient.GetServiceInstanceByNameAndSpaceReturns( 368 resources.ServiceInstance{}, 369 ccv3.IncludedResources{}, 370 ccv3.Warnings{"get instance warning"}, 371 errors.New("boof"), 372 ) 373 }) 374 375 It("returns the error and warning", func() { 376 Expect(warnings).To(ContainElement("get instance warning")) 377 Expect(executionError).To(MatchError("boof")) 378 }) 379 }) 380 }) 381 382 Describe("app lookup", func() { 383 It("makes the correct call", func() { 384 Expect(fakeCloudControllerClient.GetApplicationByNameAndSpaceCallCount()).To(Equal(1)) 385 actualAppName, actualSpaceGUID := fakeCloudControllerClient.GetApplicationByNameAndSpaceArgsForCall(0) 386 Expect(actualAppName).To(Equal(appName)) 387 Expect(actualSpaceGUID).To(Equal(spaceGUID)) 388 }) 389 390 When("not found", func() { 391 BeforeEach(func() { 392 fakeCloudControllerClient.GetApplicationByNameAndSpaceReturns( 393 resources.Application{}, 394 ccv3.Warnings{"get app warning"}, 395 ccerror.ApplicationNotFoundError{Name: appName}, 396 ) 397 }) 398 399 It("returns the error and warning", func() { 400 Expect(warnings).To(ContainElement("get app warning")) 401 Expect(executionError).To(MatchError(actionerror.ApplicationNotFoundError{Name: appName})) 402 }) 403 }) 404 405 When("fails", func() { 406 BeforeEach(func() { 407 fakeCloudControllerClient.GetApplicationByNameAndSpaceReturns( 408 resources.Application{}, 409 ccv3.Warnings{"get app warning"}, 410 errors.New("boom"), 411 ) 412 }) 413 414 It("returns the error and warning", func() { 415 Expect(warnings).To(ContainElement("get app warning")) 416 Expect(executionError).To(MatchError("boom")) 417 }) 418 }) 419 }) 420 421 Describe("binding lookup", func() { 422 It("makes the correct call", func() { 423 Expect(fakeCloudControllerClient.GetServiceCredentialBindingsCallCount()).To(Equal(1)) 424 Expect(fakeCloudControllerClient.GetServiceCredentialBindingsArgsForCall(0)).To(ConsistOf( 425 ccv3.Query{Key: ccv3.TypeFilter, Values: []string{"app"}}, 426 ccv3.Query{Key: ccv3.AppGUIDFilter, Values: []string{appGUID}}, 427 ccv3.Query{Key: ccv3.ServiceInstanceGUIDFilter, Values: []string{serviceInstanceGUID}}, 428 )) 429 }) 430 431 When("not found", func() { 432 BeforeEach(func() { 433 fakeCloudControllerClient.GetServiceCredentialBindingsReturns( 434 []resources.ServiceCredentialBinding{}, 435 ccv3.Warnings{"get bindings warning"}, 436 nil, 437 ) 438 }) 439 440 It("returns the error and warning", func() { 441 Expect(warnings).To(ContainElement("get bindings warning")) 442 Expect(executionError).To(MatchError(actionerror.ServiceBindingNotFoundError{ 443 AppGUID: appGUID, 444 ServiceInstanceGUID: serviceInstanceGUID, 445 })) 446 }) 447 }) 448 449 When("fails", func() { 450 BeforeEach(func() { 451 fakeCloudControllerClient.GetServiceCredentialBindingsReturns( 452 []resources.ServiceCredentialBinding{}, 453 ccv3.Warnings{"get binding warning"}, 454 errors.New("boom"), 455 ) 456 }) 457 458 It("returns the error and warning", func() { 459 Expect(warnings).To(ContainElement("get binding warning")) 460 Expect(executionError).To(MatchError("boom")) 461 }) 462 }) 463 }) 464 465 Describe("initiating the delete", func() { 466 It("makes the correct call", func() { 467 Expect(fakeCloudControllerClient.DeleteServiceCredentialBindingCallCount()).To(Equal(1)) 468 Expect(fakeCloudControllerClient.DeleteServiceCredentialBindingArgsForCall(0)).To(Equal(bindingGUID)) 469 }) 470 471 When("fails", func() { 472 BeforeEach(func() { 473 fakeCloudControllerClient.DeleteServiceCredentialBindingReturns( 474 "", 475 ccv3.Warnings{"delete binding warning"}, 476 errors.New("boop"), 477 ) 478 }) 479 480 It("returns the error and warnings", func() { 481 Expect(warnings).To(ContainElement("delete binding warning")) 482 Expect(executionError).To(MatchError("boop")) 483 }) 484 }) 485 }) 486 487 Describe("polling the job", func() { 488 It("polls the job", func() { 489 Expect(fakeCloudControllerClient.PollJobToEventStreamCallCount()).To(Equal(1)) 490 Expect(fakeCloudControllerClient.PollJobToEventStreamArgsForCall(0)).To(Equal(fakeJobURL)) 491 }) 492 }) 493 }) 494 })