github.com/DaAlbrecht/cf-cli@v0.0.0-20231128151943-1fe19bb400b9/api/cloudcontroller/ccv3/service_instance_test.go (about) 1 package ccv3_test 2 3 import ( 4 "encoding/json" 5 "errors" 6 "fmt" 7 "net/http" 8 9 "code.cloudfoundry.org/cli/api/cloudcontroller/ccerror" 10 . "code.cloudfoundry.org/cli/api/cloudcontroller/ccv3" 11 "code.cloudfoundry.org/cli/api/cloudcontroller/ccv3/ccv3fakes" 12 "code.cloudfoundry.org/cli/api/cloudcontroller/ccv3/internal" 13 "code.cloudfoundry.org/cli/resources" 14 "code.cloudfoundry.org/cli/types" 15 "code.cloudfoundry.org/jsonry" 16 . "github.com/onsi/ginkgo" 17 . "github.com/onsi/gomega" 18 ) 19 20 var _ = Describe("Service Instance", func() { 21 var ( 22 requester *ccv3fakes.FakeRequester 23 client *Client 24 ) 25 26 BeforeEach(func() { 27 requester = new(ccv3fakes.FakeRequester) 28 client, _ = NewFakeRequesterTestClient(requester) 29 }) 30 31 Describe("GetServiceInstances", func() { 32 var ( 33 query Query 34 instances []resources.ServiceInstance 35 included IncludedResources 36 warnings Warnings 37 executeErr error 38 ) 39 40 JustBeforeEach(func() { 41 instances, included, warnings, executeErr = client.GetServiceInstances(query) 42 }) 43 44 When("service instances exist", func() { 45 BeforeEach(func() { 46 requester.MakeListRequestCalls(func(requestParams RequestParams) (IncludedResources, Warnings, error) { 47 for i := 1; i <= 3; i++ { 48 Expect(requestParams.AppendToList(resources.ServiceInstance{ 49 GUID: fmt.Sprintf("service-instance-%d-guid", i), 50 Name: fmt.Sprintf("service-instance-%d-name", i), 51 })).NotTo(HaveOccurred()) 52 } 53 return IncludedResources{ServiceOfferings: []resources.ServiceOffering{{GUID: "fake-service-offering"}}}, Warnings{"warning-1", "warning-2"}, nil 54 }) 55 56 query = Query{ 57 Key: NameFilter, 58 Values: []string{"some-service-instance-name"}, 59 } 60 }) 61 62 It("returns a list of service instances with warnings and included resources", func() { 63 Expect(executeErr).ToNot(HaveOccurred()) 64 65 Expect(instances).To(ConsistOf( 66 resources.ServiceInstance{ 67 GUID: "service-instance-1-guid", 68 Name: "service-instance-1-name", 69 }, 70 resources.ServiceInstance{ 71 GUID: "service-instance-2-guid", 72 Name: "service-instance-2-name", 73 }, 74 resources.ServiceInstance{ 75 GUID: "service-instance-3-guid", 76 Name: "service-instance-3-name", 77 }, 78 )) 79 Expect(warnings).To(ConsistOf("warning-1", "warning-2")) 80 Expect(included).To(Equal(IncludedResources{ServiceOfferings: []resources.ServiceOffering{{GUID: "fake-service-offering"}}})) 81 82 Expect(requester.MakeListRequestCallCount()).To(Equal(1)) 83 actualParams := requester.MakeListRequestArgsForCall(0) 84 Expect(actualParams.RequestName).To(Equal(internal.GetServiceInstancesRequest)) 85 Expect(actualParams.Query).To(ConsistOf(query)) 86 Expect(actualParams.ResponseBody).To(BeAssignableToTypeOf(resources.ServiceInstance{})) 87 }) 88 }) 89 90 When("the cloud controller returns errors and warnings", func() { 91 BeforeEach(func() { 92 errors := []ccerror.V3Error{ 93 { 94 Code: 42424, 95 Detail: "Some detailed error message", 96 Title: "CF-SomeErrorTitle", 97 }, 98 { 99 Code: 11111, 100 Detail: "Some other detailed error message", 101 Title: "CF-SomeOtherErrorTitle", 102 }, 103 } 104 105 requester.MakeListRequestReturns( 106 IncludedResources{}, 107 Warnings{"this is a warning"}, 108 ccerror.MultiError{ResponseCode: http.StatusTeapot, Errors: errors}, 109 ) 110 }) 111 112 It("returns the error and all warnings", func() { 113 Expect(executeErr).To(MatchError(ccerror.MultiError{ 114 ResponseCode: http.StatusTeapot, 115 Errors: []ccerror.V3Error{ 116 { 117 Code: 42424, 118 Detail: "Some detailed error message", 119 Title: "CF-SomeErrorTitle", 120 }, 121 { 122 Code: 11111, 123 Detail: "Some other detailed error message", 124 Title: "CF-SomeOtherErrorTitle", 125 }, 126 }, 127 })) 128 Expect(warnings).To(ConsistOf("this is a warning")) 129 }) 130 }) 131 }) 132 133 Describe("GetServiceInstanceByNameAndSpace", func() { 134 const ( 135 name = "fake-service-instance-name" 136 spaceGUID = "fake-space-guid" 137 ) 138 var ( 139 instance resources.ServiceInstance 140 included IncludedResources 141 warnings Warnings 142 executeErr error 143 query []Query 144 ) 145 146 BeforeEach(func() { 147 query = []Query{{Key: Include, Values: []string{"unicorns"}}} 148 }) 149 150 JustBeforeEach(func() { 151 instance, included, warnings, executeErr = client.GetServiceInstanceByNameAndSpace(name, spaceGUID, query...) 152 }) 153 154 It("makes the correct API request", func() { 155 Expect(requester.MakeListRequestCallCount()).To(Equal(1)) 156 actualParams := requester.MakeListRequestArgsForCall(0) 157 Expect(actualParams.RequestName).To(Equal(internal.GetServiceInstancesRequest)) 158 Expect(actualParams.Query).To(ConsistOf( 159 Query{ 160 Key: NameFilter, 161 Values: []string{name}, 162 }, 163 Query{ 164 Key: SpaceGUIDFilter, 165 Values: []string{spaceGUID}, 166 }, 167 Query{ 168 Key: Include, 169 Values: []string{"unicorns"}, 170 }, 171 )) 172 Expect(actualParams.ResponseBody).To(BeAssignableToTypeOf(resources.ServiceInstance{})) 173 }) 174 175 When("there are no matches", func() { 176 BeforeEach(func() { 177 requester.MakeListRequestReturns( 178 IncludedResources{}, 179 Warnings{"this is a warning"}, 180 nil, 181 ) 182 }) 183 184 It("returns an error and warnings", func() { 185 Expect(instance).To(Equal(resources.ServiceInstance{})) 186 Expect(warnings).To(ConsistOf("this is a warning")) 187 Expect(executeErr).To(MatchError(ccerror.ServiceInstanceNotFoundError{ 188 Name: name, 189 SpaceGUID: spaceGUID, 190 })) 191 }) 192 }) 193 194 When("there is a single match", func() { 195 BeforeEach(func() { 196 requester.MakeListRequestCalls(func(requestParams RequestParams) (IncludedResources, Warnings, error) { 197 Expect(requestParams.AppendToList(resources.ServiceInstance{ 198 Name: name, 199 GUID: "service-instance-guid", 200 })).NotTo(HaveOccurred()) 201 202 return IncludedResources{ServiceOfferings: []resources.ServiceOffering{{GUID: "fake-offering-guid"}}}, 203 Warnings{"warning-1", "warning-2"}, 204 nil 205 }) 206 }) 207 208 It("returns the resource, included resources, and warnings", func() { 209 Expect(instance).To(Equal(resources.ServiceInstance{ 210 Name: name, 211 GUID: "service-instance-guid", 212 })) 213 Expect(included).To(Equal(IncludedResources{ServiceOfferings: []resources.ServiceOffering{{GUID: "fake-offering-guid"}}})) 214 Expect(warnings).To(ConsistOf("warning-1", "warning-2")) 215 Expect(executeErr).NotTo(HaveOccurred()) 216 }) 217 }) 218 219 When("there are multiple matches", func() { 220 BeforeEach(func() { 221 requester.MakeListRequestCalls(func(requestParams RequestParams) (IncludedResources, Warnings, error) { 222 for i := 1; i <= 3; i++ { 223 Expect(requestParams.AppendToList(resources.ServiceInstance{ 224 GUID: fmt.Sprintf("service-instance-%d-guid", i), 225 Name: fmt.Sprintf("service-instance-%d-name", i), 226 })).NotTo(HaveOccurred()) 227 } 228 return IncludedResources{}, Warnings{"warning-1", "warning-2"}, nil 229 }) 230 }) 231 232 It("returns the first resource and warnings", func() { 233 Expect(instance).To(Equal(resources.ServiceInstance{ 234 Name: "service-instance-1-name", 235 GUID: "service-instance-1-guid", 236 })) 237 Expect(warnings).To(ConsistOf("warning-1", "warning-2")) 238 Expect(executeErr).NotTo(HaveOccurred()) 239 }) 240 }) 241 242 When("the cloud controller returns errors and warnings", func() { 243 BeforeEach(func() { 244 errors := []ccerror.V3Error{ 245 { 246 Code: 42424, 247 Detail: "Some detailed error message", 248 Title: "CF-SomeErrorTitle", 249 }, 250 { 251 Code: 11111, 252 Detail: "Some other detailed error message", 253 Title: "CF-SomeOtherErrorTitle", 254 }, 255 } 256 257 requester.MakeListRequestCalls(func(requestParams RequestParams) (IncludedResources, Warnings, error) { 258 Expect(requestParams.AppendToList(resources.ServiceInstance{ 259 GUID: "service-instance-guid", 260 Name: "service-instance-name", 261 })).NotTo(HaveOccurred()) 262 263 return IncludedResources{}, 264 Warnings{"warning-1", "warning-2"}, 265 ccerror.MultiError{ResponseCode: http.StatusTeapot, Errors: errors} 266 }) 267 }) 268 269 It("returns the error and all warnings", func() { 270 Expect(executeErr).To(MatchError(ccerror.MultiError{ 271 ResponseCode: http.StatusTeapot, 272 Errors: []ccerror.V3Error{ 273 { 274 Code: 42424, 275 Detail: "Some detailed error message", 276 Title: "CF-SomeErrorTitle", 277 }, 278 { 279 Code: 11111, 280 Detail: "Some other detailed error message", 281 Title: "CF-SomeOtherErrorTitle", 282 }, 283 }, 284 })) 285 Expect(warnings).To(ConsistOf("warning-1", "warning-2")) 286 }) 287 }) 288 }) 289 290 Describe("GetServiceInstanceParameters", func() { 291 const guid = "fake-service-instance-guid" 292 293 BeforeEach(func() { 294 requester.MakeRequestCalls(func(params RequestParams) (JobURL, Warnings, error) { 295 json.Unmarshal([]byte(`{"foo":"bar"}`), params.ResponseBody) 296 return "", Warnings{"one", "two"}, nil 297 }) 298 }) 299 300 It("makes the correct API request", func() { 301 client.GetServiceInstanceParameters(guid) 302 303 Expect(requester.MakeRequestCallCount()).To(Equal(1)) 304 actualRequest := requester.MakeRequestArgsForCall(0) 305 Expect(actualRequest.RequestName).To(Equal(internal.GetServiceInstanceParametersRequest)) 306 Expect(actualRequest.URIParams).To(Equal(internal.Params{"service_instance_guid": guid})) 307 }) 308 309 It("returns the parameters", func() { 310 params, warnings, err := client.GetServiceInstanceParameters(guid) 311 Expect(err).NotTo(HaveOccurred()) 312 Expect(warnings).To(ConsistOf("one", "two")) 313 Expect(params).To(Equal(types.JSONObject{"foo": "bar"})) 314 }) 315 316 When("there is an error getting the parameters", func() { 317 BeforeEach(func() { 318 requester.MakeRequestReturns("", Warnings{"one", "two"}, errors.New("boom")) 319 }) 320 321 It("returns warnings and an error", func() { 322 params, warnings, err := client.GetServiceInstanceParameters(guid) 323 Expect(err).To(MatchError("boom")) 324 Expect(warnings).To(ConsistOf("one", "two")) 325 Expect(params).To(BeEmpty()) 326 }) 327 }) 328 }) 329 330 Describe("CreateServiceInstance", func() { 331 Context("synchronous response", func() { 332 When("the request succeeds", func() { 333 It("returns warnings and no errors", func() { 334 requester.MakeRequestReturns("", Warnings{"fake-warning"}, nil) 335 336 si := resources.ServiceInstance{ 337 Type: resources.UserProvidedServiceInstance, 338 Name: "fake-user-provided-service-instance", 339 SpaceGUID: "fake-space-guid", 340 Tags: types.NewOptionalStringSlice("foo", "bar"), 341 RouteServiceURL: types.NewOptionalString("https://fake-route.com"), 342 SyslogDrainURL: types.NewOptionalString("https://fake-sylogg.com"), 343 Credentials: types.NewOptionalObject(map[string]interface{}{ 344 "foo": "bar", 345 "baz": 42, 346 }), 347 } 348 349 jobURL, warnings, err := client.CreateServiceInstance(si) 350 351 Expect(jobURL).To(BeEmpty()) 352 Expect(warnings).To(ConsistOf("fake-warning")) 353 Expect(err).NotTo(HaveOccurred()) 354 355 Expect(requester.MakeRequestCallCount()).To(Equal(1)) 356 Expect(requester.MakeRequestArgsForCall(0)).To(Equal(RequestParams{ 357 RequestName: internal.PostServiceInstanceRequest, 358 RequestBody: si, 359 })) 360 }) 361 }) 362 363 When("the request fails", func() { 364 It("returns errors and warnings", func() { 365 requester.MakeRequestReturns("", Warnings{"fake-warning"}, errors.New("bang")) 366 367 si := resources.ServiceInstance{ 368 Type: resources.UserProvidedServiceInstance, 369 Name: "fake-user-provided-service-instance", 370 SpaceGUID: "fake-space-guid", 371 Tags: types.NewOptionalStringSlice("foo", "bar"), 372 RouteServiceURL: types.NewOptionalString("https://fake-route.com"), 373 SyslogDrainURL: types.NewOptionalString("https://fake-sylogg.com"), 374 Credentials: types.NewOptionalObject(map[string]interface{}{ 375 "foo": "bar", 376 "baz": 42, 377 }), 378 } 379 380 jobURL, warnings, err := client.CreateServiceInstance(si) 381 382 Expect(jobURL).To(BeEmpty()) 383 Expect(warnings).To(ConsistOf("fake-warning")) 384 Expect(err).To(MatchError("bang")) 385 }) 386 }) 387 }) 388 }) 389 390 Describe("UpdateServiceInstance", func() { 391 const ( 392 guid = "fake-service-instance-guid" 393 jobURL = JobURL("fake-job-url") 394 ) 395 396 var serviceInstance resources.ServiceInstance 397 398 Context("user provided", func() { 399 BeforeEach(func() { 400 serviceInstance = resources.ServiceInstance{ 401 Name: "fake-new-user-provided-service-instance", 402 Tags: types.NewOptionalStringSlice("foo", "bar"), 403 RouteServiceURL: types.NewOptionalString("https://fake-route.com"), 404 SyslogDrainURL: types.NewOptionalString("https://fake-sylogg.com"), 405 Credentials: types.NewOptionalObject(map[string]interface{}{ 406 "foo": "bar", 407 "baz": 42, 408 }), 409 MaintenanceInfoVersion: "9.1.2", 410 } 411 }) 412 413 When("the request succeeds", func() { 414 BeforeEach(func() { 415 requester.MakeRequestReturns(jobURL, Warnings{"fake-warning"}, nil) 416 }) 417 418 It("returns warnings and no errors", func() { 419 job, warnings, err := client.UpdateServiceInstance(guid, serviceInstance) 420 421 Expect(job).To(Equal(jobURL)) 422 Expect(warnings).To(ConsistOf("fake-warning")) 423 Expect(err).NotTo(HaveOccurred()) 424 425 Expect(requester.MakeRequestCallCount()).To(Equal(1)) 426 Expect(requester.MakeRequestArgsForCall(0)).To(Equal(RequestParams{ 427 RequestName: internal.PatchServiceInstanceRequest, 428 URIParams: internal.Params{"service_instance_guid": guid}, 429 RequestBody: serviceInstance, 430 })) 431 }) 432 }) 433 }) 434 435 Context("managed", func() { 436 BeforeEach(func() { 437 serviceInstance = resources.ServiceInstance{ 438 Name: "fake-new-user-provided-service-instance", 439 Tags: types.NewOptionalStringSlice("foo", "bar"), 440 ServicePlanGUID: guid, 441 Parameters: types.NewOptionalObject(map[string]interface{}{"some-param": "some-value"}), 442 } 443 }) 444 445 When("the request succeeds", func() { 446 BeforeEach(func() { 447 requester.MakeRequestReturns(jobURL, Warnings{"fake-warning"}, nil) 448 }) 449 450 It("returns warnings and no errors", func() { 451 job, warnings, err := client.UpdateServiceInstance(guid, serviceInstance) 452 453 Expect(job).To(Equal(jobURL)) 454 Expect(warnings).To(ConsistOf("fake-warning")) 455 Expect(err).NotTo(HaveOccurred()) 456 457 Expect(requester.MakeRequestCallCount()).To(Equal(1)) 458 Expect(requester.MakeRequestArgsForCall(0)).To(Equal(RequestParams{ 459 RequestName: internal.PatchServiceInstanceRequest, 460 URIParams: internal.Params{"service_instance_guid": guid}, 461 RequestBody: serviceInstance, 462 })) 463 }) 464 }) 465 }) 466 467 When("the request fails", func() { 468 BeforeEach(func() { 469 requester.MakeRequestReturns("", Warnings{"fake-warning"}, errors.New("bang")) 470 }) 471 472 It("returns errors and warnings", func() { 473 jobURL, warnings, err := client.UpdateServiceInstance(guid, serviceInstance) 474 475 Expect(jobURL).To(BeEmpty()) 476 Expect(warnings).To(ConsistOf("fake-warning")) 477 Expect(err).To(MatchError("bang")) 478 }) 479 }) 480 }) 481 482 Describe("DeleteServiceInstance", func() { 483 const ( 484 guid = "fake-service-instance-guid" 485 jobURL = JobURL("fake-job-url") 486 ) 487 488 It("makes the right request", func() { 489 client.DeleteServiceInstance(guid) 490 491 Expect(requester.MakeRequestCallCount()).To(Equal(1)) 492 Expect(requester.MakeRequestArgsForCall(0)).To(Equal(RequestParams{ 493 RequestName: internal.DeleteServiceInstanceRequest, 494 URIParams: internal.Params{"service_instance_guid": guid}, 495 })) 496 }) 497 498 When("there are query parameters", func() { 499 It("passes them through", func() { 500 client.DeleteServiceInstance(guid, Query{Key: NameFilter, Values: []string{"foo"}}) 501 502 Expect(requester.MakeRequestCallCount()).To(Equal(1)) 503 Expect(requester.MakeRequestArgsForCall(0).Query).To(ConsistOf(Query{Key: NameFilter, Values: []string{"foo"}})) 504 }) 505 }) 506 507 When("the request succeeds", func() { 508 BeforeEach(func() { 509 requester.MakeRequestReturns(jobURL, Warnings{"fake-warning"}, nil) 510 }) 511 512 It("returns warnings and no errors", func() { 513 job, warnings, err := client.DeleteServiceInstance(guid) 514 515 Expect(job).To(Equal(jobURL)) 516 Expect(warnings).To(ConsistOf("fake-warning")) 517 Expect(err).NotTo(HaveOccurred()) 518 }) 519 }) 520 521 When("the request fails", func() { 522 BeforeEach(func() { 523 requester.MakeRequestReturns("", Warnings{"fake-warning"}, errors.New("bang")) 524 }) 525 526 It("returns errors and warnings", func() { 527 jobURL, warnings, err := client.DeleteServiceInstance(guid) 528 529 Expect(jobURL).To(BeEmpty()) 530 Expect(warnings).To(ConsistOf("fake-warning")) 531 Expect(err).To(MatchError("bang")) 532 }) 533 }) 534 }) 535 536 Describe("shared service instances", func() { 537 Describe("ShareServiceInstanceToSpaces", func() { 538 var ( 539 serviceInstanceGUID string 540 spaceGUIDs []string 541 ) 542 543 BeforeEach(func() { 544 serviceInstanceGUID = "some-service-instance-guid" 545 spaceGUIDs = []string{"some-space-guid", "some-other-space-guid"} 546 }) 547 548 It("makes the right request", func() { 549 client.ShareServiceInstanceToSpaces(serviceInstanceGUID, spaceGUIDs) 550 551 Expect(requester.MakeRequestCallCount()).To(Equal(1)) 552 553 actualRequest := requester.MakeRequestArgsForCall(0) 554 Expect(actualRequest.RequestName).To(Equal(internal.PostServiceInstanceRelationshipsSharedSpacesRequest)) 555 Expect(actualRequest.URIParams).To(Equal(internal.Params{"service_instance_guid": serviceInstanceGUID})) 556 Expect(actualRequest.RequestBody).To(Equal(resources.RelationshipList{ 557 GUIDs: spaceGUIDs, 558 })) 559 }) 560 561 When("the request succeeds", func() { 562 BeforeEach(func() { 563 requester.MakeRequestCalls(func(params RequestParams) (JobURL, Warnings, error) { 564 json.Unmarshal([]byte(`{"data":[{"guid":"some-space-guid"}, {"guid":"some-other-space-guid"}]}`), params.ResponseBody) 565 return "", Warnings{"fake-warning"}, nil 566 }) 567 }) 568 569 It("returns warnings and no errors", func() { 570 relationships, warnings, err := client.ShareServiceInstanceToSpaces(serviceInstanceGUID, spaceGUIDs) 571 572 Expect(warnings).To(ConsistOf("fake-warning")) 573 Expect(err).NotTo(HaveOccurred()) 574 Expect(relationships).To(Equal(resources.RelationshipList{GUIDs: spaceGUIDs})) 575 }) 576 }) 577 578 When("the request fails", func() { 579 BeforeEach(func() { 580 requester.MakeRequestReturns("", Warnings{"fake-warning"}, errors.New("bang")) 581 }) 582 583 It("returns errors and warnings", func() { 584 _, warnings, err := client.ShareServiceInstanceToSpaces(serviceInstanceGUID, spaceGUIDs) 585 586 Expect(warnings).To(ConsistOf("fake-warning")) 587 Expect(err).To(MatchError("bang")) 588 }) 589 }) 590 }) 591 592 Describe("UnshareServiceInstanceFromSpace", func() { 593 var ( 594 serviceInstanceGUID string 595 spaceGUID string 596 ) 597 598 BeforeEach(func() { 599 serviceInstanceGUID = "some-service-instance-guid" 600 spaceGUID = "some-space-guid" 601 }) 602 603 It("makes the right request", func() { 604 client.UnshareServiceInstanceFromSpace(serviceInstanceGUID, spaceGUID) 605 606 Expect(requester.MakeRequestCallCount()).To(Equal(1)) 607 Expect(requester.MakeRequestArgsForCall(0)).To(Equal(RequestParams{ 608 RequestName: internal.DeleteServiceInstanceRelationshipsSharedSpaceRequest, 609 URIParams: internal.Params{ 610 "service_instance_guid": serviceInstanceGUID, 611 "space_guid": spaceGUID}, 612 })) 613 }) 614 615 When("the request succeeds", func() { 616 BeforeEach(func() { 617 requester.MakeRequestReturns("", Warnings{"fake-warning"}, nil) 618 }) 619 620 It("returns warnings and no errors", func() { 621 warnings, err := client.UnshareServiceInstanceFromSpace(serviceInstanceGUID, spaceGUID) 622 623 Expect(warnings).To(ConsistOf("fake-warning")) 624 Expect(err).NotTo(HaveOccurred()) 625 }) 626 }) 627 628 When("the request fails", func() { 629 BeforeEach(func() { 630 requester.MakeRequestReturns("", Warnings{"fake-warning"}, errors.New("bang")) 631 }) 632 633 It("returns errors and warnings", func() { 634 warnings, err := client.UnshareServiceInstanceFromSpace(serviceInstanceGUID, spaceGUID) 635 636 Expect(warnings).To(ConsistOf("fake-warning")) 637 Expect(err).To(MatchError("bang")) 638 }) 639 }) 640 }) 641 642 Describe("GetServiceInstanceSharedSpaces", func() { 643 var ( 644 serviceInstanceGUID string 645 ) 646 647 BeforeEach(func() { 648 serviceInstanceGUID = "some-service-instance-guid" 649 }) 650 651 It("makes the right request", func() { 652 client.GetServiceInstanceSharedSpaces(serviceInstanceGUID) 653 654 Expect(requester.MakeRequestCallCount()).To(Equal(1)) 655 656 actualRequest := requester.MakeRequestArgsForCall(0) 657 Expect(actualRequest.RequestName).To(Equal(internal.GetServiceInstanceRelationshipsSharedSpacesRequest)) 658 Expect(actualRequest.URIParams).To(Equal(internal.Params{"service_instance_guid": serviceInstanceGUID})) 659 Expect(actualRequest.Query).To(ConsistOf( 660 Query{ 661 Key: FieldsSpace, 662 Values: []string{"guid", "name", "relationships.organization"}, 663 }, 664 Query{ 665 Key: FieldsSpaceOrganization, 666 Values: []string{"guid", "name"}, 667 }, 668 )) 669 }) 670 671 When("the request succeeds", func() { 672 BeforeEach(func() { 673 requester.MakeRequestCalls(func(params RequestParams) (JobURL, Warnings, error) { 674 jsonry.Unmarshal([]byte(`{ 675 "data": [{"guid":"some-space-guid"},{"guid":"some-other-space-guid"}], 676 "links": { 677 "self": { 678 "href": "https://some-url/v3/service_instances/7915bc51-8203-4758-b0e2-f77bfcdc38cb/relationships/shared_spaces" 679 } 680 }, 681 "included": { 682 "spaces": [ 683 { 684 "name": "some-space-name", 685 "guid": "some-space-guid", 686 "relationships": { 687 "organization": { 688 "data": { 689 "guid": "some-org-guid" 690 } 691 } 692 } 693 }, 694 { 695 "name": "some-other-space-name", 696 "guid": "some-other-space-guid", 697 "relationships": { 698 "organization": { 699 "data": { 700 "guid": "some-org-guid" 701 } 702 } 703 } 704 } 705 ], 706 "organizations": [ 707 { 708 "name": "some-org-name", 709 "guid": "some-org-guid" 710 } 711 ] 712 } 713 }`), params.ResponseBody) 714 return "", Warnings{"fake-warning"}, nil 715 }) 716 }) 717 718 It("returns warnings and no errors", func() { 719 spaces, warnings, err := client.GetServiceInstanceSharedSpaces(serviceInstanceGUID) 720 721 Expect(warnings).To(ConsistOf("fake-warning")) 722 Expect(err).NotTo(HaveOccurred()) 723 Expect(spaces).To(Equal([]SpaceWithOrganization{ 724 { 725 SpaceGUID: "some-space-guid", 726 SpaceName: "some-space-name", 727 OrganizationName: "some-org-name", 728 }, 729 { 730 SpaceGUID: "some-other-space-guid", 731 SpaceName: "some-other-space-name", 732 OrganizationName: "some-org-name", 733 }, 734 })) 735 }) 736 }) 737 738 When("the request fails", func() { 739 BeforeEach(func() { 740 requester.MakeRequestReturns("", Warnings{"fake-warning"}, errors.New("bang")) 741 }) 742 743 It("returns errors and warnings", func() { 744 _, warnings, err := client.GetServiceInstanceSharedSpaces(serviceInstanceGUID) 745 746 Expect(warnings).To(ConsistOf("fake-warning")) 747 Expect(err).To(MatchError("bang")) 748 }) 749 }) 750 }) 751 752 Describe("GetServiceInstanceUsageSummary", func() { 753 var ( 754 serviceInstanceGUID string 755 spaceGUIDs []string 756 ) 757 758 BeforeEach(func() { 759 serviceInstanceGUID = "some-service-instance-guid" 760 spaceGUIDs = []string{"some-space-guid", "some-other-space-guid"} 761 }) 762 763 It("makes the right request", func() { 764 client.GetServiceInstanceUsageSummary(serviceInstanceGUID) 765 766 Expect(requester.MakeRequestCallCount()).To(Equal(1)) 767 768 actualRequest := requester.MakeRequestArgsForCall(0) 769 Expect(actualRequest.RequestName).To(Equal(internal.GetServiceInstanceSharedSpacesUsageSummaryRequest)) 770 Expect(actualRequest.URIParams).To(Equal(internal.Params{"service_instance_guid": serviceInstanceGUID})) 771 }) 772 773 When("the request succeeds", func() { 774 BeforeEach(func() { 775 requester.MakeRequestCalls(func(params RequestParams) (JobURL, Warnings, error) { 776 jsonry.Unmarshal([]byte(`{ 777 "usage_summary": [ 778 { 779 "space": { 780 "guid": "some-space-guid" 781 }, 782 "bound_app_count": 2 783 }, 784 { 785 "space": { 786 "guid": "some-other-space-guid" 787 }, 788 "bound_app_count": 1 789 } 790 ], 791 "links": { 792 "self": { 793 "href": "https://api.example.org/v3/service_instances/some_instance_guid/relationships/shared_spaces/usage_summary" 794 }, 795 "shared_spaces": { 796 "href": "https://api.example.org/v3/service_instances/some_instance_guid/relationships/shared_spaces" 797 }, 798 "service_instance": { 799 "href": "https://api.example.org/v3/service_instances/some_instance_guid" 800 } 801 } 802 }`), params.ResponseBody) 803 return "", Warnings{"fake-warning"}, nil 804 }) 805 }) 806 807 It("returns warnings and no errors", func() { 808 usageSummary, warnings, err := client.GetServiceInstanceUsageSummary(serviceInstanceGUID) 809 810 Expect(warnings).To(ConsistOf("fake-warning")) 811 Expect(err).NotTo(HaveOccurred()) 812 Expect(usageSummary).To(Equal([]resources.ServiceInstanceUsageSummary{{SpaceGUID: spaceGUIDs[0], BoundAppCount: 2}, {SpaceGUID: spaceGUIDs[1], BoundAppCount: 1}})) 813 }) 814 }) 815 816 When("the request fails", func() { 817 BeforeEach(func() { 818 requester.MakeRequestReturns("", Warnings{"fake-warning"}, errors.New("bang")) 819 }) 820 821 It("returns errors and warnings", func() { 822 _, warnings, err := client.GetServiceInstanceUsageSummary(serviceInstanceGUID) 823 824 Expect(warnings).To(ConsistOf("fake-warning")) 825 Expect(err).To(MatchError("bang")) 826 }) 827 }) 828 }) 829 }) 830 })