github.com/loggregator/cli@v6.33.1-0.20180224010324-82334f081791+incompatible/cf/commands/spacequota/create_space_quota_test.go (about)

     1  package spacequota_test
     2  
     3  import (
     4  	"encoding/json"
     5  
     6  	"code.cloudfoundry.org/cli/cf/commandregistry"
     7  	"code.cloudfoundry.org/cli/cf/errors"
     8  	"code.cloudfoundry.org/cli/cf/models"
     9  	"code.cloudfoundry.org/cli/cf/requirements"
    10  
    11  	"code.cloudfoundry.org/cli/cf/api/resources"
    12  	"code.cloudfoundry.org/cli/cf/api/spacequotas/spacequotasfakes"
    13  	"code.cloudfoundry.org/cli/cf/configuration/coreconfig/coreconfigfakes"
    14  	"code.cloudfoundry.org/cli/cf/requirements/requirementsfakes"
    15  	testterm "code.cloudfoundry.org/cli/util/testhelpers/terminal"
    16  
    17  	"code.cloudfoundry.org/cli/cf/api"
    18  	"code.cloudfoundry.org/cli/cf/commands/spacequota"
    19  	"code.cloudfoundry.org/cli/cf/flags"
    20  	. "code.cloudfoundry.org/cli/util/testhelpers/matchers"
    21  	"github.com/blang/semver"
    22  	. "github.com/onsi/ginkgo"
    23  	. "github.com/onsi/gomega"
    24  )
    25  
    26  var _ = Describe("create-space-quota", func() {
    27  	var (
    28  		ui        *testterm.FakeUI
    29  		quotaRepo *spacequotasfakes.FakeSpaceQuotaRepository
    30  		config    *coreconfigfakes.FakeRepository
    31  
    32  		loginReq         *requirementsfakes.FakeRequirement
    33  		targetedOrgReq   *requirementsfakes.FakeTargetedOrgRequirement
    34  		minApiVersionReq *requirementsfakes.FakeRequirement
    35  		reqFactory       *requirementsfakes.FakeFactory
    36  
    37  		deps        commandregistry.Dependency
    38  		cmd         spacequota.CreateSpaceQuota
    39  		flagContext flags.FlagContext
    40  	)
    41  
    42  	BeforeEach(func() {
    43  		ui = &testterm.FakeUI{}
    44  		quotaRepo = new(spacequotasfakes.FakeSpaceQuotaRepository)
    45  		config = new(coreconfigfakes.FakeRepository)
    46  
    47  		repoLocator := api.RepositoryLocator{}
    48  		repoLocator = repoLocator.SetSpaceQuotaRepository(quotaRepo)
    49  
    50  		deps = commandregistry.Dependency{
    51  			UI:          ui,
    52  			Config:      config,
    53  			RepoLocator: repoLocator,
    54  		}
    55  
    56  		reqFactory = new(requirementsfakes.FakeFactory)
    57  
    58  		loginReq = new(requirementsfakes.FakeRequirement)
    59  		loginReq.ExecuteReturns(nil)
    60  		reqFactory.NewLoginRequirementReturns(loginReq)
    61  
    62  		targetedOrgReq = new(requirementsfakes.FakeTargetedOrgRequirement)
    63  		targetedOrgReq.ExecuteReturns(nil)
    64  		reqFactory.NewTargetedOrgRequirementReturns(targetedOrgReq)
    65  
    66  		minApiVersionReq = new(requirementsfakes.FakeRequirement)
    67  		minApiVersionReq.ExecuteReturns(nil)
    68  		reqFactory.NewMinAPIVersionRequirementReturns(minApiVersionReq)
    69  
    70  		cmd = spacequota.CreateSpaceQuota{}
    71  		flagContext = flags.NewFlagContext(cmd.MetaData().Flags)
    72  	})
    73  
    74  	Describe("Requirements", func() {
    75  		BeforeEach(func() {
    76  			cmd.SetDependency(deps, false)
    77  		})
    78  		Context("when not exactly one arg is provided", func() {
    79  			It("fails", func() {
    80  				flagContext.Parse()
    81  				_, err := cmd.Requirements(reqFactory, flagContext)
    82  				Expect(err).To(HaveOccurred())
    83  				Expect(ui.Outputs()).To(ContainSubstrings(
    84  					[]string{"FAILED"},
    85  					[]string{"Incorrect Usage. Requires an argument"},
    86  				))
    87  			})
    88  		})
    89  
    90  		Context("when provided exactly one arg", func() {
    91  			var actualRequirements []requirements.Requirement
    92  			var err error
    93  
    94  			Context("when no flags are provided", func() {
    95  				BeforeEach(func() {
    96  					flagContext.Parse("myquota")
    97  					actualRequirements, err = cmd.Requirements(reqFactory, flagContext)
    98  					Expect(err).NotTo(HaveOccurred())
    99  				})
   100  
   101  				It("returns a login requirement", func() {
   102  					Expect(reqFactory.NewLoginRequirementCallCount()).To(Equal(1))
   103  					Expect(actualRequirements).To(ContainElement(loginReq))
   104  				})
   105  
   106  				It("returns a targeted org requirement", func() {
   107  					Expect(reqFactory.NewTargetedOrgRequirementCallCount()).To(Equal(1))
   108  					Expect(actualRequirements).To(ContainElement(targetedOrgReq))
   109  				})
   110  
   111  				It("does not return a min api requirement", func() {
   112  					Expect(reqFactory.NewMinAPIVersionRequirementCallCount()).To(Equal(0))
   113  				})
   114  			})
   115  
   116  			Context("when the -a flag is provided", func() {
   117  				BeforeEach(func() {
   118  					flagContext.Parse("myquota", "-a", "2")
   119  					actualRequirements, err = cmd.Requirements(reqFactory, flagContext)
   120  					Expect(err).NotTo(HaveOccurred())
   121  				})
   122  
   123  				It("returns a min api version requirement", func() {
   124  					Expect(reqFactory.NewMinAPIVersionRequirementCallCount()).To(Equal(1))
   125  					commandName, requiredVersion := reqFactory.NewMinAPIVersionRequirementArgsForCall(0)
   126  					Expect(commandName).To(Equal("Option '-a'"))
   127  					expectVersion, _ := semver.Make("2.40.0")
   128  					Expect(requiredVersion).To(Equal(expectVersion))
   129  					Expect(actualRequirements).To(ContainElement(minApiVersionReq))
   130  				})
   131  			})
   132  
   133  			Context("when the --reserved-route-ports is provided", func() {
   134  				BeforeEach(func() {
   135  					flagContext.Parse("myquota", "--reserved-route-ports", "2")
   136  					actualRequirements, err = cmd.Requirements(reqFactory, flagContext)
   137  					Expect(err).NotTo(HaveOccurred())
   138  				})
   139  
   140  				It("return a minimum api version requirement", func() {
   141  					Expect(reqFactory.NewMinAPIVersionRequirementCallCount()).To(Equal(1))
   142  					commandName, requiredVersion := reqFactory.NewMinAPIVersionRequirementArgsForCall(0)
   143  					Expect(commandName).To(Equal("Option '--reserved-route-ports'"))
   144  					expectVersion, _ := semver.Make("2.55.0")
   145  					Expect(requiredVersion).To(Equal(expectVersion))
   146  					Expect(actualRequirements).To(ContainElement(minApiVersionReq))
   147  				})
   148  			})
   149  		})
   150  	})
   151  
   152  	Describe("Execute", func() {
   153  		var runCLIErr error
   154  
   155  		BeforeEach(func() {
   156  			orgFields := models.OrganizationFields{
   157  				Name: "my-org",
   158  				GUID: "my-org-guid",
   159  			}
   160  
   161  			config.OrganizationFieldsReturns(orgFields)
   162  			config.UsernameReturns("my-user")
   163  		})
   164  
   165  		JustBeforeEach(func() {
   166  			cmd.SetDependency(deps, false)
   167  			runCLIErr = cmd.Execute(flagContext)
   168  		})
   169  
   170  		Context("when creating a quota succeeds", func() {
   171  			Context("without any flags", func() {
   172  				BeforeEach(func() {
   173  					flagContext.Parse("my-quota")
   174  				})
   175  
   176  				It("creates a quota with a given name", func() {
   177  					Expect(quotaRepo.CreateArgsForCall(0).Name).To(Equal("my-quota"))
   178  					Expect(quotaRepo.CreateArgsForCall(0).OrgGUID).To(Equal("my-org-guid"))
   179  					Expect(ui.Outputs()).To(ContainSubstrings(
   180  						[]string{"Creating space quota", "my-quota", "my-org", "my-user", "..."},
   181  						[]string{"OK"},
   182  					))
   183  				})
   184  
   185  				It("sets the instance memory limit to unlimiited", func() {
   186  					Expect(quotaRepo.CreateArgsForCall(0).InstanceMemoryLimit).To(Equal(int64(-1)))
   187  				})
   188  
   189  				It("sets the instance limit to unlimited", func() {
   190  					Expect(quotaRepo.CreateArgsForCall(0).AppInstanceLimit).To(Equal(resources.UnlimitedAppInstances))
   191  				})
   192  
   193  				It("defaults to not allowing paid service plans", func() {
   194  					Expect(quotaRepo.CreateArgsForCall(0).NonBasicServicesAllowed).To(BeFalse())
   195  				})
   196  			})
   197  
   198  			Context("when the -m flag is provided with valid value", func() {
   199  				BeforeEach(func() {
   200  					flagContext.Parse("-m", "50G", "erryday makin fitty jeez")
   201  				})
   202  
   203  				It("sets the memory limit", func() {
   204  					Expect(quotaRepo.CreateArgsForCall(0).MemoryLimit).To(Equal(int64(51200)))
   205  				})
   206  			})
   207  
   208  			Context("when the -i flag is provided with positive value", func() {
   209  				BeforeEach(func() {
   210  					flagContext.Parse("-i", "50G", "erryday makin fitty jeez")
   211  				})
   212  
   213  				It("sets the memory limit", func() {
   214  					Expect(quotaRepo.CreateArgsForCall(0).InstanceMemoryLimit).To(Equal(int64(51200)))
   215  				})
   216  			})
   217  
   218  			Context("when the -i flag is provided with -1", func() {
   219  				BeforeEach(func() {
   220  					flagContext.Parse("-i", "-1", "wit mah hussle")
   221  				})
   222  
   223  				It("accepts it as an appropriate value", func() {
   224  					Expect(quotaRepo.CreateArgsForCall(0).InstanceMemoryLimit).To(Equal(int64(-1)))
   225  				})
   226  			})
   227  
   228  			Context("when the -a flag is provided", func() {
   229  				BeforeEach(func() {
   230  					flagContext.Parse("-a", "50", "my special quota")
   231  				})
   232  
   233  				It("sets the instance limit", func() {
   234  					Expect(quotaRepo.CreateArgsForCall(0).AppInstanceLimit).To(Equal(50))
   235  				})
   236  			})
   237  
   238  			Context("when the -r flag is provided", func() {
   239  				BeforeEach(func() {
   240  					flagContext.Parse("-r", "12", "ecstatic")
   241  				})
   242  
   243  				It("sets the route limit", func() {
   244  					Expect(quotaRepo.CreateArgsForCall(0).RoutesLimit).To(Equal(12))
   245  				})
   246  			})
   247  
   248  			Context("when the -s flag is provided", func() {
   249  				BeforeEach(func() {
   250  					flagContext.Parse("-s", "42", "black star")
   251  				})
   252  
   253  				It("sets the service instance limit", func() {
   254  					Expect(quotaRepo.CreateArgsForCall(0).ServicesLimit).To(Equal(42))
   255  				})
   256  			})
   257  
   258  			Context("when the --reserved-route-ports flag is provided", func() {
   259  				BeforeEach(func() {
   260  					flagContext.Parse("--reserved-route-ports", "5", "square quota")
   261  				})
   262  
   263  				It("sets the quotas TCP route limit", func() {
   264  					Expect(quotaRepo.CreateArgsForCall(0).ReservedRoutePortsLimit).To(Equal(json.Number("5")))
   265  				})
   266  			})
   267  
   268  			Context("when requesting to allow paid service plans", func() {
   269  				BeforeEach(func() {
   270  					flagContext.Parse("--allow-paid-service-plans", "my-for-profit-quota")
   271  				})
   272  
   273  				It("creates the quota with paid service plans allowed", func() {
   274  					Expect(quotaRepo.CreateArgsForCall(0).NonBasicServicesAllowed).To(BeTrue())
   275  				})
   276  			})
   277  		})
   278  
   279  		Context("when the -i flag is provided with invalid value", func() {
   280  			BeforeEach(func() {
   281  				flagContext.Parse("-i", "whoops", "yo", "12")
   282  				cmd.SetDependency(deps, false)
   283  			})
   284  
   285  			It("alerts the user when parsing the memory limit fails", func() {
   286  				Expect(runCLIErr).To(HaveOccurred())
   287  				runCLIErrStr := runCLIErr.Error()
   288  				Expect(runCLIErrStr).To(ContainSubstring("Invalid instance memory limit: whoops"))
   289  				Expect(runCLIErrStr).To(ContainSubstring("Byte quantity must be an integer with a unit of measurement like M, MB, G, or GB"))
   290  			})
   291  		})
   292  
   293  		Context("when the -m flag is provided with invalid value", func() {
   294  			BeforeEach(func() {
   295  				flagContext.Parse("-m", "whoops", "wit mah hussle")
   296  				cmd.SetDependency(deps, false)
   297  			})
   298  
   299  			It("alerts the user when parsing the memory limit fails", func() {
   300  				Expect(runCLIErr).To(HaveOccurred())
   301  				runCLIErrStr := runCLIErr.Error()
   302  				Expect(runCLIErrStr).To(ContainSubstring("Invalid memory limit: whoops"))
   303  				Expect(runCLIErrStr).To(ContainSubstring("Byte quantity must be an integer with a unit of measurement like M, MB, G, or GB"))
   304  			})
   305  		})
   306  
   307  		Context("when the request fails", func() {
   308  			BeforeEach(func() {
   309  				flagContext.Parse("my-quota")
   310  				quotaRepo.CreateReturns(errors.New("WHOOP THERE IT IS"))
   311  				cmd.SetDependency(deps, false)
   312  			})
   313  
   314  			It("alets the user when creating the quota fails", func() {
   315  				Expect(runCLIErr).To(HaveOccurred())
   316  				Expect(ui.Outputs()).To(ContainSubstrings(
   317  					[]string{"Creating space quota", "my-quota", "my-org"},
   318  				))
   319  				Expect(runCLIErr.Error()).To(Equal("WHOOP THERE IT IS"))
   320  			})
   321  		})
   322  
   323  		Context("when the quota already exists", func() {
   324  			BeforeEach(func() {
   325  				flagContext.Parse("my-quota")
   326  				quotaRepo.CreateReturns(errors.NewHTTPError(400, errors.QuotaDefinitionNameTaken, "Quota Definition is taken: quota-sct"))
   327  			})
   328  
   329  			It("warns the user", func() {
   330  				Expect(runCLIErr).NotTo(HaveOccurred())
   331  				Expect(ui.Outputs()).ToNot(ContainSubstrings([]string{"FAILED"}))
   332  				Expect(ui.WarnOutputs).To(ContainSubstrings([]string{"already exists"}))
   333  			})
   334  		})
   335  	})
   336  })