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