github.com/dcarley/cf-cli@v6.24.1-0.20170220111324-4225ff346898+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  })