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  }