github.com/cloudfoundry-attic/cli-with-i18n@v6.32.1-0.20171002233121-7401370d3b85+incompatible/cf/commands/route/delete_route_test.go (about)

     1  package route_test
     2  
     3  import (
     4  	"strings"
     5  
     6  	"code.cloudfoundry.org/cli/cf/commandregistry"
     7  	"code.cloudfoundry.org/cli/cf/commands/route"
     8  	"code.cloudfoundry.org/cli/cf/configuration/coreconfig"
     9  	"code.cloudfoundry.org/cli/cf/errors"
    10  	"code.cloudfoundry.org/cli/cf/flags"
    11  	"code.cloudfoundry.org/cli/cf/models"
    12  	"code.cloudfoundry.org/cli/cf/requirements"
    13  	"code.cloudfoundry.org/cli/cf/requirements/requirementsfakes"
    14  	"github.com/blang/semver"
    15  
    16  	"code.cloudfoundry.org/cli/cf/api/apifakes"
    17  
    18  	testconfig "code.cloudfoundry.org/cli/util/testhelpers/configuration"
    19  	testterm "code.cloudfoundry.org/cli/util/testhelpers/terminal"
    20  
    21  	. "code.cloudfoundry.org/cli/util/testhelpers/matchers"
    22  	. "github.com/onsi/ginkgo"
    23  	. "github.com/onsi/gomega"
    24  )
    25  
    26  var _ = Describe("DeleteRoute", func() {
    27  	var (
    28  		ui         *testterm.FakeUI
    29  		configRepo coreconfig.Repository
    30  		routeRepo  *apifakes.FakeRouteRepository
    31  
    32  		cmd         commandregistry.Command
    33  		deps        commandregistry.Dependency
    34  		factory     *requirementsfakes.FakeFactory
    35  		flagContext flags.FlagContext
    36  
    37  		loginRequirement         requirements.Requirement
    38  		domainRequirement        *requirementsfakes.FakeDomainRequirement
    39  		minAPIVersionRequirement requirements.Requirement
    40  
    41  		fakeDomain models.DomainFields
    42  	)
    43  
    44  	BeforeEach(func() {
    45  		ui = &testterm.FakeUI{}
    46  
    47  		configRepo = testconfig.NewRepositoryWithDefaults()
    48  		routeRepo = new(apifakes.FakeRouteRepository)
    49  		repoLocator := deps.RepoLocator.SetRouteRepository(routeRepo)
    50  
    51  		deps = commandregistry.Dependency{
    52  			UI:          ui,
    53  			Config:      configRepo,
    54  			RepoLocator: repoLocator,
    55  		}
    56  
    57  		cmd = &route.DeleteRoute{}
    58  		cmd.SetDependency(deps, false)
    59  
    60  		flagContext = flags.NewFlagContext(cmd.MetaData().Flags)
    61  
    62  		factory = new(requirementsfakes.FakeFactory)
    63  
    64  		loginRequirement = &passingRequirement{Name: "login-requirement"}
    65  		factory.NewLoginRequirementReturns(loginRequirement)
    66  
    67  		domainRequirement = new(requirementsfakes.FakeDomainRequirement)
    68  		factory.NewDomainRequirementReturns(domainRequirement)
    69  
    70  		fakeDomain = models.DomainFields{
    71  			GUID: "fake-domain-guid",
    72  			Name: "fake-domain-name",
    73  		}
    74  		domainRequirement.GetDomainReturns(fakeDomain)
    75  
    76  		minAPIVersionRequirement = &passingRequirement{Name: "min-api-version-requirement"}
    77  		factory.NewMinAPIVersionRequirementReturns(minAPIVersionRequirement)
    78  	})
    79  
    80  	Describe("Help text", func() {
    81  		var usage []string
    82  
    83  		BeforeEach(func() {
    84  			dr := &route.DeleteRoute{}
    85  			up := commandregistry.CLICommandUsagePresenter(dr)
    86  			usage = strings.Split(up.Usage(), "\n")
    87  		})
    88  
    89  		It("has a HTTP route usage", func() {
    90  			Expect(usage).To(ContainElement("   Delete an HTTP route:"))
    91  			Expect(usage).To(ContainElement("      cf delete-route DOMAIN [--hostname HOSTNAME] [--path PATH] [-f]"))
    92  		})
    93  
    94  		It("has a TCP route usage", func() {
    95  			Expect(usage).To(ContainElement("   Delete a TCP route:"))
    96  			Expect(usage).To(ContainElement("      cf delete-route DOMAIN --port PORT [-f]"))
    97  		})
    98  
    99  		It("has a TCP route example", func() {
   100  			Expect(usage).To(ContainElement("   cf delete-route example.com --port 50000                 # example.com:50000"))
   101  		})
   102  
   103  		It("has a TCP option", func() {
   104  			Expect(usage).To(ContainElement("   --port              Port used to identify the TCP route"))
   105  		})
   106  	})
   107  
   108  	Describe("Requirements", func() {
   109  		Context("when not provided exactly one arg", func() {
   110  			BeforeEach(func() {
   111  				flagContext.Parse("app-name", "extra-arg")
   112  			})
   113  
   114  			It("fails with usage", func() {
   115  				_, err := cmd.Requirements(factory, flagContext)
   116  				Expect(err).To(HaveOccurred())
   117  				Expect(ui.Outputs()).To(ContainSubstrings(
   118  					[]string{"FAILED"},
   119  					[]string{"Incorrect Usage. Requires an argument"},
   120  				))
   121  			})
   122  		})
   123  
   124  		Context("when provided exactly one arg", func() {
   125  			BeforeEach(func() {
   126  				flagContext.Parse("domain-name")
   127  			})
   128  
   129  			It("returns a LoginRequirement", func() {
   130  				actualRequirements, err := cmd.Requirements(factory, flagContext)
   131  				Expect(err).NotTo(HaveOccurred())
   132  				Expect(factory.NewLoginRequirementCallCount()).To(Equal(1))
   133  				Expect(actualRequirements).To(ContainElement(loginRequirement))
   134  			})
   135  
   136  			It("returns a DomainRequirement", func() {
   137  				actualRequirements, err := cmd.Requirements(factory, flagContext)
   138  				Expect(err).NotTo(HaveOccurred())
   139  				Expect(factory.NewDomainRequirementCallCount()).To(Equal(1))
   140  
   141  				Expect(factory.NewDomainRequirementArgsForCall(0)).To(Equal("domain-name"))
   142  				Expect(actualRequirements).To(ContainElement(domainRequirement))
   143  			})
   144  
   145  			Context("when a path is passed", func() {
   146  				BeforeEach(func() {
   147  					flagContext = flags.NewFlagContext(cmd.MetaData().Flags)
   148  					flagContext.Parse("domain-name", "--path", "the-path")
   149  				})
   150  
   151  				It("returns a MinAPIVersionRequirement as the first requirement", func() {
   152  					actualRequirements, err := cmd.Requirements(factory, flagContext)
   153  					Expect(err).NotTo(HaveOccurred())
   154  
   155  					expectedVersion, err := semver.Make("2.36.0")
   156  					Expect(err).NotTo(HaveOccurred())
   157  
   158  					Expect(factory.NewMinAPIVersionRequirementCallCount()).To(Equal(1))
   159  					feature, requiredVersion := factory.NewMinAPIVersionRequirementArgsForCall(0)
   160  					Expect(feature).To(Equal("Option '--path'"))
   161  					Expect(requiredVersion).To(Equal(expectedVersion))
   162  					Expect(actualRequirements[0]).To(Equal(minAPIVersionRequirement))
   163  				})
   164  			})
   165  
   166  			Context("when a path is not passed", func() {
   167  				BeforeEach(func() {
   168  					flagContext.Parse("domain-name")
   169  				})
   170  
   171  				It("does not return a MinAPIVersionRequirement", func() {
   172  					actualRequirements, err := cmd.Requirements(factory, flagContext)
   173  					Expect(err).NotTo(HaveOccurred())
   174  					Expect(factory.NewMinAPIVersionRequirementCallCount()).To(Equal(0))
   175  					Expect(actualRequirements).NotTo(ContainElement(minAPIVersionRequirement))
   176  				})
   177  			})
   178  
   179  			Describe("deleting a tcp route", func() {
   180  				Context("when passing port with a hostname", func() {
   181  					BeforeEach(func() {
   182  						flagContext.Parse("example.com", "--port", "8080", "--hostname", "something-else")
   183  					})
   184  
   185  					It("fails", func() {
   186  						_, err := cmd.Requirements(factory, flagContext)
   187  						Expect(err).To(HaveOccurred())
   188  						Expect(ui.Outputs()).To(ContainSubstrings(
   189  							[]string{"FAILED"},
   190  							[]string{"Cannot specify port together with hostname and/or path."},
   191  						))
   192  					})
   193  				})
   194  
   195  				Context("when passing port with a path", func() {
   196  					BeforeEach(func() {
   197  						flagContext.Parse("example.com", "--port", "8080", "--path", "something-else")
   198  					})
   199  
   200  					It("fails", func() {
   201  						_, err := cmd.Requirements(factory, flagContext)
   202  						Expect(err).To(HaveOccurred())
   203  						Expect(ui.Outputs()).To(ContainSubstrings(
   204  							[]string{"FAILED"},
   205  							[]string{"Cannot specify port together with hostname and/or path."},
   206  						))
   207  					})
   208  				})
   209  
   210  				Context("when a port is passed", func() {
   211  					BeforeEach(func() {
   212  						flagContext.Parse("example.com", "--port", "8080")
   213  					})
   214  
   215  					It("returns a MinAPIVersionRequirement as the first requirement", func() {
   216  						actualRequirements, err := cmd.Requirements(factory, flagContext)
   217  						Expect(err).NotTo(HaveOccurred())
   218  
   219  						expectedVersion, err := semver.Make("2.53.0")
   220  						Expect(err).NotTo(HaveOccurred())
   221  
   222  						Expect(factory.NewMinAPIVersionRequirementCallCount()).To(Equal(1))
   223  						feature, requiredVersion := factory.NewMinAPIVersionRequirementArgsForCall(0)
   224  						Expect(feature).To(Equal("Option '--port'"))
   225  						Expect(requiredVersion).To(Equal(expectedVersion))
   226  						Expect(actualRequirements[0]).To(Equal(minAPIVersionRequirement))
   227  					})
   228  				})
   229  			})
   230  		})
   231  	})
   232  
   233  	Describe("Execute", func() {
   234  		var err error
   235  
   236  		BeforeEach(func() {
   237  			err := flagContext.Parse("domain-name")
   238  			Expect(err).NotTo(HaveOccurred())
   239  			cmd.Requirements(factory, flagContext)
   240  		})
   241  
   242  		JustBeforeEach(func() {
   243  			err = cmd.Execute(flagContext)
   244  		})
   245  
   246  		Context("when passed -n flag", func() {
   247  			BeforeEach(func() {
   248  				ui.Inputs = []string{"n"}
   249  			})
   250  
   251  			It("asks the user if they would like to proceed", func() {
   252  				Expect(err).NotTo(HaveOccurred())
   253  				Eventually(func() []string { return ui.Prompts }).Should(ContainSubstrings(
   254  					[]string{"Really delete the route"},
   255  				))
   256  			})
   257  		})
   258  
   259  		Context("when the response is to proceed", func() {
   260  			BeforeEach(func() {
   261  				ui.Inputs = []string{"y"}
   262  			})
   263  
   264  			It("tries to find the route", func() {
   265  				Expect(err).NotTo(HaveOccurred())
   266  				Eventually(routeRepo.FindCallCount).Should(Equal(1))
   267  				host, domain, path, port := routeRepo.FindArgsForCall(0)
   268  				Expect(host).To(Equal(""))
   269  				Expect(path).To(Equal(""))
   270  				Expect(port).To(Equal(0))
   271  				Expect(domain).To(Equal(fakeDomain))
   272  			})
   273  
   274  			Context("when a path is passed", func() {
   275  				BeforeEach(func() {
   276  					err := flagContext.Parse("domain-name", "-f", "--path", "the-path")
   277  					Expect(err).NotTo(HaveOccurred())
   278  					cmd.Requirements(factory, flagContext)
   279  				})
   280  
   281  				It("tries to find the route with the path", func() {
   282  					Expect(err).NotTo(HaveOccurred())
   283  					Expect(routeRepo.FindCallCount()).To(Equal(1))
   284  					_, _, path, _ := routeRepo.FindArgsForCall(0)
   285  					Expect(path).To(Equal("the-path"))
   286  				})
   287  			})
   288  
   289  			Context("when a port is passed", func() {
   290  				BeforeEach(func() {
   291  					err := flagContext.Parse("domain-name", "-f", "--port", "60000")
   292  					Expect(err).NotTo(HaveOccurred())
   293  					cmd.Requirements(factory, flagContext)
   294  				})
   295  
   296  				It("tries to find the route with the port", func() {
   297  					Expect(err).NotTo(HaveOccurred())
   298  					Expect(routeRepo.FindCallCount()).To(Equal(1))
   299  					_, _, _, port := routeRepo.FindArgsForCall(0)
   300  					Expect(port).To(Equal(60000))
   301  				})
   302  			})
   303  
   304  			Context("when the route can be found", func() {
   305  				BeforeEach(func() {
   306  					routeRepo.FindReturns(models.Route{
   307  						GUID: "route-guid",
   308  					}, nil)
   309  				})
   310  
   311  				It("tries to delete the route", func() {
   312  					Expect(err).NotTo(HaveOccurred())
   313  					Expect(routeRepo.DeleteCallCount()).To(Equal(1))
   314  					Expect(routeRepo.DeleteArgsForCall(0)).To(Equal("route-guid"))
   315  				})
   316  
   317  				Context("when deleting the route succeeds", func() {
   318  					BeforeEach(func() {
   319  						routeRepo.DeleteReturns(nil)
   320  					})
   321  
   322  					It("tells the user that it succeeded", func() {
   323  						Expect(err).NotTo(HaveOccurred())
   324  						Expect(ui.Outputs()).To(ContainSubstrings(
   325  							[]string{"OK"},
   326  						))
   327  					})
   328  				})
   329  
   330  				Context("when deleting the route fails", func() {
   331  					BeforeEach(func() {
   332  						routeRepo.DeleteReturns(errors.New("delete-err"))
   333  					})
   334  
   335  					It("fails with error", func() {
   336  						Expect(err).To(HaveOccurred())
   337  						Expect(err.Error()).To(Equal("delete-err"))
   338  					})
   339  				})
   340  			})
   341  
   342  			Context("when there is an error finding the route", func() {
   343  				BeforeEach(func() {
   344  					routeRepo.FindReturns(models.Route{}, errors.New("find-err"))
   345  				})
   346  
   347  				It("fails with error", func() {
   348  					Expect(err).To(HaveOccurred())
   349  					Expect(err.Error()).To(Equal("find-err"))
   350  				})
   351  
   352  				It("does not try to delete the route", func() {
   353  					Expect(err).To(HaveOccurred())
   354  					Expect(routeRepo.DeleteCallCount()).To(BeZero())
   355  				})
   356  			})
   357  
   358  			Context("when there is a ModelNotFoundError when finding the route", func() {
   359  				BeforeEach(func() {
   360  					routeRepo.FindReturns(models.Route{}, errors.NewModelNotFoundError("model-type", "model-name"))
   361  				})
   362  
   363  				It("tells the user that it could not delete the route", func() {
   364  					Expect(err).NotTo(HaveOccurred())
   365  					Expect(ui.Outputs()).To(ContainSubstrings(
   366  						[]string{"Unable to delete, route", "does not exist"},
   367  					))
   368  				})
   369  
   370  				It("does not try to delete the route", func() {
   371  					Expect(err).NotTo(HaveOccurred())
   372  					Expect(routeRepo.DeleteCallCount()).To(BeZero())
   373  				})
   374  			})
   375  
   376  		})
   377  
   378  		Context("when the response is not to proceed", func() {
   379  			BeforeEach(func() {
   380  				ui.Inputs = []string{"n"}
   381  			})
   382  
   383  			It("does not try to delete the route", func() {
   384  				Expect(err).NotTo(HaveOccurred())
   385  				Expect(routeRepo.DeleteCallCount()).To(Equal(0))
   386  			})
   387  		})
   388  
   389  		Context("when force is set", func() {
   390  			BeforeEach(func() {
   391  				err := flagContext.Parse("domain-name", "-f")
   392  				Expect(err).NotTo(HaveOccurred())
   393  			})
   394  
   395  			It("does not ask the user if they would like to proceed", func() {
   396  				Expect(err).NotTo(HaveOccurred())
   397  				Consistently(func() []string { return ui.Prompts }).ShouldNot(ContainSubstrings(
   398  					[]string{"Really delete the route"},
   399  				))
   400  			})
   401  		})
   402  	})
   403  })