github.com/franc20/ayesa_sap@v7.0.0-beta.28.0.20200124003224-302d4d52fa6c+incompatible/api/cloudcontroller/ccv3/domain_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/types"
     9  
    10  	. "code.cloudfoundry.org/cli/api/cloudcontroller/ccv3"
    11  	. "github.com/onsi/ginkgo"
    12  	. "github.com/onsi/gomega"
    13  	. "github.com/onsi/gomega/ghttp"
    14  )
    15  
    16  var _ = Describe("Domain", func() {
    17  	var client *Client
    18  
    19  	BeforeEach(func() {
    20  		client, _ = NewTestClient()
    21  	})
    22  
    23  	Describe("CheckRoute", func() {
    24  		var (
    25  			matches    bool
    26  			warnings   Warnings
    27  			executeErr error
    28  
    29  			domainGUID string
    30  			hostname   string
    31  			path       string
    32  		)
    33  
    34  		BeforeEach(func() {
    35  			domainGUID = "domain-guid"
    36  			hostname = ""
    37  			path = ""
    38  		})
    39  
    40  		JustBeforeEach(func() {
    41  			matches, warnings, executeErr = client.CheckRoute(domainGUID, hostname, path)
    42  		})
    43  
    44  		When("the request succeeds", func() {
    45  			When("no query params given", func() {
    46  				BeforeEach(func() {
    47  					response := `{ "matching_route": true }`
    48  
    49  					server.AppendHandlers(
    50  						CombineHandlers(
    51  							VerifyRequest(http.MethodGet, "/v3/domains/domain-guid/route_reservations"),
    52  							RespondWith(http.StatusOK, response, http.Header{"X-Cf-Warnings": {"warning-1"}}),
    53  						),
    54  					)
    55  				})
    56  
    57  				It("returns whether the route matches and all warnings", func() {
    58  					Expect(matches).To(BeTrue())
    59  					Expect(executeErr).ToNot(HaveOccurred())
    60  					Expect(warnings).To(ConsistOf("warning-1"))
    61  				})
    62  			})
    63  
    64  			When("hostname is passed in", func() {
    65  				BeforeEach(func() {
    66  					hostname = "hello"
    67  					response := `{ "matching_route": true }`
    68  
    69  					server.AppendHandlers(
    70  						CombineHandlers(
    71  							VerifyRequest(http.MethodGet, "/v3/domains/domain-guid/route_reservations", "host=hello"),
    72  							RespondWith(http.StatusOK, response, http.Header{"X-Cf-Warnings": {"warning-1"}}),
    73  						),
    74  					)
    75  				})
    76  
    77  				It("returns whether the route matches and all warnings", func() {
    78  					Expect(matches).To(BeTrue())
    79  					Expect(executeErr).ToNot(HaveOccurred())
    80  					Expect(warnings).To(ConsistOf("warning-1"))
    81  				})
    82  			})
    83  
    84  			When("path is passed in", func() {
    85  				BeforeEach(func() {
    86  					path = "/potato"
    87  					response := `{ "matching_route": true }`
    88  
    89  					server.AppendHandlers(
    90  						CombineHandlers(
    91  							VerifyRequest(http.MethodGet, "/v3/domains/domain-guid/route_reservations", "path=/potato"),
    92  							RespondWith(http.StatusOK, response, http.Header{"X-Cf-Warnings": {"warning-1"}}),
    93  						),
    94  					)
    95  				})
    96  
    97  				It("returns whether the route matches and all warnings", func() {
    98  					Expect(matches).To(BeTrue())
    99  					Expect(executeErr).ToNot(HaveOccurred())
   100  					Expect(warnings).To(ConsistOf("warning-1"))
   101  				})
   102  			})
   103  
   104  			When("hostname and path are passed in", func() {
   105  				BeforeEach(func() {
   106  					hostname = "hello"
   107  					path = "/potato"
   108  					response := `{ "matching_route": true }`
   109  
   110  					server.AppendHandlers(
   111  						CombineHandlers(
   112  							VerifyRequest(http.MethodGet, "/v3/domains/domain-guid/route_reservations", "host=hello&path=/potato"),
   113  							RespondWith(http.StatusOK, response, http.Header{"X-Cf-Warnings": {"warning-1"}}),
   114  						),
   115  					)
   116  				})
   117  
   118  				It("returns whether the route matches and all warnings", func() {
   119  					Expect(matches).To(BeTrue())
   120  					Expect(executeErr).ToNot(HaveOccurred())
   121  					Expect(warnings).To(ConsistOf("warning-1"))
   122  				})
   123  			})
   124  		})
   125  
   126  		When("the cloud controller returns errors and warnings", func() {
   127  			BeforeEach(func() {
   128  				response := `{
   129    "errors": [
   130      {
   131        "code": 10008,
   132        "detail": "The request is semantically invalid: command presence",
   133        "title": "CF-UnprocessableEntity"
   134      },
   135  	{
   136        "code": 10010,
   137        "detail": "Domain not found",
   138        "title": "CF-ResourceNotFound"
   139      }
   140    ]
   141  }`
   142  				server.AppendHandlers(
   143  					CombineHandlers(
   144  						VerifyRequest(http.MethodGet, "/v3/domains/domain-guid/route_reservations"),
   145  						RespondWith(http.StatusTeapot, response, http.Header{"X-Cf-Warnings": {"this is a warning"}}),
   146  					),
   147  				)
   148  			})
   149  
   150  			It("returns the error and all warnings", func() {
   151  				Expect(executeErr).To(MatchError(ccerror.MultiError{
   152  					ResponseCode: http.StatusTeapot,
   153  					Errors: []ccerror.V3Error{
   154  						{
   155  							Code:   10008,
   156  							Detail: "The request is semantically invalid: command presence",
   157  							Title:  "CF-UnprocessableEntity",
   158  						},
   159  						{
   160  							Code:   10010,
   161  							Detail: "Domain not found",
   162  							Title:  "CF-ResourceNotFound",
   163  						},
   164  					},
   165  				}))
   166  				Expect(warnings).To(ConsistOf("this is a warning"))
   167  			})
   168  		})
   169  	})
   170  
   171  	Describe("CreateDomain for Shared Domains", func() {
   172  		var (
   173  			domain     Domain
   174  			warnings   Warnings
   175  			executeErr error
   176  		)
   177  
   178  		JustBeforeEach(func() {
   179  			domain, warnings, executeErr = client.CreateDomain(Domain{Name: "some-name", Internal: types.NullBool{IsSet: true, Value: true}})
   180  		})
   181  
   182  		When("the request succeeds", func() {
   183  			BeforeEach(func() {
   184  				response := `{
   185  					"guid": "some-guid",
   186  					"name": "some-name",
   187  					"internal": true
   188  				}`
   189  
   190  				expectedBody := `{
   191  					"name": "some-name",
   192  					"internal": true
   193  				}`
   194  
   195  				server.AppendHandlers(
   196  					CombineHandlers(
   197  						VerifyRequest(http.MethodPost, "/v3/domains"),
   198  						VerifyJSON(expectedBody),
   199  						RespondWith(http.StatusCreated, response, http.Header{"X-Cf-Warnings": {"warning-1"}}),
   200  					),
   201  				)
   202  			})
   203  
   204  			It("returns the given domain and all warnings", func() {
   205  				Expect(executeErr).ToNot(HaveOccurred())
   206  				Expect(warnings).To(ConsistOf("warning-1"))
   207  
   208  				Expect(domain).To(Equal(Domain{
   209  					GUID:     "some-guid",
   210  					Name:     "some-name",
   211  					Internal: types.NullBool{IsSet: true, Value: true},
   212  				}))
   213  			})
   214  		})
   215  
   216  		When("the cloud controller returns errors and warnings", func() {
   217  			BeforeEach(func() {
   218  				response := `{
   219    "errors": [
   220      {
   221        "code": 10008,
   222        "detail": "The request is semantically invalid: command presence",
   223        "title": "CF-UnprocessableEntity"
   224      },
   225  		{
   226        "code": 10010,
   227        "detail": "Isolation segment not found",
   228        "title": "CF-ResourceNotFound"
   229      }
   230    ]
   231  }`
   232  				server.AppendHandlers(
   233  					CombineHandlers(
   234  						VerifyRequest(http.MethodPost, "/v3/domains"),
   235  						RespondWith(http.StatusTeapot, response, http.Header{"X-Cf-Warnings": {"this is a warning"}}),
   236  					),
   237  				)
   238  			})
   239  
   240  			It("returns the error and all warnings", func() {
   241  				Expect(executeErr).To(MatchError(ccerror.MultiError{
   242  					ResponseCode: http.StatusTeapot,
   243  					Errors: []ccerror.V3Error{
   244  						{
   245  							Code:   10008,
   246  							Detail: "The request is semantically invalid: command presence",
   247  							Title:  "CF-UnprocessableEntity",
   248  						},
   249  						{
   250  							Code:   10010,
   251  							Detail: "Isolation segment not found",
   252  							Title:  "CF-ResourceNotFound",
   253  						},
   254  					},
   255  				}))
   256  				Expect(warnings).To(ConsistOf("this is a warning"))
   257  			})
   258  		})
   259  	})
   260  
   261  	Describe("CreateDomain for Private Domains", func() {
   262  		var (
   263  			domain     Domain
   264  			warnings   Warnings
   265  			executeErr error
   266  		)
   267  
   268  		JustBeforeEach(func() {
   269  			domain, warnings, executeErr = client.CreateDomain(Domain{Name: "some-name", Internal: types.NullBool{IsSet: false, Value: true}, OrganizationGUID: "organization-guid"})
   270  		})
   271  
   272  		When("the request succeeds", func() {
   273  			BeforeEach(func() {
   274  				response := `{
   275  					"guid": "some-guid",
   276  					"name": "some-name",
   277  					"relationships": { 
   278  						"organization": { 
   279  							"data" : { 
   280  								"guid" : "organization-guid"
   281  							}
   282  						}
   283  					},
   284  					"internal": false
   285  				}`
   286  
   287  				expectedRequestBody := `{
   288  					"name": "some-name",
   289  					"relationships": {
   290  						"organization": {
   291  							"data" : {
   292  								"guid" : "organization-guid"
   293  							}
   294  						}
   295  					}
   296  				}`
   297  
   298  				server.AppendHandlers(
   299  					CombineHandlers(
   300  						VerifyRequest(http.MethodPost, "/v3/domains"),
   301  						VerifyJSON(expectedRequestBody),
   302  						RespondWith(http.StatusCreated, response, http.Header{"X-Cf-Warnings": {"warning-1"}}),
   303  					),
   304  				)
   305  			})
   306  
   307  			It("returns the given domain and all warnings", func() {
   308  				Expect(executeErr).ToNot(HaveOccurred())
   309  				Expect(warnings).To(ConsistOf("warning-1"))
   310  
   311  				Expect(domain).To(Equal(Domain{
   312  					GUID:             "some-guid",
   313  					Name:             "some-name",
   314  					OrganizationGUID: "organization-guid",
   315  					Internal:         types.NullBool{IsSet: true, Value: false},
   316  				}))
   317  			})
   318  		})
   319  
   320  		When("the cloud controller returns errors and warnings", func() {
   321  			BeforeEach(func() {
   322  				response := `{
   323    "errors": [
   324      {
   325        "code": 10008,
   326        "detail": "The request is semantically invalid: command presence",
   327        "title": "CF-UnprocessableEntity"
   328      },
   329  		{
   330        "code": 10010,
   331        "detail": "Isolation segment not found",
   332        "title": "CF-ResourceNotFound"
   333      }
   334    ]
   335  }`
   336  				server.AppendHandlers(
   337  					CombineHandlers(
   338  						VerifyRequest(http.MethodPost, "/v3/domains"),
   339  						RespondWith(http.StatusTeapot, response, http.Header{"X-Cf-Warnings": {"this is a warning"}}),
   340  					),
   341  				)
   342  			})
   343  
   344  			It("returns the error and all warnings", func() {
   345  				Expect(executeErr).To(MatchError(ccerror.MultiError{
   346  					ResponseCode: http.StatusTeapot,
   347  					Errors: []ccerror.V3Error{
   348  						{
   349  							Code:   10008,
   350  							Detail: "The request is semantically invalid: command presence",
   351  							Title:  "CF-UnprocessableEntity",
   352  						},
   353  						{
   354  							Code:   10010,
   355  							Detail: "Isolation segment not found",
   356  							Title:  "CF-ResourceNotFound",
   357  						},
   358  					},
   359  				}))
   360  				Expect(warnings).To(ConsistOf("this is a warning"))
   361  			})
   362  		})
   363  	})
   364  
   365  	Describe("DeleteDomain", func() {
   366  		var (
   367  			domainGUID   string
   368  			jobURLString string
   369  			jobURL       JobURL
   370  			warnings     Warnings
   371  			executeErr   error
   372  		)
   373  
   374  		JustBeforeEach(func() {
   375  			jobURL, warnings, executeErr = client.DeleteDomain(domainGUID)
   376  		})
   377  
   378  		When("domain exists", func() {
   379  			domainGUID = "domain-guid"
   380  			jobURLString = "https://api.test.com/v3/jobs/job-guid"
   381  
   382  			BeforeEach(func() {
   383  				server.AppendHandlers(
   384  					CombineHandlers(
   385  						VerifyRequest(http.MethodDelete, "/v3/domains/domain-guid"),
   386  						RespondWith(http.StatusAccepted, nil, http.Header{
   387  							"X-Cf-Warnings": {"this is a warning"},
   388  							"Location":      {jobURLString},
   389  						}),
   390  					),
   391  				)
   392  			})
   393  
   394  			It("returns all warnings", func() {
   395  				Expect(executeErr).NotTo(HaveOccurred())
   396  				Expect(jobURL).To(Equal(JobURL(jobURLString)))
   397  				Expect(warnings).To(ConsistOf("this is a warning"))
   398  			})
   399  		})
   400  
   401  		When("the cloud controller returns errors and warnings", func() {
   402  			BeforeEach(func() {
   403  				response := `{
   404  	  "errors": [
   405  	    {
   406  	      "code": 10008,
   407  	      "detail": "The request is semantically invalid: command presence",
   408  	      "title": "CF-UnprocessableEntity"
   409  	    },
   410  			{
   411  	      "code": 10010,
   412  	      "detail": "Isolation segment not found",
   413  	      "title": "CF-ResourceNotFound"
   414  	    }
   415  	  ]
   416  	}`
   417  				server.AppendHandlers(
   418  					CombineHandlers(
   419  						VerifyRequest(http.MethodDelete, "/v3/domains/domain-guid"),
   420  						RespondWith(http.StatusTeapot, response, http.Header{"X-Cf-Warnings": {"this is a warning"}}),
   421  					),
   422  				)
   423  			})
   424  
   425  			It("returns the error and all warnings", func() {
   426  				Expect(executeErr).To(MatchError(ccerror.MultiError{
   427  					ResponseCode: http.StatusTeapot,
   428  					Errors: []ccerror.V3Error{
   429  						{
   430  							Code:   10008,
   431  							Detail: "The request is semantically invalid: command presence",
   432  							Title:  "CF-UnprocessableEntity",
   433  						},
   434  						{
   435  							Code:   10010,
   436  							Detail: "Isolation segment not found",
   437  							Title:  "CF-ResourceNotFound",
   438  						},
   439  					},
   440  				}))
   441  				Expect(warnings).To(ConsistOf("this is a warning"))
   442  			})
   443  		})
   444  	})
   445  
   446  	Describe("GetDomains", func() {
   447  		var (
   448  			query      Query
   449  			domains    []Domain
   450  			warnings   Warnings
   451  			executeErr error
   452  		)
   453  
   454  		JustBeforeEach(func() {
   455  			domains, warnings, executeErr = client.GetDomains(query)
   456  		})
   457  
   458  		When("domains exist", func() {
   459  			BeforeEach(func() {
   460  				response1 := fmt.Sprintf(`{
   461  		"pagination": {
   462  			"next": {
   463  				"href": "%s/v3/domains?page=2&per_page=2"
   464  			}
   465  		},
   466  	  "resources": [
   467  	    {
   468  	      	"name": "domain-name-1",
   469  	      	"guid": "domain-guid-1",
   470  	      	"relationships": {
   471  	            "organization": {
   472  	                "data": {
   473  	                    "guid": "owning-org-1"
   474  	                }
   475  	            }
   476  	         }
   477  	    },
   478  	    {
   479  	      	"name": "domain-name-2",
   480  	      	"guid": "domain-guid-2",
   481  			"relationships": {
   482  	            "organization": {
   483  	                "data": {
   484  	                    "guid": "owning-org-2"
   485  	                }
   486  	            }
   487  	         }
   488  	    }
   489  	  ]
   490  	}`, server.URL())
   491  				response2 := `{
   492  		"pagination": {
   493  			"next": null
   494  		},
   495  		"resources": [
   496  		  {
   497  			"name": "domain-name-3",
   498  	         "guid": "domain-guid-3",
   499  			"relationships": {
   500  	            "organization": {
   501  	                "data": {
   502  	                    "guid": "owning-org-3"
   503  	                }
   504  	            }
   505  	         }
   506  			}
   507  		]
   508  	}`
   509  
   510  				server.AppendHandlers(
   511  					CombineHandlers(
   512  						VerifyRequest(http.MethodGet, "/v3/domains"),
   513  						RespondWith(http.StatusOK, response1, http.Header{"X-Cf-Warnings": {"this is a warning"}}),
   514  					),
   515  				)
   516  				server.AppendHandlers(
   517  					CombineHandlers(
   518  						VerifyRequest(http.MethodGet, "/v3/domains", "page=2&per_page=2"),
   519  						RespondWith(http.StatusOK, response2, http.Header{"X-Cf-Warnings": {"this is another warning"}}),
   520  					),
   521  				)
   522  
   523  				query = Query{}
   524  			})
   525  
   526  			It("returns the queried domain and all warnings", func() {
   527  				Expect(executeErr).NotTo(HaveOccurred())
   528  
   529  				Expect(domains).To(ConsistOf(
   530  					Domain{Name: "domain-name-1", GUID: "domain-guid-1", OrganizationGUID: "owning-org-1"},
   531  					Domain{Name: "domain-name-2", GUID: "domain-guid-2", OrganizationGUID: "owning-org-2"},
   532  					Domain{Name: "domain-name-3", GUID: "domain-guid-3", OrganizationGUID: "owning-org-3"},
   533  				))
   534  				Expect(warnings).To(ConsistOf("this is a warning", "this is another warning"))
   535  			})
   536  		})
   537  
   538  		When("the cloud controller returns errors and warnings", func() {
   539  			BeforeEach(func() {
   540  				response := `{
   541  	  "errors": [
   542  	    {
   543  	      "code": 10008,
   544  	      "detail": "The request is semantically invalid: command presence",
   545  	      "title": "CF-UnprocessableEntity"
   546  	    },
   547  			{
   548  	      "code": 10010,
   549  	      "detail": "Isolation segment not found",
   550  	      "title": "CF-ResourceNotFound"
   551  	    }
   552  	  ]
   553  	}`
   554  				server.AppendHandlers(
   555  					CombineHandlers(
   556  						VerifyRequest(http.MethodGet, "/v3/domains"),
   557  						RespondWith(http.StatusTeapot, response, http.Header{"X-Cf-Warnings": {"this is a warning"}}),
   558  					),
   559  				)
   560  			})
   561  
   562  			It("returns the error and all warnings", func() {
   563  				Expect(executeErr).To(MatchError(ccerror.MultiError{
   564  					ResponseCode: http.StatusTeapot,
   565  					Errors: []ccerror.V3Error{
   566  						{
   567  							Code:   10008,
   568  							Detail: "The request is semantically invalid: command presence",
   569  							Title:  "CF-UnprocessableEntity",
   570  						},
   571  						{
   572  							Code:   10010,
   573  							Detail: "Isolation segment not found",
   574  							Title:  "CF-ResourceNotFound",
   575  						},
   576  					},
   577  				}))
   578  				Expect(warnings).To(ConsistOf("this is a warning"))
   579  			})
   580  		})
   581  	})
   582  
   583  	Describe("GetDomain", func() {
   584  
   585  		var (
   586  			domainGUID string
   587  			domain     Domain
   588  			warnings   Warnings
   589  			executeErr error
   590  		)
   591  		JustBeforeEach(func() {
   592  			domainGUID = "domain-guid-1"
   593  			domain, warnings, executeErr = client.GetDomain(domainGUID)
   594  		})
   595  
   596  		When("domain is found", func() {
   597  			BeforeEach(func() {
   598  				response := `{
   599  	      	"name": "domain-name-1",
   600  	      	"guid": "domain-guid-1",
   601  					"metadata": {
   602  						"annotations": {},
   603  						"labels": {
   604  							"fun": "superfun",
   605  							"fun2": "super--fun"
   606  						}
   607  					}
   608  	    }`
   609  				server.AppendHandlers(
   610  					CombineHandlers(
   611  						VerifyRequest(http.MethodGet, "/v3/domains/domain-guid-1"),
   612  						RespondWith(http.StatusOK, response, http.Header{"X-Cf-Warnings": {"this is a warning"}}),
   613  					),
   614  				)
   615  			})
   616  
   617  			It("returns a domain and prints all warnings", func() {
   618  				Expect(executeErr).To(Not(HaveOccurred()))
   619  
   620  				Expect(domain.Name).To(Equal("domain-name-1"))
   621  
   622  				Expect(domain.GUID).To(Equal("domain-guid-1"))
   623  
   624  				Expect(domain.Metadata.Labels).To(Equal(map[string]types.NullString{
   625  					"fun":  types.NewNullString("superfun"),
   626  					"fun2": types.NewNullString("super--fun"),
   627  				}))
   628  
   629  				Expect(warnings).To(ConsistOf("this is a warning"))
   630  			})
   631  		})
   632  
   633  		When("cloud controller returns an error", func() {
   634  			BeforeEach(func() {
   635  				response := `{
   636  	  "errors": [
   637  	    {
   638  	      "code": 10008,
   639  	      "detail": "The request is semantically invalid: command presence",
   640  	      "title": "CF-UnprocessableEntity"
   641  	    },
   642  			{
   643  	      "code": 10010,
   644  	      "detail": "Domain not found",
   645  	      "title": "CF-ResourceNotFound"
   646  	    }
   647  	  ]
   648  	}`
   649  				server.AppendHandlers(
   650  					CombineHandlers(
   651  						VerifyRequest(http.MethodGet, "/v3/domains/domain-guid-1"),
   652  						RespondWith(http.StatusTeapot, response, http.Header{"X-Cf-Warnings": {"this is a warning"}}),
   653  					),
   654  				)
   655  			})
   656  
   657  			It("returns the error and all warnings", func() {
   658  				Expect(executeErr).To(MatchError(ccerror.MultiError{
   659  					ResponseCode: http.StatusTeapot,
   660  					Errors: []ccerror.V3Error{
   661  						{
   662  							Code:   10008,
   663  							Detail: "The request is semantically invalid: command presence",
   664  							Title:  "CF-UnprocessableEntity",
   665  						},
   666  						{
   667  							Code:   10010,
   668  							Detail: "Domain not found",
   669  							Title:  "CF-ResourceNotFound",
   670  						},
   671  					},
   672  				}))
   673  				Expect(warnings).To(ConsistOf("this is a warning"))
   674  			})
   675  		})
   676  	})
   677  
   678  	Describe("GetOrganizationDomains", func() {
   679  		var (
   680  			orgGUID    string
   681  			query      Query
   682  			domains    []Domain
   683  			warnings   Warnings
   684  			executeErr error
   685  		)
   686  
   687  		BeforeEach(func() {
   688  			orgGUID = "some-org-guid"
   689  		})
   690  
   691  		JustBeforeEach(func() {
   692  			domains, warnings, executeErr = client.GetOrganizationDomains(orgGUID, query)
   693  		})
   694  
   695  		When("domains exist", func() {
   696  			BeforeEach(func() {
   697  				response1 := fmt.Sprintf(`{
   698  	"pagination": {
   699  		"next": {
   700  			"href": "%s/v3/organizations/some-org-guid/domains?organization_guids=some-org-guid&page=2&per_page=2"
   701  		}
   702  	},
   703    "resources": [
   704      {
   705        	"name": "domain-name-1",
   706        	"guid": "domain-guid-1",
   707        	"relationships": {
   708              "organization": {
   709                  "data": {
   710                      "guid": "some-org-guid"
   711                  }
   712              }
   713           }
   714      },
   715      {
   716        	"name": "domain-name-2",
   717        	"guid": "domain-guid-2",
   718  		"relationships": {
   719              "organization": {
   720                  "data": {
   721                      "guid": "some-org-guid"
   722                  }
   723              }
   724           }
   725      }
   726    ]
   727  }`, server.URL())
   728  				response2 := `{
   729  	"pagination": {
   730  		"next": null
   731  	},
   732  	"resources": [
   733  		{
   734  			"name": "domain-name-3",
   735  			"guid": "domain-guid-3",
   736  			"relationships": {
   737              	"organization": {
   738                  	"data": {
   739                      	"guid": "some-org-guid"
   740                  	}
   741              	}
   742           	}
   743  		}
   744  	]
   745  }`
   746  
   747  				server.AppendHandlers(
   748  					CombineHandlers(
   749  						VerifyRequest(http.MethodGet, "/v3/organizations/some-org-guid/domains", "organization_guids=some-org-guid"),
   750  						RespondWith(http.StatusOK, response1, http.Header{"X-Cf-Warnings": {"this is a warning"}}),
   751  					),
   752  				)
   753  				server.AppendHandlers(
   754  					CombineHandlers(
   755  						VerifyRequest(http.MethodGet, "/v3/organizations/some-org-guid/domains", "organization_guids=some-org-guid&page=2&per_page=2"),
   756  						RespondWith(http.StatusOK, response2, http.Header{"X-Cf-Warnings": {"this is another warning"}}),
   757  					),
   758  				)
   759  
   760  				query = Query{
   761  					Key:    OrganizationGUIDFilter,
   762  					Values: []string{orgGUID},
   763  				}
   764  			})
   765  
   766  			It("returns the queried domain and all warnings", func() {
   767  				Expect(executeErr).NotTo(HaveOccurred())
   768  
   769  				Expect(domains).To(ConsistOf(
   770  					Domain{Name: "domain-name-1", GUID: "domain-guid-1", OrganizationGUID: orgGUID},
   771  					Domain{Name: "domain-name-2", GUID: "domain-guid-2", OrganizationGUID: orgGUID},
   772  					Domain{Name: "domain-name-3", GUID: "domain-guid-3", OrganizationGUID: orgGUID},
   773  				))
   774  				Expect(warnings).To(ConsistOf("this is a warning", "this is another warning"))
   775  			})
   776  		})
   777  
   778  		When("the cloud controller returns errors and warnings", func() {
   779  			BeforeEach(func() {
   780  				response := `{
   781    	"errors": [
   782      	{
   783        		"code": 10008,
   784        		"detail": "The request is semantically invalid: command presence",
   785        		"title": "CF-UnprocessableEntity"
   786      	},
   787  		{
   788  			"code": 10010,
   789        		"detail": "Isolation segment not found",
   790        		"title": "CF-ResourceNotFound"
   791      	}
   792    	]
   793  }`
   794  				server.AppendHandlers(
   795  					CombineHandlers(
   796  						VerifyRequest(http.MethodGet, "/v3/organizations/some-org-guid/domains"),
   797  						RespondWith(http.StatusTeapot, response, http.Header{"X-Cf-Warnings": {"this is a warning"}}),
   798  					),
   799  				)
   800  			})
   801  
   802  			It("returns the error and all warnings", func() {
   803  				Expect(executeErr).To(MatchError(ccerror.MultiError{
   804  					ResponseCode: http.StatusTeapot,
   805  					Errors: []ccerror.V3Error{
   806  						{
   807  							Code:   10008,
   808  							Detail: "The request is semantically invalid: command presence",
   809  							Title:  "CF-UnprocessableEntity",
   810  						},
   811  						{
   812  							Code:   10010,
   813  							Detail: "Isolation segment not found",
   814  							Title:  "CF-ResourceNotFound",
   815  						},
   816  					},
   817  				}))
   818  				Expect(warnings).To(ConsistOf("this is a warning"))
   819  			})
   820  		})
   821  	})
   822  
   823  	Describe("SharePrivateDomainToOrgs", func() {
   824  		var (
   825  			orgGUID    = "some-org-guid"
   826  			domainGUID = "some-domain-guid"
   827  			warnings   Warnings
   828  			executeErr error
   829  		)
   830  
   831  		JustBeforeEach(func() {
   832  			warnings, executeErr = client.SharePrivateDomainToOrgs(
   833  				domainGUID,
   834  				SharedOrgs{GUIDs: []string{orgGUID}},
   835  			)
   836  		})
   837  
   838  		When("the request succeeds", func() {
   839  			BeforeEach(func() {
   840  				response := `{"data": 
   841  								[{
   842  									"guid": "some-org-guid"
   843  								}]
   844  						}`
   845  
   846  				expectedBody := `{
   847  					"data": [
   848  						{"guid": "some-org-guid"}
   849  					]
   850  				}`
   851  
   852  				server.AppendHandlers(
   853  					CombineHandlers(
   854  						VerifyRequest(http.MethodPost, "/v3/domains/some-domain-guid/relationships/shared_organizations"),
   855  						VerifyJSON(expectedBody),
   856  						RespondWith(http.StatusOK, response, http.Header{"X-Cf-Warnings": {"this is a warning"}}),
   857  					),
   858  				)
   859  			})
   860  
   861  			It("returns all warnings", func() {
   862  				Expect(warnings).To(ConsistOf("this is a warning"))
   863  				Expect(executeErr).To(BeNil())
   864  			})
   865  		})
   866  
   867  		When("the cloud controller returns errors and warnings", func() {
   868  			BeforeEach(func() {
   869  				response := `{
   870    	"errors": [
   871      	{
   872        		"code": 10008,
   873        		"detail": "The request is semantically invalid: command presence",
   874        		"title": "CF-UnprocessableEntity"
   875      	},
   876  		{
   877  			"code": 10010,
   878        		"detail": "Organization not found",
   879        		"title": "CF-ResourceNotFound"
   880      	}
   881    	]
   882  }`
   883  				server.AppendHandlers(
   884  					CombineHandlers(
   885  						VerifyRequest(http.MethodPost, "/v3/domains/some-domain-guid/relationships/shared_organizations"),
   886  						RespondWith(http.StatusTeapot, response, http.Header{"X-Cf-Warnings": {"this is a warning"}}),
   887  					),
   888  				)
   889  			})
   890  
   891  			It("returns the error and all warnings", func() {
   892  				Expect(executeErr).To(MatchError(ccerror.MultiError{
   893  					ResponseCode: http.StatusTeapot,
   894  					Errors: []ccerror.V3Error{
   895  						{
   896  							Code:   10008,
   897  							Detail: "The request is semantically invalid: command presence",
   898  							Title:  "CF-UnprocessableEntity",
   899  						},
   900  						{
   901  							Code:   10010,
   902  							Detail: "Organization not found",
   903  							Title:  "CF-ResourceNotFound",
   904  						},
   905  					},
   906  				}))
   907  				Expect(warnings).To(ConsistOf("this is a warning"))
   908  			})
   909  		})
   910  	})
   911  
   912  	Describe("UnsharePrivateDomainFromOrg", func() {
   913  		var (
   914  			orgGUID    = "some-org-guid"
   915  			domainGUID = "some-domain-guid"
   916  			warnings   Warnings
   917  			executeErr error
   918  		)
   919  
   920  		JustBeforeEach(func() {
   921  			warnings, executeErr = client.UnsharePrivateDomainFromOrg(
   922  				domainGUID,
   923  				orgGUID,
   924  			)
   925  		})
   926  
   927  		When("the request succeeds", func() {
   928  			BeforeEach(func() {
   929  				server.AppendHandlers(
   930  					CombineHandlers(
   931  						VerifyRequest(http.MethodDelete, "/v3/domains/some-domain-guid/relationships/shared_organizations/some-org-guid"),
   932  						RespondWith(http.StatusNoContent, "", http.Header{"X-Cf-Warnings": {"this is a warning"}}),
   933  					),
   934  				)
   935  			})
   936  
   937  			It("returns all warnings", func() {
   938  				Expect(warnings).To(ConsistOf("this is a warning"))
   939  				Expect(executeErr).To(BeNil())
   940  			})
   941  		})
   942  
   943  		When("the cloud controller returns errors and warnings", func() {
   944  			BeforeEach(func() {
   945  				response := `{
   946    	"errors": [
   947      	{
   948        		"code": 10008,
   949        		"detail": "The request is semantically invalid: command presence",
   950        		"title": "CF-UnprocessableEntity"
   951      	},
   952  		{
   953  			"code": 10010,
   954        		"detail": "Organization not found",
   955        		"title": "CF-ResourceNotFound"
   956      	}
   957    	]
   958  }`
   959  				server.AppendHandlers(
   960  					CombineHandlers(
   961  						VerifyRequest(http.MethodDelete, "/v3/domains/some-domain-guid/relationships/shared_organizations/some-org-guid"),
   962  						RespondWith(http.StatusTeapot, response, http.Header{"X-Cf-Warnings": {"this is a warning"}}),
   963  					),
   964  				)
   965  			})
   966  
   967  			It("returns the error and all warnings", func() {
   968  				Expect(executeErr).To(MatchError(ccerror.MultiError{
   969  					ResponseCode: http.StatusTeapot,
   970  					Errors: []ccerror.V3Error{
   971  						{
   972  							Code:   10008,
   973  							Detail: "The request is semantically invalid: command presence",
   974  							Title:  "CF-UnprocessableEntity",
   975  						},
   976  						{
   977  							Code:   10010,
   978  							Detail: "Organization not found",
   979  							Title:  "CF-ResourceNotFound",
   980  						},
   981  					},
   982  				}))
   983  				Expect(warnings).To(ConsistOf("this is a warning"))
   984  			})
   985  		})
   986  	})
   987  })