github.com/cloudfoundry-attic/cli-with-i18n@v6.32.1-0.20171002233121-7401370d3b85+incompatible/api/cloudcontroller/ccv3/relationship_test.go (about) 1 package ccv3_test 2 3 import ( 4 "encoding/json" 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("Relationship", func() { 15 var ( 16 client *Client 17 ) 18 19 BeforeEach(func() { 20 client = NewTestClient() 21 }) 22 23 Describe("Relationship.MarshalJSON", func() { 24 Context("when the isolation segment is specified by name", func() { 25 It("contains the name in the marshaled JSON", func() { 26 body, err := json.Marshal(Relationship{GUID: "some-iso-guid"}) 27 expectedJSON := `{ 28 "data": { 29 "guid": "some-iso-guid" 30 } 31 }` 32 33 Expect(err).NotTo(HaveOccurred()) 34 Expect(body).To(MatchJSON(expectedJSON)) 35 }) 36 }) 37 38 Context("when the isolation segment is the empty string", func() { 39 It("contains null in the marshaled JSON", func() { 40 body, err := json.Marshal(Relationship{GUID: ""}) 41 expectedJSON := `{ 42 "data": null 43 }` 44 45 Expect(err).NotTo(HaveOccurred()) 46 Expect(body).To(MatchJSON(expectedJSON)) 47 }) 48 }) 49 }) 50 51 Describe("AssignSpaceToIsolationSegment", func() { 52 Context("when the assignment is successful", func() { 53 BeforeEach(func() { 54 response := `{ 55 "data": { 56 "guid": "some-isolation-segment-guid" 57 } 58 }` 59 60 requestBody := map[string]map[string]string{ 61 "data": {"guid": "some-iso-guid"}, 62 } 63 server.AppendHandlers( 64 CombineHandlers( 65 VerifyRequest(http.MethodPatch, "/v3/spaces/some-space-guid/relationships/isolation_segment"), 66 VerifyJSONRepresenting(requestBody), 67 RespondWith(http.StatusOK, response, http.Header{"X-Cf-Warnings": {"this is a warning"}}), 68 ), 69 ) 70 }) 71 72 It("returns all relationships and warnings", func() { 73 relationship, warnings, err := client.AssignSpaceToIsolationSegment("some-space-guid", "some-iso-guid") 74 Expect(err).NotTo(HaveOccurred()) 75 Expect(warnings).To(ConsistOf("this is a warning")) 76 Expect(relationship).To(Equal(Relationship{ 77 GUID: "some-isolation-segment-guid", 78 })) 79 }) 80 }) 81 }) 82 83 Describe("GetSpaceIsolationSegment", func() { 84 Context("when getting the isolation segment is successful", func() { 85 BeforeEach(func() { 86 response := `{ 87 "data": { 88 "guid": "some-isolation-segment-guid" 89 } 90 }` 91 92 server.AppendHandlers( 93 CombineHandlers( 94 VerifyRequest(http.MethodGet, "/v3/spaces/some-space-guid/relationships/isolation_segment"), 95 RespondWith(http.StatusOK, response, http.Header{"X-Cf-Warnings": {"this is a warning"}}), 96 ), 97 ) 98 }) 99 100 It("returns the relationship and warnings", func() { 101 relationship, warnings, err := client.GetSpaceIsolationSegment("some-space-guid") 102 Expect(err).NotTo(HaveOccurred()) 103 Expect(warnings).To(ConsistOf("this is a warning")) 104 Expect(relationship).To(Equal(Relationship{ 105 GUID: "some-isolation-segment-guid", 106 })) 107 }) 108 }) 109 }) 110 111 Describe("RevokeIsolationSegmentFromOrganization", func() { 112 Context("when relationship exists", func() { 113 BeforeEach(func() { 114 server.AppendHandlers( 115 CombineHandlers( 116 VerifyRequest(http.MethodDelete, "/v3/isolation_segments/segment-guid/relationships/organizations/org-guid"), 117 RespondWith(http.StatusOK, "", http.Header{"X-Cf-Warnings": {"this is a warning"}}), 118 ), 119 ) 120 }) 121 122 It("revoke the relationship", func() { 123 warnings, err := client.RevokeIsolationSegmentFromOrganization("segment-guid", "org-guid") 124 Expect(err).ToNot(HaveOccurred()) 125 Expect(warnings).To(ConsistOf("this is a warning")) 126 127 Expect(server.ReceivedRequests()).To(HaveLen(3)) 128 }) 129 }) 130 }) 131 132 Context("when an error occurs", func() { 133 BeforeEach(func() { 134 response := `{ 135 "errors": [ 136 { 137 "code": 10008, 138 "detail": "The request is semantically invalid: command presence", 139 "title": "CF-UnprocessableEntity" 140 } 141 ] 142 }` 143 144 server.AppendHandlers( 145 CombineHandlers( 146 VerifyRequest(http.MethodDelete, "/v3/isolation_segments/segment-guid/relationships/organizations/org-guid"), 147 RespondWith(http.StatusTeapot, response, http.Header{"X-Cf-Warnings": {"this is a warning"}}), 148 ), 149 ) 150 }) 151 152 It("returns the error and warnings", func() { 153 warnings, err := client.RevokeIsolationSegmentFromOrganization("segment-guid", "org-guid") 154 Expect(err).To(MatchError(ccerror.V3UnexpectedResponseError{ 155 ResponseCode: http.StatusTeapot, 156 V3ErrorResponse: ccerror.V3ErrorResponse{ 157 Errors: []ccerror.V3Error{ 158 { 159 Code: 10008, 160 Detail: "The request is semantically invalid: command presence", 161 Title: "CF-UnprocessableEntity", 162 }, 163 }, 164 }, 165 })) 166 Expect(warnings).To(ConsistOf("this is a warning")) 167 }) 168 }) 169 170 Describe("GetOrganizationDefaultIsolationSegment", func() { 171 Context("when getting the isolation segment is successful", func() { 172 BeforeEach(func() { 173 response := `{ 174 "data": { 175 "guid": "some-isolation-segment-guid" 176 } 177 }` 178 179 server.AppendHandlers( 180 CombineHandlers( 181 VerifyRequest(http.MethodGet, "/v3/organizations/some-org-guid/relationships/default_isolation_segment"), 182 RespondWith(http.StatusOK, response, http.Header{"X-Cf-Warnings": {"this is a warning"}}), 183 ), 184 ) 185 }) 186 187 It("returns the relationship and warnings", func() { 188 relationship, warnings, err := client.GetOrganizationDefaultIsolationSegment("some-org-guid") 189 Expect(err).NotTo(HaveOccurred()) 190 Expect(warnings).To(ConsistOf("this is a warning")) 191 Expect(relationship).To(Equal(Relationship{ 192 GUID: "some-isolation-segment-guid", 193 })) 194 }) 195 }) 196 197 Context("when getting the isolation segment fails with an error", func() { 198 BeforeEach(func() { 199 response := `{ 200 "errors": [ 201 { 202 "detail": "Organization not found", 203 "title": "CF-ResourceNotFound", 204 "code": 10010 205 } 206 ] 207 }` 208 server.AppendHandlers( 209 CombineHandlers( 210 VerifyRequest(http.MethodGet, "/v3/organizations/some-org-guid/relationships/default_isolation_segment"), 211 RespondWith(http.StatusNotFound, response, http.Header{"X-Cf-Warnings": {"this is a warning"}}), 212 ), 213 ) 214 }) 215 216 It("returns an error and warnings", func() { 217 _, warnings, err := client.GetOrganizationDefaultIsolationSegment("some-org-guid") 218 Expect(err).To(MatchError(ccerror.ResourceNotFoundError{ 219 Message: "Organization not found", 220 })) 221 Expect(warnings).To(ConsistOf("this is a warning")) 222 }) 223 }) 224 }) 225 226 Describe("PatchOrganizationDefaultIsolationSegment", func() { 227 Context("when patching the default organization isolation segment with non-empty isolation segment guid", func() { 228 BeforeEach(func() { 229 expectedBody := `{ 230 "data": { 231 "guid": "some-isolation-segment-guid" 232 } 233 }` 234 server.AppendHandlers( 235 CombineHandlers( 236 VerifyRequest(http.MethodPatch, "/v3/organizations/some-org-guid/relationships/default_isolation_segment"), 237 VerifyJSON(expectedBody), 238 RespondWith(http.StatusOK, "", http.Header{"X-Cf-Warnings": {"this is a warning"}}), 239 ), 240 ) 241 }) 242 243 It("patches the organization's default isolation segment", func() { 244 warnings, err := client.PatchOrganizationDefaultIsolationSegment("some-org-guid", "some-isolation-segment-guid") 245 Expect(err).ToNot(HaveOccurred()) 246 Expect(warnings).To(ConsistOf("this is a warning")) 247 }) 248 }) 249 250 Context("when patching the default organization isolation segment with empty isolation segment guid", func() { 251 BeforeEach(func() { 252 expectedBody := `{ 253 "data": null 254 }` 255 server.AppendHandlers( 256 CombineHandlers( 257 VerifyRequest(http.MethodPatch, "/v3/organizations/some-org-guid/relationships/default_isolation_segment"), 258 VerifyJSON(expectedBody), 259 RespondWith(http.StatusOK, "", http.Header{"X-Cf-Warnings": {"this is a warning"}}), 260 ), 261 ) 262 }) 263 264 It("patches the organization's default isolation segment with nil guid", func() { 265 warnings, err := client.PatchOrganizationDefaultIsolationSegment("some-org-guid", "") 266 Expect(err).ToNot(HaveOccurred()) 267 Expect(warnings).To(ConsistOf("this is a warning")) 268 }) 269 }) 270 271 Context("when patching the isolation segment fails with an error", func() { 272 BeforeEach(func() { 273 response := `{ 274 "errors": [ 275 { 276 "detail": "Organization not found", 277 "title": "CF-ResourceNotFound", 278 "code": 10010 279 } 280 ] 281 }` 282 283 server.AppendHandlers( 284 CombineHandlers( 285 VerifyRequest(http.MethodPatch, "/v3/organizations/some-org-guid/relationships/default_isolation_segment"), 286 RespondWith(http.StatusNotFound, response, http.Header{"X-Cf-Warnings": {"this is a warning"}}), 287 ), 288 ) 289 }) 290 291 It("returns an error and warnings", func() { 292 warnings, err := client.PatchOrganizationDefaultIsolationSegment("some-org-guid", "some-isolation-segment-guid") 293 Expect(err).To(MatchError(ccerror.ResourceNotFoundError{ 294 Message: "Organization not found", 295 })) 296 Expect(warnings).To(ConsistOf("this is a warning")) 297 }) 298 }) 299 }) 300 })