github.com/wanddynosios/cli/v8@v8.7.9-0.20240221182337-1a92e3a7017f/api/cloudcontroller/ccv3/isolation_segment_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/api/cloudcontroller/ccv3"
     9  	"code.cloudfoundry.org/cli/resources"
    10  	. "github.com/onsi/ginkgo"
    11  	. "github.com/onsi/gomega"
    12  	. "github.com/onsi/gomega/ghttp"
    13  )
    14  
    15  var _ = Describe("Isolation Segments", func() {
    16  	var (
    17  		client *Client
    18  	)
    19  
    20  	BeforeEach(func() {
    21  		client, _ = NewTestClient()
    22  	})
    23  
    24  	Describe("CreateIsolationSegment", func() {
    25  		var (
    26  			name string
    27  
    28  			isolationSegment resources.IsolationSegment
    29  			warnings         Warnings
    30  			executeErr       error
    31  		)
    32  
    33  		JustBeforeEach(func() {
    34  			isolationSegment, warnings, executeErr = client.CreateIsolationSegment(resources.IsolationSegment{Name: name})
    35  			name = "an_isolation_segment"
    36  		})
    37  
    38  		When("the segment does not exist", func() {
    39  			BeforeEach(func() {
    40  				response := `{
    41  					"guid": "some-guid",
    42  					"name": "an_isolation_segment"
    43  				}`
    44  
    45  				requestBody := map[string]string{
    46  					"name": name,
    47  				}
    48  
    49  				server.AppendHandlers(
    50  					CombineHandlers(
    51  						VerifyRequest(http.MethodPost, "/v3/isolation_segments"),
    52  						VerifyJSONRepresenting(requestBody),
    53  						RespondWith(http.StatusCreated, response, http.Header{"X-Cf-Warnings": {"this is a warning"}}),
    54  					),
    55  				)
    56  			})
    57  
    58  			It("returns the created segment and all warnings", func() {
    59  				Expect(executeErr).NotTo(HaveOccurred())
    60  
    61  				Expect(isolationSegment).To(Equal(resources.IsolationSegment{
    62  					Name: name,
    63  					GUID: "some-guid",
    64  				}))
    65  				Expect(warnings).To(ConsistOf("this is a warning"))
    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": 10008,
    80  							"detail": "The request is semantically invalid: command presence",
    81  							"title": "CF-UnprocessableEntity"
    82  						}
    83  					]
    84  				}`
    85  				server.AppendHandlers(
    86  					CombineHandlers(
    87  						VerifyRequest(http.MethodPost, "/v3/isolation_segments"),
    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:   10008,
   104  							Detail: "The request is semantically invalid: command presence",
   105  							Title:  "CF-UnprocessableEntity",
   106  						},
   107  					},
   108  				}))
   109  				Expect(warnings).To(ConsistOf("this is a warning"))
   110  			})
   111  		})
   112  	})
   113  
   114  	Describe("GetIsolationSegments", func() {
   115  		var (
   116  			queries []Query
   117  
   118  			segments   []resources.IsolationSegment
   119  			warnings   Warnings
   120  			executeErr error
   121  		)
   122  
   123  		JustBeforeEach(func() {
   124  			queries = []Query{
   125  				{Key: OrganizationGUIDFilter, Values: []string{"some-org-guid"}},
   126  				{Key: NameFilter, Values: []string{"iso1", "iso2", "iso3"}},
   127  			}
   128  			segments, warnings, executeErr = client.GetIsolationSegments(queries...)
   129  		})
   130  
   131  		When("the isolation segments exist", func() {
   132  			BeforeEach(func() {
   133  				response1 := fmt.Sprintf(`{
   134  					"pagination": {
   135  						"next": {
   136  							"href": "%s/v3/isolation_segments?organization_guids=some-org-guid&names=iso1,iso2,iso3&page=2&per_page=2"
   137  						}
   138  					},
   139  					"resources": [
   140  						{
   141  							"name": "iso-name-1",
   142  							"guid": "iso-guid-1"
   143  						},
   144  						{
   145  							"name": "iso-name-2",
   146  							"guid": "iso-guid-2"
   147  						}
   148  					]
   149  				}`, server.URL())
   150  				response2 := `{
   151  					"pagination": {
   152  						"next": null
   153  					},
   154  					"resources": [
   155  						{
   156  							"name": "iso-name-3",
   157  							"guid": "iso-guid-3"
   158  						}
   159  					]
   160  				}`
   161  				server.AppendHandlers(
   162  					CombineHandlers(
   163  						VerifyRequest(http.MethodGet, "/v3/isolation_segments", "organization_guids=some-org-guid&names=iso1,iso2,iso3"),
   164  						RespondWith(http.StatusOK, response1, http.Header{"X-Cf-Warnings": {"this is a warning"}}),
   165  					),
   166  				)
   167  				server.AppendHandlers(
   168  					CombineHandlers(
   169  						VerifyRequest(http.MethodGet, "/v3/isolation_segments", "organization_guids=some-org-guid&names=iso1,iso2,iso3&page=2&per_page=2"),
   170  						RespondWith(http.StatusOK, response2, http.Header{"X-Cf-Warnings": {"this is another warning"}}),
   171  					),
   172  				)
   173  			})
   174  
   175  			It("returns the queried applications and all warnings", func() {
   176  				Expect(executeErr).NotTo(HaveOccurred())
   177  
   178  				Expect(segments).To(ConsistOf(
   179  					resources.IsolationSegment{Name: "iso-name-1", GUID: "iso-guid-1"},
   180  					resources.IsolationSegment{Name: "iso-name-2", GUID: "iso-guid-2"},
   181  					resources.IsolationSegment{Name: "iso-name-3", GUID: "iso-guid-3"},
   182  				))
   183  				Expect(warnings).To(ConsistOf("this is a warning", "this is another warning"))
   184  			})
   185  		})
   186  
   187  		When("the cloud controller returns errors and warnings", func() {
   188  			BeforeEach(func() {
   189  				response := `{
   190  					"errors": [
   191  						{
   192  							"code": 10008,
   193  							"detail": "The request is semantically invalid: command presence",
   194  							"title": "CF-UnprocessableEntity"
   195  						},
   196  						{
   197  							"code": 10010,
   198  							"detail": "App not found",
   199  							"title": "CF-ResourceNotFound"
   200  						}
   201  					]
   202  				}`
   203  				server.AppendHandlers(
   204  					CombineHandlers(
   205  						VerifyRequest(http.MethodGet, "/v3/isolation_segments"),
   206  						RespondWith(http.StatusTeapot, response, http.Header{"X-Cf-Warnings": {"this is a warning"}}),
   207  					),
   208  				)
   209  			})
   210  
   211  			It("returns the error and all warnings", func() {
   212  				Expect(executeErr).To(MatchError(ccerror.MultiError{
   213  					ResponseCode: http.StatusTeapot,
   214  					Errors: []ccerror.V3Error{
   215  						{
   216  							Code:   10008,
   217  							Detail: "The request is semantically invalid: command presence",
   218  							Title:  "CF-UnprocessableEntity",
   219  						},
   220  						{
   221  							Code:   10010,
   222  							Detail: "App not found",
   223  							Title:  "CF-ResourceNotFound",
   224  						},
   225  					},
   226  				}))
   227  				Expect(warnings).To(ConsistOf("this is a warning"))
   228  			})
   229  		})
   230  	})
   231  
   232  	Describe("GetIsolationSegment", func() {
   233  		var (
   234  			warnings         Warnings
   235  			executeErr       error
   236  			isolationSegment resources.IsolationSegment
   237  		)
   238  
   239  		JustBeforeEach(func() {
   240  			isolationSegment, warnings, executeErr = client.GetIsolationSegment("some-iso-guid")
   241  		})
   242  
   243  		When("the isolation segment exists", func() {
   244  			BeforeEach(func() {
   245  				response := `{
   246  					"guid": "some-iso-guid",
   247  					"name": "an_isolation_segment"
   248  				}`
   249  				server.AppendHandlers(
   250  					CombineHandlers(
   251  						VerifyRequest(http.MethodGet, "/v3/isolation_segments/some-iso-guid"),
   252  						RespondWith(http.StatusOK, response, http.Header{"X-Cf-Warnings": {"this is a warning"}}),
   253  					),
   254  				)
   255  			})
   256  
   257  			It("returns the isolation segment and all warnings", func() {
   258  				Expect(executeErr).NotTo(HaveOccurred())
   259  				Expect(warnings).To(ConsistOf("this is a warning"))
   260  				Expect(isolationSegment).To(Equal(resources.IsolationSegment{
   261  					Name: "an_isolation_segment",
   262  					GUID: "some-iso-guid",
   263  				}))
   264  			})
   265  		})
   266  
   267  		When("the isolation segment does not exist", func() {
   268  			BeforeEach(func() {
   269  				response := `
   270  				{
   271  					  "errors": [
   272  						    {
   273  									  "detail": "Isolation segment not found",
   274  							      "title": "CF-ResourceNotFound",
   275  							      "code": 10010
   276  						    }
   277  					  ]
   278  				}`
   279  				server.AppendHandlers(
   280  					CombineHandlers(
   281  						VerifyRequest(http.MethodGet, "/v3/isolation_segments/some-iso-guid"),
   282  						RespondWith(http.StatusNotFound, response, http.Header{"X-Cf-Warnings": {"this is a warning"}}),
   283  					),
   284  				)
   285  			})
   286  
   287  			It("returns a ResourceNotFoundError", func() {
   288  				Expect(warnings).To(ConsistOf("this is a warning"))
   289  				Expect(executeErr).To(MatchError(ccerror.ResourceNotFoundError{Message: "Isolation segment not found"}))
   290  			})
   291  		})
   292  
   293  		When("the cloud controller returns errors and warnings", func() {
   294  			BeforeEach(func() {
   295  				response := `{
   296  					"errors": [
   297  						{
   298  							"code": 10008,
   299  							"detail": "The request is semantically invalid: command presence",
   300  							"title": "CF-UnprocessableEntity"
   301  						},
   302  						{
   303  							"code": 10010,
   304  							"detail": "Isolation Segment not found",
   305  							"title": "CF-ResourceNotFound"
   306  						}
   307  					]
   308  				}`
   309  				server.AppendHandlers(
   310  					CombineHandlers(
   311  						VerifyRequest(http.MethodGet, "/v3/isolation_segments/some-iso-guid"),
   312  						RespondWith(http.StatusTeapot, response, http.Header{"X-Cf-Warnings": {"this is a warning"}}),
   313  					),
   314  				)
   315  			})
   316  
   317  			It("returns the error and all warnings", func() {
   318  				Expect(executeErr).To(MatchError(ccerror.MultiError{
   319  					ResponseCode: http.StatusTeapot,
   320  					Errors: []ccerror.V3Error{
   321  						{
   322  							Code:   10008,
   323  							Detail: "The request is semantically invalid: command presence",
   324  							Title:  "CF-UnprocessableEntity",
   325  						},
   326  						{
   327  							Code:   10010,
   328  							Detail: "Isolation Segment not found",
   329  							Title:  "CF-ResourceNotFound",
   330  						},
   331  					},
   332  				}))
   333  				Expect(warnings).To(ConsistOf("this is a warning"))
   334  			})
   335  		})
   336  	})
   337  
   338  	Describe("DeleteIsolationSegment", func() {
   339  		var (
   340  			warnings   Warnings
   341  			executeErr error
   342  		)
   343  
   344  		JustBeforeEach(func() {
   345  			warnings, executeErr = client.DeleteIsolationSegment("some-iso-guid")
   346  		})
   347  
   348  		When("the delete is successful", func() {
   349  			BeforeEach(func() {
   350  				server.AppendHandlers(
   351  					CombineHandlers(
   352  						VerifyRequest(http.MethodDelete, "/v3/isolation_segments/some-iso-guid"),
   353  						RespondWith(http.StatusOK, "", http.Header{"X-Cf-Warnings": {"this is a warning"}}),
   354  					),
   355  				)
   356  			})
   357  
   358  			It("returns the queried applications and all warnings", func() {
   359  				Expect(executeErr).NotTo(HaveOccurred())
   360  				Expect(warnings).To(ConsistOf("this is a warning"))
   361  			})
   362  		})
   363  
   364  		When("the cloud controller returns errors and warnings", func() {
   365  			BeforeEach(func() {
   366  				response := `{
   367  					"errors": [
   368  						{
   369  							"code": 10008,
   370  							"detail": "The request is semantically invalid: command presence",
   371  							"title": "CF-UnprocessableEntity"
   372  						},
   373  						{
   374  							"code": 10010,
   375  							"detail": "App not found",
   376  							"title": "CF-ResourceNotFound"
   377  						}
   378  					]
   379  				}`
   380  				server.AppendHandlers(
   381  					CombineHandlers(
   382  						VerifyRequest(http.MethodDelete, "/v3/isolation_segments/some-iso-guid"),
   383  						RespondWith(http.StatusTeapot, response, http.Header{"X-Cf-Warnings": {"this is a warning"}}),
   384  					),
   385  				)
   386  			})
   387  
   388  			It("returns the error and all warnings", func() {
   389  				Expect(executeErr).To(MatchError(ccerror.MultiError{
   390  					ResponseCode: http.StatusTeapot,
   391  					Errors: []ccerror.V3Error{
   392  						{
   393  							Code:   10008,
   394  							Detail: "The request is semantically invalid: command presence",
   395  							Title:  "CF-UnprocessableEntity",
   396  						},
   397  						{
   398  							Code:   10010,
   399  							Detail: "App not found",
   400  							Title:  "CF-ResourceNotFound",
   401  						},
   402  					},
   403  				}))
   404  				Expect(warnings).To(ConsistOf("this is a warning"))
   405  			})
   406  		})
   407  	})
   408  })