github.com/arunkumar7540/cli@v6.45.0+incompatible/api/cloudcontroller/ccv3/route_test.go (about) 1 package ccv3_test 2 3 import ( 4 "fmt" 5 "net/http" 6 7 "code.cloudfoundry.org/cli/api/cloudcontroller/ccerror" 8 . "code.cloudfoundry.org/cli/api/cloudcontroller/ccv3" 9 . "github.com/onsi/ginkgo" 10 . "github.com/onsi/gomega" 11 . "github.com/onsi/gomega/ghttp" 12 ) 13 14 var _ = Describe("Route", func() { 15 var client *Client 16 17 BeforeEach(func() { 18 client, _ = NewTestClient() 19 }) 20 21 Describe("CreateRoute", func() { 22 var ( 23 route Route 24 warnings Warnings 25 executeErr error 26 spaceGUID string 27 domainGUID string 28 host string 29 path string 30 ccv3Route Route 31 ) 32 33 BeforeEach(func() { 34 host = "" 35 path = "" 36 }) 37 38 JustBeforeEach(func() { 39 spaceGUID = "space-guid" 40 domainGUID = "domain-guid" 41 ccv3Route = Route{SpaceGUID: spaceGUID, DomainGUID: domainGUID, Host: host, Path: path} 42 route, warnings, executeErr = client.CreateRoute(ccv3Route) 43 }) 44 45 When("the request succeeds", func() { 46 When("no additional flags", func() { 47 BeforeEach(func() { 48 host = "" 49 response := `{ 50 "guid": "some-route-guid", 51 "relationships": { 52 "space": { 53 "data": { "guid": "space-guid" } 54 }, 55 "domain": { 56 "data": { "guid": "domain-guid" } 57 } 58 }, 59 "host": "" 60 }` 61 62 expectedBody := `{ 63 "relationships": { 64 "space": { 65 "data": { "guid": "space-guid" } 66 }, 67 "domain": { 68 "data": { "guid": "domain-guid" } 69 } 70 } 71 }` 72 73 server.AppendHandlers( 74 CombineHandlers( 75 VerifyRequest(http.MethodPost, "/v3/routes"), 76 VerifyJSON(expectedBody), 77 RespondWith(http.StatusCreated, response, http.Header{"X-Cf-Warnings": {"warning-1"}}), 78 ), 79 ) 80 }) 81 82 It("returns the given route and all warnings", func() { 83 Expect(executeErr).ToNot(HaveOccurred()) 84 Expect(warnings).To(ConsistOf("warning-1")) 85 86 Expect(route).To(Equal(Route{ 87 GUID: "some-route-guid", 88 SpaceGUID: "space-guid", 89 DomainGUID: "domain-guid", 90 })) 91 }) 92 }) 93 94 When("hostname is passed in", func() { 95 96 BeforeEach(func() { 97 host = "cheesecake" 98 response := `{ 99 "guid": "some-route-guid", 100 "relationships": { 101 "space": { 102 "data": { "guid": "space-guid" } 103 }, 104 "domain": { 105 "data": { "guid": "domain-guid" } 106 } 107 }, 108 "host": "cheesecake" 109 }` 110 111 expectedBody := `{ 112 "relationships": { 113 "space": { 114 "data": { "guid": "space-guid" } 115 }, 116 "domain": { 117 "data": { "guid": "domain-guid" } 118 } 119 }, 120 "host": "cheesecake" 121 }` 122 123 server.AppendHandlers( 124 CombineHandlers( 125 VerifyRequest(http.MethodPost, "/v3/routes"), 126 VerifyJSON(expectedBody), 127 RespondWith(http.StatusCreated, response, http.Header{"X-Cf-Warnings": {"warning-1"}}), 128 ), 129 ) 130 }) 131 132 It("returns the given route and all warnings", func() { 133 Expect(executeErr).ToNot(HaveOccurred()) 134 Expect(warnings).To(ConsistOf("warning-1")) 135 136 Expect(route).To(Equal(Route{ 137 GUID: "some-route-guid", 138 SpaceGUID: "space-guid", 139 DomainGUID: "domain-guid", 140 Host: "cheesecake", 141 })) 142 }) 143 }) 144 145 When("path is passed in", func() { 146 BeforeEach(func() { 147 path = "lion" 148 149 response := `{ 150 "guid": "this-route-guid", 151 "relationships": { 152 "space": { 153 "data": { 154 "guid": "space-guid" 155 } 156 }, 157 "domain": { 158 "data": { 159 "guid": "domain-guid" 160 } 161 } 162 }, 163 "path": "lion" 164 }` 165 expectedRequestBody := `{ 166 "relationships": { 167 "space": { 168 "data": { 169 "guid": "space-guid" 170 } 171 }, 172 "domain": { 173 "data": { 174 "guid": "domain-guid" 175 } 176 } 177 }, 178 "path": "lion" 179 }` 180 181 server.AppendHandlers( 182 CombineHandlers( 183 VerifyRequest(http.MethodPost, "/v3/routes"), 184 VerifyJSON(expectedRequestBody), 185 RespondWith(http.StatusCreated, response, http.Header{"X-Cf-Warnings": {"warning-1"}}), 186 ), 187 ) 188 }) 189 When("the request succeeds", func() { 190 It("returns the given route and all warnings", func() { 191 Expect(executeErr).ToNot(HaveOccurred()) 192 Expect(warnings).To(ConsistOf("warning-1")) 193 194 Expect(route).To(Equal(Route{ 195 GUID: "this-route-guid", 196 SpaceGUID: "space-guid", 197 DomainGUID: "domain-guid", 198 Path: "lion", 199 })) 200 }) 201 }) 202 }) 203 204 }) 205 206 When("the cloud controller returns errors and warnings", func() { 207 BeforeEach(func() { 208 response := `{ 209 "errors": [ 210 { 211 "code": 10008, 212 "detail": "The request is semantically invalid: command presence", 213 "title": "CF-UnprocessableEntity" 214 }, 215 { 216 "code": 10010, 217 "detail": "Isolation segment not found", 218 "title": "CF-ResourceNotFound" 219 } 220 ] 221 }` 222 server.AppendHandlers( 223 CombineHandlers( 224 VerifyRequest(http.MethodPost, "/v3/routes"), 225 RespondWith(http.StatusTeapot, response, http.Header{"X-Cf-Warnings": {"this is a warning"}}), 226 ), 227 ) 228 }) 229 230 It("returns the error and all warnings", func() { 231 Expect(executeErr).To(MatchError(ccerror.MultiError{ 232 ResponseCode: http.StatusTeapot, 233 Errors: []ccerror.V3Error{ 234 { 235 Code: 10008, 236 Detail: "The request is semantically invalid: command presence", 237 Title: "CF-UnprocessableEntity", 238 }, 239 { 240 Code: 10010, 241 Detail: "Isolation segment not found", 242 Title: "CF-ResourceNotFound", 243 }, 244 }, 245 })) 246 Expect(warnings).To(ConsistOf("this is a warning")) 247 }) 248 }) 249 }) 250 251 Describe("GetRoutes", func() { 252 var ( 253 query Query 254 routes []Route 255 warnings Warnings 256 executeErr error 257 ) 258 259 JustBeforeEach(func() { 260 routes, warnings, executeErr = client.GetRoutes(query) 261 }) 262 263 When("the request succeeds", func() { 264 var ( 265 response1 string 266 response2 string 267 ) 268 269 BeforeEach(func() { 270 response1 = fmt.Sprintf(` 271 { 272 "pagination": { 273 "next": { 274 "href": "%s/v3/routes?page=2" 275 } 276 }, 277 "resources": [ 278 { 279 "guid": "route-1-guid" 280 }, 281 { 282 "guid": "route-2-guid" 283 } 284 ] 285 }`, server.URL()) 286 287 response2 = ` 288 { 289 "pagination": { 290 "next": null 291 }, 292 "resources": [ 293 { 294 "guid": "route-3-guid" 295 } 296 ] 297 }` 298 }) 299 300 When("not passing any filters", func() { 301 BeforeEach(func() { 302 query = Query{} 303 304 server.AppendHandlers( 305 CombineHandlers( 306 VerifyRequest(http.MethodGet, "/v3/routes"), 307 RespondWith(http.StatusOK, response1, http.Header{"X-Cf-Warnings": {"warning-1"}}), 308 ), 309 ) 310 server.AppendHandlers( 311 CombineHandlers( 312 VerifyRequest(http.MethodGet, "/v3/routes", "page=2"), 313 RespondWith(http.StatusOK, response2, http.Header{"X-Cf-Warnings": {"warning-2"}}), 314 ), 315 ) 316 }) 317 318 It("returns the given route and all warnings", func() { 319 Expect(executeErr).ToNot(HaveOccurred()) 320 Expect(warnings).To(ConsistOf("warning-1", "warning-2")) 321 322 Expect(routes).To(Equal([]Route{ 323 Route{ 324 GUID: "route-1-guid", 325 }, 326 Route{ 327 GUID: "route-2-guid", 328 }, 329 Route{ 330 GUID: "route-3-guid", 331 }, 332 })) 333 }) 334 }) 335 336 When("passing in a query", func() { 337 BeforeEach(func() { 338 query = Query{Key: "space_guids", Values: []string{"guid1", "guid2"}} 339 340 server.AppendHandlers( 341 CombineHandlers( 342 VerifyRequest(http.MethodGet, "/v3/routes", "space_guids=guid1,guid2"), 343 RespondWith(http.StatusOK, response1, http.Header{"X-Cf-Warnings": {"warning-1"}}), 344 ), 345 ) 346 server.AppendHandlers( 347 CombineHandlers( 348 VerifyRequest(http.MethodGet, "/v3/routes", "page=2", "space_guids=guid1,guid2"), 349 RespondWith(http.StatusOK, response2, http.Header{"X-Cf-Warnings": {"warning-2"}}), 350 ), 351 ) 352 }) 353 354 It("passes query params", func() { 355 Expect(executeErr).ToNot(HaveOccurred()) 356 Expect(warnings).To(ConsistOf("warning-1", "warning-2")) 357 358 Expect(routes).To(Equal([]Route{ 359 Route{ 360 GUID: "route-1-guid", 361 }, 362 Route{ 363 GUID: "route-2-guid", 364 }, 365 Route{ 366 GUID: "route-3-guid", 367 }, 368 })) 369 }) 370 }) 371 }) 372 }) 373 374 Describe("DeleteRoute", func() { 375 var ( 376 routeGUID string 377 jobURLString string 378 jobURL JobURL 379 warnings Warnings 380 executeErr error 381 ) 382 383 JustBeforeEach(func() { 384 jobURL, warnings, executeErr = client.DeleteRoute(routeGUID) 385 }) 386 387 When("route exists", func() { 388 routeGUID = "route-guid" 389 jobURLString = "https://api.test.com/v3/jobs/job-guid" 390 391 BeforeEach(func() { 392 server.AppendHandlers( 393 CombineHandlers( 394 VerifyRequest(http.MethodDelete, "/v3/routes/route-guid"), 395 RespondWith(http.StatusAccepted, nil, http.Header{ 396 "X-Cf-Warnings": {"this is a warning"}, 397 "Location": {jobURLString}, 398 }), 399 ), 400 ) 401 }) 402 403 It("returns all warnings", func() { 404 Expect(executeErr).NotTo(HaveOccurred()) 405 Expect(jobURL).To(Equal(JobURL(jobURLString))) 406 Expect(warnings).To(ConsistOf("this is a warning")) 407 }) 408 }) 409 410 When("the cloud controller returns errors and warnings", func() { 411 BeforeEach(func() { 412 response := `{ 413 "errors": [ 414 { 415 "code": 10008, 416 "detail": "The request is semantically invalid: command presence", 417 "title": "CF-UnprocessableEntity" 418 }, 419 { 420 "code": 10010, 421 "detail": "Isolation segment not found", 422 "title": "CF-ResourceNotFound" 423 } 424 ] 425 }` 426 server.AppendHandlers( 427 CombineHandlers( 428 VerifyRequest(http.MethodDelete, "/v3/routes/route-guid"), 429 RespondWith(http.StatusTeapot, response, http.Header{"X-Cf-Warnings": {"this is a warning"}}), 430 ), 431 ) 432 }) 433 434 It("returns the error and all warnings", func() { 435 Expect(executeErr).To(MatchError(ccerror.MultiError{ 436 ResponseCode: http.StatusTeapot, 437 Errors: []ccerror.V3Error{ 438 { 439 Code: 10008, 440 Detail: "The request is semantically invalid: command presence", 441 Title: "CF-UnprocessableEntity", 442 }, 443 { 444 Code: 10010, 445 Detail: "Isolation segment not found", 446 Title: "CF-ResourceNotFound", 447 }, 448 }, 449 })) 450 Expect(warnings).To(ConsistOf("this is a warning")) 451 }) 452 }) 453 }) 454 })