github.com/cloudfoundry-community/cloudfoundry-cli@v6.44.1-0.20240130060226-cda5ed8e89a5+incompatible/api/cloudcontroller/ccv3/domain_test.go (about)

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