github.com/dcarley/cf-cli@v6.24.1-0.20170220111324-4225ff346898+incompatible/cf/api/domains_test.go (about) 1 package api_test 2 3 import ( 4 "net/http" 5 "net/http/httptest" 6 "time" 7 8 "code.cloudfoundry.org/cli/cf/api/apifakes" 9 "code.cloudfoundry.org/cli/cf/configuration/coreconfig" 10 "code.cloudfoundry.org/cli/cf/errors" 11 "code.cloudfoundry.org/cli/cf/models" 12 "code.cloudfoundry.org/cli/cf/net" 13 "code.cloudfoundry.org/cli/cf/terminal/terminalfakes" 14 testconfig "code.cloudfoundry.org/cli/util/testhelpers/configuration" 15 testnet "code.cloudfoundry.org/cli/util/testhelpers/net" 16 17 . "code.cloudfoundry.org/cli/cf/api" 18 "code.cloudfoundry.org/cli/cf/trace/tracefakes" 19 . "code.cloudfoundry.org/cli/util/testhelpers/matchers" 20 . "github.com/onsi/ginkgo" 21 . "github.com/onsi/gomega" 22 ) 23 24 var _ = Describe("DomainRepository", func() { 25 var ( 26 ts *httptest.Server 27 handler *testnet.TestHandler 28 repo DomainRepository 29 config coreconfig.ReadWriter 30 ) 31 32 BeforeEach(func() { 33 config = testconfig.NewRepositoryWithDefaults() 34 }) 35 36 JustBeforeEach(func() { 37 gateway := net.NewCloudControllerGateway(config, time.Now, new(terminalfakes.FakeUI), new(tracefakes.FakePrinter), "") 38 repo = NewCloudControllerDomainRepository(config, gateway) 39 }) 40 41 AfterEach(func() { 42 ts.Close() 43 }) 44 45 var setupTestServer = func(reqs ...testnet.TestRequest) { 46 ts, handler = testnet.NewServer(reqs) 47 config.SetAPIEndpoint(ts.URL) 48 } 49 50 Describe("listing domains", func() { 51 BeforeEach(func() { 52 config.SetAPIVersion("2.2.0") 53 setupTestServer(firstPagePrivateDomainsRequest, secondPagePrivateDomainsRequest, firstPageSharedDomainsRequest, secondPageSharedDomainsRequest) 54 }) 55 56 It("uses the organization-scoped domains endpoints", func() { 57 receivedDomains := []models.DomainFields{} 58 apiErr := repo.ListDomainsForOrg("my-org-guid", func(d models.DomainFields) bool { 59 receivedDomains = append(receivedDomains, d) 60 return true 61 }) 62 63 Expect(apiErr).NotTo(HaveOccurred()) 64 Expect(len(receivedDomains)).To(Equal(6)) 65 Expect(receivedDomains[0].GUID).To(Equal("domain1-guid")) 66 Expect(receivedDomains[1].GUID).To(Equal("domain2-guid")) 67 Expect(receivedDomains[2].GUID).To(Equal("domain3-guid")) 68 Expect(receivedDomains[2].Shared).To(BeFalse()) 69 Expect(receivedDomains[3].GUID).To(Equal("shared-domain1-guid")) 70 Expect(receivedDomains[4].GUID).To(Equal("shared-domain2-guid")) 71 Expect(receivedDomains[5].GUID).To(Equal("shared-domain3-guid")) 72 Expect(handler).To(HaveAllRequestsCalled()) 73 }) 74 }) 75 76 Describe("getting default domain", func() { 77 BeforeEach(func() { 78 setupTestServer(firstPagePrivateDomainsRequest, secondPagePrivateDomainsRequest, firstPageSharedDomainsRequest, secondPageSharedDomainsRequest) 79 }) 80 81 It("should always return back the first shared domain", func() { 82 domain, apiErr := repo.FirstOrDefault("my-org-guid", nil) 83 84 Expect(apiErr).NotTo(HaveOccurred()) 85 Expect(domain.GUID).To(Equal("shared-domain1-guid")) 86 }) 87 }) 88 89 It("finds a shared domain by name", func() { 90 setupTestServer(apifakes.NewCloudControllerTestRequest(testnet.TestRequest{ 91 Method: "GET", 92 Path: "/v2/shared_domains?inline-relations-depth=1&q=name%3Adomain2.cf-app.com", 93 Response: testnet.TestResponse{Status: http.StatusOK, Body: ` 94 { 95 "resources": [ 96 { 97 "metadata": { "guid": "domain2-guid" }, 98 "entity": { "name": "domain2.cf-app.com" } 99 } 100 ] 101 }`}, 102 })) 103 104 domain, apiErr := repo.FindSharedByName("domain2.cf-app.com") 105 Expect(handler).To(HaveAllRequestsCalled()) 106 Expect(apiErr).NotTo(HaveOccurred()) 107 108 Expect(domain.Name).To(Equal("domain2.cf-app.com")) 109 Expect(domain.GUID).To(Equal("domain2-guid")) 110 Expect(domain.Shared).To(BeTrue()) 111 }) 112 113 It("finds a private domain by name", func() { 114 setupTestServer(apifakes.NewCloudControllerTestRequest(testnet.TestRequest{ 115 Method: "GET", 116 Path: "/v2/private_domains?inline-relations-depth=1&q=name%3Adomain2.cf-app.com", 117 Response: testnet.TestResponse{Status: http.StatusOK, Body: ` 118 { 119 "resources": [ 120 { 121 "metadata": { "guid": "domain2-guid" }, 122 "entity": { "name": "domain2.cf-app.com", "owning_organization_guid": "some-guid" } 123 } 124 ] 125 }`}, 126 })) 127 128 domain, apiErr := repo.FindPrivateByName("domain2.cf-app.com") 129 Expect(handler).To(HaveAllRequestsCalled()) 130 Expect(apiErr).NotTo(HaveOccurred()) 131 132 Expect(domain.Name).To(Equal("domain2.cf-app.com")) 133 Expect(domain.GUID).To(Equal("domain2-guid")) 134 Expect(domain.Shared).To(BeFalse()) 135 }) 136 137 It("returns shared domains with router group types", func() { 138 setupTestServer(apifakes.NewCloudControllerTestRequest(testnet.TestRequest{ 139 Method: "GET", 140 Path: "/v2/shared_domains?inline-relations-depth=1&q=name%3Adomain2.cf-app.com", 141 Response: testnet.TestResponse{Status: http.StatusOK, Body: ` 142 { 143 "resources": [ 144 { 145 "metadata": { "guid": "domain2-guid" }, 146 "entity": { 147 "name": "domain2.cf-app.com", 148 "router_group_guid": "my-random-guid", 149 "router_group_type": "tcp" 150 } 151 } 152 ] 153 }`}, 154 })) 155 156 domain, apiErr := repo.FindSharedByName("domain2.cf-app.com") 157 Expect(handler).To(HaveAllRequestsCalled()) 158 Expect(apiErr).NotTo(HaveOccurred()) 159 160 Expect(domain.Name).To(Equal("domain2.cf-app.com")) 161 Expect(domain.GUID).To(Equal("domain2-guid")) 162 Expect(domain.RouterGroupType).To(Equal("tcp")) 163 }) 164 165 Describe("finding a domain by name in an org", func() { 166 It("looks in the org's domains first", func() { 167 setupTestServer(apifakes.NewCloudControllerTestRequest(testnet.TestRequest{ 168 Method: "GET", 169 Path: "/v2/organizations/my-org-guid/private_domains?inline-relations-depth=1&q=name%3Adomain2.cf-app.com", 170 Response: testnet.TestResponse{Status: http.StatusOK, Body: ` 171 { 172 "resources": [ 173 { 174 "metadata": { "guid": "my-domain-guid" }, 175 "entity": { 176 "name": "my-example.com", 177 "owning_organization_guid": "my-org-guid" 178 } 179 } 180 ] 181 }`}, 182 })) 183 184 domain, apiErr := repo.FindByNameInOrg("domain2.cf-app.com", "my-org-guid") 185 Expect(handler).To(HaveAllRequestsCalled()) 186 Expect(apiErr).NotTo(HaveOccurred()) 187 188 Expect(domain.Name).To(Equal("my-example.com")) 189 Expect(domain.GUID).To(Equal("my-domain-guid")) 190 Expect(domain.Shared).To(BeFalse()) 191 }) 192 193 It("looks for shared domains if no there are no org-specific domains", func() { 194 setupTestServer( 195 apifakes.NewCloudControllerTestRequest(testnet.TestRequest{ 196 Method: "GET", 197 Path: "/v2/organizations/my-org-guid/private_domains?inline-relations-depth=1&q=name%3Adomain2.cf-app.com", 198 Response: testnet.TestResponse{Status: http.StatusOK, Body: `{"resources": []}`}, 199 }), 200 201 apifakes.NewCloudControllerTestRequest(testnet.TestRequest{ 202 Method: "GET", 203 Path: "/v2/shared_domains?inline-relations-depth=1&q=name%3Adomain2.cf-app.com", 204 Response: testnet.TestResponse{Status: http.StatusOK, Body: ` 205 { 206 "resources": [ 207 { 208 "metadata": { "guid": "shared-domain-guid" }, 209 "entity": { 210 "name": "shared-example.com", 211 "owning_organization_guid": null 212 } 213 } 214 ] 215 }`}, 216 })) 217 218 domain, apiErr := repo.FindByNameInOrg("domain2.cf-app.com", "my-org-guid") 219 Expect(handler).To(HaveAllRequestsCalled()) 220 Expect(apiErr).NotTo(HaveOccurred()) 221 222 Expect(domain.Name).To(Equal("shared-example.com")) 223 Expect(domain.GUID).To(Equal("shared-domain-guid")) 224 Expect(domain.Shared).To(BeTrue()) 225 }) 226 227 It("returns not found when neither endpoint returns a domain", func() { 228 setupTestServer( 229 apifakes.NewCloudControllerTestRequest(testnet.TestRequest{ 230 Method: "GET", 231 Path: "/v2/organizations/my-org-guid/private_domains?inline-relations-depth=1&q=name%3Adomain2.cf-app.com", 232 Response: testnet.TestResponse{Status: http.StatusOK, Body: `{"resources": []}`}, 233 }), 234 235 apifakes.NewCloudControllerTestRequest(testnet.TestRequest{ 236 Method: "GET", 237 Path: "/v2/shared_domains?inline-relations-depth=1&q=name%3Adomain2.cf-app.com", 238 Response: testnet.TestResponse{Status: http.StatusOK, Body: `{"resources": []}`}, 239 })) 240 241 _, apiErr := repo.FindByNameInOrg("domain2.cf-app.com", "my-org-guid") 242 Expect(handler).To(HaveAllRequestsCalled()) 243 Expect(apiErr.(*errors.ModelNotFoundError)).NotTo(BeNil()) 244 }) 245 246 It("returns not found when the global endpoint returns a private domain", func() { 247 setupTestServer( 248 apifakes.NewCloudControllerTestRequest(testnet.TestRequest{ 249 Method: "GET", 250 Path: "/v2/organizations/my-org-guid/private_domains?inline-relations-depth=1&q=name%3Adomain2.cf-app.com", 251 Response: testnet.TestResponse{Status: http.StatusOK, Body: `{"resources": []}`}, 252 }), 253 254 apifakes.NewCloudControllerTestRequest(testnet.TestRequest{ 255 Method: "GET", 256 Path: "/v2/shared_domains?inline-relations-depth=1&q=name%3Adomain2.cf-app.com", 257 Response: testnet.TestResponse{Status: http.StatusOK, Body: ` 258 { 259 "resources": [ 260 { 261 "metadata": { "guid": "shared-domain-guid" }, 262 "entity": { 263 "name": "shared-example.com", 264 "owning_organization_guid": "some-other-org-guid" 265 } 266 } 267 ] 268 }`}})) 269 270 _, apiErr := repo.FindByNameInOrg("domain2.cf-app.com", "my-org-guid") 271 Expect(handler).To(HaveAllRequestsCalled()) 272 Expect(apiErr.(*errors.ModelNotFoundError)).NotTo(BeNil()) 273 }) 274 }) 275 276 Describe("creating domains", func() { 277 Context("when the private domains endpoint is available", func() { 278 It("uses that endpoint", func() { 279 setupTestServer( 280 apifakes.NewCloudControllerTestRequest(testnet.TestRequest{ 281 Method: "POST", 282 Path: "/v2/private_domains", 283 Matcher: testnet.RequestBodyMatcher(`{"name":"example.com","owning_organization_guid":"org-guid", "wildcard": true}`), 284 Response: testnet.TestResponse{Status: http.StatusCreated, Body: ` 285 { 286 "metadata": { "guid": "abc-123" }, 287 "entity": { "name": "example.com" } 288 }`}, 289 })) 290 291 createdDomain, apiErr := repo.Create("example.com", "org-guid") 292 293 Expect(handler).To(HaveAllRequestsCalled()) 294 Expect(apiErr).NotTo(HaveOccurred()) 295 Expect(createdDomain.GUID).To(Equal("abc-123")) 296 }) 297 }) 298 }) 299 300 Describe("creating shared domains", func() { 301 Context("targeting a newer cloud controller", func() { 302 It("uses the shared domains endpoint", func() { 303 setupTestServer( 304 apifakes.NewCloudControllerTestRequest(testnet.TestRequest{ 305 Method: "POST", 306 Path: "/v2/shared_domains", 307 Matcher: testnet.RequestBodyMatcher(`{"name":"example.com", "wildcard": true}`), 308 Response: testnet.TestResponse{Status: http.StatusCreated, Body: ` 309 { 310 "metadata": { "guid": "abc-123" }, 311 "entity": { "name": "example.com" } 312 }`}}), 313 ) 314 315 apiErr := repo.CreateSharedDomain("example.com", "") 316 317 Expect(handler).To(HaveAllRequestsCalled()) 318 Expect(apiErr).NotTo(HaveOccurred()) 319 }) 320 321 It("creates a shared domain with a router_group_guid", func() { 322 setupTestServer( 323 apifakes.NewCloudControllerTestRequest(testnet.TestRequest{ 324 Method: "POST", 325 Path: "/v2/shared_domains", 326 Matcher: testnet.RequestBodyMatcher(`{"name":"example.com", "router_group_guid": "tcp-group", "wildcard": true}`), 327 Response: testnet.TestResponse{Status: http.StatusCreated, Body: ` 328 { 329 "metadata": { "guid": "abc-123" }, 330 "entity": { "name": "example.com", "router_group_guid":"tcp-group" } 331 }`}}), 332 ) 333 334 apiErr := repo.CreateSharedDomain("example.com", "tcp-group") 335 336 Expect(handler).To(HaveAllRequestsCalled()) 337 Expect(apiErr).NotTo(HaveOccurred()) 338 }) 339 }) 340 }) 341 342 Describe("deleting domains", func() { 343 Context("when the private domains endpoint is available", func() { 344 BeforeEach(func() { 345 setupTestServer(deleteDomainReq(http.StatusOK)) 346 }) 347 348 It("uses the private domains endpoint", func() { 349 apiErr := repo.Delete("my-domain-guid") 350 351 Expect(handler).To(HaveAllRequestsCalled()) 352 Expect(apiErr).NotTo(HaveOccurred()) 353 }) 354 }) 355 }) 356 357 Describe("deleting shared domains", func() { 358 Context("when the shared domains endpoint is available", func() { 359 BeforeEach(func() { 360 setupTestServer(deleteSharedDomainReq(http.StatusOK)) 361 }) 362 363 It("uses the shared domains endpoint", func() { 364 apiErr := repo.DeleteSharedDomain("my-domain-guid") 365 366 Expect(handler).To(HaveAllRequestsCalled()) 367 Expect(apiErr).NotTo(HaveOccurred()) 368 }) 369 370 It("returns an error when the delete fails", func() { 371 setupTestServer(deleteSharedDomainReq(http.StatusBadRequest)) 372 373 apiErr := repo.DeleteSharedDomain("my-domain-guid") 374 375 Expect(handler).To(HaveAllRequestsCalled()) 376 Expect(apiErr).NotTo(BeNil()) 377 }) 378 }) 379 }) 380 381 }) 382 383 var oldEndpointDomainsRequest = apifakes.NewCloudControllerTestRequest(testnet.TestRequest{ 384 Method: "GET", 385 Path: "/v2/domains", 386 Response: testnet.TestResponse{Status: http.StatusOK, Body: `{ 387 "resources": [ 388 { 389 "metadata": { 390 "guid": "domain-guid" 391 }, 392 "entity": { 393 "name": "example.com", 394 "owning_organization_guid": "my-org-guid" 395 } 396 } 397 ] 398 }`}}) 399 400 var firstPageDomainsRequest = apifakes.NewCloudControllerTestRequest(testnet.TestRequest{ 401 Method: "GET", 402 Path: "/v2/organizations/my-org-guid/private_domains", 403 Response: testnet.TestResponse{Status: http.StatusOK, Body: ` 404 { 405 "next_url": "/v2/organizations/my-org-guid/domains?page=2", 406 "resources": [ 407 { 408 "metadata": { 409 "guid": "domain1-guid", 410 }, 411 "entity": { 412 "name": "example.com", 413 "owning_organization_guid": "my-org-guid" 414 } 415 }, 416 { 417 "metadata": { 418 "guid": "domain2-guid" 419 }, 420 "entity": { 421 "name": "some-example.com", 422 "owning_organization_guid": "my-org-guid" 423 } 424 } 425 ] 426 }`}, 427 }) 428 429 var secondPageDomainsRequest = apifakes.NewCloudControllerTestRequest(testnet.TestRequest{ 430 Method: "GET", 431 Path: "/v2/organizations/my-org-guid/domains?page=2", 432 Response: testnet.TestResponse{Status: http.StatusOK, Body: ` 433 { 434 "resources": [ 435 { 436 "metadata": { 437 "guid": "domain3-guid" 438 }, 439 "entity": { 440 "name": "example.com", 441 "owning_organization_guid": "my-org-guid" 442 } 443 } 444 ] 445 }`}, 446 }) 447 448 var firstPageSharedDomainsRequest = apifakes.NewCloudControllerTestRequest(testnet.TestRequest{ 449 Method: "GET", 450 Path: "/v2/shared_domains", 451 Response: testnet.TestResponse{Status: http.StatusOK, Body: ` 452 { 453 "next_url": "/v2/shared_domains?page=2", 454 "resources": [ 455 { 456 "metadata": { 457 "guid": "shared-domain1-guid" 458 }, 459 "entity": { 460 "name": "sharedexample.com" 461 } 462 }, 463 { 464 "metadata": { 465 "guid": "shared-domain2-guid" 466 }, 467 "entity": { 468 "name": "some-other-shared-example.com" 469 } 470 } 471 ] 472 }`}, 473 }) 474 475 var secondPageSharedDomainsRequest = apifakes.NewCloudControllerTestRequest(testnet.TestRequest{ 476 Method: "GET", 477 Path: "/v2/shared_domains?page=2", 478 Response: testnet.TestResponse{Status: http.StatusOK, Body: ` 479 { 480 "resources": [ 481 { 482 "metadata": { 483 "guid": "shared-domain3-guid" 484 }, 485 "entity": { 486 "name": "yet-another-shared-example.com" 487 } 488 } 489 ] 490 }`}, 491 }) 492 493 var firstPagePrivateDomainsRequest = apifakes.NewCloudControllerTestRequest(testnet.TestRequest{ 494 Method: "GET", 495 Path: "/v2/organizations/my-org-guid/private_domains", 496 Response: testnet.TestResponse{Status: http.StatusOK, Body: ` 497 { 498 "next_url": "/v2/organizations/my-org-guid/private_domains?page=2", 499 "resources": [ 500 { 501 "metadata": { 502 "guid": "domain1-guid" 503 }, 504 "entity": { 505 "name": "example.com", 506 "owning_organization_guid": "my-org-guid" 507 } 508 }, 509 { 510 "metadata": { 511 "guid": "domain2-guid" 512 }, 513 "entity": { 514 "name": "some-example.com", 515 "owning_organization_guid": "my-org-guid" 516 } 517 } 518 ] 519 }`}, 520 }) 521 522 var secondPagePrivateDomainsRequest = apifakes.NewCloudControllerTestRequest(testnet.TestRequest{ 523 Method: "GET", 524 Path: "/v2/organizations/my-org-guid/private_domains?page=2", 525 Response: testnet.TestResponse{Status: http.StatusOK, Body: ` 526 { 527 "resources": [ 528 { 529 "metadata": { 530 "guid": "domain3-guid" 531 }, 532 "entity": { 533 "name": "example.com", 534 "owning_organization_guid": null, 535 "shared_organizations_url": "/v2/private_domains/domain3-guid/shared_organizations" 536 } 537 } 538 ] 539 }`}, 540 }) 541 542 func deleteDomainReq(statusCode int) testnet.TestRequest { 543 return apifakes.NewCloudControllerTestRequest(testnet.TestRequest{ 544 Method: "DELETE", 545 Path: "/v2/private_domains/my-domain-guid?recursive=true", 546 Response: testnet.TestResponse{Status: statusCode}, 547 }) 548 } 549 550 func deleteSharedDomainReq(statusCode int) testnet.TestRequest { 551 return apifakes.NewCloudControllerTestRequest(testnet.TestRequest{ 552 Method: "DELETE", 553 Path: "/v2/shared_domains/my-domain-guid?recursive=true", 554 Response: testnet.TestResponse{Status: statusCode}, 555 }) 556 }