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