github.com/loggregator/cli@v6.33.1-0.20180224010324-82334f081791+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 BeforeEach(func() { 24 response := ` 25 { 26 "metadata": { 27 "guid": "some-service-binding-guid" 28 } 29 }` 30 requestBody := map[string]interface{}{ 31 "service_instance_guid": "some-service-instance-guid", 32 "app_guid": "some-app-guid", 33 "parameters": map[string]interface{}{ 34 "the-service-broker": "wants this object", 35 }, 36 } 37 server.AppendHandlers( 38 CombineHandlers( 39 VerifyRequest(http.MethodPost, "/v2/service_bindings"), 40 VerifyJSONRepresenting(requestBody), 41 RespondWith(http.StatusCreated, response, http.Header{"X-Cf-Warnings": {"this is a warning"}}), 42 ), 43 ) 44 }) 45 46 It("returns the created object and warnings", func() { 47 parameters := map[string]interface{}{ 48 "the-service-broker": "wants this object", 49 } 50 serviceBinding, warnings, err := client.CreateServiceBinding("some-app-guid", "some-service-instance-guid", parameters) 51 Expect(err).NotTo(HaveOccurred()) 52 53 Expect(serviceBinding).To(Equal(ServiceBinding{GUID: "some-service-binding-guid"})) 54 Expect(warnings).To(ConsistOf(Warnings{"this is a warning"})) 55 }) 56 }) 57 58 Context("when the create returns an error", func() { 59 BeforeEach(func() { 60 response := ` 61 { 62 "description": "The app space binding to service is taken: some-app-guid some-service-instance-guid", 63 "error_code": "CF-ServiceBindingAppServiceTaken", 64 "code": 90003 65 } 66 ` 67 server.AppendHandlers( 68 CombineHandlers( 69 VerifyRequest(http.MethodPost, "/v2/service_bindings"), 70 RespondWith(http.StatusBadRequest, response, http.Header{"X-Cf-Warnings": {"this is a warning"}}), 71 ), 72 ) 73 }) 74 75 It("returns the error and warnings", func() { 76 parameters := map[string]interface{}{ 77 "the-service-broker": "wants this object", 78 } 79 _, warnings, err := client.CreateServiceBinding("some-app-guid", "some-service-instance-guid", parameters) 80 Expect(err).To(MatchError(ccerror.ServiceBindingTakenError{Message: "The app space binding to service is taken: some-app-guid some-service-instance-guid"})) 81 Expect(warnings).To(ConsistOf(Warnings{"this is a warning"})) 82 }) 83 }) 84 }) 85 86 Describe("GetServiceBindings", func() { 87 BeforeEach(func() { 88 response1 := `{ 89 "next_url": "/v2/service_bindings?q=app_guid:some-app-guid&page=2", 90 "resources": [ 91 { 92 "metadata": { 93 "guid": "service-binding-guid-1" 94 }, 95 "entity": { 96 "app_guid":"app-guid-1", 97 "service_instance_guid": "service-instance-guid-1" 98 } 99 }, 100 { 101 "metadata": { 102 "guid": "service-binding-guid-2" 103 }, 104 "entity": { 105 "app_guid":"app-guid-2", 106 "service_instance_guid": "service-instance-guid-2" 107 } 108 } 109 ] 110 }` 111 response2 := `{ 112 "next_url": null, 113 "resources": [ 114 { 115 "metadata": { 116 "guid": "service-binding-guid-3" 117 }, 118 "entity": { 119 "app_guid":"app-guid-3", 120 "service_instance_guid": "service-instance-guid-3" 121 } 122 }, 123 { 124 "metadata": { 125 "guid": "service-binding-guid-4" 126 }, 127 "entity": { 128 "app_guid":"app-guid-4", 129 "service_instance_guid": "service-instance-guid-4" 130 } 131 } 132 ] 133 }` 134 server.AppendHandlers( 135 CombineHandlers( 136 VerifyRequest(http.MethodGet, "/v2/service_bindings", "q=app_guid:some-app-guid"), 137 RespondWith(http.StatusOK, response1, http.Header{"X-Cf-Warnings": {"this is a warning"}}), 138 ), 139 ) 140 server.AppendHandlers( 141 CombineHandlers( 142 VerifyRequest(http.MethodGet, "/v2/service_bindings", "q=app_guid:some-app-guid&page=2"), 143 RespondWith(http.StatusOK, response2, http.Header{"X-Cf-Warnings": {"this is another warning"}}), 144 ), 145 ) 146 }) 147 148 Context("when service bindings exist", func() { 149 It("returns all the queried service bindings", func() { 150 serviceBindings, warnings, err := client.GetServiceBindings(Filter{ 151 Type: constant.AppGUIDFilter, 152 Operator: constant.EqualOperator, 153 Values: []string{"some-app-guid"}, 154 }) 155 Expect(err).NotTo(HaveOccurred()) 156 Expect(serviceBindings).To(ConsistOf([]ServiceBinding{ 157 {GUID: "service-binding-guid-1", AppGUID: "app-guid-1", ServiceInstanceGUID: "service-instance-guid-1"}, 158 {GUID: "service-binding-guid-2", AppGUID: "app-guid-2", ServiceInstanceGUID: "service-instance-guid-2"}, 159 {GUID: "service-binding-guid-3", AppGUID: "app-guid-3", ServiceInstanceGUID: "service-instance-guid-3"}, 160 {GUID: "service-binding-guid-4", AppGUID: "app-guid-4", ServiceInstanceGUID: "service-instance-guid-4"}, 161 })) 162 Expect(warnings).To(ConsistOf(Warnings{"this is a warning", "this is another warning"})) 163 }) 164 }) 165 }) 166 167 Describe("DeleteServiceBinding", func() { 168 Context("when the service binding exist", func() { 169 BeforeEach(func() { 170 server.AppendHandlers( 171 CombineHandlers( 172 VerifyRequest(http.MethodDelete, "/v2/service_bindings/some-service-binding-guid"), 173 RespondWith(http.StatusNoContent, "{}", http.Header{"X-Cf-Warnings": {"this is a warning"}}), 174 ), 175 ) 176 }) 177 178 It("deletes the service binding", func() { 179 warnings, err := client.DeleteServiceBinding("some-service-binding-guid") 180 Expect(err).NotTo(HaveOccurred()) 181 Expect(warnings).To(ConsistOf(Warnings{"this is a warning"})) 182 }) 183 }) 184 }) 185 186 Context("when the service binding does not exist", func() { 187 BeforeEach(func() { 188 response := `{ 189 "code": 90004, 190 "description": "The service binding could not be found: some-service-binding-guid", 191 "error_code": "CF-ServiceBindingNotFound" 192 }` 193 server.AppendHandlers( 194 CombineHandlers( 195 VerifyRequest(http.MethodDelete, "/v2/service_bindings/some-service-binding-guid"), 196 RespondWith(http.StatusNotFound, response, http.Header{"X-Cf-Warnings": {"this is a warning"}}), 197 ), 198 ) 199 }) 200 201 It("returns a not found error", func() { 202 warnings, err := client.DeleteServiceBinding("some-service-binding-guid") 203 Expect(err).To(MatchError(ccerror.ResourceNotFoundError{ 204 Message: "The service binding could not be found: some-service-binding-guid", 205 })) 206 Expect(warnings).To(ConsistOf(Warnings{"this is a warning"})) 207 }) 208 }) 209 210 Describe("GetServiceInstanceServiceBindings", func() { 211 Context("when there are service bindings", func() { 212 BeforeEach(func() { 213 response1 := `{ 214 "next_url": "/v2/service_instances/some-service-instance-guid/service_bindings?page=2", 215 "resources": [ 216 { 217 "metadata": { 218 "guid": "service-binding-guid-1" 219 }, 220 "entity": { 221 "app_guid":"app-guid-1", 222 "service_instance_guid": "service-instance-guid-1" 223 } 224 }, 225 { 226 "metadata": { 227 "guid": "service-binding-guid-2" 228 }, 229 "entity": { 230 "app_guid":"app-guid-2", 231 "service_instance_guid": "service-instance-guid-2" 232 } 233 } 234 ] 235 }` 236 response2 := `{ 237 "next_url": null, 238 "resources": [ 239 { 240 "metadata": { 241 "guid": "service-binding-guid-3" 242 }, 243 "entity": { 244 "app_guid":"app-guid-3", 245 "service_instance_guid": "service-instance-guid-3" 246 } 247 }, 248 { 249 "metadata": { 250 "guid": "service-binding-guid-4" 251 }, 252 "entity": { 253 "app_guid":"app-guid-4", 254 "service_instance_guid": "service-instance-guid-4" 255 } 256 } 257 ] 258 }` 259 server.AppendHandlers( 260 CombineHandlers( 261 VerifyRequest(http.MethodGet, "/v2/service_instances/some-service-instance-guid/service_bindings"), 262 RespondWith(http.StatusOK, response1, http.Header{"X-Cf-Warnings": {"this is a warning"}}), 263 ), 264 ) 265 server.AppendHandlers( 266 CombineHandlers( 267 VerifyRequest(http.MethodGet, "/v2/service_instances/some-service-instance-guid/service_bindings", "page=2"), 268 RespondWith(http.StatusOK, response2, http.Header{"X-Cf-Warnings": {"this is another warning"}}), 269 ), 270 ) 271 }) 272 273 It("returns all the service bindings and all warnings", func() { 274 serviceBindings, warnings, err := client.GetServiceInstanceServiceBindings("some-service-instance-guid") 275 Expect(err).NotTo(HaveOccurred()) 276 Expect(serviceBindings).To(Equal([]ServiceBinding{ 277 {GUID: "service-binding-guid-1", AppGUID: "app-guid-1", ServiceInstanceGUID: "service-instance-guid-1"}, 278 {GUID: "service-binding-guid-2", AppGUID: "app-guid-2", ServiceInstanceGUID: "service-instance-guid-2"}, 279 {GUID: "service-binding-guid-3", AppGUID: "app-guid-3", ServiceInstanceGUID: "service-instance-guid-3"}, 280 {GUID: "service-binding-guid-4", AppGUID: "app-guid-4", ServiceInstanceGUID: "service-instance-guid-4"}, 281 })) 282 Expect(warnings).To(ConsistOf(Warnings{"this is a warning", "this is another warning"})) 283 }) 284 }) 285 286 Context("when there are no service bindings", func() { 287 BeforeEach(func() { 288 response1 := `{ 289 "next_url": null, 290 "resources": [] 291 }` 292 server.AppendHandlers( 293 CombineHandlers( 294 VerifyRequest(http.MethodGet, "/v2/service_instances/some-service-instance-guid/service_bindings"), 295 RespondWith(http.StatusOK, response1, http.Header{"X-Cf-Warnings": {"this is a warning"}}), 296 ), 297 ) 298 }) 299 It("returns an empty list of service bindings and all warnings", func() { 300 serviceBindings, warnings, err := client.GetServiceInstanceServiceBindings("some-service-instance-guid") 301 Expect(err).NotTo(HaveOccurred()) 302 Expect(serviceBindings).To(HaveLen(0)) 303 Expect(warnings).To(ConsistOf(Warnings{"this is a warning"})) 304 }) 305 }) 306 307 Context("when an error is encountered", func() { 308 BeforeEach(func() { 309 response := `{ 310 "description": "Unknown request", 311 "error_code": "CF-NotFound", 312 "code": 10000 313 }` 314 server.AppendHandlers( 315 CombineHandlers( 316 VerifyRequest(http.MethodGet, "/v2/service_instances/some-service-instance-guid/service_bindings"), 317 RespondWith(http.StatusTeapot, response, http.Header{"X-Cf-Warnings": {"this is a warning"}}), 318 ), 319 ) 320 }) 321 322 It("returns an error and all warnings", func() { 323 _, warnings, err := client.GetServiceInstanceServiceBindings("some-service-instance-guid") 324 Expect(err).To(MatchError(ccerror.V2UnexpectedResponseError{ 325 V2ErrorResponse: ccerror.V2ErrorResponse{ 326 Code: 10000, 327 Description: "Unknown request", 328 ErrorCode: "CF-NotFound", 329 }, 330 RequestIDs: nil, 331 ResponseCode: 418, 332 })) 333 Expect(warnings).To(ConsistOf(Warnings{"this is a warning"})) 334 }) 335 }) 336 }) 337 338 Describe("GetUserProvidedServiceInstanceServiceBindings", func() { 339 Context("when there are service bindings", func() { 340 BeforeEach(func() { 341 response1 := `{ 342 "next_url": "/v2/user_provided_service_instances/some-user-provided-service-instance-guid/service_bindings?page=2", 343 "resources": [ 344 { 345 "metadata": { 346 "guid": "service-binding-guid-1" 347 }, 348 "entity": { 349 "app_guid":"app-guid-1", 350 "service_instance_guid": "user-provided-service-instance-guid-1" 351 } 352 }, 353 { 354 "metadata": { 355 "guid": "service-binding-guid-2" 356 }, 357 "entity": { 358 "app_guid":"app-guid-2", 359 "service_instance_guid": "user-provided-service-instance-guid-2" 360 } 361 } 362 ] 363 }` 364 response2 := `{ 365 "next_url": null, 366 "resources": [ 367 { 368 "metadata": { 369 "guid": "service-binding-guid-3" 370 }, 371 "entity": { 372 "app_guid":"app-guid-3", 373 "service_instance_guid": "user-provided-service-instance-guid-3" 374 } 375 }, 376 { 377 "metadata": { 378 "guid": "service-binding-guid-4" 379 }, 380 "entity": { 381 "app_guid":"app-guid-4", 382 "service_instance_guid": "user-provided-service-instance-guid-4" 383 } 384 } 385 ] 386 }` 387 server.AppendHandlers( 388 CombineHandlers( 389 VerifyRequest(http.MethodGet, "/v2/user_provided_service_instances/some-user-provided-service-instance-guid/service_bindings"), 390 RespondWith(http.StatusOK, response1, http.Header{"X-Cf-Warnings": {"this is a warning"}}), 391 ), 392 ) 393 server.AppendHandlers( 394 CombineHandlers( 395 VerifyRequest(http.MethodGet, "/v2/user_provided_service_instances/some-user-provided-service-instance-guid/service_bindings", "page=2"), 396 RespondWith(http.StatusOK, response2, http.Header{"X-Cf-Warnings": {"this is another warning"}}), 397 ), 398 ) 399 }) 400 401 It("returns all the service bindings and all warnings", func() { 402 serviceBindings, warnings, err := client.GetUserProvidedServiceInstanceServiceBindings("some-user-provided-service-instance-guid") 403 Expect(err).NotTo(HaveOccurred()) 404 Expect(serviceBindings).To(Equal([]ServiceBinding{ 405 {GUID: "service-binding-guid-1", AppGUID: "app-guid-1", ServiceInstanceGUID: "user-provided-service-instance-guid-1"}, 406 {GUID: "service-binding-guid-2", AppGUID: "app-guid-2", ServiceInstanceGUID: "user-provided-service-instance-guid-2"}, 407 {GUID: "service-binding-guid-3", AppGUID: "app-guid-3", ServiceInstanceGUID: "user-provided-service-instance-guid-3"}, 408 {GUID: "service-binding-guid-4", AppGUID: "app-guid-4", ServiceInstanceGUID: "user-provided-service-instance-guid-4"}, 409 })) 410 Expect(warnings).To(ConsistOf(Warnings{"this is a warning", "this is another warning"})) 411 }) 412 }) 413 414 Context("when there are no service bindings", func() { 415 BeforeEach(func() { 416 response := `{ 417 "next_url": null, 418 "resources": [] 419 }` 420 server.AppendHandlers( 421 CombineHandlers( 422 VerifyRequest(http.MethodGet, "/v2/user_provided_service_instances/some-user-provided-service-instance-guid/service_bindings"), 423 RespondWith(http.StatusOK, response, http.Header{"X-Cf-Warnings": {"this is a warning"}}), 424 ), 425 ) 426 }) 427 428 It("returns an empty list of service bindings and all warnings", func() { 429 serviceBindings, warnings, err := client.GetUserProvidedServiceInstanceServiceBindings("some-user-provided-service-instance-guid") 430 Expect(err).NotTo(HaveOccurred()) 431 Expect(serviceBindings).To(HaveLen(0)) 432 Expect(warnings).To(ConsistOf(Warnings{"this is a warning"})) 433 }) 434 }) 435 436 Context("when an error is encountered", func() { 437 BeforeEach(func() { 438 response := `{ 439 "description": "Unknown request", 440 "error_code": "CF-NotFound", 441 "code": 10000 442 }` 443 server.AppendHandlers( 444 CombineHandlers( 445 VerifyRequest(http.MethodGet, "/v2/user_provided_service_instances/some-user-provided-service-instance-guid/service_bindings"), 446 RespondWith(http.StatusTeapot, response, http.Header{"X-Cf-Warnings": {"this is a warning"}}), 447 ), 448 ) 449 }) 450 451 It("returns an error and all warnings", func() { 452 _, warnings, err := client.GetUserProvidedServiceInstanceServiceBindings("some-user-provided-service-instance-guid") 453 Expect(err).To(MatchError(ccerror.V2UnexpectedResponseError{ 454 V2ErrorResponse: ccerror.V2ErrorResponse{ 455 Code: 10000, 456 Description: "Unknown request", 457 ErrorCode: "CF-NotFound", 458 }, 459 RequestIDs: nil, 460 ResponseCode: 418, 461 })) 462 Expect(warnings).To(ConsistOf(Warnings{"this is a warning"})) 463 }) 464 }) 465 }) 466 })