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