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