github.com/nimakaviani/cli@v6.37.1-0.20180619223813-e734901a73fa+incompatible/actor/pushaction/route_test.go (about) 1 package pushaction_test 2 3 import ( 4 "errors" 5 "strings" 6 7 "code.cloudfoundry.org/cli/actor/actionerror" 8 . "code.cloudfoundry.org/cli/actor/pushaction" 9 "code.cloudfoundry.org/cli/actor/pushaction/pushactionfakes" 10 "code.cloudfoundry.org/cli/actor/v2action" 11 "code.cloudfoundry.org/cli/api/cloudcontroller/ccv2/constant" 12 "code.cloudfoundry.org/cli/util/manifest" 13 14 . "github.com/onsi/ginkgo" 15 . "github.com/onsi/gomega" 16 ) 17 18 var _ = Describe("Routes", func() { 19 var ( 20 actor *Actor 21 fakeV2Actor *pushactionfakes.FakeV2Actor 22 fakeRandomWordGenerator *pushactionfakes.FakeRandomWordGenerator 23 ) 24 25 BeforeEach(func() { 26 fakeV2Actor = new(pushactionfakes.FakeV2Actor) 27 actor = NewActor(fakeV2Actor, nil, nil) 28 29 fakeRandomWordGenerator = new(pushactionfakes.FakeRandomWordGenerator) 30 actor.WordGenerator = fakeRandomWordGenerator 31 }) 32 33 Describe("UnmapRoutes", func() { 34 var ( 35 config ApplicationConfig 36 37 returnedConfig ApplicationConfig 38 warnings Warnings 39 executeErr error 40 ) 41 42 BeforeEach(func() { 43 config = ApplicationConfig{ 44 DesiredApplication: Application{ 45 Application: v2action.Application{ 46 GUID: "some-app-guid", 47 }}, 48 } 49 }) 50 51 JustBeforeEach(func() { 52 returnedConfig, warnings, executeErr = actor.UnmapRoutes(config) 53 }) 54 55 Context("when there are routes on the application", func() { 56 BeforeEach(func() { 57 config.CurrentRoutes = []v2action.Route{ 58 {GUID: "some-route-guid-1", Host: "some-route-1", Domain: v2action.Domain{Name: "some-domain.com"}}, 59 {GUID: "some-route-guid-2", Host: "some-route-2"}, 60 } 61 }) 62 63 Context("when the unmapping is successful", func() { 64 BeforeEach(func() { 65 fakeV2Actor.UnmapRouteFromApplicationReturns(v2action.Warnings{"unmap-route-warning"}, nil) 66 }) 67 68 It("only creates the routes that do not exist", func() { 69 Expect(executeErr).ToNot(HaveOccurred()) 70 Expect(warnings).To(ConsistOf("unmap-route-warning", "unmap-route-warning")) 71 72 Expect(returnedConfig.CurrentRoutes).To(BeEmpty()) 73 74 Expect(fakeV2Actor.UnmapRouteFromApplicationCallCount()).To(Equal(2)) 75 76 routeGUID, appGUID := fakeV2Actor.UnmapRouteFromApplicationArgsForCall(0) 77 Expect(routeGUID).To(Equal("some-route-guid-1")) 78 Expect(appGUID).To(Equal("some-app-guid")) 79 80 routeGUID, appGUID = fakeV2Actor.UnmapRouteFromApplicationArgsForCall(1) 81 Expect(routeGUID).To(Equal("some-route-guid-2")) 82 Expect(appGUID).To(Equal("some-app-guid")) 83 }) 84 }) 85 86 Context("when the mapping errors", func() { 87 var expectedErr error 88 BeforeEach(func() { 89 expectedErr = errors.New("oh my") 90 fakeV2Actor.UnmapRouteFromApplicationReturns(v2action.Warnings{"unmap-route-warning"}, expectedErr) 91 }) 92 93 It("sends the warnings and errors and returns true", func() { 94 Expect(executeErr).To(MatchError(expectedErr)) 95 Expect(warnings).To(ConsistOf("unmap-route-warning")) 96 }) 97 }) 98 }) 99 }) 100 101 Describe("MapRoutes", func() { 102 var ( 103 config ApplicationConfig 104 105 returnedConfig ApplicationConfig 106 boundRoutes bool 107 warnings Warnings 108 executeErr error 109 ) 110 111 BeforeEach(func() { 112 config = ApplicationConfig{ 113 DesiredApplication: Application{ 114 Application: v2action.Application{ 115 GUID: "some-app-guid", 116 }}, 117 } 118 }) 119 120 JustBeforeEach(func() { 121 returnedConfig, boundRoutes, warnings, executeErr = actor.MapRoutes(config) 122 }) 123 124 Context("when routes need to be bound to the application", func() { 125 BeforeEach(func() { 126 config.CurrentRoutes = []v2action.Route{ 127 {GUID: "some-route-guid-2", Host: "some-route-2"}, 128 } 129 config.DesiredRoutes = []v2action.Route{ 130 {GUID: "some-route-guid-1", Host: "some-route-1", Domain: v2action.Domain{Name: "some-domain.com"}}, 131 {GUID: "some-route-guid-2", Host: "some-route-2"}, 132 {GUID: "some-route-guid-3", Host: "some-route-3"}, 133 } 134 }) 135 136 Context("when the mapping is successful", func() { 137 BeforeEach(func() { 138 fakeV2Actor.MapRouteToApplicationReturns(v2action.Warnings{"map-route-warning"}, nil) 139 }) 140 141 It("only creates the routes that do not exist", func() { 142 Expect(executeErr).ToNot(HaveOccurred()) 143 Expect(warnings).To(ConsistOf("map-route-warning", "map-route-warning")) 144 Expect(boundRoutes).To(BeTrue()) 145 146 Expect(returnedConfig.CurrentRoutes).To(Equal(config.DesiredRoutes)) 147 148 Expect(fakeV2Actor.MapRouteToApplicationCallCount()).To(Equal(2)) 149 150 routeGUID, appGUID := fakeV2Actor.MapRouteToApplicationArgsForCall(0) 151 Expect(routeGUID).To(Equal("some-route-guid-1")) 152 Expect(appGUID).To(Equal("some-app-guid")) 153 154 routeGUID, appGUID = fakeV2Actor.MapRouteToApplicationArgsForCall(1) 155 Expect(routeGUID).To(Equal("some-route-guid-3")) 156 Expect(appGUID).To(Equal("some-app-guid")) 157 }) 158 }) 159 160 Context("when the mapping errors", func() { 161 Context("when the route is bound in another space", func() { 162 BeforeEach(func() { 163 fakeV2Actor.MapRouteToApplicationReturns(v2action.Warnings{"map-route-warning"}, actionerror.RouteInDifferentSpaceError{}) 164 }) 165 166 It("sends the RouteInDifferentSpaceError (with a guid set) and warnings and returns true", func() { 167 Expect(executeErr).To(MatchError(actionerror.RouteInDifferentSpaceError{Route: "some-route-1.some-domain.com"})) 168 Expect(warnings).To(ConsistOf("map-route-warning")) 169 }) 170 }) 171 172 Context("generic error", func() { 173 var expectedErr error 174 BeforeEach(func() { 175 expectedErr = errors.New("oh my") 176 fakeV2Actor.MapRouteToApplicationReturns(v2action.Warnings{"map-route-warning"}, expectedErr) 177 }) 178 179 It("sends the warnings and errors and returns true", func() { 180 Expect(executeErr).To(MatchError(expectedErr)) 181 Expect(warnings).To(ConsistOf("map-route-warning")) 182 }) 183 }) 184 }) 185 }) 186 187 Context("when no routes need to be bound", func() { 188 It("returns false", func() { 189 Expect(executeErr).ToNot(HaveOccurred()) 190 }) 191 }) 192 }) 193 194 Describe("CalculateRoutes", func() { 195 var ( 196 routes []string 197 orgGUID string 198 spaceGUID string 199 existingRoutes []v2action.Route 200 201 calculatedRoutes []v2action.Route 202 warnings Warnings 203 executeErr error 204 ) 205 206 BeforeEach(func() { 207 routes = []string{ 208 "a.com", 209 "b.a.com", 210 "c.b.a.com", 211 "d.c.b.a.com", 212 "a.com/some-path", 213 "*.f.e.com", 214 "*.e.com", 215 } 216 orgGUID = "some-org-guid" 217 spaceGUID = "some-space-guid" 218 }) 219 220 JustBeforeEach(func() { 221 calculatedRoutes, warnings, executeErr = actor.CalculateRoutes(routes, orgGUID, spaceGUID, existingRoutes) 222 }) 223 224 Context("when there are no known routes", func() { 225 BeforeEach(func() { 226 existingRoutes = []v2action.Route{{ 227 GUID: "some-route-5", 228 Host: "banana", 229 Domain: v2action.Domain{ 230 GUID: "domain-guid-1", 231 Name: "a.com", 232 }, 233 SpaceGUID: spaceGUID, 234 }} 235 }) 236 237 Context("when a route looking up the domains is succuessful", func() { 238 BeforeEach(func() { 239 fakeV2Actor.GetDomainsByNameAndOrganizationReturns([]v2action.Domain{ 240 {GUID: "domain-guid-1", Name: "a.com"}, 241 {GUID: "domain-guid-2", Name: "b.a.com"}, 242 {GUID: "domain-guid-3", Name: "f.e.com"}, 243 {GUID: "domain-guid-4", Name: "e.com"}, 244 }, v2action.Warnings{"domain-warnings-1", "domains-warnings-2"}, nil) 245 }) 246 247 Context("when the route is invalid", func() { 248 BeforeEach(func() { 249 routes = []string{"a.com", "b.a.com", "c.b.a.com:1234"} 250 }) 251 252 It("returns back warnings and error", func() { 253 Expect(executeErr).To(MatchError(actionerror.InvalidHTTPRouteSettings{Domain: "b.a.com"})) 254 Expect(warnings).To(ConsistOf("domain-warnings-1", "domains-warnings-2")) 255 }) 256 }) 257 258 Context("when the route existance check is successful", func() { 259 BeforeEach(func() { 260 fakeV2Actor.FindRouteBoundToSpaceWithSettingsReturns(v2action.Route{}, v2action.Warnings{"find-route-warning"}, actionerror.RouteNotFoundError{}) 261 fakeV2Actor.FindRouteBoundToSpaceWithSettingsReturnsOnCall(3, v2action.Route{ 262 GUID: "route-guid-4", 263 Host: "d.c", 264 Domain: v2action.Domain{ 265 GUID: "domain-guid-2", 266 Name: "b.a.com", 267 }, 268 SpaceGUID: spaceGUID, 269 }, v2action.Warnings{"find-route-warning"}, nil) 270 }) 271 272 It("returns new and existing routes", func() { 273 Expect(executeErr).NotTo(HaveOccurred()) 274 Expect(warnings).To(ConsistOf("domain-warnings-1", "domains-warnings-2", "find-route-warning", "find-route-warning", "find-route-warning", "find-route-warning", "find-route-warning", "find-route-warning", "find-route-warning")) 275 Expect(calculatedRoutes).To(ConsistOf( 276 v2action.Route{ 277 Domain: v2action.Domain{ 278 GUID: "domain-guid-1", 279 Name: "a.com", 280 }, 281 SpaceGUID: spaceGUID, 282 }, 283 v2action.Route{ 284 Domain: v2action.Domain{ 285 GUID: "domain-guid-2", 286 Name: "b.a.com", 287 }, 288 SpaceGUID: spaceGUID, 289 }, 290 v2action.Route{ 291 Host: "c", 292 Domain: v2action.Domain{ 293 GUID: "domain-guid-2", 294 Name: "b.a.com", 295 }, 296 SpaceGUID: spaceGUID, 297 }, 298 v2action.Route{ 299 GUID: "route-guid-4", 300 Host: "d.c", 301 Domain: v2action.Domain{ 302 GUID: "domain-guid-2", 303 Name: "b.a.com", 304 }, 305 SpaceGUID: spaceGUID, 306 }, 307 v2action.Route{ 308 GUID: "some-route-5", 309 Host: "banana", 310 Domain: v2action.Domain{ 311 GUID: "domain-guid-1", 312 Name: "a.com", 313 }, 314 SpaceGUID: spaceGUID, 315 }, 316 v2action.Route{ 317 Host: "", 318 Domain: v2action.Domain{ 319 GUID: "domain-guid-1", 320 Name: "a.com", 321 }, 322 Path: "/some-path", 323 SpaceGUID: spaceGUID, 324 }, 325 v2action.Route{ 326 Host: "*", 327 Domain: v2action.Domain{ 328 GUID: "domain-guid-3", 329 Name: "f.e.com", 330 }, 331 SpaceGUID: spaceGUID, 332 }, 333 v2action.Route{ 334 Host: "*", 335 Domain: v2action.Domain{ 336 GUID: "domain-guid-4", 337 Name: "e.com", 338 }, 339 SpaceGUID: spaceGUID, 340 })) 341 342 Expect(fakeV2Actor.GetDomainsByNameAndOrganizationCallCount()).To(Equal(1)) 343 domains, passedOrgGUID := fakeV2Actor.GetDomainsByNameAndOrganizationArgsForCall(0) 344 Expect(domains).To(ConsistOf("a.com", "b.a.com", "c.b.a.com", "d.c.b.a.com", "*.f.e.com", "f.e.com", "*.e.com", "e.com")) 345 Expect(passedOrgGUID).To(Equal(orgGUID)) 346 347 Expect(fakeV2Actor.FindRouteBoundToSpaceWithSettingsCallCount()).To(Equal(7)) 348 // One check is enough here - checking 4th call since it's the only 349 // existing one. 350 Expect(fakeV2Actor.FindRouteBoundToSpaceWithSettingsArgsForCall(3)).To(Equal(v2action.Route{ 351 Host: "d.c", 352 Domain: v2action.Domain{ 353 GUID: "domain-guid-2", 354 Name: "b.a.com", 355 }, 356 SpaceGUID: spaceGUID, 357 })) 358 }) 359 }) 360 361 Context("when the route existance check fails", func() { 362 var expectedErr error 363 364 BeforeEach(func() { 365 expectedErr = errors.New("oh noes") 366 fakeV2Actor.FindRouteBoundToSpaceWithSettingsReturns(v2action.Route{}, v2action.Warnings{"find-route-warning"}, expectedErr) 367 }) 368 369 It("returns back warnings and error", func() { 370 Expect(executeErr).To(MatchError(expectedErr)) 371 Expect(warnings).To(ConsistOf("domain-warnings-1", "domains-warnings-2", "find-route-warning")) 372 }) 373 }) 374 375 Context("when one of the domains does not exist", func() { 376 BeforeEach(func() { 377 fakeV2Actor.GetDomainsByNameAndOrganizationReturns(nil, v2action.Warnings{"domain-warnings-1", "domains-warnings-2"}, nil) 378 }) 379 380 It("returns back warnings and error", func() { 381 Expect(executeErr).To(MatchError(actionerror.NoMatchingDomainError{Route: "a.com"})) 382 Expect(warnings).To(ConsistOf("domain-warnings-1", "domains-warnings-2")) 383 }) 384 }) 385 }) 386 387 Context("when looking up a domain returns an error", func() { 388 var expectedErr error 389 390 BeforeEach(func() { 391 expectedErr = errors.New("po-tate-toe") 392 fakeV2Actor.GetDomainsByNameAndOrganizationReturns(nil, v2action.Warnings{"domain-warnings-1", "domains-warnings-2"}, expectedErr) 393 }) 394 395 It("returns back warnings and error", func() { 396 Expect(executeErr).To(MatchError(expectedErr)) 397 Expect(warnings).To(ConsistOf("domain-warnings-1", "domains-warnings-2")) 398 }) 399 }) 400 }) 401 402 Context("when there are known routes", func() { 403 BeforeEach(func() { 404 existingRoutes = []v2action.Route{{ 405 GUID: "route-guid-4", 406 Host: "d.c", 407 Domain: v2action.Domain{ 408 GUID: "domain-guid-2", 409 Name: "b.a.com", 410 }, 411 SpaceGUID: spaceGUID, 412 }} 413 414 fakeV2Actor.GetDomainsByNameAndOrganizationReturns([]v2action.Domain{ 415 {GUID: "domain-guid-1", Name: "a.com"}, 416 {GUID: "domain-guid-2", Name: "b.a.com"}, 417 {GUID: "domain-guid-3", Name: "f.e.com"}, 418 {GUID: "domain-guid-4", Name: "e.com"}, 419 }, v2action.Warnings{"domain-warnings-1", "domains-warnings-2"}, nil) 420 fakeV2Actor.FindRouteBoundToSpaceWithSettingsReturns(v2action.Route{}, v2action.Warnings{"find-route-warning"}, actionerror.RouteNotFoundError{}) 421 }) 422 423 It("does not lookup known routes", func() { 424 Expect(executeErr).NotTo(HaveOccurred()) 425 Expect(warnings).To(ConsistOf("domain-warnings-1", "domains-warnings-2", "find-route-warning", "find-route-warning", "find-route-warning", "find-route-warning", "find-route-warning", "find-route-warning")) 426 Expect(calculatedRoutes).To(ConsistOf( 427 v2action.Route{ 428 Domain: v2action.Domain{ 429 GUID: "domain-guid-1", 430 Name: "a.com", 431 }, 432 SpaceGUID: spaceGUID, 433 }, 434 v2action.Route{ 435 Domain: v2action.Domain{ 436 GUID: "domain-guid-2", 437 Name: "b.a.com", 438 }, 439 SpaceGUID: spaceGUID, 440 }, 441 v2action.Route{ 442 Host: "c", 443 Domain: v2action.Domain{ 444 GUID: "domain-guid-2", 445 Name: "b.a.com", 446 }, 447 SpaceGUID: spaceGUID, 448 }, 449 v2action.Route{ 450 GUID: "route-guid-4", 451 Host: "d.c", 452 Domain: v2action.Domain{ 453 GUID: "domain-guid-2", 454 Name: "b.a.com", 455 }, 456 SpaceGUID: spaceGUID, 457 }, 458 v2action.Route{ 459 Host: "", 460 Domain: v2action.Domain{ 461 GUID: "domain-guid-1", 462 Name: "a.com", 463 }, 464 Path: "/some-path", 465 SpaceGUID: spaceGUID, 466 }, 467 v2action.Route{ 468 Host: "*", 469 Domain: v2action.Domain{ 470 GUID: "domain-guid-3", 471 Name: "f.e.com", 472 }, 473 SpaceGUID: spaceGUID, 474 }, 475 v2action.Route{ 476 Host: "*", 477 Domain: v2action.Domain{ 478 GUID: "domain-guid-4", 479 Name: "e.com", 480 }, 481 SpaceGUID: spaceGUID, 482 })) 483 484 Expect(fakeV2Actor.GetDomainsByNameAndOrganizationCallCount()).To(Equal(1)) 485 domains, passedOrgGUID := fakeV2Actor.GetDomainsByNameAndOrganizationArgsForCall(0) 486 Expect(domains).To(ConsistOf("a.com", "b.a.com", "c.b.a.com", "*.f.e.com", "f.e.com", "*.e.com", "e.com")) 487 Expect(passedOrgGUID).To(Equal(orgGUID)) 488 }) 489 }) 490 }) 491 492 Describe("CreateAndMapDefaultApplicationRoute", func() { 493 var ( 494 warnings Warnings 495 executeErr error 496 ) 497 498 JustBeforeEach(func() { 499 warnings, executeErr = actor.CreateAndMapDefaultApplicationRoute("some-org-guid", "some-space-guid", 500 v2action.Application{Name: "some-app", GUID: "some-app-guid"}) 501 }) 502 503 Context("when getting organization domains errors", func() { 504 BeforeEach(func() { 505 fakeV2Actor.GetOrganizationDomainsReturns( 506 []v2action.Domain{}, 507 v2action.Warnings{"domain-warning"}, 508 errors.New("some-error")) 509 }) 510 511 It("returns the error", func() { 512 Expect(executeErr).To(MatchError("some-error")) 513 Expect(warnings).To(ConsistOf("domain-warning")) 514 }) 515 }) 516 517 Context("when getting organization domains succeeds", func() { 518 BeforeEach(func() { 519 fakeV2Actor.GetOrganizationDomainsReturns( 520 []v2action.Domain{ 521 { 522 GUID: "some-domain-guid", 523 Name: "some-domain", 524 }, 525 }, 526 v2action.Warnings{"domain-warning"}, 527 nil, 528 ) 529 }) 530 531 Context("when getting the application routes errors", func() { 532 BeforeEach(func() { 533 fakeV2Actor.GetApplicationRoutesReturns( 534 []v2action.Route{}, 535 v2action.Warnings{"route-warning"}, 536 errors.New("some-error"), 537 ) 538 }) 539 540 It("returns the error", func() { 541 Expect(executeErr).To(MatchError("some-error")) 542 Expect(warnings).To(ConsistOf("domain-warning", "route-warning")) 543 }) 544 }) 545 546 Context("when getting the application routes succeeds", func() { 547 // TODO: do we need this context 548 Context("when the route is already bound to the app", func() { 549 BeforeEach(func() { 550 fakeV2Actor.GetApplicationRoutesReturns( 551 []v2action.Route{ 552 { 553 Host: "some-app", 554 Domain: v2action.Domain{ 555 GUID: "some-domain-guid", 556 Name: "some-domain", 557 }, 558 GUID: "some-route-guid", 559 SpaceGUID: "some-space-guid", 560 }, 561 }, 562 v2action.Warnings{"route-warning"}, 563 nil, 564 ) 565 }) 566 567 It("returns any warnings", func() { 568 Expect(executeErr).ToNot(HaveOccurred()) 569 Expect(warnings).To(ConsistOf("domain-warning", "route-warning")) 570 571 Expect(fakeV2Actor.GetOrganizationDomainsCallCount()).To(Equal(1), "Expected GetOrganizationDomains to be called once, but it was not") 572 orgGUID := fakeV2Actor.GetOrganizationDomainsArgsForCall(0) 573 Expect(orgGUID).To(Equal("some-org-guid")) 574 575 Expect(fakeV2Actor.GetApplicationRoutesCallCount()).To(Equal(1), "Expected GetApplicationRoutes to be called once, but it was not") 576 appGUID := fakeV2Actor.GetApplicationRoutesArgsForCall(0) 577 Expect(appGUID).To(Equal("some-app-guid")) 578 579 Expect(fakeV2Actor.CreateRouteCallCount()).To(Equal(0), "Expected CreateRoute to not be called but it was") 580 Expect(fakeV2Actor.MapRouteToApplicationCallCount()).To(Equal(0), "Expected MapRouteToApplication to not be called but it was") 581 }) 582 }) 583 584 Context("when the route isn't bound to the app", func() { 585 Context("when finding route in space errors", func() { 586 BeforeEach(func() { 587 fakeV2Actor.FindRouteBoundToSpaceWithSettingsReturns( 588 v2action.Route{}, 589 v2action.Warnings{"route-warning"}, 590 errors.New("some-error"), 591 ) 592 }) 593 594 It("returns the error", func() { 595 Expect(executeErr).To(MatchError("some-error")) 596 Expect(warnings).To(ConsistOf("domain-warning", "route-warning")) 597 }) 598 }) 599 600 Context("when the route exists", func() { 601 BeforeEach(func() { 602 fakeV2Actor.FindRouteBoundToSpaceWithSettingsReturns( 603 v2action.Route{ 604 GUID: "some-route-guid", 605 Host: "some-app", 606 Domain: v2action.Domain{ 607 Name: "some-domain", 608 GUID: "some-domain-guid", 609 }, 610 SpaceGUID: "some-space-guid", 611 }, 612 v2action.Warnings{"route-warning"}, 613 nil, 614 ) 615 }) 616 617 Context("when the map command returns an error", func() { 618 BeforeEach(func() { 619 fakeV2Actor.MapRouteToApplicationReturns( 620 v2action.Warnings{"map-warning"}, 621 errors.New("some-error"), 622 ) 623 }) 624 625 It("returns the error", func() { 626 Expect(executeErr).To(MatchError("some-error")) 627 Expect(warnings).To(ConsistOf("domain-warning", "route-warning", "map-warning")) 628 }) 629 }) 630 631 Context("when the map command succeeds", func() { 632 BeforeEach(func() { 633 fakeV2Actor.MapRouteToApplicationReturns( 634 v2action.Warnings{"map-warning"}, 635 nil, 636 ) 637 }) 638 639 It("maps the route to the app and returns any warnings", func() { 640 Expect(executeErr).ToNot(HaveOccurred()) 641 Expect(warnings).To(ConsistOf("domain-warning", "route-warning", "map-warning")) 642 643 Expect(fakeV2Actor.FindRouteBoundToSpaceWithSettingsCallCount()).To(Equal(1), "Expected FindRouteBoundToSpaceWithSettings to be called once, but it was not") 644 spaceRoute := fakeV2Actor.FindRouteBoundToSpaceWithSettingsArgsForCall(0) 645 Expect(spaceRoute).To(Equal(v2action.Route{ 646 Host: "some-app", 647 Domain: v2action.Domain{ 648 Name: "some-domain", 649 GUID: "some-domain-guid", 650 }, 651 SpaceGUID: "some-space-guid", 652 })) 653 654 Expect(fakeV2Actor.MapRouteToApplicationCallCount()).To(Equal(1), "Expected MapRouteToApplication to be called once, but it was not") 655 routeGUID, appGUID := fakeV2Actor.MapRouteToApplicationArgsForCall(0) 656 Expect(routeGUID).To(Equal("some-route-guid")) 657 Expect(appGUID).To(Equal("some-app-guid")) 658 }) 659 }) 660 }) 661 662 Context("when the route does not exist", func() { 663 BeforeEach(func() { 664 fakeV2Actor.FindRouteBoundToSpaceWithSettingsReturns( 665 v2action.Route{}, 666 v2action.Warnings{"route-warning"}, 667 actionerror.RouteNotFoundError{}, 668 ) 669 }) 670 671 Context("when the create route command errors", func() { 672 BeforeEach(func() { 673 fakeV2Actor.CreateRouteReturns( 674 v2action.Route{}, 675 v2action.Warnings{"route-create-warning"}, 676 errors.New("some-error"), 677 ) 678 }) 679 680 It("returns the error", func() { 681 Expect(executeErr).To(MatchError("some-error")) 682 Expect(warnings).To(ConsistOf("domain-warning", "route-warning", "route-create-warning")) 683 }) 684 }) 685 686 Context("when the create route command succeeds", func() { 687 BeforeEach(func() { 688 fakeV2Actor.CreateRouteReturns( 689 v2action.Route{ 690 GUID: "some-route-guid", 691 Host: "some-app", 692 Domain: v2action.Domain{ 693 Name: "some-domain", 694 GUID: "some-domain-guid", 695 }, 696 SpaceGUID: "some-space-guid", 697 }, 698 v2action.Warnings{"route-create-warning"}, 699 nil, 700 ) 701 }) 702 703 Context("when the map command errors", func() { 704 BeforeEach(func() { 705 fakeV2Actor.MapRouteToApplicationReturns( 706 v2action.Warnings{"map-warning"}, 707 errors.New("some-error"), 708 ) 709 }) 710 711 It("returns the error", func() { 712 Expect(executeErr).To(MatchError("some-error")) 713 Expect(warnings).To(ConsistOf("domain-warning", "route-warning", "route-create-warning", "map-warning")) 714 }) 715 }) 716 Context("when the map command succeeds", func() { 717 718 BeforeEach(func() { 719 fakeV2Actor.MapRouteToApplicationReturns( 720 v2action.Warnings{"map-warning"}, 721 nil, 722 ) 723 }) 724 725 It("creates the route, maps it to the app, and returns any warnings", func() { 726 Expect(executeErr).ToNot(HaveOccurred()) 727 Expect(warnings).To(ConsistOf("domain-warning", "route-warning", "route-create-warning", "map-warning")) 728 729 Expect(fakeV2Actor.CreateRouteCallCount()).To(Equal(1), "Expected CreateRoute to be called once, but it was not") 730 defaultRoute, shouldGeneratePort := fakeV2Actor.CreateRouteArgsForCall(0) 731 Expect(defaultRoute).To(Equal(v2action.Route{ 732 Host: "some-app", 733 Domain: v2action.Domain{ 734 Name: "some-domain", 735 GUID: "some-domain-guid", 736 }, 737 SpaceGUID: "some-space-guid", 738 })) 739 Expect(shouldGeneratePort).To(BeFalse()) 740 741 Expect(fakeV2Actor.FindRouteBoundToSpaceWithSettingsCallCount()).To(Equal(1), "Expected FindRouteBoundToSpaceWithSettings to be called once, but it was not") 742 spaceRoute := fakeV2Actor.FindRouteBoundToSpaceWithSettingsArgsForCall(0) 743 Expect(spaceRoute).To(Equal(v2action.Route{ 744 Host: "some-app", 745 Domain: v2action.Domain{ 746 Name: "some-domain", 747 GUID: "some-domain-guid", 748 }, 749 SpaceGUID: "some-space-guid", 750 })) 751 752 Expect(fakeV2Actor.MapRouteToApplicationCallCount()).To(Equal(1), "Expected MapRouteToApplication to be called once, but it was not") 753 routeGUID, appGUID := fakeV2Actor.MapRouteToApplicationArgsForCall(0) 754 Expect(routeGUID).To(Equal("some-route-guid")) 755 Expect(appGUID).To(Equal("some-app-guid")) 756 }) 757 }) 758 }) 759 }) 760 }) 761 }) 762 }) 763 }) 764 765 Describe("CreateRoutes", func() { 766 var ( 767 config ApplicationConfig 768 769 returnedConfig ApplicationConfig 770 createdRoutes bool 771 warnings Warnings 772 executeErr error 773 ) 774 775 BeforeEach(func() { 776 config = ApplicationConfig{} 777 }) 778 779 JustBeforeEach(func() { 780 returnedConfig, createdRoutes, warnings, executeErr = actor.CreateRoutes(config) 781 }) 782 783 Describe("when routes need to be created", func() { 784 BeforeEach(func() { 785 config.DesiredRoutes = []v2action.Route{ 786 {GUID: "", Host: "some-route-1"}, 787 {GUID: "some-route-guid-2", Host: "some-route-2"}, 788 {GUID: "", Host: "some-route-3"}, 789 {GUID: "", Host: "", Domain: v2action.Domain{RouterGroupType: constant.TCPRouterGroup}}, 790 } 791 }) 792 793 Context("when the creation is successful", func() { 794 BeforeEach(func() { 795 fakeV2Actor.CreateRouteReturnsOnCall(0, v2action.Route{GUID: "some-route-guid-1", Host: "some-route-1"}, v2action.Warnings{"create-route-warning"}, nil) 796 fakeV2Actor.CreateRouteReturnsOnCall(1, v2action.Route{GUID: "some-route-guid-3", Host: "some-route-3"}, v2action.Warnings{"create-route-warning"}, nil) 797 fakeV2Actor.CreateRouteReturnsOnCall(2, v2action.Route{GUID: "some-route-guid-4", Domain: v2action.Domain{RouterGroupType: constant.TCPRouterGroup}}, v2action.Warnings{"create-route-warning"}, nil) 798 }) 799 800 It("only creates the routes that do not exist", func() { 801 Expect(executeErr).ToNot(HaveOccurred()) 802 Expect(warnings).To(ConsistOf("create-route-warning", "create-route-warning", "create-route-warning")) 803 Expect(createdRoutes).To(BeTrue()) 804 Expect(returnedConfig.DesiredRoutes).To(Equal([]v2action.Route{ 805 {GUID: "some-route-guid-1", Host: "some-route-1"}, 806 {GUID: "some-route-guid-2", Host: "some-route-2"}, 807 {GUID: "some-route-guid-3", Host: "some-route-3"}, 808 {GUID: "some-route-guid-4", Domain: v2action.Domain{RouterGroupType: constant.TCPRouterGroup}}, 809 })) 810 811 Expect(fakeV2Actor.CreateRouteCallCount()).To(Equal(3)) 812 813 passedRoute, randomRoute := fakeV2Actor.CreateRouteArgsForCall(0) 814 Expect(passedRoute).To(Equal(v2action.Route{Host: "some-route-1"})) 815 Expect(randomRoute).To(BeFalse()) 816 817 passedRoute, randomRoute = fakeV2Actor.CreateRouteArgsForCall(1) 818 Expect(passedRoute).To(Equal(v2action.Route{Host: "some-route-3"})) 819 Expect(randomRoute).To(BeFalse()) 820 821 passedRoute, randomRoute = fakeV2Actor.CreateRouteArgsForCall(2) 822 Expect(passedRoute).To(Equal(v2action.Route{GUID: "", Host: "", Domain: v2action.Domain{RouterGroupType: constant.TCPRouterGroup}})) 823 Expect(randomRoute).To(BeTrue()) 824 }) 825 }) 826 827 Context("when the creation errors", func() { 828 var expectedErr error 829 830 BeforeEach(func() { 831 expectedErr = errors.New("oh my") 832 fakeV2Actor.CreateRouteReturns( 833 v2action.Route{}, 834 v2action.Warnings{"create-route-warning"}, 835 expectedErr) 836 }) 837 838 It("sends the warnings and errors and returns true", func() { 839 Expect(executeErr).To(MatchError(expectedErr)) 840 Expect(warnings).To(ConsistOf("create-route-warning")) 841 }) 842 }) 843 }) 844 845 Context("when no routes are created", func() { 846 BeforeEach(func() { 847 config.DesiredRoutes = []v2action.Route{ 848 {GUID: "some-route-guid-1", Host: "some-route-1"}, 849 {GUID: "some-route-guid-2", Host: "some-route-2"}, 850 {GUID: "some-route-guid-3", Host: "some-route-3"}, 851 } 852 }) 853 854 It("returns false", func() { 855 Expect(createdRoutes).To(BeFalse()) 856 }) 857 }) 858 }) 859 860 Describe("GenerateRandomRoute", func() { 861 var ( 862 spaceGUID string 863 orgGUID string 864 865 randomRoute v2action.Route 866 warnings Warnings 867 executeErr error 868 869 domain v2action.Domain 870 manifestApp manifest.Application 871 ) 872 873 BeforeEach(func() { 874 manifestApp = manifest.Application{ 875 Name: "some a$pp nAme", 876 } 877 spaceGUID = "some-space-guid" 878 orgGUID = "some-org-guid" 879 domain = v2action.Domain{} 880 }) 881 882 JustBeforeEach(func() { 883 randomRoute, warnings, executeErr = actor.GenerateRandomRoute(manifestApp, spaceGUID, orgGUID) 884 }) 885 886 Context("when a domain is specified", func() { 887 BeforeEach(func() { 888 manifestApp.Domain = "some-domain" 889 domain.Name = "some-domain" 890 fakeRandomWordGenerator.RandomAdjectiveReturns("striped") 891 fakeRandomWordGenerator.RandomNounReturns("apple") 892 893 fakeV2Actor.GetDomainsByNameAndOrganizationReturns( 894 []v2action.Domain{domain}, 895 v2action.Warnings{"some-organization-domain-warning"}, 896 nil, 897 ) 898 }) 899 900 It("uses the specified domain to generate a route", func() { 901 Expect(executeErr).ToNot(HaveOccurred()) 902 Expect(randomRoute).To(Equal(v2action.Route{ 903 Domain: domain, 904 Host: "some-app-name-striped-apple", 905 SpaceGUID: spaceGUID, 906 })) 907 Expect(warnings).To(ConsistOf("some-organization-domain-warning")) 908 909 Expect(fakeV2Actor.GetDomainsByNameAndOrganizationCallCount()).To(Equal(1)) 910 domainsArg, orgGUIDArg := fakeV2Actor.GetDomainsByNameAndOrganizationArgsForCall(0) 911 Expect(domainsArg).To(ConsistOf("some-domain")) 912 Expect(orgGUIDArg).To(Equal("some-org-guid")) 913 }) 914 }) 915 916 Context("when no domain is specified", func() { 917 Context("when the default domain is a tcp domain", func() { 918 BeforeEach(func() { 919 domain.RouterGroupType = constant.TCPRouterGroup 920 fakeV2Actor.GetOrganizationDomainsReturns( 921 []v2action.Domain{domain}, 922 v2action.Warnings{"some-organization-domain-warning"}, 923 nil, 924 ) 925 }) 926 927 It("generates a route with a randomly generated server side port number", func() { 928 Expect(executeErr).ToNot(HaveOccurred()) 929 Expect(randomRoute).To(Equal(v2action.Route{ 930 Domain: domain, 931 SpaceGUID: spaceGUID, 932 })) 933 Expect(warnings).To(ConsistOf("some-organization-domain-warning")) 934 935 Expect(fakeV2Actor.GetOrganizationDomainsCallCount()).To(Equal(1)) 936 Expect(fakeV2Actor.GetOrganizationDomainsArgsForCall(0)).To(Equal(orgGUID)) 937 }) 938 }) 939 940 Context("when the default domain is an http domain", func() { 941 BeforeEach(func() { 942 domain.RouterGroupType = constant.HTTPRouterGroup 943 fakeV2Actor.GetOrganizationDomainsReturns( 944 []v2action.Domain{domain}, 945 v2action.Warnings{"some-organization-domain-warning"}, 946 nil, 947 ) 948 fakeRandomWordGenerator.RandomAdjectiveReturns("striped") 949 fakeRandomWordGenerator.RandomNounReturns("apple") 950 }) 951 952 Context("when the app name is partially sanitized", func() { 953 BeforeEach(func() { 954 manifestApp.Name = "a--b" 955 }) 956 957 It("generates a route whose hostname is a sanitized app name and two randomly generated words", func() { 958 Expect(executeErr).ToNot(HaveOccurred()) 959 Expect(randomRoute).To(Equal(v2action.Route{ 960 Domain: domain, 961 SpaceGUID: spaceGUID, 962 Host: "a--b-striped-apple", 963 })) 964 Expect(warnings).To(ConsistOf("some-organization-domain-warning")) 965 }) 966 }) 967 968 Context("when the app name is fully sanitized", func() { 969 BeforeEach(func() { 970 manifestApp.Name = "@@@" 971 }) 972 973 It("generates a route whose hostname is a sanitized app name and two randomly generated words", func() { 974 Expect(executeErr).ToNot(HaveOccurred()) 975 Expect(randomRoute).To(Equal(v2action.Route{ 976 Domain: domain, 977 SpaceGUID: spaceGUID, 978 Host: "striped-apple", 979 })) 980 Expect(warnings).To(ConsistOf("some-organization-domain-warning")) 981 }) 982 }) 983 }) 984 985 Context("when the default domain lookup fails", func() { 986 BeforeEach(func() { 987 fakeV2Actor.GetOrganizationDomainsReturns( 988 []v2action.Domain{domain}, 989 v2action.Warnings{"some-organization-domain-warning"}, 990 errors.New("some-error"), 991 ) 992 }) 993 It("returns an error and a warning", func() { 994 Expect(executeErr).To(MatchError("some-error")) 995 Expect(warnings).To(ConsistOf("some-organization-domain-warning")) 996 }) 997 }) 998 }) 999 }) 1000 1001 Describe("GetGeneratedRoute", func() { 1002 var ( 1003 providedManifest manifest.Application 1004 orgGUID string 1005 spaceGUID string 1006 knownRoutes []v2action.Route 1007 1008 defaultRoute v2action.Route 1009 warnings Warnings 1010 executeErr error 1011 1012 domain v2action.Domain 1013 ) 1014 1015 BeforeEach(func() { 1016 providedManifest = manifest.Application{ 1017 Name: "Some-App", 1018 } 1019 orgGUID = "some-org-guid" 1020 spaceGUID = "some-space-guid" 1021 knownRoutes = nil 1022 1023 domain = v2action.Domain{ 1024 Name: "shared-domain.com", 1025 GUID: "some-shared-domain-guid", 1026 } 1027 }) 1028 1029 JustBeforeEach(func() { 1030 defaultRoute, warnings, executeErr = actor.GetGeneratedRoute(providedManifest, orgGUID, spaceGUID, knownRoutes) 1031 }) 1032 1033 Context("the domain is provided", func() { 1034 BeforeEach(func() { 1035 providedManifest.Domain = "shared-domain.com" 1036 }) 1037 1038 Context("when the provided domain exists", func() { 1039 BeforeEach(func() { 1040 domain.Type = constant.SharedDomain 1041 1042 // Assumes new route 1043 fakeV2Actor.FindRouteBoundToSpaceWithSettingsReturns(v2action.Route{}, v2action.Warnings{"get-route-warnings"}, actionerror.RouteNotFoundError{}) 1044 }) 1045 1046 Context("when the provided domain is an HTTP domain", func() { 1047 BeforeEach(func() { 1048 fakeV2Actor.GetDomainsByNameAndOrganizationReturns( 1049 []v2action.Domain{domain}, 1050 v2action.Warnings{"some-organization-domain-warning"}, 1051 nil, 1052 ) 1053 }) 1054 1055 It("it uses the provided domain instead of the first shared domain", func() { 1056 Expect(executeErr).ToNot(HaveOccurred()) 1057 Expect(warnings).To(ConsistOf("some-organization-domain-warning", "get-route-warnings")) 1058 Expect(defaultRoute).To(Equal(v2action.Route{ 1059 Domain: domain, 1060 Host: strings.ToLower(providedManifest.Name), 1061 SpaceGUID: spaceGUID, 1062 })) 1063 1064 Expect(fakeV2Actor.GetDomainsByNameAndOrganizationCallCount()).To(Equal(1)) 1065 domainNamesArg, orgGUIDArg := fakeV2Actor.GetDomainsByNameAndOrganizationArgsForCall(0) 1066 Expect(domainNamesArg).To(Equal([]string{"shared-domain.com"})) 1067 Expect(orgGUIDArg).To(Equal(orgGUID)) 1068 1069 Expect(fakeV2Actor.FindRouteBoundToSpaceWithSettingsCallCount()).To(Equal(1)) 1070 Expect(fakeV2Actor.FindRouteBoundToSpaceWithSettingsArgsForCall(0)).To(Equal(v2action.Route{ 1071 Domain: domain, 1072 Host: strings.ToLower(providedManifest.Name), 1073 SpaceGUID: spaceGUID, 1074 })) 1075 }) 1076 }) 1077 1078 Context("when the provided domain is an TCP domain", func() { 1079 BeforeEach(func() { 1080 domain.RouterGroupType = constant.TCPRouterGroup 1081 1082 fakeV2Actor.GetDomainsByNameAndOrganizationReturns( 1083 []v2action.Domain{domain}, 1084 v2action.Warnings{"some-organization-domain-warning"}, 1085 nil, 1086 ) 1087 }) 1088 1089 It("it uses the provided domain instead of the first shared domain and has no host", func() { 1090 Expect(executeErr).ToNot(HaveOccurred()) 1091 Expect(warnings).To(ConsistOf("some-organization-domain-warning")) 1092 Expect(defaultRoute).To(Equal(v2action.Route{ 1093 Domain: domain, 1094 SpaceGUID: spaceGUID, 1095 })) 1096 1097 Expect(fakeV2Actor.GetDomainsByNameAndOrganizationCallCount()).To(Equal(1)) 1098 domainNamesArg, orgGUIDArg := fakeV2Actor.GetDomainsByNameAndOrganizationArgsForCall(0) 1099 Expect(domainNamesArg).To(Equal([]string{"shared-domain.com"})) 1100 Expect(orgGUIDArg).To(Equal(orgGUID)) 1101 1102 Expect(fakeV2Actor.FindRouteBoundToSpaceWithSettingsCallCount()).To(Equal(0)) 1103 }) 1104 }) 1105 }) 1106 1107 Context("when the provided domain does not exist", func() { 1108 BeforeEach(func() { 1109 fakeV2Actor.GetDomainsByNameAndOrganizationReturns( 1110 []v2action.Domain{}, 1111 v2action.Warnings{"some-organization-domain-warning"}, 1112 nil, 1113 ) 1114 }) 1115 1116 It("returns an DomainNotFoundError", func() { 1117 Expect(executeErr).To(MatchError(actionerror.DomainNotFoundError{Name: "shared-domain.com"})) 1118 Expect(warnings).To(ConsistOf("some-organization-domain-warning")) 1119 }) 1120 }) 1121 }) 1122 1123 Context("the hostname is provided", func() { 1124 BeforeEach(func() { 1125 providedManifest.Hostname = "some HO_ST" 1126 }) 1127 1128 Context("when the domain is an HTTP domain", func() { 1129 BeforeEach(func() { 1130 domain.Type = constant.SharedDomain 1131 fakeV2Actor.GetOrganizationDomainsReturns( 1132 []v2action.Domain{domain}, 1133 v2action.Warnings{"some-organization-domain-warning"}, 1134 nil, 1135 ) 1136 1137 // Assumes new route 1138 fakeV2Actor.FindRouteBoundToSpaceWithSettingsReturns(v2action.Route{}, v2action.Warnings{"get-route-warnings"}, actionerror.RouteNotFoundError{}) 1139 }) 1140 1141 It("it uses the provided hostname instead of the app name", func() { 1142 Expect(executeErr).ToNot(HaveOccurred()) 1143 Expect(warnings).To(ConsistOf("some-organization-domain-warning", "get-route-warnings")) 1144 Expect(defaultRoute).To(Equal(v2action.Route{ 1145 Domain: domain, 1146 Host: "some-host", 1147 SpaceGUID: spaceGUID, 1148 })) 1149 1150 Expect(fakeV2Actor.FindRouteBoundToSpaceWithSettingsCallCount()).To(Equal(1)) 1151 Expect(fakeV2Actor.FindRouteBoundToSpaceWithSettingsArgsForCall(0)).To(Equal(v2action.Route{ 1152 Domain: domain, 1153 Host: "some-host", 1154 SpaceGUID: spaceGUID, 1155 })) 1156 }) 1157 }) 1158 1159 Context("when the provided domain is an TCP domain", func() { 1160 BeforeEach(func() { 1161 domain.RouterGroupType = constant.TCPRouterGroup 1162 fakeV2Actor.GetOrganizationDomainsReturns( 1163 []v2action.Domain{domain}, 1164 v2action.Warnings{"some-organization-domain-warning"}, 1165 nil, 1166 ) 1167 }) 1168 1169 It("returns an error", func() { 1170 Expect(executeErr).To(MatchError(actionerror.HostnameWithTCPDomainError{})) 1171 Expect(warnings).To(ConsistOf("some-organization-domain-warning")) 1172 }) 1173 }) 1174 }) 1175 1176 Context("when no hostname is requested", func() { 1177 BeforeEach(func() { 1178 providedManifest.NoHostname = true 1179 1180 // Assumes new route 1181 fakeV2Actor.FindRouteBoundToSpaceWithSettingsReturns(v2action.Route{}, v2action.Warnings{"get-route-warnings"}, actionerror.RouteNotFoundError{}) 1182 }) 1183 1184 Context("the domain is a private domain", func() { 1185 BeforeEach(func() { 1186 domain.Type = constant.PrivateDomain 1187 fakeV2Actor.GetOrganizationDomainsReturns([]v2action.Domain{domain}, nil, nil) 1188 }) 1189 1190 It("does not set the hostname for the route", func() { 1191 Expect(executeErr).ToNot(HaveOccurred()) 1192 Expect(defaultRoute).To(Equal(v2action.Route{ 1193 Domain: domain, 1194 SpaceGUID: spaceGUID, 1195 })) 1196 1197 Expect(fakeV2Actor.FindRouteBoundToSpaceWithSettingsCallCount()).To(Equal(1)) 1198 Expect(fakeV2Actor.FindRouteBoundToSpaceWithSettingsArgsForCall(0)).To(Equal(v2action.Route{ 1199 Domain: domain, 1200 SpaceGUID: spaceGUID, 1201 })) 1202 }) 1203 }) 1204 1205 Context("the domain is a shared domain", func() { 1206 Context("when the domain is a TCP Domain", func() { 1207 BeforeEach(func() { 1208 domain.Type = constant.SharedDomain 1209 domain.RouterGroupType = constant.TCPRouterGroup 1210 fakeV2Actor.GetOrganizationDomainsReturns([]v2action.Domain{domain}, v2action.Warnings{"private-domain-warnings", "shared-domain-warnings"}, nil) 1211 }) 1212 1213 It("returns a TCP route", func() { 1214 Expect(executeErr).ToNot(HaveOccurred()) 1215 Expect(warnings).To(ConsistOf("private-domain-warnings", "shared-domain-warnings")) 1216 Expect(defaultRoute).To(Equal(v2action.Route{ 1217 Domain: domain, 1218 SpaceGUID: spaceGUID, 1219 })) 1220 }) 1221 }) 1222 1223 Context("when the domain is an HTTP Domain", func() { 1224 BeforeEach(func() { 1225 domain.Type = constant.SharedDomain 1226 fakeV2Actor.GetOrganizationDomainsReturns([]v2action.Domain{domain}, v2action.Warnings{"private-domain-warnings", "shared-domain-warnings"}, nil) 1227 }) 1228 1229 It("returns an error and warnings", func() { 1230 Expect(executeErr).To(MatchError(actionerror.NoHostnameAndSharedDomainError{})) 1231 Expect(warnings).To(ConsistOf("private-domain-warnings", "shared-domain-warnings")) 1232 }) 1233 }) 1234 }) 1235 }) 1236 1237 Context("the route path is provided", func() { 1238 BeforeEach(func() { 1239 providedManifest.RoutePath = "/some-route-path" 1240 }) 1241 1242 Context("when the domain is an HTTP domain", func() { 1243 BeforeEach(func() { 1244 domain.Type = constant.SharedDomain 1245 fakeV2Actor.GetOrganizationDomainsReturns( 1246 []v2action.Domain{domain}, 1247 v2action.Warnings{"some-organization-domain-warning"}, 1248 nil, 1249 ) 1250 1251 // Assumes new route 1252 fakeV2Actor.FindRouteBoundToSpaceWithSettingsReturns(v2action.Route{}, v2action.Warnings{"get-route-warnings"}, actionerror.RouteNotFoundError{}) 1253 }) 1254 1255 It("it uses the provided route-path for the route", func() { 1256 Expect(executeErr).ToNot(HaveOccurred()) 1257 Expect(warnings).To(ConsistOf("some-organization-domain-warning", "get-route-warnings")) 1258 Expect(defaultRoute).To(Equal(v2action.Route{ 1259 Domain: domain, 1260 Host: "some-app", 1261 SpaceGUID: spaceGUID, 1262 Path: "/some-route-path", 1263 })) 1264 1265 Expect(fakeV2Actor.FindRouteBoundToSpaceWithSettingsCallCount()).To(Equal(1)) 1266 Expect(fakeV2Actor.FindRouteBoundToSpaceWithSettingsArgsForCall(0)).To(Equal(v2action.Route{ 1267 Domain: domain, 1268 Host: "some-app", 1269 SpaceGUID: spaceGUID, 1270 Path: "/some-route-path", 1271 })) 1272 }) 1273 }) 1274 1275 Context("when the provided domain is a TCP domain", func() { 1276 BeforeEach(func() { 1277 domain.RouterGroupType = constant.TCPRouterGroup 1278 fakeV2Actor.GetOrganizationDomainsReturns( 1279 []v2action.Domain{domain}, 1280 v2action.Warnings{"some-organization-domain-warning"}, 1281 nil, 1282 ) 1283 }) 1284 1285 It("returns an error", func() { 1286 Expect(executeErr).To(MatchError(actionerror.RoutePathWithTCPDomainError{})) 1287 Expect(warnings).To(ConsistOf("some-organization-domain-warning")) 1288 }) 1289 1290 }) 1291 }) 1292 1293 Context("when no route settings are provided (default route)", func() { 1294 Context("when retrieving the domains is successful", func() { 1295 BeforeEach(func() { 1296 fakeV2Actor.GetOrganizationDomainsReturns( 1297 []v2action.Domain{domain}, 1298 v2action.Warnings{"private-domain-warnings", "shared-domain-warnings"}, 1299 nil, 1300 ) 1301 }) 1302 1303 Context("when the app name is simple", func() { 1304 Context("when the route exists", func() { 1305 BeforeEach(func() { 1306 fakeV2Actor.FindRouteBoundToSpaceWithSettingsReturns(v2action.Route{ 1307 Domain: domain, 1308 GUID: "some-route-guid", 1309 Host: "some-app", 1310 SpaceGUID: spaceGUID, 1311 }, v2action.Warnings{"get-route-warnings"}, nil) 1312 }) 1313 1314 It("returns the route and warnings", func() { 1315 Expect(executeErr).ToNot(HaveOccurred()) 1316 Expect(warnings).To(ConsistOf("private-domain-warnings", "shared-domain-warnings", "get-route-warnings")) 1317 1318 Expect(defaultRoute).To(Equal(v2action.Route{ 1319 Domain: domain, 1320 GUID: "some-route-guid", 1321 Host: "some-app", 1322 SpaceGUID: spaceGUID, 1323 })) 1324 1325 Expect(fakeV2Actor.GetOrganizationDomainsCallCount()).To(Equal(1)) 1326 Expect(fakeV2Actor.GetOrganizationDomainsArgsForCall(0)).To(Equal(orgGUID)) 1327 1328 Expect(fakeV2Actor.FindRouteBoundToSpaceWithSettingsCallCount()).To(Equal(1)) 1329 Expect(fakeV2Actor.FindRouteBoundToSpaceWithSettingsArgsForCall(0)).To(Equal(v2action.Route{ 1330 Domain: domain, 1331 Host: strings.ToLower(providedManifest.Name), 1332 SpaceGUID: spaceGUID, 1333 })) 1334 }) 1335 1336 Context("when the route is in known routes", func() { 1337 BeforeEach(func() { 1338 knownRoutes = []v2action.Route{{ 1339 Domain: domain, 1340 GUID: "some-route-guid", 1341 Host: strings.ToLower(providedManifest.Name), 1342 SpaceGUID: spaceGUID, 1343 }} 1344 }) 1345 1346 It("should return the known route and warnings", func() { 1347 Expect(executeErr).ToNot(HaveOccurred()) 1348 Expect(warnings).To(ConsistOf("private-domain-warnings", "shared-domain-warnings")) 1349 1350 Expect(defaultRoute).To(Equal(v2action.Route{ 1351 Domain: domain, 1352 GUID: "some-route-guid", 1353 Host: strings.ToLower(providedManifest.Name), 1354 SpaceGUID: spaceGUID, 1355 })) 1356 1357 Expect(fakeV2Actor.FindRouteBoundToSpaceWithSettingsCallCount()).To(Equal(0)) 1358 }) 1359 }) 1360 1361 Context("when the route does not exist", func() { 1362 BeforeEach(func() { 1363 fakeV2Actor.FindRouteBoundToSpaceWithSettingsReturns(v2action.Route{}, v2action.Warnings{"get-route-warnings"}, actionerror.RouteNotFoundError{}) 1364 }) 1365 1366 It("returns a partial route", func() { 1367 Expect(executeErr).ToNot(HaveOccurred()) 1368 Expect(warnings).To(ConsistOf("private-domain-warnings", "shared-domain-warnings", "get-route-warnings")) 1369 1370 Expect(defaultRoute).To(Equal(v2action.Route{Domain: domain, Host: strings.ToLower(providedManifest.Name), SpaceGUID: spaceGUID})) 1371 }) 1372 }) 1373 1374 Context("when retrieving the routes errors", func() { 1375 var expectedErr error 1376 1377 BeforeEach(func() { 1378 expectedErr = errors.New("whoops") 1379 fakeV2Actor.FindRouteBoundToSpaceWithSettingsReturns(v2action.Route{}, v2action.Warnings{"get-route-warnings"}, expectedErr) 1380 }) 1381 1382 It("returns errors and warnings", func() { 1383 Expect(executeErr).To(MatchError(expectedErr)) 1384 Expect(warnings).To(ConsistOf("private-domain-warnings", "shared-domain-warnings", "get-route-warnings")) 1385 }) 1386 }) 1387 }) 1388 }) 1389 1390 Context("when the app name is complex", func() { 1391 BeforeEach(func() { 1392 providedManifest.Name = "$Some App 1234567890" 1393 }) 1394 1395 It("provides the sanitized application name to FindRouteBoundToSpaceWithSettings", func() { 1396 Expect(fakeV2Actor.FindRouteBoundToSpaceWithSettingsCallCount()).To(Equal(1)) 1397 Expect(fakeV2Actor.FindRouteBoundToSpaceWithSettingsArgsForCall(0)).To(Equal(v2action.Route{ 1398 Domain: domain, 1399 Host: "some-app-1234567890", 1400 SpaceGUID: spaceGUID, 1401 })) 1402 }) 1403 }) 1404 1405 Context("when the app name is not a usable hostname", func() { 1406 BeforeEach(func() { 1407 providedManifest.Name = " %^ @# **(& " 1408 }) 1409 1410 It("provides the sanitized application name to FindRouteBoundToSpaceWithSettings", func() { 1411 Expect(fakeV2Actor.FindRouteBoundToSpaceWithSettingsCallCount()).To(Equal(1)) 1412 Expect(fakeV2Actor.FindRouteBoundToSpaceWithSettingsArgsForCall(0)).To(Equal(v2action.Route{ 1413 Domain: domain, 1414 SpaceGUID: spaceGUID, 1415 })) 1416 }) 1417 }) 1418 }) 1419 1420 Context("when retrieving the domains errors", func() { 1421 var expectedErr error 1422 1423 BeforeEach(func() { 1424 expectedErr = errors.New("whoops") 1425 fakeV2Actor.GetOrganizationDomainsReturns([]v2action.Domain{}, v2action.Warnings{"private-domain-warnings", "shared-domain-warnings"}, expectedErr) 1426 }) 1427 1428 It("returns errors and warnings", func() { 1429 Expect(executeErr).To(MatchError(expectedErr)) 1430 Expect(warnings).To(ConsistOf("private-domain-warnings", "shared-domain-warnings")) 1431 }) 1432 }) 1433 }) 1434 }) 1435 })