github.com/cloudfoundry-attic/cli-with-i18n@v6.32.1-0.20171002233121-7401370d3b85+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  
    12  	. "github.com/onsi/ginkgo"
    13  	. "github.com/onsi/gomega"
    14  )
    15  
    16  var _ = Describe("Routes", func() {
    17  	var (
    18  		actor       *Actor
    19  		fakeV2Actor *pushactionfakes.FakeV2Actor
    20  	)
    21  
    22  	BeforeEach(func() {
    23  		fakeV2Actor = new(pushactionfakes.FakeV2Actor)
    24  		actor = NewActor(fakeV2Actor, nil)
    25  	})
    26  
    27  	Describe("BindRoutes", func() {
    28  		var (
    29  			config ApplicationConfig
    30  
    31  			returnedConfig ApplicationConfig
    32  			boundRoutes    bool
    33  			warnings       Warnings
    34  			executeErr     error
    35  		)
    36  
    37  		BeforeEach(func() {
    38  			config = ApplicationConfig{
    39  				DesiredApplication: Application{
    40  					Application: v2action.Application{
    41  						GUID: "some-app-guid",
    42  					}},
    43  			}
    44  		})
    45  
    46  		JustBeforeEach(func() {
    47  			returnedConfig, boundRoutes, warnings, executeErr = actor.BindRoutes(config)
    48  		})
    49  
    50  		Context("when routes need to be bound to the application", func() {
    51  			BeforeEach(func() {
    52  				config.CurrentRoutes = []v2action.Route{
    53  					{GUID: "some-route-guid-2", Host: "some-route-2"},
    54  				}
    55  				config.DesiredRoutes = []v2action.Route{
    56  					{GUID: "some-route-guid-1", Host: "some-route-1", Domain: v2action.Domain{Name: "some-domain.com"}},
    57  					{GUID: "some-route-guid-2", Host: "some-route-2"},
    58  					{GUID: "some-route-guid-3", Host: "some-route-3"},
    59  				}
    60  			})
    61  
    62  			Context("when the binding is successful", func() {
    63  				BeforeEach(func() {
    64  					fakeV2Actor.BindRouteToApplicationReturns(v2action.Warnings{"bind-route-warning"}, nil)
    65  				})
    66  
    67  				It("only creates the routes that do not exist", func() {
    68  					Expect(executeErr).ToNot(HaveOccurred())
    69  					Expect(warnings).To(ConsistOf("bind-route-warning", "bind-route-warning"))
    70  					Expect(boundRoutes).To(BeTrue())
    71  
    72  					Expect(returnedConfig.CurrentRoutes).To(Equal(config.DesiredRoutes))
    73  
    74  					Expect(fakeV2Actor.BindRouteToApplicationCallCount()).To(Equal(2))
    75  
    76  					routeGUID, appGUID := fakeV2Actor.BindRouteToApplicationArgsForCall(0)
    77  					Expect(routeGUID).To(Equal("some-route-guid-1"))
    78  					Expect(appGUID).To(Equal("some-app-guid"))
    79  
    80  					routeGUID, appGUID = fakeV2Actor.BindRouteToApplicationArgsForCall(1)
    81  					Expect(routeGUID).To(Equal("some-route-guid-3"))
    82  					Expect(appGUID).To(Equal("some-app-guid"))
    83  				})
    84  			})
    85  
    86  			Context("when the binding errors", func() {
    87  				Context("when the route is bound in another space", func() {
    88  					BeforeEach(func() {
    89  						fakeV2Actor.BindRouteToApplicationReturns(v2action.Warnings{"bind-route-warning"}, v2action.RouteInDifferentSpaceError{})
    90  					})
    91  
    92  					It("sends the RouteInDifferentSpaceError (with a guid set) and warnings and returns true", func() {
    93  						Expect(executeErr).To(MatchError(v2action.RouteInDifferentSpaceError{Route: "some-route-1.some-domain.com"}))
    94  						Expect(warnings).To(ConsistOf("bind-route-warning"))
    95  					})
    96  				})
    97  
    98  				Context("generic error", func() {
    99  					var expectedErr error
   100  					BeforeEach(func() {
   101  						expectedErr = errors.New("oh my")
   102  						fakeV2Actor.BindRouteToApplicationReturns(v2action.Warnings{"bind-route-warning"}, expectedErr)
   103  					})
   104  
   105  					It("sends the warnings and errors and returns true", func() {
   106  						Expect(executeErr).To(MatchError(expectedErr))
   107  						Expect(warnings).To(ConsistOf("bind-route-warning"))
   108  					})
   109  				})
   110  			})
   111  		})
   112  
   113  		Context("when no routes need to be bound", func() {
   114  			It("returns false", func() {
   115  				Expect(executeErr).ToNot(HaveOccurred())
   116  			})
   117  		})
   118  	})
   119  
   120  	Describe("CalculateRoutes", func() {
   121  		var (
   122  			routes         []string
   123  			orgGUID        string
   124  			spaceGUID      string
   125  			existingRoutes []v2action.Route
   126  
   127  			calculatedRoutes []v2action.Route
   128  			warnings         Warnings
   129  			executeErr       error
   130  		)
   131  
   132  		BeforeEach(func() {
   133  			routes = []string{
   134  				"a.com",
   135  				"b.a.com",
   136  				"c.b.a.com",
   137  				"d.c.b.a.com",
   138  				"a.com/some-path",
   139  			}
   140  			orgGUID = "some-org-guid"
   141  			spaceGUID = "some-space-guid"
   142  		})
   143  
   144  		JustBeforeEach(func() {
   145  			calculatedRoutes, warnings, executeErr = actor.CalculateRoutes(routes, orgGUID, spaceGUID, existingRoutes)
   146  		})
   147  
   148  		Context("when there are no known routes", func() {
   149  			BeforeEach(func() {
   150  				existingRoutes = []v2action.Route{{
   151  					GUID: "some-route-5",
   152  					Host: "banana",
   153  					Domain: v2action.Domain{
   154  						GUID: "domain-guid-1",
   155  						Name: "a.com",
   156  					},
   157  					SpaceGUID: spaceGUID,
   158  				}}
   159  			})
   160  
   161  			Context("when a route looking up the domains is succuessful", func() {
   162  				BeforeEach(func() {
   163  					fakeV2Actor.GetDomainsByNameAndOrganizationReturns([]v2action.Domain{
   164  						{GUID: "domain-guid-1", Name: "a.com"},
   165  						{GUID: "domain-guid-2", Name: "b.a.com"},
   166  					}, v2action.Warnings{"domain-warnings-1", "domains-warnings-2"}, nil)
   167  				})
   168  
   169  				Context("when the route existance check is successful", func() {
   170  					BeforeEach(func() {
   171  						fakeV2Actor.FindRouteBoundToSpaceWithSettingsReturns(v2action.Route{}, v2action.Warnings{"find-route-warning"}, v2action.RouteNotFoundError{})
   172  						fakeV2Actor.FindRouteBoundToSpaceWithSettingsReturnsOnCall(3, v2action.Route{
   173  							GUID: "route-guid-4",
   174  							Host: "d.c",
   175  							Domain: v2action.Domain{
   176  								GUID: "domain-guid-2",
   177  								Name: "b.a.com",
   178  							},
   179  							SpaceGUID: spaceGUID,
   180  						}, v2action.Warnings{"find-route-warning"}, nil)
   181  					})
   182  
   183  					It("returns new and existing routes", func() {
   184  						Expect(executeErr).NotTo(HaveOccurred())
   185  						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"))
   186  						Expect(calculatedRoutes).To(ConsistOf(
   187  							v2action.Route{
   188  								Domain: v2action.Domain{
   189  									GUID: "domain-guid-1",
   190  									Name: "a.com",
   191  								},
   192  								SpaceGUID: spaceGUID,
   193  							},
   194  							v2action.Route{
   195  								Domain: v2action.Domain{
   196  									GUID: "domain-guid-2",
   197  									Name: "b.a.com",
   198  								},
   199  								SpaceGUID: spaceGUID,
   200  							},
   201  							v2action.Route{
   202  								Host: "c",
   203  								Domain: v2action.Domain{
   204  									GUID: "domain-guid-2",
   205  									Name: "b.a.com",
   206  								},
   207  								SpaceGUID: spaceGUID,
   208  							},
   209  							v2action.Route{
   210  								GUID: "route-guid-4",
   211  								Host: "d.c",
   212  								Domain: v2action.Domain{
   213  									GUID: "domain-guid-2",
   214  									Name: "b.a.com",
   215  								},
   216  								SpaceGUID: spaceGUID,
   217  							},
   218  							v2action.Route{
   219  								GUID: "some-route-5",
   220  								Host: "banana",
   221  								Domain: v2action.Domain{
   222  									GUID: "domain-guid-1",
   223  									Name: "a.com",
   224  								},
   225  								SpaceGUID: spaceGUID,
   226  							},
   227  							v2action.Route{
   228  								Host: "",
   229  								Domain: v2action.Domain{
   230  									GUID: "domain-guid-1",
   231  									Name: "a.com",
   232  								},
   233  								Path:      "/some-path",
   234  								SpaceGUID: spaceGUID,
   235  							}))
   236  
   237  						Expect(fakeV2Actor.GetDomainsByNameAndOrganizationCallCount()).To(Equal(1))
   238  						domains, passedOrgGUID := fakeV2Actor.GetDomainsByNameAndOrganizationArgsForCall(0)
   239  						Expect(domains).To(ConsistOf("a.com", "b.a.com", "c.b.a.com", "d.c.b.a.com"))
   240  						Expect(passedOrgGUID).To(Equal(orgGUID))
   241  
   242  						Expect(fakeV2Actor.FindRouteBoundToSpaceWithSettingsCallCount()).To(Equal(5))
   243  						// One check is enough here - checking 4th call since it's the only
   244  						// existing one.
   245  						Expect(fakeV2Actor.FindRouteBoundToSpaceWithSettingsArgsForCall(3)).To(Equal(v2action.Route{
   246  							Host: "d.c",
   247  							Domain: v2action.Domain{
   248  								GUID: "domain-guid-2",
   249  								Name: "b.a.com",
   250  							},
   251  							SpaceGUID: spaceGUID,
   252  						}))
   253  					})
   254  				})
   255  
   256  				Context("when the route existance check fails", func() {
   257  					var expectedErr error
   258  
   259  					BeforeEach(func() {
   260  						expectedErr = errors.New("oh noes")
   261  						fakeV2Actor.FindRouteBoundToSpaceWithSettingsReturns(v2action.Route{}, v2action.Warnings{"find-route-warning"}, expectedErr)
   262  					})
   263  
   264  					It("returns back warnings and error", func() {
   265  						Expect(executeErr).To(MatchError(expectedErr))
   266  						Expect(warnings).To(ConsistOf("domain-warnings-1", "domains-warnings-2", "find-route-warning"))
   267  					})
   268  				})
   269  
   270  				Context("when one of the domains does not exist", func() {
   271  					BeforeEach(func() {
   272  						fakeV2Actor.GetDomainsByNameAndOrganizationReturns(nil, v2action.Warnings{"domain-warnings-1", "domains-warnings-2"}, nil)
   273  					})
   274  
   275  					It("returns back warnings and error", func() {
   276  						Expect(executeErr).To(MatchError(actionerror.NoMatchingDomainError{Route: "a.com"}))
   277  						Expect(warnings).To(ConsistOf("domain-warnings-1", "domains-warnings-2"))
   278  					})
   279  				})
   280  
   281  				Context("when TCP properties are being set on a HTTP domain", func() {
   282  					BeforeEach(func() {
   283  						routes = []string{"a.com", "b.a.com", "c.b.a.com:1234"}
   284  					})
   285  
   286  					It("returns back warnings and error", func() {
   287  						Expect(executeErr).To(MatchError(actionerror.InvalidHTTPRouteSettings{Domain: "b.a.com"}))
   288  						Expect(warnings).To(ConsistOf("domain-warnings-1", "domains-warnings-2"))
   289  					})
   290  				})
   291  			})
   292  
   293  			Context("when looking up a domain returns an error", func() {
   294  				var expectedErr error
   295  
   296  				BeforeEach(func() {
   297  					expectedErr = errors.New("po-tate-toe")
   298  					fakeV2Actor.GetDomainsByNameAndOrganizationReturns(nil, v2action.Warnings{"domain-warnings-1", "domains-warnings-2"}, expectedErr)
   299  				})
   300  
   301  				It("returns back warnings and error", func() {
   302  					Expect(executeErr).To(MatchError(expectedErr))
   303  					Expect(warnings).To(ConsistOf("domain-warnings-1", "domains-warnings-2"))
   304  				})
   305  			})
   306  		})
   307  
   308  		Context("when there are known routes", func() {
   309  			BeforeEach(func() {
   310  				existingRoutes = []v2action.Route{{
   311  					GUID: "route-guid-4",
   312  					Host: "d.c",
   313  					Domain: v2action.Domain{
   314  						GUID: "domain-guid-2",
   315  						Name: "b.a.com",
   316  					},
   317  					SpaceGUID: spaceGUID,
   318  				}}
   319  
   320  				fakeV2Actor.GetDomainsByNameAndOrganizationReturns([]v2action.Domain{
   321  					{GUID: "domain-guid-1", Name: "a.com"},
   322  					{GUID: "domain-guid-2", Name: "b.a.com"},
   323  				}, v2action.Warnings{"domain-warnings-1", "domains-warnings-2"}, nil)
   324  				fakeV2Actor.FindRouteBoundToSpaceWithSettingsReturns(v2action.Route{}, v2action.Warnings{"find-route-warning"}, v2action.RouteNotFoundError{})
   325  			})
   326  
   327  			It("does not lookup known routes", func() {
   328  				Expect(executeErr).NotTo(HaveOccurred())
   329  				Expect(warnings).To(ConsistOf("domain-warnings-1", "domains-warnings-2", "find-route-warning", "find-route-warning", "find-route-warning", "find-route-warning"))
   330  				Expect(calculatedRoutes).To(ConsistOf(
   331  					v2action.Route{
   332  						Domain: v2action.Domain{
   333  							GUID: "domain-guid-1",
   334  							Name: "a.com",
   335  						},
   336  						SpaceGUID: spaceGUID,
   337  					},
   338  					v2action.Route{
   339  						Domain: v2action.Domain{
   340  							GUID: "domain-guid-2",
   341  							Name: "b.a.com",
   342  						},
   343  						SpaceGUID: spaceGUID,
   344  					},
   345  					v2action.Route{
   346  						Host: "c",
   347  						Domain: v2action.Domain{
   348  							GUID: "domain-guid-2",
   349  							Name: "b.a.com",
   350  						},
   351  						SpaceGUID: spaceGUID,
   352  					},
   353  					v2action.Route{
   354  						GUID: "route-guid-4",
   355  						Host: "d.c",
   356  						Domain: v2action.Domain{
   357  							GUID: "domain-guid-2",
   358  							Name: "b.a.com",
   359  						},
   360  						SpaceGUID: spaceGUID,
   361  					},
   362  					v2action.Route{
   363  						Host: "",
   364  						Domain: v2action.Domain{
   365  							GUID: "domain-guid-1",
   366  							Name: "a.com",
   367  						},
   368  						Path:      "/some-path",
   369  						SpaceGUID: spaceGUID,
   370  					}))
   371  
   372  				Expect(fakeV2Actor.GetDomainsByNameAndOrganizationCallCount()).To(Equal(1))
   373  				domains, passedOrgGUID := fakeV2Actor.GetDomainsByNameAndOrganizationArgsForCall(0)
   374  				Expect(domains).To(ConsistOf("a.com", "b.a.com", "c.b.a.com"))
   375  				Expect(passedOrgGUID).To(Equal(orgGUID))
   376  			})
   377  		})
   378  	})
   379  
   380  	Describe("CreateAndBindApplicationRoutes", func() {
   381  		var (
   382  			warnings   Warnings
   383  			executeErr error
   384  		)
   385  
   386  		JustBeforeEach(func() {
   387  			warnings, executeErr = actor.CreateAndBindApplicationRoutes("some-org-guid", "some-space-guid",
   388  				v2action.Application{Name: "some-app", GUID: "some-app-guid"})
   389  		})
   390  
   391  		Context("when getting organization domains errors", func() {
   392  			BeforeEach(func() {
   393  				fakeV2Actor.GetOrganizationDomainsReturns(
   394  					[]v2action.Domain{},
   395  					v2action.Warnings{"domain-warning"},
   396  					errors.New("some-error"))
   397  			})
   398  
   399  			It("returns the error", func() {
   400  				Expect(executeErr).To(MatchError("some-error"))
   401  				Expect(warnings).To(ConsistOf("domain-warning"))
   402  			})
   403  		})
   404  
   405  		Context("when getting organization domains succeeds", func() {
   406  			BeforeEach(func() {
   407  				fakeV2Actor.GetOrganizationDomainsReturns(
   408  					[]v2action.Domain{
   409  						{
   410  							GUID: "some-domain-guid",
   411  							Name: "some-domain",
   412  						},
   413  					},
   414  					v2action.Warnings{"domain-warning"},
   415  					nil,
   416  				)
   417  			})
   418  
   419  			Context("when getting the application routes errors", func() {
   420  				BeforeEach(func() {
   421  					fakeV2Actor.GetApplicationRoutesReturns(
   422  						[]v2action.Route{},
   423  						v2action.Warnings{"route-warning"},
   424  						errors.New("some-error"),
   425  					)
   426  				})
   427  
   428  				It("returns the error", func() {
   429  					Expect(executeErr).To(MatchError("some-error"))
   430  					Expect(warnings).To(ConsistOf("domain-warning", "route-warning"))
   431  				})
   432  			})
   433  
   434  			Context("when getting the application routes succeeds", func() {
   435  				// TODO: do we need this context
   436  				Context("when the route is already bound to the app", func() {
   437  					BeforeEach(func() {
   438  						fakeV2Actor.GetApplicationRoutesReturns(
   439  							[]v2action.Route{
   440  								{
   441  									Host: "some-app",
   442  									Domain: v2action.Domain{
   443  										GUID: "some-domain-guid",
   444  										Name: "some-domain",
   445  									},
   446  									GUID:      "some-route-guid",
   447  									SpaceGUID: "some-space-guid",
   448  								},
   449  							},
   450  							v2action.Warnings{"route-warning"},
   451  							nil,
   452  						)
   453  					})
   454  
   455  					It("returns any warnings", func() {
   456  						Expect(executeErr).ToNot(HaveOccurred())
   457  						Expect(warnings).To(ConsistOf("domain-warning", "route-warning"))
   458  
   459  						Expect(fakeV2Actor.GetOrganizationDomainsCallCount()).To(Equal(1), "Expected GetOrganizationDomains to be called once, but it was not")
   460  						orgGUID := fakeV2Actor.GetOrganizationDomainsArgsForCall(0)
   461  						Expect(orgGUID).To(Equal("some-org-guid"))
   462  
   463  						Expect(fakeV2Actor.GetApplicationRoutesCallCount()).To(Equal(1), "Expected GetApplicationRoutes to be called once, but it was not")
   464  						appGUID := fakeV2Actor.GetApplicationRoutesArgsForCall(0)
   465  						Expect(appGUID).To(Equal("some-app-guid"))
   466  
   467  						Expect(fakeV2Actor.CreateRouteCallCount()).To(Equal(0), "Expected CreateRoute to not be called but it was")
   468  						Expect(fakeV2Actor.BindRouteToApplicationCallCount()).To(Equal(0), "Expected BindRouteToApplication to not be called but it was")
   469  					})
   470  				})
   471  
   472  				Context("when the route isn't bound to the app", func() {
   473  					Context("when finding route in space errors", func() {
   474  						BeforeEach(func() {
   475  							fakeV2Actor.FindRouteBoundToSpaceWithSettingsReturns(
   476  								v2action.Route{},
   477  								v2action.Warnings{"route-warning"},
   478  								errors.New("some-error"),
   479  							)
   480  						})
   481  
   482  						It("returns the error", func() {
   483  							Expect(executeErr).To(MatchError("some-error"))
   484  							Expect(warnings).To(ConsistOf("domain-warning", "route-warning"))
   485  						})
   486  					})
   487  
   488  					Context("when the route exists", func() {
   489  						BeforeEach(func() {
   490  							fakeV2Actor.FindRouteBoundToSpaceWithSettingsReturns(
   491  								v2action.Route{
   492  									GUID: "some-route-guid",
   493  									Host: "some-app",
   494  									Domain: v2action.Domain{
   495  										Name: "some-domain",
   496  										GUID: "some-domain-guid",
   497  									},
   498  									SpaceGUID: "some-space-guid",
   499  								},
   500  								v2action.Warnings{"route-warning"},
   501  								nil,
   502  							)
   503  						})
   504  
   505  						Context("when the bind command returns an error", func() {
   506  							BeforeEach(func() {
   507  								fakeV2Actor.BindRouteToApplicationReturns(
   508  									v2action.Warnings{"bind-warning"},
   509  									errors.New("some-error"),
   510  								)
   511  							})
   512  
   513  							It("returns the error", func() {
   514  								Expect(executeErr).To(MatchError("some-error"))
   515  								Expect(warnings).To(ConsistOf("domain-warning", "route-warning", "bind-warning"))
   516  							})
   517  						})
   518  
   519  						Context("when the bind command succeeds", func() {
   520  							BeforeEach(func() {
   521  								fakeV2Actor.BindRouteToApplicationReturns(
   522  									v2action.Warnings{"bind-warning"},
   523  									nil,
   524  								)
   525  							})
   526  
   527  							It("binds the route to the app and returns any warnings", func() {
   528  								Expect(executeErr).ToNot(HaveOccurred())
   529  								Expect(warnings).To(ConsistOf("domain-warning", "route-warning", "bind-warning"))
   530  
   531  								Expect(fakeV2Actor.FindRouteBoundToSpaceWithSettingsCallCount()).To(Equal(1), "Expected FindRouteBoundToSpaceWithSettings to be called once, but it was not")
   532  								spaceRoute := fakeV2Actor.FindRouteBoundToSpaceWithSettingsArgsForCall(0)
   533  								Expect(spaceRoute).To(Equal(v2action.Route{
   534  									Host: "some-app",
   535  									Domain: v2action.Domain{
   536  										Name: "some-domain",
   537  										GUID: "some-domain-guid",
   538  									},
   539  									SpaceGUID: "some-space-guid",
   540  								}))
   541  
   542  								Expect(fakeV2Actor.BindRouteToApplicationCallCount()).To(Equal(1), "Expected BindRouteToApplication to be called once, but it was not")
   543  								routeGUID, appGUID := fakeV2Actor.BindRouteToApplicationArgsForCall(0)
   544  								Expect(routeGUID).To(Equal("some-route-guid"))
   545  								Expect(appGUID).To(Equal("some-app-guid"))
   546  							})
   547  						})
   548  					})
   549  
   550  					Context("when the route does not exist", func() {
   551  						BeforeEach(func() {
   552  							fakeV2Actor.FindRouteBoundToSpaceWithSettingsReturns(
   553  								v2action.Route{},
   554  								v2action.Warnings{"route-warning"},
   555  								v2action.RouteNotFoundError{},
   556  							)
   557  						})
   558  
   559  						Context("when the create route command errors", func() {
   560  							BeforeEach(func() {
   561  								fakeV2Actor.CreateRouteReturns(
   562  									v2action.Route{},
   563  									v2action.Warnings{"route-create-warning"},
   564  									errors.New("some-error"),
   565  								)
   566  							})
   567  
   568  							It("returns the error", func() {
   569  								Expect(executeErr).To(MatchError("some-error"))
   570  								Expect(warnings).To(ConsistOf("domain-warning", "route-warning", "route-create-warning"))
   571  							})
   572  						})
   573  
   574  						Context("when the create route command succeeds", func() {
   575  							BeforeEach(func() {
   576  								fakeV2Actor.CreateRouteReturns(
   577  									v2action.Route{
   578  										GUID: "some-route-guid",
   579  										Host: "some-app",
   580  										Domain: v2action.Domain{
   581  											Name: "some-domain",
   582  											GUID: "some-domain-guid",
   583  										},
   584  										SpaceGUID: "some-space-guid",
   585  									},
   586  									v2action.Warnings{"route-create-warning"},
   587  									nil,
   588  								)
   589  							})
   590  
   591  							Context("when the bind command errors", func() {
   592  								BeforeEach(func() {
   593  									fakeV2Actor.BindRouteToApplicationReturns(
   594  										v2action.Warnings{"bind-warning"},
   595  										errors.New("some-error"),
   596  									)
   597  								})
   598  
   599  								It("returns the error", func() {
   600  									Expect(executeErr).To(MatchError("some-error"))
   601  									Expect(warnings).To(ConsistOf("domain-warning", "route-warning", "route-create-warning", "bind-warning"))
   602  								})
   603  							})
   604  							Context("when the bind command succeeds", func() {
   605  
   606  								BeforeEach(func() {
   607  									fakeV2Actor.BindRouteToApplicationReturns(
   608  										v2action.Warnings{"bind-warning"},
   609  										nil,
   610  									)
   611  								})
   612  
   613  								It("creates the route, binds it to the app, and returns any warnings", func() {
   614  									Expect(executeErr).ToNot(HaveOccurred())
   615  									Expect(warnings).To(ConsistOf("domain-warning", "route-warning", "route-create-warning", "bind-warning"))
   616  
   617  									Expect(fakeV2Actor.CreateRouteCallCount()).To(Equal(1), "Expected CreateRoute to be called once, but it was not")
   618  									defaultRoute, shouldGeneratePort := fakeV2Actor.CreateRouteArgsForCall(0)
   619  									Expect(defaultRoute).To(Equal(v2action.Route{
   620  										Host: "some-app",
   621  										Domain: v2action.Domain{
   622  											Name: "some-domain",
   623  											GUID: "some-domain-guid",
   624  										},
   625  										SpaceGUID: "some-space-guid",
   626  									}))
   627  									Expect(shouldGeneratePort).To(BeFalse())
   628  
   629  									Expect(fakeV2Actor.FindRouteBoundToSpaceWithSettingsCallCount()).To(Equal(1), "Expected FindRouteBoundToSpaceWithSettings to be called once, but it was not")
   630  									spaceRoute := fakeV2Actor.FindRouteBoundToSpaceWithSettingsArgsForCall(0)
   631  									Expect(spaceRoute).To(Equal(v2action.Route{
   632  										Host: "some-app",
   633  										Domain: v2action.Domain{
   634  											Name: "some-domain",
   635  											GUID: "some-domain-guid",
   636  										},
   637  										SpaceGUID: "some-space-guid",
   638  									}))
   639  
   640  									Expect(fakeV2Actor.BindRouteToApplicationCallCount()).To(Equal(1), "Expected BindRouteToApplication to be called once, but it was not")
   641  									routeGUID, appGUID := fakeV2Actor.BindRouteToApplicationArgsForCall(0)
   642  									Expect(routeGUID).To(Equal("some-route-guid"))
   643  									Expect(appGUID).To(Equal("some-app-guid"))
   644  								})
   645  							})
   646  						})
   647  					})
   648  				})
   649  			})
   650  		})
   651  	})
   652  
   653  	Describe("CreateRoutes", func() {
   654  		var (
   655  			config ApplicationConfig
   656  
   657  			returnedConfig ApplicationConfig
   658  			createdRoutes  bool
   659  			warnings       Warnings
   660  			executeErr     error
   661  		)
   662  
   663  		BeforeEach(func() {
   664  			config = ApplicationConfig{}
   665  		})
   666  
   667  		JustBeforeEach(func() {
   668  			returnedConfig, createdRoutes, warnings, executeErr = actor.CreateRoutes(config)
   669  		})
   670  
   671  		Describe("when routes need to be created", func() {
   672  			BeforeEach(func() {
   673  				config.DesiredRoutes = []v2action.Route{
   674  					{GUID: "", Host: "some-route-1"},
   675  					{GUID: "some-route-guid-2", Host: "some-route-2"},
   676  					{GUID: "", Host: "some-route-3"},
   677  				}
   678  			})
   679  
   680  			Context("when the creation is successful", func() {
   681  				BeforeEach(func() {
   682  					fakeV2Actor.CreateRouteReturnsOnCall(0, v2action.Route{GUID: "some-route-guid-1", Host: "some-route-1"}, v2action.Warnings{"create-route-warning"}, nil)
   683  					fakeV2Actor.CreateRouteReturnsOnCall(1, v2action.Route{GUID: "some-route-guid-3", Host: "some-route-3"}, v2action.Warnings{"create-route-warning"}, nil)
   684  				})
   685  
   686  				It("only creates the routes that do not exist", func() {
   687  					Expect(executeErr).ToNot(HaveOccurred())
   688  					Expect(warnings).To(ConsistOf("create-route-warning", "create-route-warning"))
   689  					Expect(createdRoutes).To(BeTrue())
   690  					Expect(returnedConfig.DesiredRoutes).To(Equal([]v2action.Route{
   691  						{GUID: "some-route-guid-1", Host: "some-route-1"},
   692  						{GUID: "some-route-guid-2", Host: "some-route-2"},
   693  						{GUID: "some-route-guid-3", Host: "some-route-3"},
   694  					}))
   695  
   696  					Expect(fakeV2Actor.CreateRouteCallCount()).To(Equal(2))
   697  					Expect(fakeV2Actor.CreateRouteArgsForCall(0)).To(Equal(v2action.Route{Host: "some-route-1"}))
   698  					Expect(fakeV2Actor.CreateRouteArgsForCall(1)).To(Equal(v2action.Route{Host: "some-route-3"}))
   699  				})
   700  			})
   701  
   702  			Context("when the creation errors", func() {
   703  				var expectedErr error
   704  
   705  				BeforeEach(func() {
   706  					expectedErr = errors.New("oh my")
   707  					fakeV2Actor.CreateRouteReturns(
   708  						v2action.Route{},
   709  						v2action.Warnings{"create-route-warning"},
   710  						expectedErr)
   711  				})
   712  
   713  				It("sends the warnings and errors and returns true", func() {
   714  					Expect(executeErr).To(MatchError(expectedErr))
   715  					Expect(warnings).To(ConsistOf("create-route-warning"))
   716  				})
   717  			})
   718  		})
   719  
   720  		Context("when no routes are created", func() {
   721  			BeforeEach(func() {
   722  				config.DesiredRoutes = []v2action.Route{
   723  					{GUID: "some-route-guid-1", Host: "some-route-1"},
   724  					{GUID: "some-route-guid-2", Host: "some-route-2"},
   725  					{GUID: "some-route-guid-3", Host: "some-route-3"},
   726  				}
   727  			})
   728  
   729  			It("returns false", func() {
   730  				Expect(createdRoutes).To(BeFalse())
   731  			})
   732  		})
   733  	})
   734  
   735  	Describe("GetRouteWithDefaultDomain", func() {
   736  		var (
   737  			host        string
   738  			orgGUID     string
   739  			spaceGUID   string
   740  			knownRoutes []v2action.Route
   741  
   742  			defaultRoute v2action.Route
   743  			warnings     Warnings
   744  			executeErr   error
   745  
   746  			domain v2action.Domain
   747  		)
   748  
   749  		BeforeEach(func() {
   750  			host = "Some-App"
   751  			orgGUID = "some-org-guid"
   752  			spaceGUID = "some-space-guid"
   753  			knownRoutes = nil
   754  
   755  			domain = v2action.Domain{
   756  				Name: "private-domain.com",
   757  				GUID: "some-private-domain-guid",
   758  			}
   759  		})
   760  
   761  		JustBeforeEach(func() {
   762  			defaultRoute, warnings, executeErr = actor.GetRouteWithDefaultDomain(host, orgGUID, spaceGUID, knownRoutes)
   763  		})
   764  
   765  		Context("when retrieving the domains is successful", func() {
   766  			BeforeEach(func() {
   767  				fakeV2Actor.GetOrganizationDomainsReturns(
   768  					[]v2action.Domain{domain},
   769  					v2action.Warnings{"private-domain-warnings", "shared-domain-warnings"},
   770  					nil,
   771  				)
   772  			})
   773  
   774  			Context("when the route exists", func() {
   775  				BeforeEach(func() {
   776  					// Assumes new route
   777  					fakeV2Actor.FindRouteBoundToSpaceWithSettingsReturns(v2action.Route{
   778  						Domain:    domain,
   779  						GUID:      "some-route-guid",
   780  						Host:      strings.ToLower(host),
   781  						SpaceGUID: spaceGUID,
   782  					}, v2action.Warnings{"get-route-warnings"}, nil)
   783  				})
   784  
   785  				It("returns the route and warnings", func() {
   786  					Expect(executeErr).ToNot(HaveOccurred())
   787  					Expect(warnings).To(ConsistOf("private-domain-warnings", "shared-domain-warnings", "get-route-warnings"))
   788  
   789  					Expect(defaultRoute).To(Equal(v2action.Route{
   790  						Domain:    domain,
   791  						GUID:      "some-route-guid",
   792  						Host:      strings.ToLower(host),
   793  						SpaceGUID: spaceGUID,
   794  					}))
   795  
   796  					Expect(fakeV2Actor.GetOrganizationDomainsCallCount()).To(Equal(1))
   797  					Expect(fakeV2Actor.GetOrganizationDomainsArgsForCall(0)).To(Equal(orgGUID))
   798  
   799  					Expect(fakeV2Actor.FindRouteBoundToSpaceWithSettingsCallCount()).To(Equal(1))
   800  					Expect(fakeV2Actor.FindRouteBoundToSpaceWithSettingsArgsForCall(0)).To(Equal(v2action.Route{Domain: domain, Host: strings.ToLower(host), SpaceGUID: spaceGUID}))
   801  				})
   802  
   803  				Context("when the route has been found", func() {
   804  					BeforeEach(func() {
   805  						knownRoutes = []v2action.Route{{
   806  							Domain:    domain,
   807  							GUID:      "some-route-guid",
   808  							Host:      strings.ToLower(host),
   809  							SpaceGUID: spaceGUID,
   810  						}}
   811  					})
   812  
   813  					It("should return the known route and warnings", func() {
   814  						Expect(executeErr).ToNot(HaveOccurred())
   815  						Expect(warnings).To(ConsistOf("private-domain-warnings", "shared-domain-warnings"))
   816  
   817  						Expect(defaultRoute).To(Equal(v2action.Route{
   818  							Domain:    domain,
   819  							GUID:      "some-route-guid",
   820  							Host:      strings.ToLower(host),
   821  							SpaceGUID: spaceGUID,
   822  						}))
   823  
   824  						Expect(fakeV2Actor.FindRouteBoundToSpaceWithSettingsCallCount()).To(Equal(0))
   825  					})
   826  				})
   827  			})
   828  
   829  			Context("when the route does not exist", func() {
   830  				BeforeEach(func() {
   831  					fakeV2Actor.FindRouteBoundToSpaceWithSettingsReturns(v2action.Route{}, v2action.Warnings{"get-route-warnings"}, v2action.RouteNotFoundError{})
   832  				})
   833  
   834  				It("returns a partial route", func() {
   835  					Expect(executeErr).ToNot(HaveOccurred())
   836  					Expect(warnings).To(ConsistOf("private-domain-warnings", "shared-domain-warnings", "get-route-warnings"))
   837  
   838  					Expect(defaultRoute).To(Equal(v2action.Route{Domain: domain, Host: strings.ToLower(host), SpaceGUID: spaceGUID}))
   839  				})
   840  			})
   841  
   842  			Context("when retrieving the routes errors", func() {
   843  				var expectedErr error
   844  
   845  				BeforeEach(func() {
   846  					expectedErr = errors.New("whoops")
   847  					fakeV2Actor.FindRouteBoundToSpaceWithSettingsReturns(v2action.Route{}, v2action.Warnings{"get-route-warnings"}, expectedErr)
   848  				})
   849  
   850  				It("returns errors and warnings", func() {
   851  					Expect(executeErr).To(MatchError(expectedErr))
   852  					Expect(warnings).To(ConsistOf("private-domain-warnings", "shared-domain-warnings", "get-route-warnings"))
   853  				})
   854  			})
   855  		})
   856  
   857  		Context("when retrieving the domains errors", func() {
   858  			var expectedErr error
   859  
   860  			BeforeEach(func() {
   861  				expectedErr = errors.New("whoops")
   862  				fakeV2Actor.GetOrganizationDomainsReturns([]v2action.Domain{}, v2action.Warnings{"private-domain-warnings", "shared-domain-warnings"}, expectedErr)
   863  			})
   864  
   865  			It("returns errors and warnings", func() {
   866  				Expect(executeErr).To(MatchError(expectedErr))
   867  				Expect(warnings).To(ConsistOf("private-domain-warnings", "shared-domain-warnings"))
   868  			})
   869  		})
   870  	})
   871  })