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 })