github.com/LukasHeimann/cloudfoundrycli@v7.1.0+incompatible/actor/v7action/route_test.go (about)

     1  package v7action_test
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  
     7  	"code.cloudfoundry.org/cli/api/cloudcontroller/ccv3/constant"
     8  	"code.cloudfoundry.org/cli/resources"
     9  
    10  	"code.cloudfoundry.org/cli/actor/actionerror"
    11  	. "code.cloudfoundry.org/cli/actor/v7action"
    12  	"code.cloudfoundry.org/cli/actor/v7action/v7actionfakes"
    13  	"code.cloudfoundry.org/cli/api/cloudcontroller/ccerror"
    14  	"code.cloudfoundry.org/cli/api/cloudcontroller/ccv3"
    15  	. "github.com/onsi/ginkgo"
    16  	. "github.com/onsi/gomega"
    17  )
    18  
    19  var _ = Describe("Route Actions", func() {
    20  	var (
    21  		actor                     *Actor
    22  		fakeCloudControllerClient *v7actionfakes.FakeCloudControllerClient
    23  	)
    24  
    25  	BeforeEach(func() {
    26  		actor, fakeCloudControllerClient, _, _, _, _, _ = NewTestActor()
    27  	})
    28  
    29  	Describe("CreateRoute", func() {
    30  		var (
    31  			warnings   Warnings
    32  			executeErr error
    33  			hostname   string
    34  			path       string
    35  			port       int
    36  		)
    37  
    38  		BeforeEach(func() {
    39  			hostname = ""
    40  			path = ""
    41  			port = 0
    42  		})
    43  
    44  		JustBeforeEach(func() {
    45  			_, warnings, executeErr = actor.CreateRoute("space-guid", "domain-name", hostname, path, port)
    46  		})
    47  
    48  		When("the API layer calls are successful", func() {
    49  			BeforeEach(func() {
    50  				fakeCloudControllerClient.GetDomainsReturns(
    51  					[]resources.Domain{
    52  						{Name: "domain-name", GUID: "domain-guid"},
    53  					},
    54  					ccv3.Warnings{"get-domains-warning"},
    55  					nil,
    56  				)
    57  
    58  				fakeCloudControllerClient.CreateRouteReturns(
    59  					resources.Route{GUID: "route-guid", SpaceGUID: "space-guid", DomainGUID: "domain-guid", Host: "hostname", Path: "path-name"},
    60  					ccv3.Warnings{"create-warning-1", "create-warning-2"},
    61  					nil)
    62  			})
    63  
    64  			When("a host and path are given", func() {
    65  				BeforeEach(func() {
    66  					hostname = "hostname"
    67  					path = "/path-name"
    68  				})
    69  
    70  				It("returns the route with '/<path>' and prints warnings", func() {
    71  					Expect(warnings).To(ConsistOf("create-warning-1", "create-warning-2", "get-domains-warning"))
    72  					Expect(executeErr).ToNot(HaveOccurred())
    73  
    74  					Expect(fakeCloudControllerClient.CreateRouteCallCount()).To(Equal(1))
    75  					passedRoute := fakeCloudControllerClient.CreateRouteArgsForCall(0)
    76  
    77  					Expect(passedRoute).To(Equal(
    78  						resources.Route{
    79  							SpaceGUID:  "space-guid",
    80  							DomainGUID: "domain-guid",
    81  							Host:       hostname,
    82  							Path:       path,
    83  						},
    84  					))
    85  				})
    86  			})
    87  
    88  			When("a port is given", func() {
    89  				BeforeEach(func() {
    90  					port = 1234
    91  				})
    92  
    93  				It("returns the route with port and prints warnings", func() {
    94  					Expect(warnings).To(ConsistOf("create-warning-1", "create-warning-2", "get-domains-warning"))
    95  					Expect(executeErr).ToNot(HaveOccurred())
    96  
    97  					Expect(fakeCloudControllerClient.CreateRouteCallCount()).To(Equal(1))
    98  					passedRoute := fakeCloudControllerClient.CreateRouteArgsForCall(0)
    99  
   100  					Expect(passedRoute).To(Equal(
   101  						resources.Route{
   102  							SpaceGUID:  "space-guid",
   103  							DomainGUID: "domain-guid",
   104  							Port:       1234,
   105  						},
   106  					))
   107  				})
   108  			})
   109  		})
   110  
   111  		When("the API call to get the domain returns an error", func() {
   112  			When("the cc client returns an RouteNotUniqueError", func() {
   113  				BeforeEach(func() {
   114  					fakeCloudControllerClient.GetDomainsReturns(
   115  						[]resources.Domain{
   116  							{Name: "domain-name", GUID: "domain-guid"},
   117  						},
   118  						ccv3.Warnings{"get-domains-warning"},
   119  						nil,
   120  					)
   121  
   122  					fakeCloudControllerClient.GetOrganizationsReturns(
   123  						[]resources.Organization{
   124  							{Name: "org-name", GUID: "org-guid"},
   125  						},
   126  						ccv3.Warnings{"get-orgs-warning"},
   127  						nil,
   128  					)
   129  
   130  					fakeCloudControllerClient.GetSpacesReturns(
   131  						[]resources.Space{
   132  							{Name: "space-name", GUID: "space-guid"},
   133  						},
   134  						ccv3.IncludedResources{},
   135  						ccv3.Warnings{"get-spaces-warning"},
   136  						nil,
   137  					)
   138  
   139  					fakeCloudControllerClient.CreateRouteReturns(
   140  						resources.Route{},
   141  						ccv3.Warnings{"create-route-warning"},
   142  						ccerror.RouteNotUniqueError{
   143  							UnprocessableEntityError: ccerror.UnprocessableEntityError{Message: "some cool error"},
   144  						},
   145  					)
   146  				})
   147  
   148  				It("returns the RouteAlreadyExistsError and warnings", func() {
   149  					Expect(executeErr).To(MatchError(actionerror.RouteAlreadyExistsError{
   150  						Err: ccerror.RouteNotUniqueError{
   151  							UnprocessableEntityError: ccerror.UnprocessableEntityError{Message: "some cool error"},
   152  						},
   153  					}))
   154  					Expect(warnings).To(ConsistOf("get-domains-warning", "create-route-warning"))
   155  				})
   156  			})
   157  
   158  			When("the cc client returns a different error", func() {
   159  				BeforeEach(func() {
   160  					fakeCloudControllerClient.GetDomainsReturns(
   161  						[]resources.Domain{},
   162  						ccv3.Warnings{"domain-warning-1", "domain-warning-2"},
   163  						errors.New("api-domains-error"),
   164  					)
   165  				})
   166  
   167  				It("it returns an error and prints warnings", func() {
   168  					Expect(warnings).To(ConsistOf("domain-warning-1", "domain-warning-2"))
   169  					Expect(executeErr).To(MatchError("api-domains-error"))
   170  
   171  					Expect(fakeCloudControllerClient.GetDomainsCallCount()).To(Equal(1))
   172  					Expect(fakeCloudControllerClient.CreateRouteCallCount()).To(Equal(0))
   173  				})
   174  			})
   175  		})
   176  	})
   177  
   178  	Describe("GetRoutesBySpace", func() {
   179  		var (
   180  			routes     []resources.Route
   181  			warnings   Warnings
   182  			labels     string
   183  			executeErr error
   184  		)
   185  
   186  		BeforeEach(func() {
   187  			labels = ""
   188  			fakeCloudControllerClient.GetDomainsReturns(
   189  				[]resources.Domain{
   190  					{Name: "domain1-name", GUID: "domain1-guid"},
   191  					{Name: "domain2-name", GUID: "domain2-guid"},
   192  				},
   193  				ccv3.Warnings{"get-domains-warning"},
   194  				nil,
   195  			)
   196  
   197  			fakeCloudControllerClient.GetRoutesReturns(
   198  				[]resources.Route{
   199  					{GUID: "route1-guid", SpaceGUID: "space-guid", DomainGUID: "domain1-guid", Host: "hostname", URL: "hostname.domain1-name", Destinations: []resources.RouteDestination{}},
   200  					{GUID: "route2-guid", SpaceGUID: "space-guid", DomainGUID: "domain2-guid", Path: "/my-path", URL: "domain2-name/my-path", Destinations: []resources.RouteDestination{}},
   201  					{GUID: "route3-guid", SpaceGUID: "space-guid", DomainGUID: "domain1-guid", URL: "domain1-name", Destinations: []resources.RouteDestination{}},
   202  				},
   203  				ccv3.Warnings{"get-route-warning-1", "get-route-warning-2"},
   204  				nil,
   205  			)
   206  		})
   207  
   208  		JustBeforeEach(func() {
   209  			routes, warnings, executeErr = actor.GetRoutesBySpace("space-guid", labels)
   210  		})
   211  
   212  		When("the API layer calls are successful", func() {
   213  			It("returns the routes and warnings", func() {
   214  				Expect(routes).To(Equal([]resources.Route{
   215  					{GUID: "route1-guid", SpaceGUID: "space-guid", DomainGUID: "domain1-guid", Host: "hostname", URL: "hostname.domain1-name", Destinations: []resources.RouteDestination{}},
   216  					{GUID: "route2-guid", SpaceGUID: "space-guid", DomainGUID: "domain2-guid", Path: "/my-path", URL: "domain2-name/my-path", Destinations: []resources.RouteDestination{}},
   217  					{GUID: "route3-guid", SpaceGUID: "space-guid", DomainGUID: "domain1-guid", URL: "domain1-name", Destinations: []resources.RouteDestination{}},
   218  				}))
   219  				Expect(warnings).To(ConsistOf("get-route-warning-1", "get-route-warning-2"))
   220  				Expect(executeErr).ToNot(HaveOccurred())
   221  
   222  				Expect(fakeCloudControllerClient.GetRoutesCallCount()).To(Equal(1))
   223  				query := fakeCloudControllerClient.GetRoutesArgsForCall(0)
   224  				Expect(query).To(HaveLen(1))
   225  				Expect(query[0].Key).To(Equal(ccv3.SpaceGUIDFilter))
   226  				Expect(query[0].Values).To(ConsistOf("space-guid"))
   227  			})
   228  
   229  			When("a label selector is provided", func() {
   230  				BeforeEach(func() {
   231  					labels = "ink=blink"
   232  				})
   233  
   234  				It("passes a label selector query", func() {
   235  					Expect(executeErr).ToNot(HaveOccurred())
   236  
   237  					Expect(fakeCloudControllerClient.GetRoutesCallCount()).To(Equal(1))
   238  					expectedQuery := []ccv3.Query{
   239  						{Key: ccv3.SpaceGUIDFilter, Values: []string{"space-guid"}},
   240  						{Key: ccv3.LabelSelectorFilter, Values: []string{"ink=blink"}},
   241  					}
   242  					actualQuery := fakeCloudControllerClient.GetRoutesArgsForCall(0)
   243  					Expect(actualQuery).To(Equal(expectedQuery))
   244  				})
   245  			})
   246  		})
   247  
   248  		When("getting routes fails", func() {
   249  			var err = errors.New("failed to get route")
   250  
   251  			BeforeEach(func() {
   252  				fakeCloudControllerClient.GetRoutesReturns(
   253  					nil,
   254  					ccv3.Warnings{"get-route-warning-1", "get-route-warning-2"},
   255  					err)
   256  			})
   257  
   258  			It("returns the error and any warnings", func() {
   259  				Expect(executeErr).To(Equal(err))
   260  				Expect(warnings).To(ConsistOf("get-route-warning-1", "get-route-warning-2"))
   261  			})
   262  		})
   263  	})
   264  
   265  	Describe("GetRoute", func() {
   266  		BeforeEach(func() {
   267  			fakeCloudControllerClient.GetDomainsReturns(
   268  				[]resources.Domain{{Name: "domain-name", GUID: "domain-guid"}},
   269  				ccv3.Warnings{"get-domains-warning"},
   270  				nil,
   271  			)
   272  		})
   273  
   274  		When("the route has a host and a path", func() {
   275  			BeforeEach(func() {
   276  				fakeCloudControllerClient.GetDomainsReturnsOnCall(
   277  					0,
   278  					[]resources.Domain{},
   279  					ccv3.Warnings{"get-domains-warning-1"},
   280  					nil,
   281  				)
   282  
   283  				fakeCloudControllerClient.GetDomainsReturnsOnCall(
   284  					1,
   285  					[]resources.Domain{
   286  						{Name: "domain-name", GUID: "domain-guid"},
   287  					},
   288  					ccv3.Warnings{"get-domains-warning-2"},
   289  					nil,
   290  				)
   291  
   292  				fakeCloudControllerClient.GetRoutesReturns(
   293  					[]resources.Route{
   294  						{
   295  							GUID:       "route1-guid",
   296  							SpaceGUID:  "space-guid",
   297  							DomainGUID: "domain-guid",
   298  							Host:       "hostname",
   299  							URL:        "hostname.domain-name",
   300  							Path:       "/the-path",
   301  						},
   302  					},
   303  					ccv3.Warnings{"get-route-warning-1", "get-route-warning-2"},
   304  					nil,
   305  				)
   306  			})
   307  
   308  			It("returns the route and warnings", func() {
   309  				route, warnings, executeErr := actor.GetRoute("hostname.domain-name/the-path", "space-guid")
   310  				Expect(route.GUID).To(Equal("route1-guid"))
   311  				Expect(warnings).To(ConsistOf("get-route-warning-1", "get-route-warning-2", "get-domains-warning-1", "get-domains-warning-2"))
   312  				Expect(executeErr).ToNot(HaveOccurred())
   313  
   314  				Expect(fakeCloudControllerClient.GetDomainsCallCount()).To(Equal(2))
   315  				query := fakeCloudControllerClient.GetDomainsArgsForCall(0)
   316  				Expect(query[0].Key).To(Equal(ccv3.NameFilter))
   317  				Expect(query[0].Values).To(ConsistOf("hostname.domain-name"))
   318  
   319  				query = fakeCloudControllerClient.GetDomainsArgsForCall(1)
   320  				Expect(query[0].Key).To(Equal(ccv3.NameFilter))
   321  				Expect(query[0].Values).To(ConsistOf("domain-name"))
   322  
   323  				Expect(fakeCloudControllerClient.GetRoutesCallCount()).To(Equal(1))
   324  				query = fakeCloudControllerClient.GetRoutesArgsForCall(0)
   325  				Expect(query).To(HaveLen(4))
   326  				Expect(query[0].Key).To(Equal(ccv3.SpaceGUIDFilter))
   327  				Expect(query[0].Values).To(ConsistOf("space-guid"))
   328  				Expect(query[1].Key).To(Equal(ccv3.DomainGUIDFilter))
   329  				Expect(query[1].Values).To(ConsistOf("domain-guid"))
   330  				Expect(query[2].Key).To(Equal(ccv3.HostsFilter))
   331  				Expect(query[2].Values).To(ConsistOf("hostname"))
   332  				Expect(query[3].Key).To(Equal(ccv3.PathsFilter))
   333  				Expect(query[3].Values).To(ConsistOf("/the-path"))
   334  			})
   335  		})
   336  
   337  		When("the route does not have a host", func() {
   338  			BeforeEach(func() {
   339  				fakeCloudControllerClient.GetRoutesReturns(
   340  					[]resources.Route{
   341  						{
   342  							GUID:       "route1-guid",
   343  							SpaceGUID:  "space-guid",
   344  							DomainGUID: "domain-guid",
   345  							Host:       "",
   346  							URL:        "domain-name",
   347  							Path:       "",
   348  						},
   349  					},
   350  					ccv3.Warnings{},
   351  					nil,
   352  				)
   353  			})
   354  
   355  			It("returns the route and warnings", func() {
   356  				_, _, executeErr := actor.GetRoute("domain-name", "space-guid")
   357  				Expect(executeErr).ToNot(HaveOccurred())
   358  
   359  				Expect(fakeCloudControllerClient.GetDomainsCallCount()).To(Equal(1))
   360  				query := fakeCloudControllerClient.GetDomainsArgsForCall(0)
   361  				Expect(query[0].Key).To(Equal(ccv3.NameFilter))
   362  				Expect(query[0].Values).To(ConsistOf("domain-name"))
   363  
   364  				Expect(fakeCloudControllerClient.GetRoutesCallCount()).To(Equal(1))
   365  				query = fakeCloudControllerClient.GetRoutesArgsForCall(0)
   366  				Expect(query[2].Key).To(Equal(ccv3.HostsFilter))
   367  				Expect(query[2].Values).To(ConsistOf(""))
   368  			})
   369  		})
   370  
   371  		When("the route has a port", func() {
   372  			BeforeEach(func() {
   373  				fakeCloudControllerClient.GetDomainsReturns(
   374  					[]resources.Domain{{
   375  						Name:      "domain-name",
   376  						GUID:      "domain-guid",
   377  						Protocols: []string{"tcp"},
   378  					}},
   379  					ccv3.Warnings{"get-domains-warning"},
   380  					nil,
   381  				)
   382  
   383  				fakeCloudControllerClient.GetRoutesReturns(
   384  					[]resources.Route{
   385  						{
   386  							GUID:       "route1-guid",
   387  							SpaceGUID:  "space-guid",
   388  							DomainGUID: "domain-guid",
   389  							Host:       "",
   390  							URL:        "domain-name",
   391  							Path:       "",
   392  						},
   393  					},
   394  					ccv3.Warnings{},
   395  					nil,
   396  				)
   397  			})
   398  
   399  			It("returns the route and warnings", func() {
   400  				_, _, executeErr := actor.GetRoute("domain-name:8080", "space-guid")
   401  				Expect(executeErr).ToNot(HaveOccurred())
   402  
   403  				query := fakeCloudControllerClient.GetDomainsArgsForCall(0)
   404  				Expect(query[0].Key).To(Equal(ccv3.NameFilter))
   405  				Expect(query[0].Values).To(ConsistOf("domain-name"))
   406  
   407  				Expect(fakeCloudControllerClient.GetRoutesCallCount()).To(Equal(1))
   408  				query = fakeCloudControllerClient.GetRoutesArgsForCall(0)
   409  				Expect(query[4].Key).To(Equal(ccv3.PortsFilter))
   410  				Expect(query[4].Values).To(ConsistOf("8080"))
   411  			})
   412  		})
   413  
   414  		When("invalid domain cannot be found", func() {
   415  			BeforeEach(func() {
   416  				fakeCloudControllerClient.GetDomainsReturns(
   417  					[]resources.Domain{},
   418  					ccv3.Warnings{"get-domains-warning"},
   419  					nil,
   420  				)
   421  			})
   422  
   423  			It("returns the error and any warnings", func() {
   424  				_, warnings, executeErr := actor.GetRoute("unsplittabledomain/the-path", "space-guid")
   425  				Expect(warnings).To(ConsistOf("get-domains-warning"))
   426  				Expect(executeErr).To(MatchError(actionerror.DomainNotFoundError{Name: "unsplittabledomain"}))
   427  			})
   428  		})
   429  
   430  		When("the route does not exist", func() {
   431  			BeforeEach(func() {
   432  				fakeCloudControllerClient.GetDomainsReturns(
   433  					[]resources.Domain{{
   434  						Name:      "domain-name",
   435  						GUID:      "domain-guid",
   436  						Protocols: []string{"http"},
   437  					}},
   438  					ccv3.Warnings{"get-domains-warning"},
   439  					nil,
   440  				)
   441  
   442  				fakeCloudControllerClient.GetRoutesReturns(
   443  					[]resources.Route{},
   444  					ccv3.Warnings{"get-route-warning-1", "get-route-warning-2"},
   445  					nil,
   446  				)
   447  			})
   448  
   449  			It("returns the error and any warnings", func() {
   450  				_, warnings, executeErr := actor.GetRoute("unsplittabledomain/the-path", "space-guid")
   451  				Expect(warnings).To(ConsistOf("get-domains-warning", "get-route-warning-1", "get-route-warning-2"))
   452  				Expect(executeErr).To(MatchError(actionerror.RouteNotFoundError{Host: "", DomainName: "domain-name", Path: "/the-path"}))
   453  			})
   454  		})
   455  
   456  		When("getting domain fails", func() {
   457  			var err = errors.New("failed to get domain")
   458  
   459  			BeforeEach(func() {
   460  				fakeCloudControllerClient.GetDomainsReturns(
   461  					nil,
   462  					ccv3.Warnings{"get-domains-warning"},
   463  					err,
   464  				)
   465  			})
   466  
   467  			It("returns the error and any warnings", func() {
   468  				_, warnings, executeErr := actor.GetRoute("hostname.domain-name/the-path", "space-guid")
   469  				Expect(warnings).To(ConsistOf("get-domains-warning"))
   470  				Expect(executeErr).To(Equal(err))
   471  			})
   472  		})
   473  
   474  		When("getting route fails", func() {
   475  			var err = errors.New("failed to get route")
   476  
   477  			BeforeEach(func() {
   478  				fakeCloudControllerClient.GetRoutesReturns(
   479  					nil,
   480  					ccv3.Warnings{"get-route-warning-1", "get-route-warning-2"},
   481  					err)
   482  			})
   483  
   484  			It("returns the error and any warnings", func() {
   485  				_, warnings, executeErr := actor.GetRoute("hostname.domain-name/the-path", "space-guid")
   486  				Expect(executeErr).To(Equal(err))
   487  				Expect(warnings).To(ConsistOf("get-domains-warning", "get-route-warning-1", "get-route-warning-2"))
   488  			})
   489  		})
   490  	})
   491  
   492  	Describe("GetRoutesByOrg", func() {
   493  		var (
   494  			routes     []resources.Route
   495  			warnings   Warnings
   496  			executeErr error
   497  			labels     string
   498  		)
   499  
   500  		BeforeEach(func() {
   501  			labels = ""
   502  
   503  			fakeCloudControllerClient.GetRoutesReturns(
   504  				[]resources.Route{
   505  					{GUID: "route1-guid", SpaceGUID: "space1-guid", URL: "hostname.domain1-name", DomainGUID: "domain1-guid", Host: "hostname"},
   506  					{GUID: "route2-guid", SpaceGUID: "space2-guid", URL: "domain2-name/my-path", DomainGUID: "domain2-guid", Path: "/my-path"},
   507  					{GUID: "route3-guid", SpaceGUID: "space1-guid", URL: "domain1-name", DomainGUID: "domain1-guid"},
   508  				},
   509  				ccv3.Warnings{"get-route-warning-1", "get-route-warning-2"},
   510  				nil,
   511  			)
   512  		})
   513  
   514  		JustBeforeEach(func() {
   515  			routes, warnings, executeErr = actor.GetRoutesByOrg("org-guid", labels)
   516  		})
   517  
   518  		When("the API layer calls are successful", func() {
   519  			It("returns the routes and warnings", func() {
   520  				Expect(routes).To(Equal([]resources.Route{
   521  					{
   522  						GUID:       "route1-guid",
   523  						SpaceGUID:  "space1-guid",
   524  						DomainGUID: "domain1-guid",
   525  						Host:       "hostname",
   526  						URL:        "hostname.domain1-name",
   527  					},
   528  					{
   529  						GUID:       "route2-guid",
   530  						SpaceGUID:  "space2-guid",
   531  						DomainGUID: "domain2-guid",
   532  						Path:       "/my-path",
   533  						URL:        "domain2-name/my-path",
   534  					},
   535  					{
   536  						GUID:       "route3-guid",
   537  						SpaceGUID:  "space1-guid",
   538  						DomainGUID: "domain1-guid",
   539  						URL:        "domain1-name",
   540  					},
   541  				}))
   542  				Expect(warnings).To(ConsistOf("get-route-warning-1", "get-route-warning-2"))
   543  				Expect(executeErr).ToNot(HaveOccurred())
   544  
   545  				Expect(fakeCloudControllerClient.GetRoutesCallCount()).To(Equal(1))
   546  				query := fakeCloudControllerClient.GetRoutesArgsForCall(0)
   547  				Expect(query).To(HaveLen(1))
   548  				Expect(query[0].Key).To(Equal(ccv3.OrganizationGUIDFilter))
   549  				Expect(query[0].Values).To(ConsistOf("org-guid"))
   550  			})
   551  
   552  			When("a label selector is provided", func() {
   553  				BeforeEach(func() {
   554  					labels = "env=prod"
   555  				})
   556  
   557  				It("converts it into a query key", func() {
   558  					Expect(executeErr).ToNot(HaveOccurred())
   559  
   560  					Expect(fakeCloudControllerClient.GetRoutesCallCount()).To(Equal(1))
   561  					expectedQuery := []ccv3.Query{
   562  						{Key: ccv3.OrganizationGUIDFilter, Values: []string{"org-guid"}},
   563  						{Key: ccv3.LabelSelectorFilter, Values: []string{"env=prod"}},
   564  					}
   565  					actualQuery := fakeCloudControllerClient.GetRoutesArgsForCall(0)
   566  					Expect(actualQuery).To(Equal(expectedQuery))
   567  				})
   568  			})
   569  		})
   570  
   571  		When("getting routes fails", func() {
   572  			var err = errors.New("failed to get route")
   573  
   574  			BeforeEach(func() {
   575  				fakeCloudControllerClient.GetRoutesReturns(
   576  					nil,
   577  					ccv3.Warnings{"get-route-warning-1", "get-route-warning-2"},
   578  					err)
   579  			})
   580  
   581  			It("returns the error and any warnings", func() {
   582  				Expect(executeErr).To(Equal(err))
   583  				Expect(warnings).To(ConsistOf("get-route-warning-1", "get-route-warning-2"))
   584  			})
   585  		})
   586  	})
   587  
   588  	Describe("GetRouteSummaries", func() {
   589  		var (
   590  			routes         []resources.Route
   591  			routeSummaries []RouteSummary
   592  			warnings       Warnings
   593  			executeErr     error
   594  		)
   595  
   596  		BeforeEach(func() {
   597  			routes = []resources.Route{
   598  				{
   599  					GUID: "route-guid-1",
   600  					Destinations: []resources.RouteDestination{
   601  						{
   602  							App: resources.RouteDestinationApp{
   603  								GUID: "app-guid-1",
   604  							},
   605  						},
   606  					},
   607  				},
   608  				{
   609  					GUID: "route-guid-2",
   610  					Destinations: []resources.RouteDestination{
   611  						{
   612  							App: resources.RouteDestinationApp{
   613  								GUID: "app-guid-1",
   614  							},
   615  						},
   616  						{
   617  							App: resources.RouteDestinationApp{
   618  								GUID: "app-guid-2",
   619  							},
   620  						},
   621  					},
   622  				},
   623  				{
   624  					GUID:         "route-guid-3",
   625  					Destinations: []resources.RouteDestination{},
   626  					DomainGUID:   "domain-guid-1",
   627  					Port:         1028,
   628  					URL:          "domain-1.com:1028",
   629  				},
   630  			}
   631  
   632  			fakeCloudControllerClient.GetApplicationsReturns(
   633  				[]resources.Application{
   634  					{
   635  						GUID: "app-guid-1",
   636  						Name: "app-name-1",
   637  					},
   638  					{
   639  						GUID: "app-guid-2",
   640  						Name: "app-name-2",
   641  					},
   642  				},
   643  				ccv3.Warnings{"get-apps-warning"},
   644  				nil,
   645  			)
   646  		})
   647  
   648  		JustBeforeEach(func() {
   649  			routeSummaries, warnings, executeErr = actor.GetRouteSummaries(routes)
   650  		})
   651  
   652  		When("the API layer calls are successful", func() {
   653  			It("returns the routes and warnings", func() {
   654  				Expect(routeSummaries).To(Equal([]RouteSummary{
   655  					{
   656  						Route: resources.Route{
   657  							GUID: "route-guid-1",
   658  							Destinations: []resources.RouteDestination{
   659  								{
   660  									App: resources.RouteDestinationApp{GUID: "app-guid-1"},
   661  								},
   662  							},
   663  						},
   664  						AppNames: []string{"app-name-1"},
   665  					},
   666  					{
   667  						Route: resources.Route{
   668  							GUID: "route-guid-2",
   669  							Destinations: []resources.RouteDestination{
   670  								{
   671  									App: resources.RouteDestinationApp{GUID: "app-guid-1"},
   672  								},
   673  								{
   674  									App: resources.RouteDestinationApp{GUID: "app-guid-2"},
   675  								},
   676  							},
   677  						},
   678  						AppNames: []string{"app-name-1", "app-name-2"},
   679  					},
   680  					{
   681  						Route: resources.Route{
   682  							GUID:         "route-guid-3",
   683  							Destinations: []resources.RouteDestination{},
   684  							DomainGUID:   "domain-guid-1",
   685  							Port:         1028,
   686  							URL:          "domain-1.com:1028",
   687  						},
   688  						AppNames:   nil,
   689  						DomainName: "domain-1.com",
   690  					},
   691  				}))
   692  				Expect(warnings).To(ConsistOf("get-apps-warning"))
   693  				Expect(executeErr).ToNot(HaveOccurred())
   694  
   695  				Expect(fakeCloudControllerClient.GetApplicationsCallCount()).To(Equal(1))
   696  				query := fakeCloudControllerClient.GetApplicationsArgsForCall(0)
   697  				Expect(query).To(ConsistOf(
   698  					ccv3.Query{Key: ccv3.GUIDFilter, Values: []string{"app-guid-1", "app-guid-2"}},
   699  				))
   700  			})
   701  		})
   702  
   703  		When("getting apps fails", func() {
   704  			var err = errors.New("failed to get apps")
   705  
   706  			BeforeEach(func() {
   707  				fakeCloudControllerClient.GetApplicationsReturns(
   708  					nil,
   709  					ccv3.Warnings{"get-apps-warning"},
   710  					err,
   711  				)
   712  			})
   713  
   714  			It("returns the error and any warnings", func() {
   715  				Expect(executeErr).To(Equal(err))
   716  				Expect(warnings).To(ConsistOf("get-apps-warning"))
   717  			})
   718  		})
   719  	})
   720  
   721  	Describe("GetRouteDestinations", func() {
   722  		var (
   723  			routeGUID    string
   724  			destinations []resources.RouteDestination
   725  
   726  			executeErr error
   727  			warnings   Warnings
   728  		)
   729  
   730  		JustBeforeEach(func() {
   731  			destinations, warnings, executeErr = actor.GetRouteDestinations(routeGUID)
   732  		})
   733  
   734  		BeforeEach(func() {
   735  			routeGUID = "route-guid"
   736  		})
   737  
   738  		When("the cloud controller client errors", func() {
   739  			BeforeEach(func() {
   740  				fakeCloudControllerClient.GetRouteDestinationsReturns(
   741  					nil,
   742  					ccv3.Warnings{"get-destinations-warning"},
   743  					errors.New("get-destinations-error"),
   744  				)
   745  			})
   746  
   747  			It("returns the error and warnings", func() {
   748  				Expect(executeErr).To(MatchError(errors.New("get-destinations-error")))
   749  				Expect(warnings).To(ConsistOf("get-destinations-warning"))
   750  			})
   751  		})
   752  
   753  		When("the cloud controller client succeeds", func() {
   754  			BeforeEach(func() {
   755  				fakeCloudControllerClient.GetRouteDestinationsReturns(
   756  					[]resources.RouteDestination{
   757  						{GUID: "destination-guid-1", App: resources.RouteDestinationApp{GUID: "app-guid-1"}},
   758  						{GUID: "destination-guid-2", App: resources.RouteDestinationApp{GUID: "app-guid-2"}},
   759  					},
   760  					ccv3.Warnings{"get-destinations-warning"},
   761  					nil,
   762  				)
   763  			})
   764  
   765  			It("returns the destinations and warnings", func() {
   766  				Expect(executeErr).ToNot(HaveOccurred())
   767  				Expect(warnings).To(ConsistOf("get-destinations-warning"))
   768  				Expect(destinations).To(ConsistOf(
   769  					resources.RouteDestination{GUID: "destination-guid-1", App: resources.RouteDestinationApp{GUID: "app-guid-1"}},
   770  					resources.RouteDestination{GUID: "destination-guid-2", App: resources.RouteDestinationApp{GUID: "app-guid-2"}},
   771  				))
   772  			})
   773  		})
   774  	})
   775  
   776  	Describe("GetRouteDestinationByAppGUID", func() {
   777  		var (
   778  			routeGUID   = "route-guid"
   779  			appGUID     = "app-guid"
   780  			route       = resources.Route{GUID: routeGUID}
   781  			destination resources.RouteDestination
   782  
   783  			executeErr error
   784  		)
   785  
   786  		JustBeforeEach(func() {
   787  			destination, executeErr = actor.GetRouteDestinationByAppGUID(route, appGUID)
   788  		})
   789  
   790  		When("the cloud controller client succeeds with a matching app", func() {
   791  			BeforeEach(func() {
   792  				route.Destinations = []resources.RouteDestination{
   793  					{
   794  						GUID: "destination-guid-1",
   795  						App:  resources.RouteDestinationApp{GUID: appGUID, Process: struct{ Type string }{Type: "worker"}},
   796  					},
   797  					{
   798  						GUID: "destination-guid-2",
   799  						App:  resources.RouteDestinationApp{GUID: appGUID, Process: struct{ Type string }{Type: constant.ProcessTypeWeb}},
   800  					},
   801  					{
   802  						GUID: "destination-guid-3",
   803  						App:  resources.RouteDestinationApp{GUID: "app-guid-2", Process: struct{ Type string }{Type: constant.ProcessTypeWeb}},
   804  					},
   805  				}
   806  			})
   807  
   808  			It("returns the matching destination and warnings", func() {
   809  				Expect(executeErr).ToNot(HaveOccurred())
   810  				Expect(destination).To(Equal(resources.RouteDestination{
   811  					GUID: "destination-guid-2",
   812  					App:  resources.RouteDestinationApp{GUID: appGUID, Process: struct{ Type string }{Type: constant.ProcessTypeWeb}},
   813  				}))
   814  			})
   815  		})
   816  
   817  		When("the cloud controller client succeeds without a matching app", func() {
   818  			BeforeEach(func() {
   819  				route.Destinations = []resources.RouteDestination{
   820  					{
   821  						GUID: "destination-guid-1",
   822  						App:  resources.RouteDestinationApp{GUID: appGUID, Process: struct{ Type string }{Type: "worker"}},
   823  					},
   824  					{
   825  						GUID: "destination-guid-2",
   826  						App:  resources.RouteDestinationApp{GUID: "app-guid-2", Process: struct{ Type string }{Type: constant.ProcessTypeWeb}},
   827  					},
   828  					{
   829  						GUID: "destination-guid-3",
   830  						App:  resources.RouteDestinationApp{GUID: "app-guid-3", Process: struct{ Type string }{Type: constant.ProcessTypeWeb}},
   831  					},
   832  				}
   833  			})
   834  
   835  			It("returns an error and warnings", func() {
   836  				Expect(destination).To(Equal(resources.RouteDestination{}))
   837  				Expect(executeErr).To(MatchError(actionerror.RouteDestinationNotFoundError{
   838  					AppGUID:     appGUID,
   839  					ProcessType: constant.ProcessTypeWeb,
   840  					RouteGUID:   routeGUID,
   841  				}))
   842  			})
   843  		})
   844  	})
   845  
   846  	Describe("DeleteRoute", func() {
   847  		When("deleting a route", func() {
   848  			var (
   849  				warnings   Warnings
   850  				executeErr error
   851  			)
   852  			BeforeEach(func() {
   853  				fakeCloudControllerClient.GetDomainsReturns(
   854  					[]resources.Domain{
   855  						{GUID: "domain-guid", Name: "domain.com"},
   856  					},
   857  					ccv3.Warnings{"get-domains-warning"},
   858  					nil,
   859  				)
   860  
   861  				fakeCloudControllerClient.GetRoutesReturns(
   862  					[]resources.Route{
   863  						{GUID: "route-guid"},
   864  					},
   865  					ccv3.Warnings{"get-routes-warning"},
   866  					nil,
   867  				)
   868  				fakeCloudControllerClient.DeleteRouteReturns(
   869  					ccv3.JobURL("https://jobs/job_guid"),
   870  					ccv3.Warnings{"delete-warning"},
   871  					nil,
   872  				)
   873  			})
   874  
   875  			When("in the HTTP case", func() {
   876  				BeforeEach(func() {
   877  					warnings, executeErr = actor.DeleteRoute("domain.com", "hostname", "/path", 0)
   878  				})
   879  
   880  				It("delegates to the cloud controller client", func() {
   881  					Expect(executeErr).NotTo(HaveOccurred())
   882  					Expect(warnings).To(ConsistOf("get-domains-warning", "get-routes-warning", "delete-warning"))
   883  
   884  					// Get the domain
   885  					Expect(fakeCloudControllerClient.GetDomainsCallCount()).To(Equal(1))
   886  					query := fakeCloudControllerClient.GetDomainsArgsForCall(0)
   887  					Expect(query).To(ConsistOf([]ccv3.Query{
   888  						{Key: ccv3.NameFilter, Values: []string{"domain.com"}},
   889  					}))
   890  
   891  					// Get the route based on the domain GUID
   892  					Expect(fakeCloudControllerClient.GetRoutesCallCount()).To(Equal(1))
   893  					query = fakeCloudControllerClient.GetRoutesArgsForCall(0)
   894  					Expect(query).To(ConsistOf([]ccv3.Query{
   895  						{Key: ccv3.DomainGUIDFilter, Values: []string{"domain-guid"}},
   896  						{Key: ccv3.HostsFilter, Values: []string{"hostname"}},
   897  						{Key: ccv3.PathsFilter, Values: []string{"/path"}},
   898  					}))
   899  
   900  					// Delete the route asynchronously
   901  					Expect(fakeCloudControllerClient.DeleteRouteCallCount()).To(Equal(1))
   902  					passedRouteGuid := fakeCloudControllerClient.DeleteRouteArgsForCall(0)
   903  					Expect(passedRouteGuid).To(Equal("route-guid"))
   904  
   905  					// Poll the delete job
   906  					Expect(fakeCloudControllerClient.PollJobCallCount()).To(Equal(1))
   907  					responseJobUrl := fakeCloudControllerClient.PollJobArgsForCall(0)
   908  					Expect(responseJobUrl).To(Equal(ccv3.JobURL("https://jobs/job_guid")))
   909  				})
   910  			})
   911  
   912  			When("in the TCP case", func() {
   913  				BeforeEach(func() {
   914  					fakeCloudControllerClient.GetDomainsReturns(
   915  						[]resources.Domain{
   916  							{
   917  								GUID:      "domain-guid",
   918  								Name:      "domain.com",
   919  								Protocols: []string{"tcp"},
   920  							},
   921  						},
   922  						ccv3.Warnings{"get-domains-warning"},
   923  						nil,
   924  					)
   925  
   926  					warnings, executeErr = actor.DeleteRoute("domain.com", "", "", 1026)
   927  				})
   928  
   929  				It("delegates to the cloud controller client", func() {
   930  					Expect(executeErr).NotTo(HaveOccurred())
   931  					Expect(warnings).To(ConsistOf("get-domains-warning", "get-routes-warning", "delete-warning"))
   932  
   933  					// Get the domain
   934  					Expect(fakeCloudControllerClient.GetDomainsCallCount()).To(Equal(1))
   935  					query := fakeCloudControllerClient.GetDomainsArgsForCall(0)
   936  					Expect(query).To(ConsistOf([]ccv3.Query{
   937  						{Key: ccv3.NameFilter, Values: []string{"domain.com"}},
   938  					}))
   939  
   940  					// Get the route based on the domain GUID
   941  					Expect(fakeCloudControllerClient.GetRoutesCallCount()).To(Equal(1))
   942  					query = fakeCloudControllerClient.GetRoutesArgsForCall(0)
   943  					Expect(query).To(ConsistOf([]ccv3.Query{
   944  						{Key: ccv3.DomainGUIDFilter, Values: []string{"domain-guid"}},
   945  						{Key: ccv3.HostsFilter, Values: []string{""}},
   946  						{Key: ccv3.PathsFilter, Values: []string{""}},
   947  						{Key: ccv3.PortsFilter, Values: []string{"1026"}},
   948  					}))
   949  
   950  					// Delete the route asynchronously
   951  					Expect(fakeCloudControllerClient.DeleteRouteCallCount()).To(Equal(1))
   952  					passedRouteGuid := fakeCloudControllerClient.DeleteRouteArgsForCall(0)
   953  					Expect(passedRouteGuid).To(Equal("route-guid"))
   954  
   955  					// Poll the delete job
   956  					Expect(fakeCloudControllerClient.PollJobCallCount()).To(Equal(1))
   957  					responseJobUrl := fakeCloudControllerClient.PollJobArgsForCall(0)
   958  					Expect(responseJobUrl).To(Equal(ccv3.JobURL("https://jobs/job_guid")))
   959  				})
   960  			})
   961  
   962  			When("getting domains fails", func() {
   963  				BeforeEach(func() {
   964  					fakeCloudControllerClient.GetDomainsReturns(
   965  						nil,
   966  						ccv3.Warnings{"get-domains-warning"},
   967  						errors.New("get-domains-error"),
   968  					)
   969  				})
   970  
   971  				It("returns the error", func() {
   972  					warnings, err := actor.DeleteRoute("domain.com", "hostname", "path", 0)
   973  					Expect(err).To(MatchError("get-domains-error"))
   974  					Expect(warnings).To(ConsistOf("get-domains-warning"))
   975  				})
   976  			})
   977  
   978  			When("getting routes fails", func() {
   979  				BeforeEach(func() {
   980  					fakeCloudControllerClient.GetRoutesReturns(
   981  						nil,
   982  						ccv3.Warnings{"get-routes-warning"},
   983  						errors.New("get-routes-error"),
   984  					)
   985  				})
   986  
   987  				It("returns the error", func() {
   988  					warnings, err := actor.DeleteRoute("domain.com", "hostname", "path", 0)
   989  					Expect(err).To(MatchError("get-routes-error"))
   990  					Expect(warnings).To(ConsistOf("get-domains-warning", "get-routes-warning"))
   991  				})
   992  			})
   993  
   994  			When("deleting route fails", func() {
   995  				BeforeEach(func() {
   996  					fakeCloudControllerClient.DeleteRouteReturns(
   997  						"",
   998  						ccv3.Warnings{"delete-route-warning"},
   999  						errors.New("delete-route-error"),
  1000  					)
  1001  				})
  1002  
  1003  				It("returns the error", func() {
  1004  					warnings, err := actor.DeleteRoute("domain.com", "hostname", "path", 0)
  1005  					Expect(err).To(MatchError("delete-route-error"))
  1006  					Expect(warnings).To(ConsistOf("get-domains-warning", "get-routes-warning", "delete-route-warning"))
  1007  				})
  1008  			})
  1009  
  1010  			When("polling the job fails", func() {
  1011  				BeforeEach(func() {
  1012  					fakeCloudControllerClient.PollJobReturns(
  1013  						ccv3.Warnings{"poll-job-warning"},
  1014  						errors.New("async-route-delete-error"),
  1015  					)
  1016  				})
  1017  
  1018  				It("returns the error", func() {
  1019  					warnings, err := actor.DeleteRoute("domain.com", "hostname", "path", 0)
  1020  					Expect(err).To(MatchError("async-route-delete-error"))
  1021  					Expect(warnings).To(ConsistOf(
  1022  						"get-domains-warning",
  1023  						"get-routes-warning",
  1024  						"delete-warning",
  1025  						"poll-job-warning",
  1026  					))
  1027  				})
  1028  			})
  1029  
  1030  			When("no routes are returned", func() {
  1031  				BeforeEach(func() {
  1032  					fakeCloudControllerClient.GetRoutesReturns(
  1033  						[]resources.Route{},
  1034  						ccv3.Warnings{"get-routes-warning"},
  1035  						nil,
  1036  					)
  1037  				})
  1038  
  1039  				It("returns the error", func() {
  1040  					warnings, err := actor.DeleteRoute("domain.com", "hostname", "/path", 0)
  1041  					Expect(err).To(Equal(actionerror.RouteNotFoundError{
  1042  						DomainName: "domain.com",
  1043  						DomainGUID: "domain-guid",
  1044  						Host:       "hostname",
  1045  						Path:       "/path",
  1046  						Port:       0,
  1047  					}))
  1048  					Expect(warnings).To(ConsistOf("get-domains-warning", "get-routes-warning"))
  1049  				})
  1050  			})
  1051  		})
  1052  	})
  1053  
  1054  	Describe("GetRouteByAttributes", func() {
  1055  		var (
  1056  			domainName = "some-domain.com"
  1057  			domainGUID = "domain-guid"
  1058  			hostname   string
  1059  			path       string
  1060  			port       int
  1061  
  1062  			executeErr error
  1063  			warnings   Warnings
  1064  			route      resources.Route
  1065  			domain     resources.Domain
  1066  		)
  1067  
  1068  		BeforeEach(func() {
  1069  			hostname = ""
  1070  			path = ""
  1071  			port = 0
  1072  		})
  1073  
  1074  		JustBeforeEach(func() {
  1075  			route, warnings, executeErr = actor.GetRouteByAttributes(domain, hostname, path, port)
  1076  		})
  1077  
  1078  		When("dealing with HTTP routes", func() {
  1079  			BeforeEach(func() {
  1080  				domain = resources.Domain{
  1081  					Name:      domainName,
  1082  					GUID:      domainGUID,
  1083  					Protocols: []string{"http"},
  1084  				}
  1085  				hostname = "hostname"
  1086  				path = "/path"
  1087  			})
  1088  
  1089  			When("The cc client errors", func() {
  1090  				BeforeEach(func() {
  1091  					fakeCloudControllerClient.GetRoutesReturns(nil, ccv3.Warnings{"get-routes-warning"}, errors.New("scooby"))
  1092  				})
  1093  				It("returns and empty route, warnings, and the error", func() {
  1094  					Expect(fakeCloudControllerClient.GetRoutesCallCount()).To(Equal(1))
  1095  
  1096  					Expect(warnings).To(ConsistOf("get-routes-warning"))
  1097  					Expect(executeErr).To(MatchError(errors.New("scooby")))
  1098  				})
  1099  			})
  1100  
  1101  			When("the cc client succeeds and a route is found", func() {
  1102  				BeforeEach(func() {
  1103  					fakeCloudControllerClient.GetRoutesReturns([]resources.Route{{
  1104  						DomainGUID: domainGUID,
  1105  						Host:       hostname,
  1106  						Path:       path,
  1107  					}}, ccv3.Warnings{"get-routes-warning"}, nil)
  1108  				})
  1109  
  1110  				It("returns the route and the warnings", func() {
  1111  					Expect(fakeCloudControllerClient.GetRoutesCallCount()).To(Equal(1))
  1112  					actualQueries := fakeCloudControllerClient.GetRoutesArgsForCall(0)
  1113  					Expect(actualQueries).To(ConsistOf(
  1114  						ccv3.Query{Key: ccv3.DomainGUIDFilter, Values: []string{domainGUID}},
  1115  						ccv3.Query{Key: ccv3.HostsFilter, Values: []string{hostname}},
  1116  						ccv3.Query{Key: ccv3.PathsFilter, Values: []string{path}},
  1117  					))
  1118  
  1119  					Expect(warnings).To(ConsistOf("get-routes-warning"))
  1120  					Expect(executeErr).ToNot(HaveOccurred())
  1121  					Expect(route).To(Equal(resources.Route{
  1122  						DomainGUID: domainGUID,
  1123  						Host:       hostname,
  1124  						Path:       path,
  1125  					}))
  1126  				})
  1127  			})
  1128  
  1129  			When("the cc client succeeds and a route is not found", func() {
  1130  				BeforeEach(func() {
  1131  					fakeCloudControllerClient.GetRoutesReturns([]resources.Route{}, ccv3.Warnings{"get-routes-warning"}, nil)
  1132  				})
  1133  
  1134  				It("returns the route and the warnings", func() {
  1135  					Expect(fakeCloudControllerClient.GetRoutesCallCount()).To(Equal(1))
  1136  
  1137  					Expect(warnings).To(ConsistOf("get-routes-warning"))
  1138  					Expect(executeErr).To(MatchError(actionerror.RouteNotFoundError{
  1139  						DomainName: domainName,
  1140  						DomainGUID: domainGUID,
  1141  						Host:       hostname,
  1142  						Path:       path,
  1143  					}))
  1144  				})
  1145  			})
  1146  		})
  1147  
  1148  		When("dealing with TCP routes", func() {
  1149  			BeforeEach(func() {
  1150  				domain = resources.Domain{
  1151  					Name:      domainName,
  1152  					GUID:      domainGUID,
  1153  					Protocols: []string{"tcp"},
  1154  				}
  1155  				port = 1028
  1156  			})
  1157  
  1158  			When("The cc client errors", func() {
  1159  				BeforeEach(func() {
  1160  					fakeCloudControllerClient.GetRoutesReturns(nil, ccv3.Warnings{"get-routes-warning"}, errors.New("scooby"))
  1161  				})
  1162  
  1163  				It("returns and empty route, warnings, and the error", func() {
  1164  					Expect(fakeCloudControllerClient.GetRoutesCallCount()).To(Equal(1))
  1165  
  1166  					Expect(warnings).To(ConsistOf("get-routes-warning"))
  1167  					Expect(executeErr).To(MatchError(errors.New("scooby")))
  1168  				})
  1169  			})
  1170  
  1171  			When("the cc client succeeds and a route is found", func() {
  1172  				BeforeEach(func() {
  1173  					fakeCloudControllerClient.GetRoutesReturns([]resources.Route{{
  1174  						DomainGUID: domainGUID,
  1175  						Port:       port,
  1176  					}}, ccv3.Warnings{"get-routes-warning"}, nil)
  1177  				})
  1178  
  1179  				It("returns the route and the warnings", func() {
  1180  					Expect(fakeCloudControllerClient.GetRoutesCallCount()).To(Equal(1))
  1181  					actualQueries := fakeCloudControllerClient.GetRoutesArgsForCall(0)
  1182  					Expect(actualQueries).To(ConsistOf(
  1183  						ccv3.Query{Key: ccv3.DomainGUIDFilter, Values: []string{domainGUID}},
  1184  						ccv3.Query{Key: ccv3.PortsFilter, Values: []string{fmt.Sprintf("%d", port)}},
  1185  						ccv3.Query{Key: ccv3.HostsFilter, Values: []string{""}},
  1186  						ccv3.Query{Key: ccv3.PathsFilter, Values: []string{""}},
  1187  					))
  1188  
  1189  					Expect(warnings).To(ConsistOf("get-routes-warning"))
  1190  					Expect(executeErr).ToNot(HaveOccurred())
  1191  					Expect(route).To(Equal(resources.Route{
  1192  						DomainGUID: domainGUID,
  1193  						Port:       port,
  1194  					}))
  1195  				})
  1196  			})
  1197  
  1198  			When("the cc client succeeds and a route is not found", func() {
  1199  				BeforeEach(func() {
  1200  					fakeCloudControllerClient.GetRoutesReturns([]resources.Route{}, ccv3.Warnings{"get-routes-warning"}, nil)
  1201  				})
  1202  				It("returns the route and the warnings", func() {
  1203  					Expect(fakeCloudControllerClient.GetRoutesCallCount()).To(Equal(1))
  1204  
  1205  					Expect(warnings).To(ConsistOf("get-routes-warning"))
  1206  					Expect(executeErr).To(MatchError(actionerror.RouteNotFoundError{
  1207  						DomainName: domainName,
  1208  						DomainGUID: domainGUID,
  1209  						Port:       port,
  1210  					}))
  1211  				})
  1212  			})
  1213  		})
  1214  	})
  1215  
  1216  	Describe("MapRoute", func() {
  1217  		var (
  1218  			routeGUID string
  1219  			appGUID   string
  1220  
  1221  			executeErr error
  1222  			warnings   Warnings
  1223  		)
  1224  
  1225  		JustBeforeEach(func() {
  1226  			warnings, executeErr = actor.MapRoute(routeGUID, appGUID)
  1227  		})
  1228  
  1229  		BeforeEach(func() {
  1230  			routeGUID = "route-guid"
  1231  			appGUID = "app-guid"
  1232  		})
  1233  
  1234  		When("the cloud controller client errors", func() {
  1235  			BeforeEach(func() {
  1236  				fakeCloudControllerClient.MapRouteReturns(ccv3.Warnings{"map-route-warning"}, errors.New("map-route-error"))
  1237  			})
  1238  
  1239  			It("returns the error and warnings", func() {
  1240  				Expect(executeErr).To(MatchError(errors.New("map-route-error")))
  1241  				Expect(warnings).To(ConsistOf("map-route-warning"))
  1242  			})
  1243  		})
  1244  
  1245  		When("the cloud controller client succeeds", func() {
  1246  			BeforeEach(func() {
  1247  				fakeCloudControllerClient.MapRouteReturns(ccv3.Warnings{"map-route-warning"}, nil)
  1248  			})
  1249  
  1250  			It("returns the error and warnings", func() {
  1251  				Expect(executeErr).ToNot(HaveOccurred())
  1252  				Expect(warnings).To(ConsistOf("map-route-warning"))
  1253  			})
  1254  		})
  1255  	})
  1256  
  1257  	Describe("UnmapRoute", func() {
  1258  		var (
  1259  			routeGUID       string
  1260  			destinationGUID string
  1261  
  1262  			executeErr error
  1263  			warnings   Warnings
  1264  		)
  1265  
  1266  		JustBeforeEach(func() {
  1267  			warnings, executeErr = actor.UnmapRoute(routeGUID, destinationGUID)
  1268  		})
  1269  
  1270  		BeforeEach(func() {
  1271  			routeGUID = "route-guid"
  1272  			destinationGUID = "destination-guid"
  1273  		})
  1274  
  1275  		When("the cloud controller client errors", func() {
  1276  			BeforeEach(func() {
  1277  				fakeCloudControllerClient.UnmapRouteReturns(ccv3.Warnings{"unmap-route-warning"}, errors.New("unmap-route-error"))
  1278  			})
  1279  
  1280  			It("returns the error and warnings", func() {
  1281  				Expect(executeErr).To(MatchError(errors.New("unmap-route-error")))
  1282  				Expect(warnings).To(ConsistOf("unmap-route-warning"))
  1283  			})
  1284  		})
  1285  
  1286  		When("the cloud controller client succeeds", func() {
  1287  			BeforeEach(func() {
  1288  				fakeCloudControllerClient.UnmapRouteReturns(ccv3.Warnings{"unmap-route-warning"}, nil)
  1289  			})
  1290  
  1291  			It("returns the error and warnings", func() {
  1292  				Expect(executeErr).ToNot(HaveOccurred())
  1293  				Expect(warnings).To(ConsistOf("unmap-route-warning"))
  1294  			})
  1295  		})
  1296  	})
  1297  
  1298  	Describe("DeleteOrphanedRoutes", func() {
  1299  		var (
  1300  			spaceGUID string
  1301  
  1302  			warnings   Warnings
  1303  			executeErr error
  1304  		)
  1305  		BeforeEach(func() {
  1306  			spaceGUID = "space-guid"
  1307  		})
  1308  
  1309  		JustBeforeEach(func() {
  1310  			warnings, executeErr = actor.DeleteOrphanedRoutes(spaceGUID)
  1311  		})
  1312  
  1313  		When("the cloud controller client succeeds", func() {
  1314  			BeforeEach(func() {
  1315  				fakeCloudControllerClient.DeleteOrphanedRoutesReturns(
  1316  					ccv3.JobURL("job"),
  1317  					ccv3.Warnings{"delete-orphaned-routes-warning"},
  1318  					nil,
  1319  				)
  1320  			})
  1321  
  1322  			It("deletes orphaned routes", func() {
  1323  				Expect(fakeCloudControllerClient.DeleteOrphanedRoutesCallCount()).To(Equal(1))
  1324  				Expect(fakeCloudControllerClient.DeleteOrphanedRoutesArgsForCall(0)).To(Equal(spaceGUID))
  1325  			})
  1326  
  1327  			When("polling the job succeeds", func() {
  1328  				BeforeEach(func() {
  1329  					fakeCloudControllerClient.PollJobReturns(ccv3.Warnings{"poll-job-warning"}, nil)
  1330  				})
  1331  				It("returns the error and warnings", func() {
  1332  					Expect(executeErr).ToNot(HaveOccurred())
  1333  					Expect(warnings).To(ConsistOf("delete-orphaned-routes-warning", "poll-job-warning"))
  1334  
  1335  					Expect(fakeCloudControllerClient.PollJobCallCount()).To(Equal(1))
  1336  					Expect(fakeCloudControllerClient.PollJobArgsForCall(0)).To(Equal(ccv3.JobURL("job")))
  1337  				})
  1338  			})
  1339  
  1340  			When("polling the job errors", func() {
  1341  				BeforeEach(func() {
  1342  					fakeCloudControllerClient.PollJobReturns(ccv3.Warnings{"poll-job-warning"}, errors.New("poll-error"))
  1343  				})
  1344  				It("returns the error and warnings", func() {
  1345  					Expect(executeErr).To(MatchError("poll-error"))
  1346  					Expect(warnings).To(ConsistOf("delete-orphaned-routes-warning", "poll-job-warning"))
  1347  
  1348  					Expect(fakeCloudControllerClient.PollJobCallCount()).To(Equal(1))
  1349  					Expect(fakeCloudControllerClient.PollJobArgsForCall(0)).To(Equal(ccv3.JobURL("job")))
  1350  				})
  1351  			})
  1352  		})
  1353  
  1354  		When("the cloud controller client error", func() {
  1355  			BeforeEach(func() {
  1356  				fakeCloudControllerClient.DeleteOrphanedRoutesReturns(
  1357  					ccv3.JobURL(""),
  1358  					ccv3.Warnings{"delete-orphaned-routes-warning"},
  1359  					errors.New("orphaned-error"),
  1360  				)
  1361  			})
  1362  
  1363  			It("returns the error and warnings", func() {
  1364  				Expect(executeErr).To(MatchError("orphaned-error"))
  1365  				Expect(warnings).To(ConsistOf("delete-orphaned-routes-warning"))
  1366  
  1367  				Expect(fakeCloudControllerClient.DeleteOrphanedRoutesCallCount()).To(Equal(1))
  1368  				Expect(fakeCloudControllerClient.DeleteOrphanedRoutesArgsForCall(0)).To(Equal(spaceGUID))
  1369  
  1370  				Expect(fakeCloudControllerClient.PollJobCallCount()).To(Equal(0))
  1371  			})
  1372  		})
  1373  	})
  1374  
  1375  	Describe("GetApplicationRoutes", func() {
  1376  		var (
  1377  			appGUID string
  1378  
  1379  			routes     []resources.Route
  1380  			warnings   Warnings
  1381  			executeErr error
  1382  		)
  1383  
  1384  		BeforeEach(func() {
  1385  			appGUID = "some-app-guid"
  1386  		})
  1387  
  1388  		JustBeforeEach(func() {
  1389  			routes, warnings, executeErr = actor.GetApplicationRoutes(appGUID)
  1390  		})
  1391  
  1392  		When("getting routes fails", func() {
  1393  			BeforeEach(func() {
  1394  				fakeCloudControllerClient.GetApplicationRoutesReturns(
  1395  					[]resources.Route{},
  1396  					ccv3.Warnings{"get-application-routes-warning"},
  1397  					errors.New("application-routes-error"),
  1398  				)
  1399  			})
  1400  
  1401  			It("returns the warnings and error", func() {
  1402  				Expect(executeErr).To(MatchError("application-routes-error"))
  1403  				Expect(warnings).To(ConsistOf("get-application-routes-warning"))
  1404  
  1405  				Expect(fakeCloudControllerClient.GetApplicationRoutesCallCount()).To(Equal(1))
  1406  				Expect(fakeCloudControllerClient.GetApplicationRoutesArgsForCall(0)).To(Equal(appGUID))
  1407  			})
  1408  		})
  1409  
  1410  		When("getting routes succeeds", func() {
  1411  			BeforeEach(func() {
  1412  				fakeCloudControllerClient.GetApplicationRoutesReturns(
  1413  					[]resources.Route{
  1414  						{
  1415  							GUID:       "some-route-guid",
  1416  							URL:        "some-url.sh",
  1417  							SpaceGUID:  "routes-space-guid",
  1418  							DomainGUID: "routes-domain-guid",
  1419  						},
  1420  					},
  1421  					ccv3.Warnings{"get-application-routes-warning"},
  1422  					nil,
  1423  				)
  1424  			})
  1425  
  1426  			It("returns the warnings and routes", func() {
  1427  				Expect(executeErr).NotTo(HaveOccurred())
  1428  				Expect(warnings).To(ConsistOf("get-application-routes-warning"))
  1429  
  1430  				Expect(fakeCloudControllerClient.GetApplicationRoutesCallCount()).To(Equal(1))
  1431  				Expect(fakeCloudControllerClient.GetApplicationRoutesArgsForCall(0)).To(Equal(appGUID))
  1432  
  1433  				Expect(routes).To(ConsistOf(
  1434  					resources.Route{
  1435  						GUID:       "some-route-guid",
  1436  						URL:        "some-url.sh",
  1437  						SpaceGUID:  "routes-space-guid",
  1438  						DomainGUID: "routes-domain-guid",
  1439  					},
  1440  				))
  1441  			})
  1442  
  1443  			When("no routes are returned", func() {
  1444  				BeforeEach(func() {
  1445  					fakeCloudControllerClient.GetApplicationRoutesReturns(
  1446  						[]resources.Route{},
  1447  						ccv3.Warnings{"get-application-routes-warning"},
  1448  						nil,
  1449  					)
  1450  				})
  1451  
  1452  				It("returns an empty list", func() {
  1453  					Expect(executeErr).NotTo(HaveOccurred())
  1454  					Expect(warnings).To(ConsistOf("get-application-routes-warning"))
  1455  					Expect(routes).To(HaveLen(0))
  1456  				})
  1457  			})
  1458  		})
  1459  	})
  1460  })