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 })