github.com/dcarley/cf-cli@v6.24.1-0.20170220111324-4225ff346898+incompatible/cf/actors/routes_test.go (about)

     1  package actors_test
     2  
     3  import (
     4  	"errors"
     5  
     6  	. "code.cloudfoundry.org/cli/cf/actors"
     7  	"code.cloudfoundry.org/cli/cf/api/apifakes"
     8  	cferrors "code.cloudfoundry.org/cli/cf/errors"
     9  	"code.cloudfoundry.org/cli/cf/errors/errorsfakes"
    10  	"code.cloudfoundry.org/cli/cf/models"
    11  	"code.cloudfoundry.org/cli/cf/terminal/terminalfakes"
    12  	"code.cloudfoundry.org/cli/util/words/generator/generatorfakes"
    13  	. "github.com/onsi/ginkgo"
    14  	. "github.com/onsi/gomega"
    15  )
    16  
    17  var _ = Describe("Routes", func() {
    18  	var (
    19  		fakeUI               *terminalfakes.FakeUI
    20  		fakeRouteRepository  *apifakes.FakeRouteRepository
    21  		fakeDomainRepository *apifakes.FakeDomainRepository
    22  		routeActor           RouteActor
    23  
    24  		expectedRoute  models.Route
    25  		expectedDomain models.DomainFields
    26  		wordGenerator  *generatorfakes.FakeWordGenerator
    27  	)
    28  
    29  	BeforeEach(func() {
    30  		fakeUI = &terminalfakes.FakeUI{}
    31  		fakeRouteRepository = new(apifakes.FakeRouteRepository)
    32  		fakeDomainRepository = new(apifakes.FakeDomainRepository)
    33  		routeActor = NewRouteActor(fakeUI, fakeRouteRepository, fakeDomainRepository)
    34  		wordGenerator = new(generatorfakes.FakeWordGenerator)
    35  	})
    36  
    37  	Describe("CreateRandomTCPRoute", func() {
    38  		BeforeEach(func() {
    39  			expectedDomain = models.DomainFields{
    40  				Name: "dies-tcp.com",
    41  			}
    42  
    43  			expectedRoute = models.Route{
    44  				GUID: "some-guid",
    45  			}
    46  
    47  			fakeRouteRepository.CreateReturns(expectedRoute, nil)
    48  		})
    49  
    50  		It("calls Create on the route repo", func() {
    51  			routeActor.CreateRandomTCPRoute(expectedDomain)
    52  
    53  			host, d, path, port, randomPort := fakeRouteRepository.CreateArgsForCall(0)
    54  			Expect(host).To(BeEmpty())
    55  			Expect(d).To(Equal(expectedDomain))
    56  			Expect(path).To(BeEmpty())
    57  			Expect(port).To(Equal(0))
    58  			Expect(randomPort).To(BeTrue())
    59  		})
    60  
    61  		It("states that a route is being created", func() {
    62  			routeActor.CreateRandomTCPRoute(expectedDomain)
    63  
    64  			Expect(fakeUI.SayCallCount()).To(Equal(1))
    65  			Expect(fakeUI.SayArgsForCall(0)).To(ContainSubstring("Creating random route for"))
    66  		})
    67  
    68  		It("returns the route retrieved from the repository", func() {
    69  			actualRoute, err := routeActor.CreateRandomTCPRoute(expectedDomain)
    70  			Expect(err).NotTo(HaveOccurred())
    71  
    72  			Expect(actualRoute).To(Equal(expectedRoute))
    73  		})
    74  
    75  		It("prints an error when creating the route fails", func() {
    76  			expectedError := errors.New("big bad error message")
    77  			fakeRouteRepository.CreateReturns(models.Route{}, expectedError)
    78  
    79  			actualRoute, err := routeActor.CreateRandomTCPRoute(expectedDomain)
    80  			Expect(err).To(Equal(expectedError))
    81  			Expect(actualRoute).To(Equal(models.Route{}))
    82  		})
    83  	})
    84  
    85  	Describe("FindOrCreateRoute", func() {
    86  		var (
    87  			expectedHostname string
    88  			expectedPath     string
    89  		)
    90  
    91  		BeforeEach(func() {
    92  			expectedHostname = "hostname"
    93  			expectedPath = "path"
    94  
    95  			expectedDomain = models.DomainFields{
    96  				Name:            "foo.com",
    97  				RouterGroupType: "tcp",
    98  			}
    99  
   100  			expectedRoute = models.Route{
   101  				Domain: expectedDomain,
   102  				Host:   expectedHostname,
   103  				Path:   expectedPath,
   104  			}
   105  		})
   106  
   107  		Context("the route exists", func() {
   108  			BeforeEach(func() {
   109  				fakeRouteRepository.FindReturns(expectedRoute, nil)
   110  			})
   111  
   112  			It("does not create a route", func() {
   113  				route, err := routeActor.FindOrCreateRoute(expectedHostname, expectedDomain, expectedPath, 0, false)
   114  				Expect(route).To(Equal(expectedRoute))
   115  				Expect(err).ToNot(HaveOccurred())
   116  
   117  				Expect(fakeRouteRepository.CreateCallCount()).To(Equal(0))
   118  
   119  				Expect(fakeUI.SayCallCount()).To(Equal(1))
   120  				output, _ := fakeUI.SayArgsForCall(0)
   121  				Expect(output).To(MatchRegexp("Using route.*hostname.foo.com/path"))
   122  			})
   123  		})
   124  
   125  		Context("the route does not exist", func() {
   126  			BeforeEach(func() {
   127  				fakeRouteRepository.FindReturns(models.Route{}, cferrors.NewModelNotFoundError("foo", "bar"))
   128  			})
   129  
   130  			Context("with a random port", func() {
   131  				var tcpRoute models.Route
   132  
   133  				BeforeEach(func() {
   134  					tcpRoute = models.Route{Port: 4}
   135  					fakeRouteRepository.CreateReturns(tcpRoute, nil)
   136  				})
   137  
   138  				It("creates a route with a TCP Route", func() {
   139  					route, err := routeActor.FindOrCreateRoute("", expectedDomain, "", 0, true)
   140  					Expect(route).To(Equal(tcpRoute))
   141  					Expect(err).ToNot(HaveOccurred())
   142  
   143  					Expect(fakeRouteRepository.CreateCallCount()).To(Equal(1))
   144  					hostname, domain, path, port, randomPort := fakeRouteRepository.CreateArgsForCall(0)
   145  					Expect(hostname).To(BeEmpty())
   146  					Expect(domain).To(Equal(expectedDomain))
   147  					Expect(path).To(BeEmpty())
   148  					Expect(port).To(Equal(0))
   149  					Expect(randomPort).To(BeTrue())
   150  
   151  					Expect(fakeUI.SayCallCount()).To(Equal(2))
   152  					output, _ := fakeUI.SayArgsForCall(0)
   153  					Expect(output).To(MatchRegexp("Creating random route for"))
   154  				})
   155  			})
   156  
   157  			Context("without a specific port", func() {
   158  				BeforeEach(func() {
   159  					fakeRouteRepository.CreateReturns(expectedRoute, nil)
   160  				})
   161  
   162  				It("creates a route ", func() {
   163  					route, err := routeActor.FindOrCreateRoute(expectedHostname, expectedDomain, "", 1337, false)
   164  					Expect(route).To(Equal(expectedRoute))
   165  					Expect(err).ToNot(HaveOccurred())
   166  
   167  					Expect(fakeRouteRepository.CreateCallCount()).To(Equal(1))
   168  					hostname, domain, path, port, randomPort := fakeRouteRepository.CreateArgsForCall(0)
   169  					Expect(hostname).To(Equal(expectedHostname))
   170  					Expect(domain).To(Equal(expectedDomain))
   171  					Expect(path).To(Equal(""))
   172  					Expect(port).To(Equal(1337))
   173  					Expect(randomPort).To(BeFalse())
   174  
   175  					Expect(fakeUI.SayCallCount()).To(Equal(2))
   176  					output, _ := fakeUI.SayArgsForCall(0)
   177  					Expect(output).To(MatchRegexp("Creating route.*hostname.foo.com:1337"))
   178  				})
   179  			})
   180  
   181  			Context("with a path", func() {
   182  				BeforeEach(func() {
   183  					fakeRouteRepository.CreateReturns(expectedRoute, nil)
   184  				})
   185  
   186  				It("creates a route ", func() {
   187  					route, err := routeActor.FindOrCreateRoute(expectedHostname, expectedDomain, expectedPath, 0, false)
   188  					Expect(route).To(Equal(expectedRoute))
   189  					Expect(err).ToNot(HaveOccurred())
   190  
   191  					Expect(fakeRouteRepository.CreateCallCount()).To(Equal(1))
   192  					hostname, domain, path, port, randomPort := fakeRouteRepository.CreateArgsForCall(0)
   193  					Expect(hostname).To(Equal(expectedHostname))
   194  					Expect(domain).To(Equal(expectedDomain))
   195  					Expect(path).To(Equal(expectedPath))
   196  					Expect(port).To(Equal(0))
   197  					Expect(randomPort).To(BeFalse())
   198  
   199  					Expect(fakeUI.SayCallCount()).To(Equal(2))
   200  					output, _ := fakeUI.SayArgsForCall(0)
   201  					Expect(output).To(MatchRegexp("Creating route.*hostname.foo.com/path"))
   202  				})
   203  			})
   204  		})
   205  	})
   206  
   207  	Describe("BindRoute", func() {
   208  		var (
   209  			expectedApp models.Application
   210  		)
   211  
   212  		BeforeEach(func() {
   213  			expectedRoute = models.Route{
   214  				GUID: "route-guid",
   215  			}
   216  			expectedApp = models.Application{
   217  				ApplicationFields: models.ApplicationFields{
   218  					Name: "app-name",
   219  					GUID: "app-guid",
   220  				},
   221  			}
   222  		})
   223  
   224  		Context("when the app has the route", func() {
   225  			BeforeEach(func() {
   226  				routeSummary := models.RouteSummary{
   227  					GUID: expectedRoute.GUID,
   228  				}
   229  				expectedApp.Routes = append(expectedApp.Routes, routeSummary)
   230  			})
   231  
   232  			It("does nothing", func() {
   233  				err := routeActor.BindRoute(expectedApp, expectedRoute)
   234  				Expect(err).To(BeNil())
   235  
   236  				Expect(fakeRouteRepository.BindCallCount()).To(Equal(0))
   237  			})
   238  		})
   239  
   240  		Context("when the app does not have a route", func() {
   241  			It("binds the route", func() {
   242  				err := routeActor.BindRoute(expectedApp, expectedRoute)
   243  				Expect(err).To(BeNil())
   244  
   245  				Expect(fakeRouteRepository.BindCallCount()).To(Equal(1))
   246  				routeGUID, appGUID := fakeRouteRepository.BindArgsForCall(0)
   247  				Expect(routeGUID).To(Equal(expectedRoute.GUID))
   248  				Expect(appGUID).To(Equal(expectedApp.ApplicationFields.GUID))
   249  
   250  				Expect(fakeUI.SayArgsForCall(0)).To(MatchRegexp("Binding .* to .*app-name"))
   251  				Expect(fakeUI.OkCallCount()).To(Equal(1))
   252  			})
   253  
   254  			Context("when the route is already in use", func() {
   255  				var expectedErr *errorsfakes.FakeHTTPError
   256  				BeforeEach(func() {
   257  					expectedErr = new(errorsfakes.FakeHTTPError)
   258  					expectedErr.ErrorCodeReturns(cferrors.InvalidRelation)
   259  					fakeRouteRepository.BindReturns(expectedErr)
   260  				})
   261  
   262  				It("outputs the error", func() {
   263  					err := routeActor.BindRoute(expectedApp, expectedRoute)
   264  					Expect(err.Error()).To(MatchRegexp("The route *. is already in use"))
   265  				})
   266  			})
   267  		})
   268  	})
   269  
   270  	Describe("UnbindAll", func() {
   271  		var app models.Application
   272  
   273  		BeforeEach(func() {
   274  			app = models.Application{
   275  				ApplicationFields: models.ApplicationFields{
   276  					GUID: "my-app-guid",
   277  				},
   278  				Routes: []models.RouteSummary{
   279  					{
   280  						GUID:   "my-route-guid-1",
   281  						Domain: models.DomainFields{Name: "mydomain1.com"},
   282  					},
   283  					{
   284  						GUID:   "my-route-guid-2",
   285  						Domain: models.DomainFields{Name: "mydomain2.com"},
   286  					},
   287  				},
   288  			}
   289  		})
   290  
   291  		Context("when unbinding does not work", func() {
   292  			var expectedError error
   293  
   294  			BeforeEach(func() {
   295  				expectedError = errors.New("ZOHMYGOD DUN BROKE")
   296  				fakeRouteRepository.UnbindReturns(expectedError)
   297  			})
   298  
   299  			It("returns the error immediately", func() {
   300  				err := routeActor.UnbindAll(app)
   301  				Expect(err).To(Equal(expectedError))
   302  
   303  				Expect(fakeRouteRepository.UnbindCallCount()).To(Equal(1))
   304  			})
   305  		})
   306  
   307  		Context("when unbinding works", func() {
   308  			It("unbinds the route for the app", func() {
   309  				err := routeActor.UnbindAll(app)
   310  				Expect(err).NotTo(HaveOccurred())
   311  
   312  				Expect(fakeRouteRepository.UnbindCallCount()).To(Equal(2))
   313  
   314  				routeGUID, appGUID := fakeRouteRepository.UnbindArgsForCall(0)
   315  				Expect(routeGUID).To(Equal("my-route-guid-1"))
   316  				Expect(appGUID).To(Equal("my-app-guid"))
   317  
   318  				routeGUID, appGUID = fakeRouteRepository.UnbindArgsForCall(1)
   319  				Expect(routeGUID).To(Equal("my-route-guid-2"))
   320  				Expect(appGUID).To(Equal("my-app-guid"))
   321  
   322  				Expect(fakeUI.SayCallCount()).To(Equal(2))
   323  
   324  				message, _ := fakeUI.SayArgsForCall(0)
   325  				Expect(message).To(ContainSubstring("Removing route"))
   326  
   327  				message, _ = fakeUI.SayArgsForCall(1)
   328  				Expect(message).To(ContainSubstring("Removing route"))
   329  			})
   330  		})
   331  	})
   332  
   333  	Describe("FindDomain", func() {
   334  		var (
   335  			routeName           string
   336  			hostname            string
   337  			domain              models.DomainFields
   338  			findDomainErr       error
   339  			domainNotFoundError error
   340  		)
   341  
   342  		BeforeEach(func() {
   343  			routeName = "my-hostname.my-domain.com"
   344  			domainNotFoundError = cferrors.NewModelNotFoundError("Domain", routeName)
   345  		})
   346  
   347  		JustBeforeEach(func() {
   348  			hostname, domain, findDomainErr = routeActor.FindDomain(routeName)
   349  		})
   350  		Context("when the route belongs to a private domain", func() {
   351  			Context("and do not have a hostname", func() {
   352  				var privateDomain models.DomainFields
   353  
   354  				BeforeEach(func() {
   355  					routeName = "my-domain.com"
   356  					privateDomain = models.DomainFields{
   357  						GUID: "private-domain-guid",
   358  					}
   359  					fakeDomainRepository.FindPrivateByNameReturns(privateDomain, nil)
   360  				})
   361  
   362  				It("returns the private domain", func() {
   363  					Expect(findDomainErr).NotTo(HaveOccurred())
   364  					Expect(fakeDomainRepository.FindPrivateByNameCallCount()).To(Equal(1))
   365  					Expect(fakeDomainRepository.FindPrivateByNameArgsForCall(0)).To(Equal("my-domain.com"))
   366  					Expect(hostname).To(Equal(""))
   367  					Expect(domain).To(Equal(privateDomain))
   368  				})
   369  			})
   370  
   371  			Context("and have a hostname", func() {
   372  				var privateDomain models.DomainFields
   373  
   374  				BeforeEach(func() {
   375  					routeName = "my-hostname.my-domain.com"
   376  					privateDomain = models.DomainFields{
   377  						GUID: "private-domain-guid",
   378  					}
   379  					fakeDomainRepository.FindPrivateByNameStub = func(name string) (models.DomainFields, error) {
   380  						if name == "my-domain.com" {
   381  							return privateDomain, nil
   382  						}
   383  						return models.DomainFields{}, domainNotFoundError
   384  					}
   385  				})
   386  
   387  				It("returns the private domain", func() {
   388  					Expect(findDomainErr).NotTo(HaveOccurred())
   389  					Expect(fakeDomainRepository.FindPrivateByNameCallCount()).To(Equal(2))
   390  					Expect(fakeDomainRepository.FindPrivateByNameArgsForCall(0)).To(Equal("my-hostname.my-domain.com"))
   391  					Expect(hostname).To(Equal("my-hostname"))
   392  					Expect(domain).To(Equal(privateDomain))
   393  				})
   394  			})
   395  		})
   396  		Context("when the route belongs to a shared domain", func() {
   397  			var (
   398  				sharedDomain models.DomainFields
   399  			)
   400  
   401  			BeforeEach(func() {
   402  				sharedDomain = models.DomainFields{
   403  					GUID: "shared-domain-guid",
   404  				}
   405  				fakeDomainRepository.FindPrivateByNameStub = func(name string) (models.DomainFields, error) {
   406  					return models.DomainFields{}, domainNotFoundError
   407  				}
   408  			})
   409  
   410  			Context("when the route has no hostname", func() {
   411  				BeforeEach(func() {
   412  					fakeDomainRepository.FindSharedByNameStub = func(name string) (models.DomainFields, error) {
   413  						if name == "my-hostname.my-domain.com" {
   414  							return sharedDomain, nil
   415  						}
   416  						return models.DomainFields{}, domainNotFoundError
   417  					}
   418  				})
   419  
   420  				It("returns the shared domain", func() {
   421  					Expect(findDomainErr).NotTo(HaveOccurred())
   422  					Expect(fakeDomainRepository.FindPrivateByNameCallCount()).To(Equal(2))
   423  					Expect(fakeDomainRepository.FindSharedByNameCallCount()).To(Equal(1))
   424  					Expect(fakeDomainRepository.FindSharedByNameArgsForCall(0)).To(Equal("my-hostname.my-domain.com"))
   425  					Expect(hostname).To(Equal(""))
   426  					Expect(domain).To(Equal(sharedDomain))
   427  				})
   428  			})
   429  
   430  			Context("when the route has a hostname", func() {
   431  				BeforeEach(func() {
   432  					fakeDomainRepository.FindSharedByNameStub = func(name string) (models.DomainFields, error) {
   433  						if name == "my-domain.com" {
   434  							return sharedDomain, nil
   435  						}
   436  						return models.DomainFields{}, domainNotFoundError
   437  					}
   438  				})
   439  
   440  				It("returns the shared domain and hostname", func() {
   441  					Expect(findDomainErr).NotTo(HaveOccurred())
   442  					Expect(fakeDomainRepository.FindPrivateByNameCallCount()).To(Equal(2))
   443  					Expect(fakeDomainRepository.FindSharedByNameCallCount()).To(Equal(2))
   444  					Expect(fakeDomainRepository.FindSharedByNameArgsForCall(0)).To(Equal("my-hostname.my-domain.com"))
   445  					Expect(fakeDomainRepository.FindSharedByNameArgsForCall(1)).To(Equal("my-domain.com"))
   446  					Expect(hostname).To(Equal("my-hostname"))
   447  					Expect(domain).To(Equal(sharedDomain))
   448  				})
   449  			})
   450  		})
   451  
   452  		Context("when the route does not belong to any existing domains", func() {
   453  			BeforeEach(func() {
   454  				routeName = "non-existant-domain.com"
   455  				fakeDomainRepository.FindPrivateByNameReturns(models.DomainFields{}, domainNotFoundError)
   456  				fakeDomainRepository.FindSharedByNameReturns(models.DomainFields{}, domainNotFoundError)
   457  			})
   458  
   459  			It("returns an error", func() {
   460  				Expect(findDomainErr).To(HaveOccurred())
   461  				Expect(findDomainErr.Error()).To(Equal("The route non-existant-domain.com did not match any existing domains."))
   462  			})
   463  		})
   464  	})
   465  
   466  	Describe("FindPath", func() {
   467  		Context("when there is a path", func() {
   468  			It("returns the route without path and the path", func() {
   469  				routeName := "host.domain/long/path"
   470  				route, path := routeActor.FindPath(routeName)
   471  				Expect(route).To(Equal("host.domain"))
   472  				Expect(path).To(Equal("long/path"))
   473  			})
   474  		})
   475  
   476  		Context("when there is no path", func() {
   477  			It("returns the route path and the empty string", func() {
   478  				routeName := "host.domain"
   479  				route, path := routeActor.FindPath(routeName)
   480  				Expect(route).To(Equal("host.domain"))
   481  				Expect(path).To(Equal(""))
   482  			})
   483  		})
   484  	})
   485  
   486  	Describe("FindPort", func() {
   487  		Context("when there is a port", func() {
   488  			It("returns the route without port and the port", func() {
   489  				routeName := "host.domain:12345"
   490  				route, port, err := routeActor.FindPort(routeName)
   491  				Expect(route).To(Equal("host.domain"))
   492  				Expect(port).To(Equal(12345))
   493  				Expect(err).NotTo(HaveOccurred())
   494  			})
   495  		})
   496  
   497  		Context("when there is no port", func() {
   498  			It("returns the route port and invalid port", func() {
   499  				routeName := "host.domain"
   500  				route, port, err := routeActor.FindPort(routeName)
   501  				Expect(route).To(Equal("host.domain"))
   502  				Expect(port).To(Equal(0))
   503  				Expect(err).NotTo(HaveOccurred())
   504  			})
   505  		})
   506  
   507  		Context("when there is an invalid port", func() {
   508  			It("returns an error", func() {
   509  				routeName := "host.domain:thisisnotaport"
   510  				_, _, err := routeActor.FindPort(routeName)
   511  				Expect(err).To(HaveOccurred())
   512  			})
   513  		})
   514  	})
   515  
   516  	Describe("FindAndBindRoute", func() {
   517  		var (
   518  			routeName            string
   519  			findAndBindRouteErr  error
   520  			appParamsFromContext models.AppParams
   521  		)
   522  
   523  		BeforeEach(func() {
   524  			appParamsFromContext = models.AppParams{}
   525  		})
   526  
   527  		JustBeforeEach(func() {
   528  			appName := "app-name"
   529  			findAndBindRouteErr = routeActor.FindAndBindRoute(
   530  				routeName,
   531  				models.Application{
   532  					ApplicationFields: models.ApplicationFields{
   533  						Name: appName,
   534  						GUID: "app-guid",
   535  					},
   536  				},
   537  				appParamsFromContext,
   538  			)
   539  		})
   540  
   541  		Context("when the route is a HTTP route", func() {
   542  			var httpDomain models.DomainFields
   543  
   544  			BeforeEach(func() {
   545  				httpDomain = models.DomainFields{
   546  					Name: "domain.com",
   547  					GUID: "domain-guid",
   548  				}
   549  				domainNotFoundError := cferrors.NewModelNotFoundError("Domain", "some-domain.com")
   550  
   551  				fakeDomainRepository.FindPrivateByNameReturns(models.DomainFields{}, domainNotFoundError)
   552  				fakeDomainRepository.FindSharedByNameStub = func(name string) (models.DomainFields, error) {
   553  					if name == "domain.com" {
   554  						return httpDomain, nil
   555  					}
   556  					return models.DomainFields{}, domainNotFoundError
   557  				}
   558  			})
   559  
   560  			Context("contains a port", func() {
   561  				BeforeEach(func() {
   562  					routeName = "domain.com:3333"
   563  				})
   564  
   565  				It("should return an error", func() {
   566  					Expect(findAndBindRouteErr).To(HaveOccurred())
   567  					Expect(findAndBindRouteErr.Error()).To(Equal("Port not allowed in HTTP route domain.com"))
   568  				})
   569  			})
   570  
   571  			Context("does not contain a port", func() {
   572  				BeforeEach(func() {
   573  					routeName = "host.domain.com"
   574  
   575  					fakeRouteRepository.FindReturns(models.Route{}, cferrors.NewModelNotFoundError("Route", "some-route"))
   576  					fakeRouteRepository.CreateReturns(
   577  						models.Route{
   578  							GUID:   "route-guid",
   579  							Domain: httpDomain,
   580  							Path:   "path",
   581  						},
   582  						nil,
   583  					)
   584  					fakeRouteRepository.BindReturns(nil)
   585  				})
   586  
   587  				It("creates and binds the route", func() {
   588  					Expect(findAndBindRouteErr).NotTo(HaveOccurred())
   589  
   590  					actualDomainName := fakeDomainRepository.FindSharedByNameArgsForCall(1)
   591  					Expect(actualDomainName).To(Equal("domain.com"))
   592  
   593  					actualHost, actualDomain, actualPath, actualPort := fakeRouteRepository.FindArgsForCall(0)
   594  					Expect(actualHost).To(Equal("host"))
   595  					Expect(actualDomain).To(Equal(httpDomain))
   596  					Expect(actualPath).To(Equal(""))
   597  					Expect(actualPort).To(Equal(0))
   598  
   599  					actualHost, actualDomain, actualPath, actualPort, actualUseRandomPort := fakeRouteRepository.CreateArgsForCall(0)
   600  					Expect(actualHost).To(Equal("host"))
   601  					Expect(actualDomain).To(Equal(httpDomain))
   602  					Expect(actualPath).To(Equal(""))
   603  					Expect(actualPort).To(Equal(0))
   604  					Expect(actualUseRandomPort).To(BeFalse())
   605  
   606  					routeGUID, appGUID := fakeRouteRepository.BindArgsForCall(0)
   607  					Expect(routeGUID).To(Equal("route-guid"))
   608  					Expect(appGUID).To(Equal("app-guid"))
   609  				})
   610  
   611  				Context("contains a path", func() {
   612  					BeforeEach(func() {
   613  						routeName = "host.domain.com/path"
   614  					})
   615  
   616  					It("creates and binds the route", func() {
   617  						Expect(findAndBindRouteErr).NotTo(HaveOccurred())
   618  
   619  						actualDomainName := fakeDomainRepository.FindSharedByNameArgsForCall(1)
   620  						Expect(actualDomainName).To(Equal("domain.com"))
   621  
   622  						actualHost, actualDomain, actualPath, actualPort := fakeRouteRepository.FindArgsForCall(0)
   623  						Expect(actualHost).To(Equal("host"))
   624  						Expect(actualDomain).To(Equal(httpDomain))
   625  						Expect(actualPath).To(Equal("path"))
   626  						Expect(actualPort).To(Equal(0))
   627  
   628  						actualHost, actualDomain, actualPath, actualPort, actualUseRandomPort := fakeRouteRepository.CreateArgsForCall(0)
   629  						Expect(actualHost).To(Equal("host"))
   630  						Expect(actualDomain).To(Equal(httpDomain))
   631  						Expect(actualPath).To(Equal("path"))
   632  						Expect(actualPort).To(Equal(0))
   633  						Expect(actualUseRandomPort).To(BeFalse())
   634  
   635  						routeGUID, appGUID := fakeRouteRepository.BindArgsForCall(0)
   636  						Expect(routeGUID).To(Equal("route-guid"))
   637  						Expect(appGUID).To(Equal("app-guid"))
   638  					})
   639  				})
   640  			})
   641  
   642  			Context("the --hostname flag is provided", func() {
   643  				BeforeEach(func() {
   644  					appParamsFromContext = models.AppParams{
   645  						Hosts: []string{"flag-hostname"},
   646  					}
   647  				})
   648  
   649  				Context("the route contains a hostname", func() {
   650  					BeforeEach(func() {
   651  						routeName = "host.domain.com/path"
   652  					})
   653  
   654  					It("should replace only the hostname", func() {
   655  						Expect(findAndBindRouteErr).NotTo(HaveOccurred())
   656  
   657  						actualHost, actualDomain, actualPath, actualPort := fakeRouteRepository.FindArgsForCall(0)
   658  						Expect(actualHost).To(Equal("flag-hostname"))
   659  						Expect(actualDomain).To(Equal(httpDomain))
   660  						Expect(actualPath).To(Equal("path"))
   661  						Expect(actualPort).To(Equal(0))
   662  					})
   663  				})
   664  
   665  				Context("the route does not contain a hostname", func() {
   666  					BeforeEach(func() {
   667  						routeName = "domain.com"
   668  					})
   669  
   670  					It("should set only the hostname", func() {
   671  						Expect(findAndBindRouteErr).NotTo(HaveOccurred())
   672  
   673  						actualHost, actualDomain, actualPath, actualPort := fakeRouteRepository.FindArgsForCall(0)
   674  						Expect(actualHost).To(Equal("flag-hostname"))
   675  						Expect(actualDomain).To(Equal(httpDomain))
   676  						Expect(actualPath).To(Equal(""))
   677  						Expect(actualPort).To(Equal(0))
   678  					})
   679  				})
   680  			})
   681  		})
   682  
   683  		Context("when -d domains is set", func() {
   684  			BeforeEach(func() {
   685  				appParamsFromContext = models.AppParams{
   686  					Domains: []string{"shared-domain.com"},
   687  				}
   688  			})
   689  
   690  			Context("it is a http shared domain", func() {
   691  				BeforeEach(func() {
   692  					httpDomain := models.DomainFields{
   693  						Name:            "shared-domain.com",
   694  						GUID:            "shared-domain-guid",
   695  						RouterGroupType: "",
   696  						Shared:          true,
   697  					}
   698  					domainNotFoundError := cferrors.NewModelNotFoundError("Domain", "some-domain.com")
   699  
   700  					fakeDomainRepository.FindPrivateByNameReturns(models.DomainFields{}, domainNotFoundError)
   701  					fakeDomainRepository.FindSharedByNameStub = func(name string) (models.DomainFields, error) {
   702  						if name == "shared-domain.com" {
   703  							return httpDomain, nil
   704  						}
   705  						return models.DomainFields{}, domainNotFoundError
   706  					}
   707  
   708  					fakeRouteRepository.FindReturns(models.Route{}, cferrors.NewModelNotFoundError("", ""))
   709  				})
   710  
   711  				Context("when the hostname is present in the original route", func() {
   712  					BeforeEach(func() {
   713  						routeName = "hostname.old-domain.com/path"
   714  					})
   715  
   716  					It("replace the domain from manifest", func() {
   717  						Expect(findAndBindRouteErr).NotTo(HaveOccurred())
   718  
   719  						Expect(fakeRouteRepository.FindCallCount()).To(Equal(1))
   720  
   721  						Expect(fakeRouteRepository.CreateCallCount()).To(Equal(1))
   722  						actualHost, actualDomain, actualPath, actualPort, actualUseRandomPort := fakeRouteRepository.CreateArgsForCall(0)
   723  						Expect(actualHost).To(Equal("hostname"))
   724  						Expect(actualDomain.Name).To(Equal("shared-domain.com"))
   725  						Expect(actualPath).To(Equal("path"))
   726  						Expect(actualPort).To(Equal(0))
   727  						Expect(actualUseRandomPort).To(BeFalse())
   728  					})
   729  				})
   730  
   731  				Context("when the hostname is provided as a flag", func() {
   732  					BeforeEach(func() {
   733  						routeName = "old-domain.com/path"
   734  						appParamsFromContext = models.AppParams{
   735  							Domains: []string{"shared-domain.com"},
   736  							Hosts:   []string{"hostname"},
   737  						}
   738  					})
   739  
   740  					It("replace the domain from manifest", func() {
   741  						Expect(findAndBindRouteErr).NotTo(HaveOccurred())
   742  
   743  						Expect(fakeRouteRepository.FindCallCount()).To(Equal(1))
   744  
   745  						Expect(fakeRouteRepository.CreateCallCount()).To(Equal(1))
   746  						actualHost, actualDomain, actualPath, actualPort, actualUseRandomPort := fakeRouteRepository.CreateArgsForCall(0)
   747  						Expect(actualHost).To(Equal("hostname"))
   748  						Expect(actualDomain.Name).To(Equal("shared-domain.com"))
   749  						Expect(actualPath).To(Equal("path"))
   750  						Expect(actualPort).To(Equal(0))
   751  						Expect(actualUseRandomPort).To(BeFalse())
   752  					})
   753  				})
   754  
   755  				Context("when the path is provided as a flag", func() {
   756  					BeforeEach(func() {
   757  						routeName = "hostname.old-domain.com/oldpath"
   758  						path := "path"
   759  						appParamsFromContext = models.AppParams{
   760  							Domains:   []string{"shared-domain.com"},
   761  							RoutePath: &path,
   762  						}
   763  					})
   764  
   765  					It("replace the domain and path from manifest", func() {
   766  						Expect(findAndBindRouteErr).NotTo(HaveOccurred())
   767  
   768  						Expect(fakeRouteRepository.FindCallCount()).To(Equal(1))
   769  
   770  						Expect(fakeRouteRepository.CreateCallCount()).To(Equal(1))
   771  						actualHost, actualDomain, actualPath, actualPort, actualUseRandomPort := fakeRouteRepository.CreateArgsForCall(0)
   772  						Expect(actualHost).To(Equal("hostname"))
   773  						Expect(actualDomain.Name).To(Equal("shared-domain.com"))
   774  						Expect(actualPath).To(Equal("path"))
   775  						Expect(actualPort).To(Equal(0))
   776  						Expect(actualUseRandomPort).To(BeFalse())
   777  					})
   778  				})
   779  			})
   780  
   781  			Context("when it is a private domain", func() {
   782  				BeforeEach(func() {
   783  					httpDomain := models.DomainFields{
   784  						Name:            "private-domain.com",
   785  						GUID:            "private-domain-guid",
   786  						RouterGroupType: "",
   787  					}
   788  
   789  					fakeDomainRepository.FindPrivateByNameReturns(httpDomain, nil)
   790  
   791  					fakeRouteRepository.FindReturns(models.Route{}, cferrors.NewModelNotFoundError("", ""))
   792  					routeName = "hostname.old-domain.com/path"
   793  					appParamsFromContext = models.AppParams{
   794  						Domains: []string{"private-domain.com"},
   795  					}
   796  				})
   797  
   798  				It("replace the domain from manifest", func() {
   799  					Expect(findAndBindRouteErr).NotTo(HaveOccurred())
   800  
   801  					Expect(fakeRouteRepository.FindCallCount()).To(Equal(1))
   802  
   803  					Expect(fakeRouteRepository.CreateCallCount()).To(Equal(1))
   804  					actualHost, actualDomain, actualPath, actualPort, actualUseRandomPort := fakeRouteRepository.CreateArgsForCall(0)
   805  					Expect(actualHost).To(BeEmpty())
   806  					Expect(actualDomain.Name).To(Equal("private-domain.com"))
   807  					Expect(actualPath).To(Equal("path"))
   808  					Expect(actualPort).To(BeZero())
   809  					Expect(actualUseRandomPort).To(BeFalse())
   810  				})
   811  			})
   812  		})
   813  
   814  		Context("the --random-route flag is provided", func() {
   815  			BeforeEach(func() {
   816  				appParamsFromContext = models.AppParams{
   817  					UseRandomRoute: true,
   818  				}
   819  
   820  				fakeRouteRepository.FindReturns(models.Route{}, cferrors.NewModelNotFoundError("Route", "tcp-domain.com:3333"))
   821  			})
   822  
   823  			Context("it is a http route", func() {
   824  				var httpDomain models.DomainFields
   825  
   826  				BeforeEach(func() {
   827  					httpDomain = models.DomainFields{
   828  						Name: "domain.com",
   829  						GUID: "domain-guid",
   830  					}
   831  					domainNotFoundError := cferrors.NewModelNotFoundError("Domain", "some-domain.com")
   832  
   833  					fakeDomainRepository.FindPrivateByNameReturns(models.DomainFields{}, domainNotFoundError)
   834  					fakeDomainRepository.FindSharedByNameStub = func(name string) (models.DomainFields, error) {
   835  						if name == "domain.com" {
   836  							return httpDomain, nil
   837  						}
   838  						return models.DomainFields{}, domainNotFoundError
   839  					}
   840  				})
   841  
   842  				Context("the route does not have a hostname", func() {
   843  					BeforeEach(func() {
   844  						routeName = "domain.com/path"
   845  					})
   846  					It("should append a random name ", func() {
   847  						Expect(findAndBindRouteErr).NotTo(HaveOccurred())
   848  
   849  						actualHost, actualDomain, actualPath, actualPort := fakeRouteRepository.FindArgsForCall(0)
   850  						Expect(actualHost).To(MatchRegexp("[a-z]-[a-z]"))
   851  						Expect(actualDomain.Name).To(Equal("domain.com"))
   852  						Expect(actualPath).To(Equal("path"))
   853  						Expect(actualPort).To(Equal(0))
   854  						actualHost, actualDomain, actualPath, actualPort, useRandomPort := fakeRouteRepository.CreateArgsForCall(0)
   855  						Expect(actualHost).To(MatchRegexp("[a-z]-[a-z]"))
   856  						Expect(actualDomain.Name).To(Equal("domain.com"))
   857  						Expect(actualPath).To(Equal("path"))
   858  						Expect(actualPort).To(Equal(0))
   859  						Expect(useRandomPort).To(BeFalse())
   860  					})
   861  				})
   862  
   863  				Context("the route has a hostname", func() {
   864  					BeforeEach(func() {
   865  						routeName = "host.domain.com/path"
   866  					})
   867  					It("should replace the hostname with a random name", func() {
   868  						Expect(findAndBindRouteErr).NotTo(HaveOccurred())
   869  
   870  						actualHost, actualDomain, actualPath, actualPort := fakeRouteRepository.FindArgsForCall(0)
   871  						Expect(actualHost).To(MatchRegexp("[a-z]-[a-z]"))
   872  						Expect(actualDomain.Name).To(Equal("domain.com"))
   873  						Expect(actualPath).To(Equal("path"))
   874  						Expect(actualPort).To(Equal(0))
   875  					})
   876  				})
   877  
   878  				Context("when --hostname flag is present", func() {
   879  					BeforeEach(func() {
   880  						appParamsFromContext = models.AppParams{
   881  							UseRandomRoute: true,
   882  							Hosts:          []string{"flag-hostname"},
   883  						}
   884  						routeName = "host.domain.com/path"
   885  
   886  					})
   887  
   888  					It("should replace the hostname with flag hostname", func() {
   889  						Expect(findAndBindRouteErr).NotTo(HaveOccurred())
   890  
   891  						actualHost, actualDomain, actualPath, actualPort := fakeRouteRepository.FindArgsForCall(0)
   892  						Expect(actualHost).To(Equal("flag-hostname"))
   893  						Expect(actualDomain.Name).To(Equal("domain.com"))
   894  						Expect(actualPath).To(Equal("path"))
   895  						Expect(actualPort).To(Equal(0))
   896  					})
   897  				})
   898  			})
   899  
   900  			Context("it is a tcp route", func() {
   901  				var tcpDomain models.DomainFields
   902  
   903  				BeforeEach(func() {
   904  					tcpDomain = models.DomainFields{
   905  						Name:            "tcp-domain.com",
   906  						GUID:            "tcp-domain-guid",
   907  						RouterGroupGUID: "tcp-guid",
   908  						RouterGroupType: "tcp",
   909  					}
   910  					domainNotFoundError := cferrors.NewModelNotFoundError("Domain", "some-domain.com")
   911  
   912  					fakeDomainRepository.FindPrivateByNameReturns(models.DomainFields{}, domainNotFoundError)
   913  					fakeDomainRepository.FindSharedByNameStub = func(name string) (models.DomainFields, error) {
   914  						if name == "tcp-domain.com" {
   915  							return tcpDomain, nil
   916  						}
   917  						return models.DomainFields{}, domainNotFoundError
   918  					}
   919  					routeName = "tcp-domain.com:3333"
   920  				})
   921  
   922  				It("replaces the provided port with a random port", func() {
   923  					Expect(findAndBindRouteErr).NotTo(HaveOccurred())
   924  					Expect(fakeRouteRepository.FindCallCount()).To(Equal(0))
   925  
   926  					actualHost, actualDomain, actualPath, actualPort, useRandomPort := fakeRouteRepository.CreateArgsForCall(0)
   927  					Expect(actualHost).To(Equal(""))
   928  					Expect(actualDomain.Name).To(Equal("tcp-domain.com"))
   929  					Expect(actualPath).To(Equal(""))
   930  					Expect(actualPort).To(Equal(0))
   931  					Expect(useRandomPort).To(Equal(true))
   932  				})
   933  			})
   934  		})
   935  
   936  		Context("the --route-path flag is provided", func() {
   937  			BeforeEach(func() {
   938  				path := "flag-routepath"
   939  				appParamsFromContext = models.AppParams{
   940  					RoutePath: &path,
   941  				}
   942  			})
   943  
   944  			Context("it is a http route", func() {
   945  				var httpDomain models.DomainFields
   946  
   947  				BeforeEach(func() {
   948  					httpDomain = models.DomainFields{
   949  						Name: "domain.com",
   950  						GUID: "domain-guid",
   951  					}
   952  					domainNotFoundError := cferrors.NewModelNotFoundError("Domain", "some-domain.com")
   953  
   954  					fakeDomainRepository.FindPrivateByNameReturns(models.DomainFields{}, domainNotFoundError)
   955  					fakeDomainRepository.FindSharedByNameStub = func(name string) (models.DomainFields, error) {
   956  						if name == "domain.com" {
   957  							return httpDomain, nil
   958  						}
   959  						return models.DomainFields{}, domainNotFoundError
   960  					}
   961  				})
   962  
   963  				Context("it does not have a path", func() {
   964  					BeforeEach(func() {
   965  						routeName = "host.domain.com"
   966  					})
   967  
   968  					It("adds the path to the route", func() {
   969  						Expect(findAndBindRouteErr).NotTo(HaveOccurred())
   970  
   971  						actualHost, actualDomain, actualPath, actualPort := fakeRouteRepository.FindArgsForCall(0)
   972  						Expect(actualHost).To(Equal("host"))
   973  						Expect(actualDomain.Name).To(Equal("domain.com"))
   974  						Expect(actualPath).To(Equal("flag-routepath"))
   975  						Expect(actualPort).To(Equal(0))
   976  					})
   977  				})
   978  
   979  				Context("a path is already specified on the route", func() {
   980  					BeforeEach(func() {
   981  						routeName = "host.domain.com/path"
   982  					})
   983  
   984  					It("replaces the path on the route", func() {
   985  						Expect(findAndBindRouteErr).NotTo(HaveOccurred())
   986  
   987  						actualHost, actualDomain, actualPath, actualPort := fakeRouteRepository.FindArgsForCall(0)
   988  						Expect(actualHost).To(Equal("host"))
   989  						Expect(actualDomain.Name).To(Equal("domain.com"))
   990  						Expect(actualPath).To(Equal("flag-routepath"))
   991  						Expect(actualPort).To(Equal(0))
   992  					})
   993  				})
   994  			})
   995  
   996  			Context("it is a tcp route", func() {
   997  				var tcpDomain models.DomainFields
   998  
   999  				BeforeEach(func() {
  1000  					tcpDomain = models.DomainFields{
  1001  						Name:            "tcp-domain.com",
  1002  						GUID:            "tcp-domain-guid",
  1003  						RouterGroupGUID: "tcp-guid",
  1004  						RouterGroupType: "tcp",
  1005  					}
  1006  					domainNotFoundError := cferrors.NewModelNotFoundError("Domain", "some-domain.com")
  1007  
  1008  					fakeDomainRepository.FindPrivateByNameReturns(models.DomainFields{}, domainNotFoundError)
  1009  					fakeDomainRepository.FindSharedByNameStub = func(name string) (models.DomainFields, error) {
  1010  						if name == "tcp-domain.com" {
  1011  							return tcpDomain, nil
  1012  						}
  1013  						return models.DomainFields{}, domainNotFoundError
  1014  					}
  1015  					routeName = "tcp-domain.com:3333"
  1016  				})
  1017  
  1018  				It("does not use the flag", func() {
  1019  					Expect(findAndBindRouteErr).NotTo(HaveOccurred())
  1020  
  1021  					actualHost, actualDomain, actualPath, actualPort := fakeRouteRepository.FindArgsForCall(0)
  1022  					Expect(actualHost).To(Equal(""))
  1023  					Expect(actualDomain.Name).To(Equal("tcp-domain.com"))
  1024  					Expect(actualPath).To(Equal(""))
  1025  					Expect(actualPort).To(Equal(3333))
  1026  				})
  1027  			})
  1028  		})
  1029  
  1030  		Context("when the route is a TCP route", func() {
  1031  			var tcpDomain models.DomainFields
  1032  
  1033  			BeforeEach(func() {
  1034  				tcpDomain = models.DomainFields{
  1035  					Name:            "tcp-domain.com",
  1036  					GUID:            "tcp-domain-guid",
  1037  					RouterGroupGUID: "tcp-guid",
  1038  					RouterGroupType: "tcp",
  1039  				}
  1040  				domainNotFoundError := cferrors.NewModelNotFoundError("Domain", "some-domain.com")
  1041  
  1042  				fakeDomainRepository.FindPrivateByNameReturns(models.DomainFields{}, domainNotFoundError)
  1043  				fakeDomainRepository.FindSharedByNameStub = func(name string) (models.DomainFields, error) {
  1044  					if name == "tcp-domain.com" {
  1045  						return tcpDomain, nil
  1046  					}
  1047  					return models.DomainFields{}, domainNotFoundError
  1048  				}
  1049  			})
  1050  
  1051  			Context("contains a path", func() {
  1052  				BeforeEach(func() {
  1053  					routeName = "tcp-domain.com:3333/path"
  1054  				})
  1055  
  1056  				It("returns an error", func() {
  1057  					Expect(findAndBindRouteErr).To(HaveOccurred())
  1058  					Expect(findAndBindRouteErr.Error()).To(Equal("Path not allowed in TCP route tcp-domain.com"))
  1059  				})
  1060  			})
  1061  
  1062  			Context("does not contain a path", func() {
  1063  				BeforeEach(func() {
  1064  					routeName = "tcp-domain.com:3333"
  1065  
  1066  					fakeRouteRepository.FindReturns(models.Route{}, cferrors.NewModelNotFoundError("Route", "some-route"))
  1067  					fakeRouteRepository.CreateReturns(
  1068  						models.Route{
  1069  							GUID:   "route-guid",
  1070  							Domain: tcpDomain,
  1071  							Path:   "path",
  1072  						},
  1073  						nil,
  1074  					)
  1075  					fakeRouteRepository.BindReturns(nil)
  1076  				})
  1077  
  1078  				It("creates and binds the route", func() {
  1079  					Expect(findAndBindRouteErr).NotTo(HaveOccurred())
  1080  
  1081  					actualDomainName := fakeDomainRepository.FindSharedByNameArgsForCall(0)
  1082  					Expect(actualDomainName).To(Equal("tcp-domain.com"))
  1083  
  1084  					actualHost, actualDomain, actualPath, actualPort := fakeRouteRepository.FindArgsForCall(0)
  1085  					Expect(actualHost).To(Equal(""))
  1086  					Expect(actualDomain).To(Equal(tcpDomain))
  1087  					Expect(actualPath).To(Equal(""))
  1088  					Expect(actualPort).To(Equal(3333))
  1089  
  1090  					actualHost, actualDomain, actualPath, actualPort, actualUseRandomPort := fakeRouteRepository.CreateArgsForCall(0)
  1091  					Expect(actualHost).To(Equal(""))
  1092  					Expect(actualDomain).To(Equal(tcpDomain))
  1093  					Expect(actualPath).To(Equal(""))
  1094  					Expect(actualPort).To(Equal(3333))
  1095  					Expect(actualUseRandomPort).To(BeFalse())
  1096  
  1097  					routeGUID, appGUID := fakeRouteRepository.BindArgsForCall(0)
  1098  					Expect(routeGUID).To(Equal("route-guid"))
  1099  					Expect(appGUID).To(Equal("app-guid"))
  1100  				})
  1101  			})
  1102  
  1103  			Context("the --hostname flag is provided", func() {
  1104  				BeforeEach(func() {
  1105  					routeName = "tcp-domain.com:3333"
  1106  					appParamsFromContext = models.AppParams{
  1107  						Hosts: []string{"flag-hostname"},
  1108  					}
  1109  				})
  1110  
  1111  				It("should not change the route", func() {
  1112  					Expect(findAndBindRouteErr).NotTo(HaveOccurred())
  1113  
  1114  					actualHost, actualDomain, actualPath, actualPort := fakeRouteRepository.FindArgsForCall(0)
  1115  					Expect(actualHost).To(Equal(""))
  1116  					Expect(actualDomain).To(Equal(tcpDomain))
  1117  					Expect(actualPath).To(Equal(""))
  1118  					Expect(actualPort).To(Equal(3333))
  1119  				})
  1120  			})
  1121  		})
  1122  	})
  1123  })