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