github.com/nimakaviani/cli@v6.37.1-0.20180619223813-e734901a73fa+incompatible/api/cloudcontroller/ccv2/service_binding_test.go (about) 1 package ccv2_test 2 3 import ( 4 "net/http" 5 6 "code.cloudfoundry.org/cli/api/cloudcontroller/ccerror" 7 . "code.cloudfoundry.org/cli/api/cloudcontroller/ccv2" 8 "code.cloudfoundry.org/cli/api/cloudcontroller/ccv2/constant" 9 . "github.com/onsi/ginkgo" 10 . "github.com/onsi/gomega" 11 . "github.com/onsi/gomega/ghttp" 12 ) 13 14 var _ = Describe("Service Binding", func() { 15 var client *Client 16 17 BeforeEach(func() { 18 client = NewTestClient() 19 }) 20 21 Describe("CreateServiceBinding", func() { 22 Context("when the create is successful", func() { 23 Context("when a service binding name is provided", func() { 24 BeforeEach(func() { 25 expectedRequestBody := map[string]interface{}{ 26 "service_instance_guid": "some-service-instance-guid", 27 "app_guid": "some-app-guid", 28 "name": "some-binding-name", 29 "parameters": map[string]interface{}{ 30 "the-service-broker": "wants this object", 31 }, 32 } 33 response := ` 34 { 35 "metadata": { 36 "guid": "some-service-binding-guid" 37 } 38 }` 39 server.AppendHandlers( 40 CombineHandlers( 41 VerifyRequest(http.MethodPost, "/v2/service_bindings"), 42 VerifyJSONRepresenting(expectedRequestBody), 43 RespondWith(http.StatusCreated, response, http.Header{"X-Cf-Warnings": {"this is a warning"}}), 44 ), 45 ) 46 }) 47 48 It("returns the created object and warnings", func() { 49 parameters := map[string]interface{}{ 50 "the-service-broker": "wants this object", 51 } 52 serviceBinding, warnings, err := client.CreateServiceBinding("some-app-guid", "some-service-instance-guid", "some-binding-name", parameters) 53 Expect(err).NotTo(HaveOccurred()) 54 55 Expect(serviceBinding).To(Equal(ServiceBinding{GUID: "some-service-binding-guid"})) 56 Expect(warnings).To(ConsistOf(Warnings{"this is a warning"})) 57 }) 58 }) 59 60 Context("when a service binding name is not provided", func() { 61 BeforeEach(func() { 62 expectedRequestBody := map[string]interface{}{ 63 "service_instance_guid": "some-service-instance-guid", 64 "app_guid": "some-app-guid", 65 "parameters": map[string]interface{}{ 66 "the-service-broker": "wants this object", 67 }, 68 } 69 response := ` 70 { 71 "metadata": { 72 "guid": "some-service-binding-guid" 73 } 74 }` 75 server.AppendHandlers( 76 CombineHandlers( 77 VerifyRequest(http.MethodPost, "/v2/service_bindings"), 78 VerifyJSONRepresenting(expectedRequestBody), 79 RespondWith(http.StatusCreated, response, http.Header{"X-Cf-Warnings": {"this is a warning"}}), 80 ), 81 ) 82 }) 83 84 It("returns the created object and warnings", func() { 85 parameters := map[string]interface{}{ 86 "the-service-broker": "wants this object", 87 } 88 serviceBinding, warnings, err := client.CreateServiceBinding("some-app-guid", "some-service-instance-guid", "", parameters) 89 Expect(err).NotTo(HaveOccurred()) 90 91 Expect(serviceBinding).To(Equal(ServiceBinding{GUID: "some-service-binding-guid"})) 92 Expect(warnings).To(ConsistOf(Warnings{"this is a warning"})) 93 }) 94 }) 95 }) 96 97 Context("when the create returns an error", func() { 98 BeforeEach(func() { 99 response := ` 100 { 101 "description": "The app space binding to service is taken: some-app-guid some-service-instance-guid", 102 "error_code": "CF-ServiceBindingAppServiceTaken", 103 "code": 90003 104 } 105 ` 106 server.AppendHandlers( 107 CombineHandlers( 108 VerifyRequest(http.MethodPost, "/v2/service_bindings"), 109 RespondWith(http.StatusBadRequest, response, http.Header{"X-Cf-Warnings": {"this is a warning"}}), 110 ), 111 ) 112 }) 113 114 It("returns the error and warnings", func() { 115 parameters := map[string]interface{}{ 116 "the-service-broker": "wants this object", 117 } 118 _, warnings, err := client.CreateServiceBinding("some-app-guid", "some-service-instance-guid", "", parameters) 119 Expect(err).To(MatchError(ccerror.ServiceBindingTakenError{Message: "The app space binding to service is taken: some-app-guid some-service-instance-guid"})) 120 Expect(warnings).To(ConsistOf(Warnings{"this is a warning"})) 121 }) 122 }) 123 }) 124 125 Describe("DeleteServiceBinding", func() { 126 Context("when the service binding exist", func() { 127 BeforeEach(func() { 128 server.AppendHandlers(CombineHandlers(VerifyRequest(http.MethodDelete, "/v2/service_bindings/some-service-binding-guid"), RespondWith(http.StatusNoContent, "{}", http.Header{"X-Cf-Warnings": {"this is a warning"}}))) 129 }) 130 131 It("deletes the service binding", func() { 132 warnings, err := client.DeleteServiceBinding("some-service-binding-guid") 133 Expect(err).NotTo(HaveOccurred()) 134 Expect(warnings).To(ConsistOf(Warnings{"this is a warning"})) 135 }) 136 }) 137 138 Context("when the service binding does not exist", func() { 139 BeforeEach(func() { 140 response := `{ 141 "code": 90004, 142 "description": "The service binding could not be found: some-service-binding-guid", 143 "error_code": "CF-ServiceBindingNotFound" 144 }` 145 server.AppendHandlers( 146 CombineHandlers( 147 VerifyRequest(http.MethodDelete, "/v2/service_bindings/some-service-binding-guid"), 148 RespondWith(http.StatusNotFound, response, http.Header{"X-Cf-Warnings": {"this is a warning"}}), 149 ), 150 ) 151 }) 152 153 It("returns a not found error", func() { 154 warnings, err := client.DeleteServiceBinding("some-service-binding-guid") 155 Expect(err).To(MatchError(ccerror.ResourceNotFoundError{ 156 Message: "The service binding could not be found: some-service-binding-guid", 157 })) 158 Expect(warnings).To(ConsistOf(Warnings{"this is a warning"})) 159 }) 160 }) 161 }) 162 163 Describe("GetServiceBinding", func() { 164 var ( 165 serviceBinding ServiceBinding 166 warnings Warnings 167 executeErr error 168 ) 169 170 JustBeforeEach(func() { 171 serviceBinding, warnings, executeErr = client.GetServiceBinding("some-service-binding-guid") 172 }) 173 174 Context("when the cc returns an error", func() { 175 BeforeEach(func() { 176 response := `{ 177 "code": 1, 178 "description": "some error description", 179 "error_code": "CF-SomeError" 180 }` 181 server.AppendHandlers( 182 CombineHandlers( 183 VerifyRequest(http.MethodGet, "/v2/service_bindings/some-service-binding-guid"), 184 RespondWith(http.StatusTeapot, response, http.Header{"X-Cf-Warnings": {"warning-1, warning-2"}}), 185 ), 186 ) 187 }) 188 189 It("returns the error", func() { 190 Expect(executeErr).To(MatchError(ccerror.V2UnexpectedResponseError{ 191 V2ErrorResponse: ccerror.V2ErrorResponse{ 192 Code: 1, 193 Description: "some error description", 194 ErrorCode: "CF-SomeError", 195 }, 196 ResponseCode: http.StatusTeapot, 197 })) 198 199 Expect(warnings).To(ConsistOf("warning-1", "warning-2")) 200 }) 201 }) 202 203 Context("when there are no errors", func() { 204 BeforeEach(func() { 205 response := `{ 206 "metadata": { 207 "guid": "service-binding-guid-1" 208 }, 209 "entity": { 210 "app_guid":"app-guid-1", 211 "service_instance_guid": "service-instance-guid-1" 212 } 213 }` 214 server.AppendHandlers( 215 CombineHandlers( 216 VerifyRequest(http.MethodGet, "/v2/service_bindings/some-service-binding-guid"), 217 RespondWith(http.StatusOK, response, http.Header{"X-Cf-Warnings": {"warning-1, warning-2"}}), 218 ), 219 ) 220 }) 221 222 It("returns the service binding", func() { 223 Expect(executeErr).ToNot(HaveOccurred()) 224 Expect(warnings).To(ConsistOf("warning-1", "warning-2")) 225 226 Expect(serviceBinding).To(Equal(ServiceBinding{ 227 GUID: "service-binding-guid-1", 228 AppGUID: "app-guid-1", 229 ServiceInstanceGUID: "service-instance-guid-1", 230 })) 231 }) 232 }) 233 }) 234 235 Describe("GetServiceBindings", func() { 236 BeforeEach(func() { 237 response1 := `{ 238 "next_url": "/v2/service_bindings?q=app_guid:some-app-guid&page=2", 239 "resources": [ 240 { 241 "metadata": { 242 "guid": "service-binding-guid-1" 243 }, 244 "entity": { 245 "app_guid":"app-guid-1", 246 "service_instance_guid": "service-instance-guid-1" 247 } 248 }, 249 { 250 "metadata": { 251 "guid": "service-binding-guid-2" 252 }, 253 "entity": { 254 "app_guid":"app-guid-2", 255 "service_instance_guid": "service-instance-guid-2" 256 } 257 } 258 ] 259 }` 260 response2 := `{ 261 "next_url": null, 262 "resources": [ 263 { 264 "metadata": { 265 "guid": "service-binding-guid-3" 266 }, 267 "entity": { 268 "app_guid":"app-guid-3", 269 "service_instance_guid": "service-instance-guid-3" 270 } 271 }, 272 { 273 "metadata": { 274 "guid": "service-binding-guid-4" 275 }, 276 "entity": { 277 "app_guid":"app-guid-4", 278 "service_instance_guid": "service-instance-guid-4" 279 } 280 } 281 ] 282 }` 283 server.AppendHandlers( 284 CombineHandlers( 285 VerifyRequest(http.MethodGet, "/v2/service_bindings", "q=app_guid:some-app-guid"), 286 RespondWith(http.StatusOK, response1, http.Header{"X-Cf-Warnings": {"this is a warning"}}), 287 ), 288 ) 289 server.AppendHandlers( 290 CombineHandlers( 291 VerifyRequest(http.MethodGet, "/v2/service_bindings", "q=app_guid:some-app-guid&page=2"), 292 RespondWith(http.StatusOK, response2, http.Header{"X-Cf-Warnings": {"this is another warning"}}), 293 ), 294 ) 295 }) 296 297 Context("when service bindings exist", func() { 298 It("returns all the queried service bindings", func() { 299 serviceBindings, warnings, err := client.GetServiceBindings(Filter{ 300 Type: constant.AppGUIDFilter, 301 Operator: constant.EqualOperator, 302 Values: []string{"some-app-guid"}, 303 }) 304 Expect(err).NotTo(HaveOccurred()) 305 Expect(serviceBindings).To(ConsistOf([]ServiceBinding{ 306 {GUID: "service-binding-guid-1", AppGUID: "app-guid-1", ServiceInstanceGUID: "service-instance-guid-1"}, 307 {GUID: "service-binding-guid-2", AppGUID: "app-guid-2", ServiceInstanceGUID: "service-instance-guid-2"}, 308 {GUID: "service-binding-guid-3", AppGUID: "app-guid-3", ServiceInstanceGUID: "service-instance-guid-3"}, 309 {GUID: "service-binding-guid-4", AppGUID: "app-guid-4", ServiceInstanceGUID: "service-instance-guid-4"}, 310 })) 311 Expect(warnings).To(ConsistOf(Warnings{"this is a warning", "this is another warning"})) 312 }) 313 }) 314 }) 315 316 Describe("GetServiceInstanceServiceBindings", func() { 317 Context("when there are service bindings", func() { 318 BeforeEach(func() { 319 response1 := `{ 320 "next_url": "/v2/service_instances/some-service-instance-guid/service_bindings?page=2", 321 "resources": [ 322 { 323 "metadata": { 324 "guid": "service-binding-guid-1" 325 }, 326 "entity": { 327 "app_guid":"app-guid-1", 328 "service_instance_guid": "service-instance-guid-1" 329 } 330 }, 331 { 332 "metadata": { 333 "guid": "service-binding-guid-2" 334 }, 335 "entity": { 336 "app_guid":"app-guid-2", 337 "service_instance_guid": "service-instance-guid-2" 338 } 339 } 340 ] 341 }` 342 response2 := `{ 343 "next_url": null, 344 "resources": [ 345 { 346 "metadata": { 347 "guid": "service-binding-guid-3" 348 }, 349 "entity": { 350 "app_guid":"app-guid-3", 351 "service_instance_guid": "service-instance-guid-3" 352 } 353 }, 354 { 355 "metadata": { 356 "guid": "service-binding-guid-4" 357 }, 358 "entity": { 359 "app_guid":"app-guid-4", 360 "service_instance_guid": "service-instance-guid-4" 361 } 362 } 363 ] 364 }` 365 server.AppendHandlers( 366 CombineHandlers( 367 VerifyRequest(http.MethodGet, "/v2/service_instances/some-service-instance-guid/service_bindings"), 368 RespondWith(http.StatusOK, response1, http.Header{"X-Cf-Warnings": {"this is a warning"}}), 369 ), 370 ) 371 server.AppendHandlers( 372 CombineHandlers( 373 VerifyRequest(http.MethodGet, "/v2/service_instances/some-service-instance-guid/service_bindings", "page=2"), 374 RespondWith(http.StatusOK, response2, http.Header{"X-Cf-Warnings": {"this is another warning"}}), 375 ), 376 ) 377 }) 378 379 It("returns all the service bindings and all warnings", func() { 380 serviceBindings, warnings, err := client.GetServiceInstanceServiceBindings("some-service-instance-guid") 381 Expect(err).NotTo(HaveOccurred()) 382 Expect(serviceBindings).To(Equal([]ServiceBinding{ 383 {GUID: "service-binding-guid-1", AppGUID: "app-guid-1", ServiceInstanceGUID: "service-instance-guid-1"}, 384 {GUID: "service-binding-guid-2", AppGUID: "app-guid-2", ServiceInstanceGUID: "service-instance-guid-2"}, 385 {GUID: "service-binding-guid-3", AppGUID: "app-guid-3", ServiceInstanceGUID: "service-instance-guid-3"}, 386 {GUID: "service-binding-guid-4", AppGUID: "app-guid-4", ServiceInstanceGUID: "service-instance-guid-4"}, 387 })) 388 Expect(warnings).To(ConsistOf(Warnings{"this is a warning", "this is another warning"})) 389 }) 390 }) 391 392 Context("when there are no service bindings", func() { 393 BeforeEach(func() { 394 response1 := `{ 395 "next_url": null, 396 "resources": [] 397 }` 398 server.AppendHandlers( 399 CombineHandlers( 400 VerifyRequest(http.MethodGet, "/v2/service_instances/some-service-instance-guid/service_bindings"), 401 RespondWith(http.StatusOK, response1, http.Header{"X-Cf-Warnings": {"this is a warning"}}), 402 ), 403 ) 404 }) 405 It("returns an empty list of service bindings and all warnings", func() { 406 serviceBindings, warnings, err := client.GetServiceInstanceServiceBindings("some-service-instance-guid") 407 Expect(err).NotTo(HaveOccurred()) 408 Expect(serviceBindings).To(HaveLen(0)) 409 Expect(warnings).To(ConsistOf(Warnings{"this is a warning"})) 410 }) 411 }) 412 413 Context("when an error is encountered", func() { 414 BeforeEach(func() { 415 response := `{ 416 "description": "Unknown request", 417 "error_code": "CF-NotFound", 418 "code": 10000 419 }` 420 server.AppendHandlers( 421 CombineHandlers( 422 VerifyRequest(http.MethodGet, "/v2/service_instances/some-service-instance-guid/service_bindings"), 423 RespondWith(http.StatusTeapot, response, http.Header{"X-Cf-Warnings": {"this is a warning"}}), 424 ), 425 ) 426 }) 427 428 It("returns an error and all warnings", func() { 429 _, warnings, err := client.GetServiceInstanceServiceBindings("some-service-instance-guid") 430 Expect(err).To(MatchError(ccerror.V2UnexpectedResponseError{ 431 V2ErrorResponse: ccerror.V2ErrorResponse{ 432 Code: 10000, 433 Description: "Unknown request", 434 ErrorCode: "CF-NotFound", 435 }, 436 RequestIDs: nil, 437 ResponseCode: 418, 438 })) 439 Expect(warnings).To(ConsistOf(Warnings{"this is a warning"})) 440 }) 441 }) 442 }) 443 444 Describe("GetUserProvidedServiceInstanceServiceBindings", func() { 445 Context("when there are service bindings", func() { 446 BeforeEach(func() { 447 response1 := `{ 448 "next_url": "/v2/user_provided_service_instances/some-user-provided-service-instance-guid/service_bindings?page=2", 449 "resources": [ 450 { 451 "metadata": { 452 "guid": "service-binding-guid-1" 453 }, 454 "entity": { 455 "app_guid":"app-guid-1", 456 "service_instance_guid": "user-provided-service-instance-guid-1" 457 } 458 }, 459 { 460 "metadata": { 461 "guid": "service-binding-guid-2" 462 }, 463 "entity": { 464 "app_guid":"app-guid-2", 465 "service_instance_guid": "user-provided-service-instance-guid-2" 466 } 467 } 468 ] 469 }` 470 response2 := `{ 471 "next_url": null, 472 "resources": [ 473 { 474 "metadata": { 475 "guid": "service-binding-guid-3" 476 }, 477 "entity": { 478 "app_guid":"app-guid-3", 479 "service_instance_guid": "user-provided-service-instance-guid-3" 480 } 481 }, 482 { 483 "metadata": { 484 "guid": "service-binding-guid-4" 485 }, 486 "entity": { 487 "app_guid":"app-guid-4", 488 "service_instance_guid": "user-provided-service-instance-guid-4" 489 } 490 } 491 ] 492 }` 493 server.AppendHandlers( 494 CombineHandlers( 495 VerifyRequest(http.MethodGet, "/v2/user_provided_service_instances/some-user-provided-service-instance-guid/service_bindings"), 496 RespondWith(http.StatusOK, response1, http.Header{"X-Cf-Warnings": {"this is a warning"}}), 497 ), 498 ) 499 server.AppendHandlers( 500 CombineHandlers( 501 VerifyRequest(http.MethodGet, "/v2/user_provided_service_instances/some-user-provided-service-instance-guid/service_bindings", "page=2"), 502 RespondWith(http.StatusOK, response2, http.Header{"X-Cf-Warnings": {"this is another warning"}}), 503 ), 504 ) 505 }) 506 507 It("returns all the service bindings and all warnings", func() { 508 serviceBindings, warnings, err := client.GetUserProvidedServiceInstanceServiceBindings("some-user-provided-service-instance-guid") 509 Expect(err).NotTo(HaveOccurred()) 510 Expect(serviceBindings).To(Equal([]ServiceBinding{ 511 {GUID: "service-binding-guid-1", AppGUID: "app-guid-1", ServiceInstanceGUID: "user-provided-service-instance-guid-1"}, 512 {GUID: "service-binding-guid-2", AppGUID: "app-guid-2", ServiceInstanceGUID: "user-provided-service-instance-guid-2"}, 513 {GUID: "service-binding-guid-3", AppGUID: "app-guid-3", ServiceInstanceGUID: "user-provided-service-instance-guid-3"}, 514 {GUID: "service-binding-guid-4", AppGUID: "app-guid-4", ServiceInstanceGUID: "user-provided-service-instance-guid-4"}, 515 })) 516 Expect(warnings).To(ConsistOf(Warnings{"this is a warning", "this is another warning"})) 517 }) 518 }) 519 520 Context("when there are no service bindings", func() { 521 BeforeEach(func() { 522 response := `{ 523 "next_url": null, 524 "resources": [] 525 }` 526 server.AppendHandlers( 527 CombineHandlers( 528 VerifyRequest(http.MethodGet, "/v2/user_provided_service_instances/some-user-provided-service-instance-guid/service_bindings"), 529 RespondWith(http.StatusOK, response, http.Header{"X-Cf-Warnings": {"this is a warning"}}), 530 ), 531 ) 532 }) 533 534 It("returns an empty list of service bindings and all warnings", func() { 535 serviceBindings, warnings, err := client.GetUserProvidedServiceInstanceServiceBindings("some-user-provided-service-instance-guid") 536 Expect(err).NotTo(HaveOccurred()) 537 Expect(serviceBindings).To(HaveLen(0)) 538 Expect(warnings).To(ConsistOf(Warnings{"this is a warning"})) 539 }) 540 }) 541 542 Context("when an error is encountered", func() { 543 BeforeEach(func() { 544 response := `{ 545 "description": "Unknown request", 546 "error_code": "CF-NotFound", 547 "code": 10000 548 }` 549 server.AppendHandlers( 550 CombineHandlers( 551 VerifyRequest(http.MethodGet, "/v2/user_provided_service_instances/some-user-provided-service-instance-guid/service_bindings"), 552 RespondWith(http.StatusTeapot, response, http.Header{"X-Cf-Warnings": {"this is a warning"}}), 553 ), 554 ) 555 }) 556 557 It("returns an error and all warnings", func() { 558 _, warnings, err := client.GetUserProvidedServiceInstanceServiceBindings("some-user-provided-service-instance-guid") 559 Expect(err).To(MatchError(ccerror.V2UnexpectedResponseError{ 560 V2ErrorResponse: ccerror.V2ErrorResponse{ 561 Code: 10000, 562 Description: "Unknown request", 563 ErrorCode: "CF-NotFound", 564 }, 565 RequestIDs: nil, 566 ResponseCode: 418, 567 })) 568 Expect(warnings).To(ConsistOf(Warnings{"this is a warning"})) 569 }) 570 }) 571 }) 572 })