github.com/mook-as/cf-cli@v7.0.0-beta.28.0.20200120190804-b91c115fae48+incompatible/cf/actors/services_plans_test.go (about) 1 package actors_test 2 3 import ( 4 "code.cloudfoundry.org/cli/cf/errors" 5 6 "code.cloudfoundry.org/cli/cf/actors" 7 "code.cloudfoundry.org/cli/cf/actors/planbuilder/planbuilderfakes" 8 "code.cloudfoundry.org/cli/cf/actors/servicebuilder/servicebuilderfakes" 9 "code.cloudfoundry.org/cli/cf/api/apifakes" 10 "code.cloudfoundry.org/cli/cf/api/organizations/organizationsfakes" 11 "code.cloudfoundry.org/cli/cf/models" 12 13 . "github.com/onsi/ginkgo" 14 . "github.com/onsi/gomega" 15 ) 16 17 var _ = Describe("Service Plans", func() { 18 var ( 19 actor actors.ServicePlanActor 20 21 servicePlanRepo *apifakes.OldFakeServicePlanRepo 22 servicePlanVisibilityRepo *apifakes.FakeServicePlanVisibilityRepository 23 orgRepo *organizationsfakes.FakeOrganizationRepository 24 25 planBuilder *planbuilderfakes.FakePlanBuilder 26 serviceBuilder *servicebuilderfakes.FakeServiceBuilder 27 28 privateServicePlanVisibilityFields models.ServicePlanVisibilityFields 29 publicServicePlanVisibilityFields models.ServicePlanVisibilityFields 30 limitedServicePlanVisibilityFields models.ServicePlanVisibilityFields 31 32 publicServicePlan models.ServicePlanFields 33 privateServicePlan models.ServicePlanFields 34 limitedServicePlan models.ServicePlanFields 35 36 publicService models.ServiceOffering 37 mixedService models.ServiceOffering 38 privateService models.ServiceOffering 39 publicAndLimitedService models.ServiceOffering 40 41 org1 models.Organization 42 org2 models.Organization 43 44 visibility1 models.ServicePlanVisibilityFields 45 ) 46 47 BeforeEach(func() { 48 servicePlanRepo = new(apifakes.OldFakeServicePlanRepo) 49 servicePlanVisibilityRepo = new(apifakes.FakeServicePlanVisibilityRepository) 50 orgRepo = new(organizationsfakes.FakeOrganizationRepository) 51 planBuilder = new(planbuilderfakes.FakePlanBuilder) 52 serviceBuilder = new(servicebuilderfakes.FakeServiceBuilder) 53 54 actor = actors.NewServicePlanHandler(servicePlanRepo, servicePlanVisibilityRepo, orgRepo, planBuilder, serviceBuilder) 55 56 org1 = models.Organization{} 57 org1.Name = "org-1" 58 org1.GUID = "org-1-guid" 59 60 org2 = models.Organization{} 61 org2.Name = "org-2" 62 org2.GUID = "org-2-guid" 63 64 orgRepo.FindByNameReturns(org1, nil) 65 66 publicServicePlanVisibilityFields = models.ServicePlanVisibilityFields{ 67 GUID: "public-service-plan-visibility-guid", 68 ServicePlanGUID: "public-service-plan-guid", 69 } 70 71 privateServicePlanVisibilityFields = models.ServicePlanVisibilityFields{ 72 GUID: "private-service-plan-visibility-guid", 73 ServicePlanGUID: "private-service-plan-guid", 74 } 75 76 limitedServicePlanVisibilityFields = models.ServicePlanVisibilityFields{ 77 GUID: "limited-service-plan-visibility-guid", 78 ServicePlanGUID: "limited-service-plan-guid", 79 OrganizationGUID: "org-1-guid", 80 } 81 82 publicServicePlan = models.ServicePlanFields{ 83 Name: "public-service-plan", 84 GUID: "public-service-plan-guid", 85 Public: true, 86 } 87 88 privateServicePlan = models.ServicePlanFields{ 89 Name: "private-service-plan", 90 GUID: "private-service-plan-guid", 91 Public: false, 92 } 93 94 limitedServicePlan = models.ServicePlanFields{ 95 Name: "limited-service-plan", 96 GUID: "limited-service-plan-guid", 97 Public: false, 98 } 99 100 publicService = models.ServiceOffering{ 101 ServiceOfferingFields: models.ServiceOfferingFields{ 102 Label: "my-public-service", 103 GUID: "my-public-service-guid", 104 }, 105 Plans: []models.ServicePlanFields{ 106 publicServicePlan, 107 publicServicePlan, 108 }, 109 } 110 111 mixedService = models.ServiceOffering{ 112 ServiceOfferingFields: models.ServiceOfferingFields{ 113 Label: "my-mixed-service", 114 GUID: "my-mixed-service-guid", 115 }, 116 Plans: []models.ServicePlanFields{ 117 publicServicePlan, 118 privateServicePlan, 119 limitedServicePlan, 120 }, 121 } 122 123 privateService = models.ServiceOffering{ 124 ServiceOfferingFields: models.ServiceOfferingFields{ 125 Label: "my-private-service", 126 GUID: "my-private-service-guid", 127 }, 128 Plans: []models.ServicePlanFields{ 129 privateServicePlan, 130 privateServicePlan, 131 }, 132 } 133 publicAndLimitedService = models.ServiceOffering{ 134 ServiceOfferingFields: models.ServiceOfferingFields{ 135 Label: "my-public-and-limited-service", 136 GUID: "my-public-and-limited-service-guid", 137 }, 138 Plans: []models.ServicePlanFields{ 139 publicServicePlan, 140 publicServicePlan, 141 limitedServicePlan, 142 }, 143 } 144 145 visibility1 = models.ServicePlanVisibilityFields{ 146 GUID: "visibility-guid-1", 147 OrganizationGUID: "org-1-guid", 148 ServicePlanGUID: "limited-service-plan-guid", 149 } 150 }) 151 152 Describe(".UpdateAllPlansForService", func() { 153 BeforeEach(func() { 154 servicePlanVisibilityRepo.SearchReturns( 155 []models.ServicePlanVisibilityFields{privateServicePlanVisibilityFields}, nil, 156 ) 157 158 servicePlanRepo.SearchReturns = map[string][]models.ServicePlanFields{ 159 "my-mixed-service-guid": { 160 publicServicePlan, 161 privateServicePlan, 162 }, 163 } 164 }) 165 166 It("Returns an error if the service cannot be found", func() { 167 serviceBuilder.GetServiceByNameWithPlansReturns(models.ServiceOffering{}, errors.New("service was not found")) 168 err := actor.UpdateAllPlansForService("not-a-service", true) 169 Expect(err.Error()).To(Equal("service was not found")) 170 }) 171 172 It("Removes the service plan visibilities for any non-public service plans", func() { 173 serviceBuilder.GetServiceByNameWithPlansReturns(mixedService, nil) 174 err := actor.UpdateAllPlansForService("my-mixed-service", true) 175 Expect(err).ToNot(HaveOccurred()) 176 177 servicePlanVisibilityGUID := servicePlanVisibilityRepo.DeleteArgsForCall(0) 178 Expect(servicePlanVisibilityGUID).To(Equal("private-service-plan-visibility-guid")) 179 }) 180 181 Context("when setting all plans to public", func() { 182 It("Sets all non-public service plans to public", func() { 183 serviceBuilder.GetServiceByNameWithPlansReturns(mixedService, nil) 184 err := actor.UpdateAllPlansForService("my-mixed-service", true) 185 Expect(err).ToNot(HaveOccurred()) 186 187 servicePlan, serviceGUID, public := servicePlanRepo.UpdateArgsForCall(0) 188 Expect(servicePlan.Public).To(BeFalse()) 189 Expect(serviceGUID).To(Equal("my-mixed-service-guid")) 190 Expect(public).To(BeTrue()) 191 }) 192 193 It("Does not try to update service plans if they are all already public", func() { 194 servicePlanRepo.SearchReturns = map[string][]models.ServicePlanFields{ 195 "my-public-service-guid": { 196 publicServicePlan, 197 publicServicePlan, 198 }, 199 } 200 201 err := actor.UpdateAllPlansForService("my-public-service", true) 202 Expect(err).ToNot(HaveOccurred()) 203 204 Expect(servicePlanRepo.UpdateCallCount()).To(Equal(0)) 205 }) 206 }) 207 208 Context("when setting all plans to private", func() { 209 It("Sets all public service plans to private", func() { 210 serviceBuilder.GetServiceByNameWithPlansReturns(mixedService, nil) 211 212 err := actor.UpdateAllPlansForService("my-mixed-service", false) 213 Expect(err).ToNot(HaveOccurred()) 214 215 servicePlan, serviceGUID, public := servicePlanRepo.UpdateArgsForCall(0) 216 Expect(servicePlan.Public).To(BeTrue()) 217 Expect(serviceGUID).To(Equal("my-mixed-service-guid")) 218 Expect(public).To(BeFalse()) 219 }) 220 221 It("Does not try to update service plans if they are all already private", func() { 222 serviceBuilder.GetServiceByNameWithPlansReturns(privateService, nil) 223 224 err := actor.UpdateAllPlansForService("my-private-service", false) 225 Expect(err).ToNot(HaveOccurred()) 226 227 Expect(servicePlanRepo.UpdateCallCount()).To(Equal(0)) 228 }) 229 }) 230 }) 231 232 Describe(".UpdateOrgForService", func() { 233 BeforeEach(func() { 234 serviceBuilder.GetServiceByNameWithPlansReturns(mixedService, nil) 235 236 orgRepo.FindByNameReturns(org1, nil) 237 }) 238 239 It("Returns an error if the service cannot be found", func() { 240 serviceBuilder.GetServiceByNameWithPlansReturns(models.ServiceOffering{}, errors.New("service was not found")) 241 242 err := actor.UpdateOrgForService("not-a-service", "org-1", true) 243 Expect(err.Error()).To(Equal("service was not found")) 244 }) 245 246 Context("when giving access to all plans for a single org", func() { 247 It("creates a service plan visibility for all plans", func() { 248 err := actor.UpdateOrgForService("my-mixed-service", "org-1", true) 249 Expect(err).ToNot(HaveOccurred()) 250 251 Expect(servicePlanVisibilityRepo.CreateCallCount()).To(Equal(2)) 252 253 planGUID, orgGUID := servicePlanVisibilityRepo.CreateArgsForCall(0) 254 Expect(planGUID).To(Equal("private-service-plan-guid")) 255 Expect(orgGUID).To(Equal("org-1-guid")) 256 257 planGUID, orgGUID = servicePlanVisibilityRepo.CreateArgsForCall(1) 258 Expect(planGUID).To(Equal("limited-service-plan-guid")) 259 Expect(orgGUID).To(Equal("org-1-guid")) 260 }) 261 262 It("Does not try to update service plans if they are all already public or the org already has access", func() { 263 serviceBuilder.GetServiceByNameWithPlansReturns(publicAndLimitedService, nil) 264 265 err := actor.UpdateOrgForService("my-public-and-limited-service", "org-1", true) 266 Expect(err).ToNot(HaveOccurred()) 267 Expect(servicePlanVisibilityRepo.CreateCallCount()).To(Equal(1)) 268 }) 269 }) 270 271 Context("when disabling access to all plans for a single org", func() { 272 It("deletes the associated visibilities for all limited plans", func() { 273 serviceBuilder.GetServiceByNameWithPlansReturns(publicAndLimitedService, nil) 274 servicePlanVisibilityRepo.SearchReturns([]models.ServicePlanVisibilityFields{visibility1}, nil) 275 err := actor.UpdateOrgForService("my-public-and-limited-service", "org-1", false) 276 Expect(err).ToNot(HaveOccurred()) 277 Expect(servicePlanVisibilityRepo.DeleteCallCount()).To(Equal(1)) 278 279 services := servicePlanVisibilityRepo.SearchArgsForCall(0) 280 Expect(services["organization_guid"]).To(Equal("org-1-guid")) 281 282 visibilityGUID := servicePlanVisibilityRepo.DeleteArgsForCall(0) 283 Expect(visibilityGUID).To(Equal("visibility-guid-1")) 284 }) 285 286 It("Does not try to update service plans if they are all public", func() { 287 serviceBuilder.GetServiceByNameWithPlansReturns(publicService, nil) 288 289 err := actor.UpdateOrgForService("my-public-and-limited-service", "org-1", false) 290 Expect(err).ToNot(HaveOccurred()) 291 Expect(servicePlanVisibilityRepo.DeleteCallCount()).To(Equal(0)) 292 }) 293 294 It("Does not try to update service plans if the org already did not have visibility", func() { 295 serviceBuilder.GetServiceByNameWithPlansReturns(privateService, nil) 296 297 err := actor.UpdateOrgForService("my-private-service", "org-1", false) 298 Expect(err).ToNot(HaveOccurred()) 299 Expect(servicePlanVisibilityRepo.DeleteCallCount()).To(Equal(0)) 300 }) 301 }) 302 }) 303 304 Describe(".UpdateSinglePlanForService", func() { 305 It("Returns an error if the service cannot be found", func() { 306 serviceBuilder.GetServiceByNameWithPlansReturns(models.ServiceOffering{}, errors.New("service was not found")) 307 err := actor.UpdateSinglePlanForService("not-a-service", "public-service-plan", true) 308 Expect(err.Error()).To(Equal("service was not found")) 309 }) 310 311 It("Returns an error if the plan cannot be found", func() { 312 serviceBuilder.GetServiceByNameWithPlansReturns(mixedService, nil) 313 err := actor.UpdateSinglePlanForService("my-mixed-service", "not-a-service-plan", true) 314 Expect(err.Error()).To(Equal("The plan not-a-service-plan could not be found for service my-mixed-service")) 315 }) 316 317 Context("when setting a public service plan to public", func() { 318 It("Does not try to update the service plan", func() { 319 serviceBuilder.GetServiceByNameWithPlansReturns(mixedService, nil) 320 err := actor.UpdateSinglePlanForService("my-mixed-service", "public-service-plan", true) 321 Expect(err).ToNot(HaveOccurred()) 322 Expect(servicePlanRepo.UpdateCallCount()).To(Equal(0)) 323 }) 324 }) 325 326 Context("when setting private service plan to public", func() { 327 BeforeEach(func() { 328 servicePlanVisibilityRepo.SearchReturns( 329 []models.ServicePlanVisibilityFields{privateServicePlanVisibilityFields}, nil) 330 }) 331 332 It("removes the service plan visibilities for the service plan", func() { 333 serviceBuilder.GetServiceByNameWithPlansReturns(mixedService, nil) 334 err := actor.UpdateSinglePlanForService("my-mixed-service", "private-service-plan", true) 335 Expect(err).ToNot(HaveOccurred()) 336 337 servicePlanVisibilityGUID := servicePlanVisibilityRepo.DeleteArgsForCall(0) 338 Expect(servicePlanVisibilityGUID).To(Equal("private-service-plan-visibility-guid")) 339 }) 340 341 It("sets a service plan to public", func() { 342 serviceBuilder.GetServiceByNameWithPlansReturns(mixedService, nil) 343 err := actor.UpdateSinglePlanForService("my-mixed-service", "private-service-plan", true) 344 Expect(err).ToNot(HaveOccurred()) 345 346 servicePlan, serviceGUID, public := servicePlanRepo.UpdateArgsForCall(0) 347 Expect(servicePlan.Public).To(BeFalse()) 348 Expect(serviceGUID).To(Equal("my-mixed-service-guid")) 349 Expect(public).To(BeTrue()) 350 }) 351 }) 352 353 Context("when setting a private service plan to private", func() { 354 It("Does not try to update the service plan", func() { 355 serviceBuilder.GetServiceByNameWithPlansReturns(mixedService, nil) 356 err := actor.UpdateSinglePlanForService("my-mixed-service", "private-service-plan", false) 357 Expect(err).ToNot(HaveOccurred()) 358 Expect(servicePlanRepo.UpdateCallCount()).To(Equal(0)) 359 }) 360 }) 361 362 Context("When setting public service plan to private", func() { 363 BeforeEach(func() { 364 servicePlanVisibilityRepo.SearchReturns( 365 []models.ServicePlanVisibilityFields{publicServicePlanVisibilityFields}, nil) 366 }) 367 368 It("removes the service plan visibilities for the service plan", func() { 369 serviceBuilder.GetServiceByNameWithPlansReturns(mixedService, nil) 370 err := actor.UpdateSinglePlanForService("my-mixed-service", "public-service-plan", false) 371 Expect(err).ToNot(HaveOccurred()) 372 373 servicePlanVisibilityGUID := servicePlanVisibilityRepo.DeleteArgsForCall(0) 374 Expect(servicePlanVisibilityGUID).To(Equal("public-service-plan-visibility-guid")) 375 }) 376 377 It("sets the plan to private", func() { 378 serviceBuilder.GetServiceByNameWithPlansReturns(mixedService, nil) 379 err := actor.UpdateSinglePlanForService("my-mixed-service", "public-service-plan", false) 380 Expect(err).ToNot(HaveOccurred()) 381 382 servicePlan, serviceGUID, public := servicePlanRepo.UpdateArgsForCall(0) 383 Expect(servicePlan.Public).To(BeTrue()) 384 Expect(serviceGUID).To(Equal("my-mixed-service-guid")) 385 Expect(public).To(BeFalse()) 386 }) 387 }) 388 }) 389 390 Describe(".UpdatePlanAndOrgForService", func() { 391 BeforeEach(func() { 392 orgRepo.FindByNameReturns(org1, nil) 393 }) 394 395 It("returns an error if the service cannot be found", func() { 396 serviceBuilder.GetServiceByNameWithPlansReturns(models.ServiceOffering{}, errors.New("service was not found")) 397 398 err := actor.UpdatePlanAndOrgForService("not-a-service", "public-service-plan", "public-org", true) 399 Expect(err.Error()).To(Equal("service was not found")) 400 }) 401 402 It("returns an error if the org cannot be found", func() { 403 orgRepo.FindByNameReturns(models.Organization{}, errors.NewModelNotFoundError("organization", "not-an-org")) 404 err := actor.UpdatePlanAndOrgForService("a-real-service", "public-service-plan", "not-an-org", true) 405 Expect(err).To(HaveOccurred()) 406 }) 407 408 It("returns an error if the plan cannot be found", func() { 409 serviceBuilder.GetServiceByNameWithPlansReturns(mixedService, nil) 410 411 err := actor.UpdatePlanAndOrgForService("a-real-service", "not-a-plan", "org-1", true) 412 Expect(err).To(HaveOccurred()) 413 }) 414 415 Context("when disabling access to a single plan for a single org", func() { 416 Context("for a public plan", func() { 417 It("does not try and delete the visibility", func() { 418 serviceBuilder.GetServiceByNameWithPlansReturns(mixedService, nil) 419 err := actor.UpdatePlanAndOrgForService("my-mixed-service", "public-service-plan", "org-1", false) 420 Expect(err).NotTo(HaveOccurred()) 421 422 Expect(servicePlanVisibilityRepo.DeleteCallCount()).To(Equal(0)) 423 }) 424 }) 425 426 Context("for a private plan", func() { 427 Context("with no service plan visibilities", func() { 428 It("does not try and delete the visibility", func() { 429 serviceBuilder.GetServiceByNameWithPlansReturns(mixedService, nil) 430 err := actor.UpdatePlanAndOrgForService("my-mixed-service", "private-service-plan", "org-1", false) 431 432 Expect(servicePlanVisibilityRepo.DeleteCallCount()).To(Equal(0)) 433 Expect(err).NotTo(HaveOccurred()) 434 }) 435 }) 436 437 Context("with service plan visibilities", func() { 438 BeforeEach(func() { 439 servicePlanVisibilityRepo.SearchReturns( 440 []models.ServicePlanVisibilityFields{limitedServicePlanVisibilityFields}, nil) 441 442 }) 443 It("deletes a service plan visibility", func() { 444 serviceBuilder.GetServiceByNameWithPlansReturns(mixedService, nil) 445 err := actor.UpdatePlanAndOrgForService("my-mixed-service", "limited-service-plan", "org-1", false) 446 447 servicePlanVisGUID := servicePlanVisibilityRepo.DeleteArgsForCall(0) 448 Expect(err).NotTo(HaveOccurred()) 449 Expect(servicePlanVisGUID).To(Equal("limited-service-plan-visibility-guid")) 450 }) 451 452 It("does not call delete on the non-existant service plan visibility", func() { 453 serviceBuilder.GetServiceByNameWithPlansReturns(mixedService, nil) 454 orgRepo.FindByNameReturns(org2, nil) 455 servicePlanVisibilityRepo.SearchReturns(nil, nil) 456 err := actor.UpdatePlanAndOrgForService("my-mixed-service", "limited-service-plan", "org-2", false) 457 Expect(err).NotTo(HaveOccurred()) 458 459 Expect(servicePlanVisibilityRepo.DeleteCallCount()).To(Equal(0)) 460 }) 461 }) 462 }) 463 }) 464 465 Context("when enabling access", func() { 466 Context("for a public plan", func() { 467 It("does not try and create the visibility", func() { 468 serviceBuilder.GetServiceByNameWithPlansReturns(mixedService, nil) 469 err := actor.UpdatePlanAndOrgForService("my-mixed-service", "public-service-plan", "org-1", true) 470 471 Expect(servicePlanVisibilityRepo.CreateCallCount()).To(Equal(0)) 472 Expect(err).NotTo(HaveOccurred()) 473 }) 474 }) 475 476 Context("for a private plan", func() { 477 It("returns None", func() { 478 serviceBuilder.GetServiceByNameWithPlansReturns(mixedService, nil) 479 err := actor.UpdatePlanAndOrgForService("my-mixed-service", "private-service-plan", "org-1", true) 480 481 Expect(err).NotTo(HaveOccurred()) 482 }) 483 484 It("creates a service plan visibility", func() { 485 serviceBuilder.GetServiceByNameWithPlansReturns(mixedService, nil) 486 err := actor.UpdatePlanAndOrgForService("my-mixed-service", "private-service-plan", "org-1", true) 487 488 servicePlanGUID, orgGUID := servicePlanVisibilityRepo.CreateArgsForCall(0) 489 Expect(err).NotTo(HaveOccurred()) 490 Expect(servicePlanGUID).To(Equal("private-service-plan-guid")) 491 Expect(orgGUID).To(Equal("org-1-guid")) 492 }) 493 }) 494 }) 495 }) 496 })