github.com/ablease/cli@v6.37.1-0.20180613014814-3adbb7d7fb19+incompatible/api/cloudcontroller/ccv2/route_test.go (about)

     1  package ccv2_test
     2  
     3  import (
     4  	"net/http"
     5  
     6  	"code.cloudfoundry.org/cli/api/cloudcontroller/ccerror"
     7  	. "code.cloudfoundry.org/cli/api/cloudcontroller/ccv2"
     8  	"code.cloudfoundry.org/cli/api/cloudcontroller/ccv2/constant"
     9  	"code.cloudfoundry.org/cli/types"
    10  	. "github.com/onsi/ginkgo"
    11  	. "github.com/onsi/gomega"
    12  	. "github.com/onsi/gomega/ghttp"
    13  )
    14  
    15  var _ = Describe("Route", func() {
    16  	var client *Client
    17  
    18  	BeforeEach(func() {
    19  		client = NewTestClient()
    20  	})
    21  
    22  	Describe("CreateRoute", func() {
    23  		Context("when route creation is successful", func() {
    24  			Context("when generate port is true", func() {
    25  				BeforeEach(func() {
    26  					response := `
    27  						{
    28  							"metadata": {
    29  								"guid": "some-route-guid"
    30  							},
    31  							"entity": {
    32  								"domain_guid": "some-domain-guid",
    33  								"host": "some-host",
    34  								"path": "some-path",
    35  								"port": 100000,
    36  								"space_guid": "some-space-guid"
    37  							}
    38  						}`
    39  					requestBody := map[string]interface{}{
    40  						"domain_guid": "some-domain-guid",
    41  						"host":        "some-host",
    42  						"path":        "some-path",
    43  						"port":        42,
    44  						"space_guid":  "some-space-guid",
    45  					}
    46  					server.AppendHandlers(
    47  						CombineHandlers(
    48  							VerifyRequest(http.MethodPost, "/v2/routes", "generate_port=true"),
    49  							VerifyJSONRepresenting(requestBody),
    50  							RespondWith(http.StatusCreated, response, http.Header{"X-Cf-Warnings": {"this is a warning"}}),
    51  						),
    52  					)
    53  				})
    54  
    55  				It("creates the route with a random port", func() {
    56  					route, warnings, err := client.CreateRoute(Route{
    57  						DomainGUID: "some-domain-guid",
    58  						Host:       "some-host",
    59  						Path:       "some-path",
    60  						Port:       types.NullInt{IsSet: true, Value: 42},
    61  						SpaceGUID:  "some-space-guid",
    62  					}, true)
    63  
    64  					Expect(err).ToNot(HaveOccurred())
    65  					Expect(warnings).To(ConsistOf("this is a warning"))
    66  					Expect(route).To(Equal(Route{
    67  						DomainGUID: "some-domain-guid",
    68  						GUID:       "some-route-guid",
    69  						Host:       "some-host",
    70  						Path:       "some-path",
    71  						Port:       types.NullInt{IsSet: true, Value: 100000},
    72  						SpaceGUID:  "some-space-guid",
    73  					}))
    74  				})
    75  			})
    76  
    77  			Context("when generate route is false", func() {
    78  				BeforeEach(func() {
    79  					response := `
    80  						{
    81  							"metadata": {
    82  								"guid": "some-route-guid"
    83  							},
    84  							"entity": {
    85  								"domain_guid": "some-domain-guid",
    86  								"host": "some-host",
    87  								"path": "some-path",
    88  								"port": 42,
    89  								"space_guid": "some-space-guid"
    90  							}
    91  						}`
    92  					requestBody := map[string]interface{}{
    93  						"domain_guid": "some-domain-guid",
    94  						"host":        "some-host",
    95  						"path":        "some-path",
    96  						"port":        42,
    97  						"space_guid":  "some-space-guid",
    98  					}
    99  					server.AppendHandlers(
   100  						CombineHandlers(
   101  							VerifyRequest(http.MethodPost, "/v2/routes"),
   102  							VerifyJSONRepresenting(requestBody),
   103  							RespondWith(http.StatusCreated, response, http.Header{"X-Cf-Warnings": {"this is a warning"}}),
   104  						),
   105  					)
   106  				})
   107  
   108  				It("creates the route with the given port", func() {
   109  					route, warnings, err := client.CreateRoute(Route{
   110  						DomainGUID: "some-domain-guid",
   111  						Host:       "some-host",
   112  						Path:       "some-path",
   113  						Port:       types.NullInt{IsSet: true, Value: 42},
   114  						SpaceGUID:  "some-space-guid",
   115  					}, false)
   116  
   117  					Expect(err).ToNot(HaveOccurred())
   118  					Expect(warnings).To(ConsistOf("this is a warning"))
   119  					Expect(route).To(Equal(Route{
   120  						DomainGUID: "some-domain-guid",
   121  						GUID:       "some-route-guid",
   122  						Host:       "some-host",
   123  						Path:       "some-path",
   124  						Port:       types.NullInt{IsSet: true, Value: 42},
   125  						SpaceGUID:  "some-space-guid",
   126  					}))
   127  				})
   128  			})
   129  
   130  			Context("when sending a basic route", func() {
   131  				BeforeEach(func() {
   132  					response := `
   133  						{
   134  							"metadata": {
   135  								"guid": "some-route-guid"
   136  							},
   137  							"entity": {
   138  								"domain_guid": "some-domain-guid",
   139  								"space_guid": "some-space-guid"
   140  							}
   141  						}`
   142  					requestBody := map[string]interface{}{
   143  						"port":        nil,
   144  						"domain_guid": "some-domain-guid",
   145  						"space_guid":  "some-space-guid",
   146  					}
   147  					server.AppendHandlers(
   148  						CombineHandlers(
   149  							VerifyRequest(http.MethodPost, "/v2/routes"),
   150  							VerifyJSONRepresenting(requestBody),
   151  							RespondWith(http.StatusCreated, response, http.Header{"X-Cf-Warnings": {"this is a warning"}}),
   152  						),
   153  					)
   154  				})
   155  
   156  				It("creates the route with only the space and domain guids", func() {
   157  					route, warnings, err := client.CreateRoute(Route{
   158  						DomainGUID: "some-domain-guid",
   159  						SpaceGUID:  "some-space-guid",
   160  					}, false)
   161  
   162  					Expect(err).ToNot(HaveOccurred())
   163  					Expect(warnings).To(ConsistOf("this is a warning"))
   164  					Expect(route).To(Equal(Route{
   165  						DomainGUID: "some-domain-guid",
   166  						GUID:       "some-route-guid",
   167  						SpaceGUID:  "some-space-guid",
   168  					}))
   169  				})
   170  			})
   171  		})
   172  
   173  		Context("when the cc returns an error", func() {
   174  			BeforeEach(func() {
   175  				response := `{
   176  					"code": 10001,
   177  					"description": "Some Error",
   178  					"error_code": "CF-SomeError"
   179  				}`
   180  				server.AppendHandlers(
   181  					CombineHandlers(
   182  						VerifyRequest(http.MethodPost, "/v2/routes"),
   183  						RespondWith(http.StatusTeapot, response, http.Header{"X-Cf-Warnings": {"this is a warning"}}),
   184  					),
   185  				)
   186  			})
   187  
   188  			It("returns an error", func() {
   189  				_, warnings, err := client.CreateRoute(Route{}, false)
   190  				Expect(err).To(MatchError(ccerror.V2UnexpectedResponseError{
   191  					ResponseCode: http.StatusTeapot,
   192  					V2ErrorResponse: ccerror.V2ErrorResponse{
   193  						Code:        10001,
   194  						Description: "Some Error",
   195  						ErrorCode:   "CF-SomeError",
   196  					},
   197  				}))
   198  				Expect(warnings).To(ConsistOf("this is a warning"))
   199  			})
   200  		})
   201  	})
   202  
   203  	Describe("DeleteRoute", func() {
   204  		Context("when the route exists", func() {
   205  			BeforeEach(func() {
   206  				server.AppendHandlers(
   207  					CombineHandlers(
   208  						VerifyRequest(http.MethodDelete, "/v2/routes/some-route-guid"),
   209  						RespondWith(http.StatusNoContent, "{}", http.Header{"X-Cf-Warnings": {"this is a warning"}}),
   210  					),
   211  				)
   212  			})
   213  
   214  			It("deletes the route and returns all warnings", func() {
   215  				warnings, err := client.DeleteRoute("some-route-guid")
   216  				Expect(err).NotTo(HaveOccurred())
   217  				Expect(warnings).To(ConsistOf(Warnings{"this is a warning"}))
   218  			})
   219  		})
   220  
   221  		Context("when the route does not exist", func() {
   222  			BeforeEach(func() {
   223  				response := `{
   224  				"code": 210002,
   225  				"description": "The route could not be found: some-route-guid",
   226  				"error_code": "CF-RouteNotFound"
   227  			}`
   228  				server.AppendHandlers(
   229  					CombineHandlers(
   230  						VerifyRequest(http.MethodDelete, "/v2/routes/some-route-guid"),
   231  						RespondWith(http.StatusNotFound, response),
   232  					),
   233  				)
   234  			})
   235  
   236  			It("returns an error", func() {
   237  				_, err := client.DeleteRoute("some-route-guid")
   238  				Expect(err).To(MatchError(ccerror.ResourceNotFoundError{
   239  					Message: "The route could not be found: some-route-guid",
   240  				}))
   241  			})
   242  		})
   243  	})
   244  
   245  	Describe("DeleteRouteApplication", func() {
   246  		Context("when the delete is successful", func() {
   247  			BeforeEach(func() {
   248  				server.AppendHandlers(
   249  					CombineHandlers(
   250  						VerifyRequest(http.MethodDelete, "/v2/routes/some-route-guid/apps/some-app-guid"),
   251  						RespondWith(http.StatusNoContent, nil, http.Header{"X-Cf-Warnings": {"this is a warning"}}),
   252  					),
   253  				)
   254  			})
   255  
   256  			It("returns the route and warnings", func() {
   257  				warnings, err := client.DeleteRouteApplication("some-route-guid", "some-app-guid")
   258  				Expect(err).ToNot(HaveOccurred())
   259  				Expect(warnings).To(ConsistOf("this is a warning"))
   260  			})
   261  		})
   262  
   263  		Context("when the cc returns an error", func() {
   264  			BeforeEach(func() {
   265  				response := `{
   266  					"code": 10001,
   267  					"description": "Some Error",
   268  					"error_code": "CF-SomeError"
   269  				}`
   270  				server.AppendHandlers(
   271  					CombineHandlers(
   272  						VerifyRequest(http.MethodDelete, "/v2/routes/some-route-guid/apps/some-app-guid"),
   273  						RespondWith(http.StatusTeapot, response, http.Header{"X-Cf-Warnings": {"this is a warning"}}),
   274  					),
   275  				)
   276  			})
   277  
   278  			It("returns an error", func() {
   279  				warnings, err := client.DeleteRouteApplication("some-route-guid", "some-app-guid")
   280  				Expect(err).To(MatchError(ccerror.V2UnexpectedResponseError{
   281  					ResponseCode: http.StatusTeapot,
   282  					V2ErrorResponse: ccerror.V2ErrorResponse{
   283  						Code:        10001,
   284  						Description: "Some Error",
   285  						ErrorCode:   "CF-SomeError",
   286  					},
   287  				}))
   288  				Expect(warnings).To(ConsistOf("this is a warning"))
   289  			})
   290  		})
   291  	})
   292  
   293  	Describe("DoesRouteExist", func() {
   294  		var (
   295  			route      Route
   296  			exists     bool
   297  			warnings   Warnings
   298  			executeErr error
   299  		)
   300  
   301  		JustBeforeEach(func() {
   302  			exists, warnings, executeErr = client.DoesRouteExist(route)
   303  		})
   304  
   305  		Context("API Version < MinVersionHTTPRoutePath", func() {
   306  			BeforeEach(func() {
   307  				client = NewClientWithCustomAPIVersion("2.35.0")
   308  			})
   309  
   310  			Context("with minimum params", func() {
   311  				BeforeEach(func() {
   312  					server.AppendHandlers(
   313  						CombineHandlers(
   314  							VerifyRequest(http.MethodGet, "/v2/routes/reserved/domain/some-domain-guid/host/some-host"),
   315  							RespondWith(http.StatusNoContent, "{}", http.Header{"X-Cf-Warnings": {"this is a warning"}}),
   316  						),
   317  					)
   318  
   319  					route = Route{DomainGUID: "some-domain-guid", Host: "some-host"}
   320  				})
   321  
   322  				It("does not contain any params", func() {
   323  					Expect(executeErr).NotTo(HaveOccurred())
   324  					Expect(warnings).To(ConsistOf(Warnings{"this is a warning"}))
   325  					Expect(exists).To(BeTrue())
   326  				})
   327  			})
   328  
   329  			Context("with all the params", func() {
   330  				BeforeEach(func() {
   331  					server.AppendHandlers(
   332  						CombineHandlers(
   333  							VerifyRequest(http.MethodGet, "/v2/routes/reserved/domain/some-domain-guid/host/some-host", "&"),
   334  							RespondWith(http.StatusNoContent, "{}", http.Header{"X-Cf-Warnings": {"this is a warning"}}),
   335  						),
   336  					)
   337  					route = Route{
   338  						Host:       "some-host",
   339  						DomainGUID: "some-domain-guid",
   340  						Path:       "some-path",
   341  						Port:       types.NullInt{IsSet: true, Value: 42},
   342  					}
   343  				})
   344  
   345  				It("contains all requested parameters", func() {
   346  					Expect(executeErr).NotTo(HaveOccurred())
   347  					Expect(warnings).To(ConsistOf(Warnings{"this is a warning"}))
   348  					Expect(exists).To(BeTrue())
   349  				})
   350  			})
   351  		})
   352  
   353  		Context("MinVersionHTTPRoutePath <= API Version < MinVersionNoHostInReservedRouteEndpoint", func() {
   354  			BeforeEach(func() {
   355  				client = NewClientWithCustomAPIVersion("2.36.0")
   356  			})
   357  
   358  			Context("when the route exists", func() {
   359  				Context("with minimum params", func() {
   360  					BeforeEach(func() {
   361  						server.AppendHandlers(
   362  							CombineHandlers(
   363  								VerifyRequest(http.MethodGet, "/v2/routes/reserved/domain/some-domain-guid/host/some-host"),
   364  								RespondWith(http.StatusNoContent, "{}", http.Header{"X-Cf-Warnings": {"this is a warning"}}),
   365  							),
   366  						)
   367  						route = Route{DomainGUID: "some-domain-guid", Host: "some-host"}
   368  					})
   369  
   370  					It("does not contain any params", func() {
   371  						Expect(executeErr).NotTo(HaveOccurred())
   372  						Expect(warnings).To(ConsistOf(Warnings{"this is a warning"}))
   373  					})
   374  				})
   375  
   376  				Context("with all the params", func() {
   377  					BeforeEach(func() {
   378  						server.AppendHandlers(
   379  							CombineHandlers(
   380  								VerifyRequest(http.MethodGet, "/v2/routes/reserved/domain/some-domain-guid/host/some-host", "path=some-path"),
   381  								RespondWith(http.StatusNoContent, "{}", http.Header{"X-Cf-Warnings": {"this is a warning"}}),
   382  							),
   383  						)
   384  						route = Route{
   385  							Host:       "some-host",
   386  							DomainGUID: "some-domain-guid",
   387  							Path:       "some-path",
   388  						}
   389  					})
   390  
   391  					It("contains all requested parameters", func() {
   392  						Expect(executeErr).NotTo(HaveOccurred())
   393  						Expect(warnings).To(ConsistOf(Warnings{"this is a warning"}))
   394  						Expect(exists).To(BeTrue())
   395  					})
   396  				})
   397  			})
   398  
   399  			Context("when the route does not exist", func() {
   400  				BeforeEach(func() {
   401  					server.AppendHandlers(
   402  						CombineHandlers(
   403  							VerifyRequest(http.MethodGet, "/v2/routes/reserved/domain/some-domain-guid/host/some-host"),
   404  							RespondWith(http.StatusNotFound, "{}", http.Header{"X-Cf-Warnings": {"this is a warning"}}),
   405  						),
   406  					)
   407  					route = Route{Host: "some-host", DomainGUID: "some-domain-guid"}
   408  				})
   409  
   410  				It("returns false", func() {
   411  					Expect(executeErr).NotTo(HaveOccurred())
   412  					Expect(warnings).To(ConsistOf(Warnings{"this is a warning"}))
   413  					Expect(exists).To(BeFalse())
   414  				})
   415  			})
   416  
   417  			Context("when the CC executeErrors", func() {
   418  				BeforeEach(func() {
   419  					response := `{
   420  						"code": 777,
   421  						"description": "The route could not be found: some-route-guid",
   422  						"error_code": "CF-WUT"
   423  					}`
   424  					server.AppendHandlers(
   425  						CombineHandlers(
   426  							VerifyRequest(http.MethodGet, "/v2/routes/reserved/domain/some-domain-guid/host/some-host"),
   427  							RespondWith(http.StatusTeapot, response, http.Header{"X-Cf-Warnings": {"this is a warning"}}),
   428  						),
   429  					)
   430  					route = Route{Host: "some-host", DomainGUID: "some-domain-guid"}
   431  				})
   432  
   433  				It("returns the error", func() {
   434  					Expect(executeErr).To(MatchError(ccerror.V2UnexpectedResponseError{
   435  						V2ErrorResponse: ccerror.V2ErrorResponse{
   436  							Code:        777,
   437  							Description: "The route could not be found: some-route-guid",
   438  							ErrorCode:   "CF-WUT",
   439  						},
   440  						ResponseCode: http.StatusTeapot,
   441  					}))
   442  					Expect(warnings).To(ConsistOf(Warnings{"this is a warning"}))
   443  				})
   444  			})
   445  		})
   446  
   447  		Context("MinVersionNoHostInReservedRouteEndpoint <= API Version", func() {
   448  			BeforeEach(func() {
   449  				client = NewClientWithCustomAPIVersion("2.55.0")
   450  			})
   451  
   452  			Context("when the route exists", func() {
   453  				Context("with minimum params", func() {
   454  					BeforeEach(func() {
   455  						server.AppendHandlers(
   456  							CombineHandlers(
   457  								VerifyRequest(http.MethodGet, "/v2/routes/reserved/domain/some-domain-guid"),
   458  								RespondWith(http.StatusNoContent, "{}", http.Header{"X-Cf-Warnings": {"this is a warning"}}),
   459  							),
   460  						)
   461  						route = Route{DomainGUID: "some-domain-guid"}
   462  					})
   463  
   464  					It("does not contain any params", func() {
   465  						Expect(executeErr).NotTo(HaveOccurred())
   466  						Expect(warnings).To(ConsistOf(Warnings{"this is a warning"}))
   467  					})
   468  				})
   469  
   470  				Context("with all the params", func() {
   471  					BeforeEach(func() {
   472  						server.AppendHandlers(
   473  							CombineHandlers(
   474  								VerifyRequest(http.MethodGet, "/v2/routes/reserved/domain/some-domain-guid", "host=some-host&path=some-path&port=42"),
   475  								RespondWith(http.StatusNoContent, "{}", http.Header{"X-Cf-Warnings": {"this is a warning"}}),
   476  							),
   477  						)
   478  						route = Route{
   479  							Host:       "some-host",
   480  							DomainGUID: "some-domain-guid",
   481  							Path:       "some-path",
   482  							Port:       types.NullInt{IsSet: true, Value: 42},
   483  						}
   484  					})
   485  
   486  					It("contains all requested parameters", func() {
   487  						Expect(executeErr).NotTo(HaveOccurred())
   488  						Expect(warnings).To(ConsistOf(Warnings{"this is a warning"}))
   489  						Expect(exists).To(BeTrue())
   490  					})
   491  				})
   492  			})
   493  
   494  			Context("when the route does not exist", func() {
   495  				BeforeEach(func() {
   496  					server.AppendHandlers(
   497  						CombineHandlers(
   498  							VerifyRequest(http.MethodGet, "/v2/routes/reserved/domain/some-domain-guid", "host=some-host"),
   499  							RespondWith(http.StatusNotFound, "{}", http.Header{"X-Cf-Warnings": {"this is a warning"}}),
   500  						),
   501  					)
   502  					route = Route{Host: "some-host", DomainGUID: "some-domain-guid"}
   503  				})
   504  
   505  				It("returns false", func() {
   506  					Expect(executeErr).NotTo(HaveOccurred())
   507  					Expect(warnings).To(ConsistOf(Warnings{"this is a warning"}))
   508  					Expect(exists).To(BeFalse())
   509  				})
   510  			})
   511  
   512  			Context("when the CC errors", func() {
   513  				BeforeEach(func() {
   514  					response := `{
   515  						"code": 777,
   516  						"description": "The route could not be found: some-route-guid",
   517  						"error_code": "CF-WUT"
   518  					}`
   519  					server.AppendHandlers(
   520  						CombineHandlers(
   521  							VerifyRequest(http.MethodGet, "/v2/routes/reserved/domain/some-domain-guid", "host=some-host"),
   522  							RespondWith(http.StatusTeapot, response, http.Header{"X-Cf-Warnings": {"this is a warning"}}),
   523  						),
   524  					)
   525  					route = Route{Host: "some-host", DomainGUID: "some-domain-guid"}
   526  				})
   527  
   528  				It("returns the error", func() {
   529  					Expect(executeErr).To(MatchError(ccerror.V2UnexpectedResponseError{
   530  						V2ErrorResponse: ccerror.V2ErrorResponse{
   531  							Code:        777,
   532  							Description: "The route could not be found: some-route-guid",
   533  							ErrorCode:   "CF-WUT",
   534  						},
   535  						ResponseCode: http.StatusTeapot,
   536  					}))
   537  					Expect(warnings).To(ConsistOf(Warnings{"this is a warning"}))
   538  				})
   539  			})
   540  		})
   541  	})
   542  
   543  	Describe("GetApplicationRoutes", func() {
   544  		Context("when there are routes in this space", func() {
   545  			BeforeEach(func() {
   546  				response1 := `{
   547  				"next_url": "/v2/apps/some-app-guid/routes?q=organization_guid:some-org-guid&page=2",
   548  				"resources": [
   549  					{
   550  						"metadata": {
   551  							"guid": "route-guid-1",
   552  							"updated_at": null
   553  						},
   554  						"entity": {
   555  							"host": "host-1",
   556  							"path": "path",
   557  							"port": null,
   558  							"domain_guid": "some-http-domain",
   559  							"space_guid": "some-space-guid-1"
   560  						}
   561  					},
   562  					{
   563  						"metadata": {
   564  							"guid": "route-guid-2",
   565  							"updated_at": null
   566  						},
   567  						"entity": {
   568  							"host": "host-2",
   569  							"path": "",
   570  							"port": 3333,
   571  							"domain_guid": "some-tcp-domain",
   572  							"space_guid": "some-space-guid-1"
   573  						}
   574  					}
   575  				]
   576  			}`
   577  				response2 := `{
   578  				"next_url": null,
   579  				"resources": [
   580  					{
   581  						"metadata": {
   582  							"guid": "route-guid-3",
   583  							"updated_at": null
   584  						},
   585  						"entity": {
   586  							"host": "host-3",
   587  							"path": "path",
   588  							"port": null,
   589  							"domain_guid": "some-http-domain",
   590  							"space_guid": "some-space-guid-1"
   591  						}
   592  					},
   593  					{
   594  						"metadata": {
   595  							"guid": "route-guid-4",
   596  							"updated_at": null
   597  						},
   598  						"entity": {
   599  							"host": "host-4",
   600  							"path": "",
   601  							"port": 333,
   602  							"domain_guid": "some-tcp-domain",
   603  							"space_guid": "some-space-guid-1"
   604  						}
   605  					}
   606  				]
   607  			}`
   608  				server.AppendHandlers(
   609  					CombineHandlers(
   610  						VerifyRequest(http.MethodGet, "/v2/apps/some-app-guid/routes", "q=organization_guid:some-org-guid"),
   611  						RespondWith(http.StatusOK, response1, http.Header{"X-Cf-Warnings": {"this is a warning"}}),
   612  					),
   613  				)
   614  				server.AppendHandlers(
   615  					CombineHandlers(
   616  						VerifyRequest(http.MethodGet, "/v2/apps/some-app-guid/routes", "q=organization_guid:some-org-guid&page=2"),
   617  						RespondWith(http.StatusOK, response2, http.Header{"X-Cf-Warnings": {"this is another warning"}}),
   618  					),
   619  				)
   620  			})
   621  
   622  			It("returns all the routes and all warnings", func() {
   623  				routes, warnings, err := client.GetApplicationRoutes("some-app-guid", Filter{
   624  					Type:     constant.OrganizationGUIDFilter,
   625  					Operator: constant.EqualOperator,
   626  					Values:   []string{"some-org-guid"},
   627  				})
   628  				Expect(err).NotTo(HaveOccurred())
   629  				Expect(routes).To(ConsistOf([]Route{
   630  					{
   631  						GUID:       "route-guid-1",
   632  						Host:       "host-1",
   633  						Path:       "path",
   634  						Port:       types.NullInt{IsSet: false},
   635  						DomainGUID: "some-http-domain",
   636  						SpaceGUID:  "some-space-guid-1",
   637  					},
   638  					{
   639  						GUID:       "route-guid-2",
   640  						Host:       "host-2",
   641  						Path:       "",
   642  						Port:       types.NullInt{IsSet: true, Value: 3333},
   643  						DomainGUID: "some-tcp-domain",
   644  						SpaceGUID:  "some-space-guid-1",
   645  					},
   646  					{
   647  						GUID:       "route-guid-3",
   648  						Host:       "host-3",
   649  						Path:       "path",
   650  						Port:       types.NullInt{IsSet: false},
   651  						DomainGUID: "some-http-domain",
   652  						SpaceGUID:  "some-space-guid-1",
   653  					},
   654  					{
   655  						GUID:       "route-guid-4",
   656  						Host:       "host-4",
   657  						Path:       "",
   658  						Port:       types.NullInt{IsSet: true, Value: 333},
   659  						DomainGUID: "some-tcp-domain",
   660  						SpaceGUID:  "some-space-guid-1",
   661  					},
   662  				}))
   663  				Expect(warnings).To(ConsistOf(Warnings{"this is a warning", "this is another warning"}))
   664  			})
   665  		})
   666  
   667  		Context("when there are no routes bound to the app", func() {
   668  			BeforeEach(func() {
   669  				response := `{
   670  				"next_url": "",
   671  				"resources": []
   672  			}`
   673  				server.AppendHandlers(
   674  					CombineHandlers(
   675  						VerifyRequest(http.MethodGet, "/v2/apps/some-app-guid/routes"),
   676  						RespondWith(http.StatusOK, response),
   677  					),
   678  				)
   679  			})
   680  
   681  			It("returns an empty list of routes", func() {
   682  				routes, _, err := client.GetApplicationRoutes("some-app-guid")
   683  				Expect(err).NotTo(HaveOccurred())
   684  				Expect(routes).To(BeEmpty())
   685  			})
   686  		})
   687  
   688  		Context("when the app is not found", func() {
   689  			BeforeEach(func() {
   690  				response := `{
   691  					"code": 10000,
   692  					"description": "The app could not be found: some-app-guid",
   693  					"error_code": "CF-AppNotFound"
   694  				}`
   695  				server.AppendHandlers(
   696  					CombineHandlers(
   697  						VerifyRequest(http.MethodGet, "/v2/apps/some-app-guid/routes"),
   698  						RespondWith(http.StatusNotFound, response),
   699  					),
   700  				)
   701  			})
   702  
   703  			It("returns an error", func() {
   704  				routes, _, err := client.GetApplicationRoutes("some-app-guid")
   705  				Expect(err).To(MatchError(ccerror.ResourceNotFoundError{
   706  					Message: "The app could not be found: some-app-guid",
   707  				}))
   708  				Expect(routes).To(BeEmpty())
   709  			})
   710  		})
   711  	})
   712  
   713  	Describe("GetRoute", func() {
   714  		var (
   715  			route      Route
   716  			warnings   Warnings
   717  			executeErr error
   718  		)
   719  
   720  		JustBeforeEach(func() {
   721  			route, warnings, executeErr = client.GetRoute("some-route-guid")
   722  		})
   723  
   724  		Context("when the cc returns an error", func() {
   725  			BeforeEach(func() {
   726  				response := `{
   727  					"code": 1,
   728  					"description": "some error description",
   729  					"error_code": "CF-SomeError"
   730  				}`
   731  				server.AppendHandlers(
   732  					CombineHandlers(
   733  						VerifyRequest(http.MethodGet, "/v2/routes/some-route-guid"),
   734  						RespondWith(http.StatusTeapot, response, http.Header{"X-Cf-Warnings": {"warning-1, warning-2"}}),
   735  					),
   736  				)
   737  			})
   738  
   739  			It("returns the error", func() {
   740  				Expect(executeErr).To(MatchError(ccerror.V2UnexpectedResponseError{
   741  					V2ErrorResponse: ccerror.V2ErrorResponse{
   742  						Code:        1,
   743  						Description: "some error description",
   744  						ErrorCode:   "CF-SomeError",
   745  					},
   746  					ResponseCode: http.StatusTeapot,
   747  				}))
   748  
   749  				Expect(warnings).To(ConsistOf("warning-1", "warning-2"))
   750  			})
   751  		})
   752  
   753  		Context("when there are no errors", func() {
   754  			BeforeEach(func() {
   755  				response := `{
   756  						"metadata": {
   757  							"guid": "route-guid-1",
   758  							"updated_at": null
   759  						},
   760  						"entity": {
   761  							"host": "host-1",
   762  							"path": "path",
   763  							"port": null,
   764  							"domain_guid": "some-http-domain",
   765  							"space_guid": "some-space-guid-1"
   766  						}
   767  					}`
   768  				server.AppendHandlers(
   769  					CombineHandlers(
   770  						VerifyRequest(http.MethodGet, "/v2/routes/some-route-guid"),
   771  						RespondWith(http.StatusOK, response, http.Header{"X-Cf-Warnings": {"warning-1, warning-2"}}),
   772  					),
   773  				)
   774  			})
   775  
   776  			It("returns the route", func() {
   777  				Expect(executeErr).ToNot(HaveOccurred())
   778  				Expect(warnings).To(ConsistOf("warning-1", "warning-2"))
   779  
   780  				Expect(route).To(Equal(Route{
   781  					GUID:       "route-guid-1",
   782  					Host:       "host-1",
   783  					Path:       "path",
   784  					Port:       types.NullInt{IsSet: false},
   785  					DomainGUID: "some-http-domain",
   786  					SpaceGUID:  "some-space-guid-1",
   787  				}))
   788  			})
   789  		})
   790  	})
   791  
   792  	Describe("GetRoutes", func() {
   793  		Context("when there are routes", func() {
   794  			BeforeEach(func() {
   795  				response1 := `{
   796  				"next_url": "/v2/routes?q=organization_guid:some-org-guid&page=2",
   797  				"resources": [
   798  					{
   799  						"metadata": {
   800  							"guid": "route-guid-1",
   801  							"updated_at": null
   802  						},
   803  						"entity": {
   804  							"host": "host-1",
   805  							"path": "path",
   806  							"port": null,
   807  							"domain_guid": "some-http-domain",
   808  							"space_guid": "some-space-guid-1"
   809  						}
   810  					},
   811  					{
   812  						"metadata": {
   813  							"guid": "route-guid-2",
   814  							"updated_at": null
   815  						},
   816  						"entity": {
   817  							"host": "host-2",
   818  							"path": "",
   819  							"port": 3333,
   820  							"domain_guid": "some-tcp-domain",
   821  							"space_guid": "some-space-guid-1"
   822  						}
   823  					}
   824  				]
   825  			}`
   826  				response2 := `{
   827  				"next_url": null,
   828  				"resources": [
   829  					{
   830  						"metadata": {
   831  							"guid": "route-guid-3",
   832  							"updated_at": null
   833  						},
   834  						"entity": {
   835  							"host": "host-3",
   836  							"path": "path",
   837  							"port": null,
   838  							"domain_guid": "some-http-domain",
   839  							"space_guid": "some-space-guid-2"
   840  						}
   841  					},
   842  					{
   843  						"metadata": {
   844  							"guid": "route-guid-4",
   845  							"updated_at": null
   846  						},
   847  						"entity": {
   848  							"host": "host-4",
   849  							"path": "",
   850  							"port": 333,
   851  							"domain_guid": "some-tcp-domain",
   852  							"space_guid": "some-space-guid-2"
   853  						}
   854  					}
   855  				]
   856  			}`
   857  				server.AppendHandlers(
   858  					CombineHandlers(
   859  						VerifyRequest(http.MethodGet, "/v2/routes", "q=organization_guid:some-org-guid"),
   860  						RespondWith(http.StatusOK, response1, http.Header{"X-Cf-Warnings": {"this is a warning"}}),
   861  					),
   862  				)
   863  				server.AppendHandlers(
   864  					CombineHandlers(
   865  						VerifyRequest(http.MethodGet, "/v2/routes", "q=organization_guid:some-org-guid&page=2"),
   866  						RespondWith(http.StatusOK, response2, http.Header{"X-Cf-Warnings": {"this is another warning"}}),
   867  					),
   868  				)
   869  			})
   870  
   871  			It("returns all the routes and all warnings", func() {
   872  				routes, warnings, err := client.GetRoutes(Filter{
   873  					Type:     constant.OrganizationGUIDFilter,
   874  					Operator: constant.EqualOperator,
   875  					Values:   []string{"some-org-guid"},
   876  				})
   877  				Expect(err).NotTo(HaveOccurred())
   878  				Expect(routes).To(ConsistOf([]Route{
   879  					{
   880  						GUID:       "route-guid-1",
   881  						Host:       "host-1",
   882  						Path:       "path",
   883  						Port:       types.NullInt{IsSet: false},
   884  						DomainGUID: "some-http-domain",
   885  						SpaceGUID:  "some-space-guid-1",
   886  					},
   887  					{
   888  						GUID:       "route-guid-2",
   889  						Host:       "host-2",
   890  						Path:       "",
   891  						Port:       types.NullInt{IsSet: true, Value: 3333},
   892  						DomainGUID: "some-tcp-domain",
   893  						SpaceGUID:  "some-space-guid-1",
   894  					},
   895  					{
   896  						GUID:       "route-guid-3",
   897  						Host:       "host-3",
   898  						Path:       "path",
   899  						Port:       types.NullInt{IsSet: false},
   900  						DomainGUID: "some-http-domain",
   901  						SpaceGUID:  "some-space-guid-2",
   902  					},
   903  					{
   904  						GUID:       "route-guid-4",
   905  						Host:       "host-4",
   906  						Path:       "",
   907  						Port:       types.NullInt{IsSet: true, Value: 333},
   908  						DomainGUID: "some-tcp-domain",
   909  						SpaceGUID:  "some-space-guid-2",
   910  					},
   911  				}))
   912  				Expect(warnings).To(ConsistOf(Warnings{"this is a warning", "this is another warning"}))
   913  			})
   914  		})
   915  
   916  		Context("when the cc returns an error", func() {
   917  			BeforeEach(func() {
   918  				response := `{
   919  					"code": 10001,
   920  					"description": "Some Error",
   921  					"error_code": "CF-SomeError"
   922  				}`
   923  				server.AppendHandlers(
   924  					CombineHandlers(
   925  						VerifyRequest(http.MethodGet, "/v2/routes"),
   926  						RespondWith(http.StatusTeapot, response),
   927  					),
   928  				)
   929  			})
   930  
   931  			It("returns an error", func() {
   932  				_, _, err := client.GetRoutes()
   933  				Expect(err).To(MatchError(ccerror.V2UnexpectedResponseError{
   934  					ResponseCode: http.StatusTeapot,
   935  					V2ErrorResponse: ccerror.V2ErrorResponse{
   936  						Code:        10001,
   937  						Description: "Some Error",
   938  						ErrorCode:   "CF-SomeError",
   939  					},
   940  				}))
   941  			})
   942  		})
   943  	})
   944  
   945  	Describe("GetSpaceRoutes", func() {
   946  		Context("when there are routes in this space", func() {
   947  			BeforeEach(func() {
   948  				response1 := `{
   949  				"next_url": "/v2/spaces/some-space-guid/routes?q=space_guid:some-space-guid&page=2",
   950  				"resources": [
   951  					{
   952  						"metadata": {
   953  							"guid": "route-guid-1",
   954  							"updated_at": null
   955  						},
   956  						"entity": {
   957  							"host": "host-1",
   958  							"path": "path",
   959  							"port": null,
   960  							"domain_guid": "some-http-domain",
   961  							"space_guid": "some-space-guid-1"
   962  						}
   963  					},
   964  					{
   965  						"metadata": {
   966  							"guid": "route-guid-2",
   967  							"updated_at": null
   968  						},
   969  						"entity": {
   970  							"host": "host-2",
   971  							"path": "",
   972  							"port": 3333,
   973  							"domain_guid": "some-tcp-domain",
   974  							"space_guid": "some-space-guid-1"
   975  						}
   976  					}
   977  				]
   978  			}`
   979  				response2 := `{
   980  				"next_url": null,
   981  				"resources": [
   982  					{
   983  						"metadata": {
   984  							"guid": "route-guid-3",
   985  							"updated_at": null
   986  						},
   987  						"entity": {
   988  							"host": "host-3",
   989  							"path": "path",
   990  							"port": null,
   991  							"domain_guid": "some-http-domain",
   992  							"space_guid": "some-space-guid-1"
   993  						}
   994  					},
   995  					{
   996  						"metadata": {
   997  							"guid": "route-guid-4",
   998  							"updated_at": null
   999  						},
  1000  						"entity": {
  1001  							"host": "host-4",
  1002  							"path": "",
  1003  							"port": 333,
  1004  							"domain_guid": "some-tcp-domain",
  1005  							"space_guid": "some-space-guid-1"
  1006  						}
  1007  					}
  1008  				]
  1009  			}`
  1010  				server.AppendHandlers(
  1011  					CombineHandlers(
  1012  						VerifyRequest(http.MethodGet, "/v2/spaces/some-space-guid/routes", "q=space_guid:some-space-guid"),
  1013  						RespondWith(http.StatusOK, response1, http.Header{"X-Cf-Warnings": {"this is a warning"}}),
  1014  					),
  1015  				)
  1016  				server.AppendHandlers(
  1017  					CombineHandlers(
  1018  						VerifyRequest(http.MethodGet, "/v2/spaces/some-space-guid/routes", "q=space_guid:some-space-guid&page=2"),
  1019  						RespondWith(http.StatusOK, response2, http.Header{"X-Cf-Warnings": {"this is another warning"}}),
  1020  					),
  1021  				)
  1022  			})
  1023  
  1024  			It("returns all the routes and all warnings", func() {
  1025  				routes, warnings, err := client.GetSpaceRoutes("some-space-guid", Filter{
  1026  					Type:     constant.SpaceGUIDFilter,
  1027  					Operator: constant.EqualOperator,
  1028  					Values:   []string{"some-space-guid"},
  1029  				})
  1030  				Expect(err).NotTo(HaveOccurred())
  1031  				Expect(routes).To(ConsistOf([]Route{
  1032  					{
  1033  						GUID:       "route-guid-1",
  1034  						Host:       "host-1",
  1035  						Path:       "path",
  1036  						Port:       types.NullInt{IsSet: false},
  1037  						DomainGUID: "some-http-domain",
  1038  						SpaceGUID:  "some-space-guid-1",
  1039  					},
  1040  					{
  1041  						GUID:       "route-guid-2",
  1042  						Host:       "host-2",
  1043  						Path:       "",
  1044  						Port:       types.NullInt{IsSet: true, Value: 3333},
  1045  						DomainGUID: "some-tcp-domain",
  1046  						SpaceGUID:  "some-space-guid-1",
  1047  					},
  1048  					{
  1049  						GUID:       "route-guid-3",
  1050  						Host:       "host-3",
  1051  						Path:       "path",
  1052  						Port:       types.NullInt{IsSet: false},
  1053  						DomainGUID: "some-http-domain",
  1054  						SpaceGUID:  "some-space-guid-1",
  1055  					},
  1056  					{
  1057  						GUID:       "route-guid-4",
  1058  						Host:       "host-4",
  1059  						Path:       "",
  1060  						Port:       types.NullInt{IsSet: true, Value: 333},
  1061  						DomainGUID: "some-tcp-domain",
  1062  						SpaceGUID:  "some-space-guid-1",
  1063  					},
  1064  				}))
  1065  				Expect(warnings).To(ConsistOf(Warnings{"this is a warning", "this is another warning"}))
  1066  			})
  1067  		})
  1068  
  1069  		Context("when there are no routes in this space", func() {
  1070  			BeforeEach(func() {
  1071  				response := `{
  1072  				"next_url": "",
  1073  				"resources": []
  1074  			}`
  1075  				server.AppendHandlers(
  1076  					CombineHandlers(
  1077  						VerifyRequest(http.MethodGet, "/v2/spaces/some-space-guid/routes"),
  1078  						RespondWith(http.StatusOK, response),
  1079  					),
  1080  				)
  1081  			})
  1082  
  1083  			It("returns an empty list of routes", func() {
  1084  				routes, _, err := client.GetSpaceRoutes("some-space-guid")
  1085  				Expect(err).NotTo(HaveOccurred())
  1086  				Expect(routes).To(BeEmpty())
  1087  			})
  1088  		})
  1089  
  1090  		Context("when the space is not found", func() {
  1091  			BeforeEach(func() {
  1092  				response := `{
  1093  					"code": 40004,
  1094  					"description": "The app space could not be found: some-space-guid",
  1095  					"error_code": "CF-SpaceNotFound"
  1096  				}`
  1097  				server.AppendHandlers(
  1098  					CombineHandlers(
  1099  						VerifyRequest(http.MethodGet, "/v2/spaces/some-space-guid/routes"),
  1100  						RespondWith(http.StatusNotFound, response),
  1101  					),
  1102  				)
  1103  			})
  1104  
  1105  			It("returns an error", func() {
  1106  				routes, _, err := client.GetSpaceRoutes("some-space-guid")
  1107  				Expect(err).To(MatchError(ccerror.ResourceNotFoundError{
  1108  					Message: "The app space could not be found: some-space-guid",
  1109  				}))
  1110  				Expect(routes).To(BeEmpty())
  1111  			})
  1112  		})
  1113  	})
  1114  
  1115  	Describe("UpdateRouteApplication", func() {
  1116  		Context("when route mapping is successful", func() {
  1117  			BeforeEach(func() {
  1118  				response := `
  1119  						{
  1120  							"metadata": {
  1121  								"guid": "some-route-guid"
  1122  							},
  1123  							"entity": {
  1124  								"domain_guid": "some-domain-guid",
  1125  								"host": "some-host",
  1126  								"path": "some-path",
  1127  								"port": 42,
  1128  								"space_guid": "some-space-guid"
  1129  							}
  1130  						}`
  1131  				server.AppendHandlers(
  1132  					CombineHandlers(
  1133  						VerifyRequest(http.MethodPut, "/v2/routes/some-route-guid/apps/some-app-guid"),
  1134  						RespondWith(http.StatusCreated, response, http.Header{"X-Cf-Warnings": {"this is a warning"}}),
  1135  					),
  1136  				)
  1137  			})
  1138  
  1139  			It("returns the route and warnings", func() {
  1140  				route, warnings, err := client.UpdateRouteApplication("some-route-guid", "some-app-guid")
  1141  				Expect(err).ToNot(HaveOccurred())
  1142  				Expect(warnings).To(ConsistOf("this is a warning"))
  1143  
  1144  				Expect(route).To(Equal(Route{
  1145  					DomainGUID: "some-domain-guid",
  1146  					GUID:       "some-route-guid",
  1147  					Host:       "some-host",
  1148  					Path:       "some-path",
  1149  					Port:       types.NullInt{IsSet: true, Value: 42},
  1150  					SpaceGUID:  "some-space-guid",
  1151  				}))
  1152  			})
  1153  		})
  1154  
  1155  		Context("when the cc returns an error", func() {
  1156  			BeforeEach(func() {
  1157  				response := `{
  1158  					"code": 10001,
  1159  					"description": "Some Error",
  1160  					"error_code": "CF-SomeError"
  1161  				}`
  1162  				server.AppendHandlers(
  1163  					CombineHandlers(
  1164  						VerifyRequest(http.MethodPut, "/v2/routes/some-route-guid/apps/some-app-guid"),
  1165  						RespondWith(http.StatusTeapot, response, http.Header{"X-Cf-Warnings": {"this is a warning"}}),
  1166  					),
  1167  				)
  1168  			})
  1169  
  1170  			It("returns an error", func() {
  1171  				_, warnings, err := client.UpdateRouteApplication("some-route-guid", "some-app-guid")
  1172  				Expect(err).To(MatchError(ccerror.V2UnexpectedResponseError{
  1173  					ResponseCode: http.StatusTeapot,
  1174  					V2ErrorResponse: ccerror.V2ErrorResponse{
  1175  						Code:        10001,
  1176  						Description: "Some Error",
  1177  						ErrorCode:   "CF-SomeError",
  1178  					},
  1179  				}))
  1180  				Expect(warnings).To(ConsistOf("this is a warning"))
  1181  			})
  1182  		})
  1183  	})
  1184  })