github.com/mook-as/cf-cli@v7.0.0-beta.28.0.20200120190804-b91c115fae48+incompatible/api/cloudcontroller/ccv3/metadata_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 9 . "code.cloudfoundry.org/cli/api/cloudcontroller/ccv3" 10 "code.cloudfoundry.org/cli/types" 11 . "github.com/onsi/ginkgo" 12 . "github.com/onsi/gomega" 13 . "github.com/onsi/gomega/ghttp" 14 ) 15 16 const errorResponse = `{ 17 "errors": [ 18 { 19 "code": 10008, 20 "detail": "Metadata label key error: 'invalid*key' contains invalid characters", 21 "title": "CF-UnprocessableEntity" 22 } 23 ] 24 }` 25 26 var _ = Describe("Metadata", func() { 27 var client *Client 28 29 BeforeEach(func() { 30 client, _ = NewTestClient() 31 }) 32 33 Describe("UpdateResourceMetadata", func() { 34 var ( 35 metadataToUpdate Metadata 36 resourceGUID string 37 updatedMetadata ResourceMetadata 38 warnings Warnings 39 executeErr error 40 ) 41 testForResourceType := func(resourceType string, resourceTypeNameForURI string) { 42 if resourceTypeNameForURI == "" { 43 resourceTypeNameForURI = resourceType 44 } 45 46 When(fmt.Sprintf("updating metadata on %s", resourceType), func() { 47 48 JustBeforeEach(func() { 49 resourceGUID = "some-guid" 50 updatedMetadata, warnings, executeErr = client.UpdateResourceMetadata(resourceType, resourceGUID, metadataToUpdate) 51 }) 52 53 When(fmt.Sprintf("the %s is updated successfully", resourceType), func() { 54 BeforeEach(func() { 55 response := fmt.Sprintf(`{ 56 "guid": "some-guid", 57 "name": "some-%s-type", 58 "metadata": { 59 "labels": { 60 "k1":"v1", 61 "k2":"v2" 62 } 63 } 64 }`, resourceType) 65 66 expectedBody := map[string]interface{}{ 67 "metadata": map[string]interface{}{ 68 "labels": map[string]string{ 69 "k1": "v1", 70 "k2": "v2", 71 }, 72 }, 73 } 74 75 server.AppendHandlers( 76 CombineHandlers( 77 VerifyRequest(http.MethodPatch, fmt.Sprintf("/v3/%ss/some-guid", resourceTypeNameForURI)), 78 VerifyJSONRepresenting(expectedBody), 79 RespondWith(http.StatusOK, response, http.Header{"X-Cf-Warnings": {"this is a warning"}}), 80 ), 81 ) 82 83 metadataToUpdate = Metadata{ 84 Labels: map[string]types.NullString{ 85 "k1": types.NewNullString("v1"), 86 "k2": types.NewNullString("v2"), 87 }, 88 } 89 }) 90 91 It("should include the labels in the JSON", func() { 92 Expect(executeErr).ToNot(HaveOccurred()) 93 Expect(warnings).To(ConsistOf(Warnings{"this is a warning"})) 94 Expect(server.ReceivedRequests()).To(HaveLen(3)) 95 Expect(updatedMetadata.Metadata.Labels).To(BeEquivalentTo( 96 map[string]types.NullString{ 97 "k1": types.NewNullString("v1"), 98 "k2": types.NewNullString("v2"), 99 })) 100 }) 101 }) 102 103 When("Cloud Controller returns errors and warnings", func() { 104 BeforeEach(func() { 105 expectedBody := map[string]interface{}{ 106 "metadata": map[string]interface{}{ 107 "labels": map[string]string{ 108 "invalid*key": "v1", 109 "k2": "v2", 110 }, 111 }, 112 } 113 114 server.AppendHandlers( 115 CombineHandlers( 116 VerifyRequest(http.MethodPatch, fmt.Sprintf("/v3/%ss/some-guid", resourceTypeNameForURI)), 117 VerifyJSONRepresenting(expectedBody), 118 RespondWith(http.StatusUnprocessableEntity, errorResponse, http.Header{"X-Cf-Warnings": {"this is another warning"}}), 119 ), 120 ) 121 122 metadataToUpdate = Metadata{ 123 Labels: map[string]types.NullString{ 124 "invalid*key": types.NewNullString("v1"), 125 "k2": types.NewNullString("v2"), 126 }, 127 } 128 }) 129 130 It("returns the error and all warnings", func() { 131 Expect(executeErr).To(MatchError(ccerror.UnprocessableEntityError{ 132 Message: "Metadata label key error: 'invalid*key' contains invalid characters", 133 })) 134 Expect(warnings).To(ConsistOf(Warnings{"this is another warning"})) 135 }) 136 }) 137 }) 138 } 139 140 testForResourceType("app", "") 141 testForResourceType("domain", "") 142 testForResourceType("buildpack", "") 143 testForResourceType("org", "organization") 144 testForResourceType("route", "") 145 testForResourceType("space", "") 146 testForResourceType("stack", "") 147 148 When("updating metadata on an unsupported resource", func() { 149 It("returns an error", func() { 150 _, _, err := client.UpdateResourceMetadata("anything", "fake-guid", Metadata{}) 151 Expect(err).To(MatchError("unknown resource type (anything) requested")) 152 }) 153 }) 154 }) 155 156 Describe("UpdateResourceMetadataAsync", func() { 157 When("updating metadata on service-broker", func() { 158 When("the service-broker is updated successfully", func() { 159 It("sends the correct data and returns the job URL", func() { 160 server.AppendHandlers( 161 CombineHandlers( 162 VerifyRequest(http.MethodPatch, "/v3/service_brokers/some-guid"), 163 VerifyJSON(`{"metadata":{"labels":{"k1":"v1","k2":"v2"}}}`), 164 RespondWith(http.StatusAccepted, "", http.Header{"X-Cf-Warnings": {"this is a warning"}, "Location": {"fake-job-url"}}), 165 ), 166 ) 167 168 metadataToUpdate := Metadata{ 169 Labels: map[string]types.NullString{ 170 "k1": types.NewNullString("v1"), 171 "k2": types.NewNullString("v2"), 172 }, 173 } 174 175 jobURL, warnings, err := client.UpdateResourceMetadataAsync("service-broker", "some-guid", metadataToUpdate) 176 Expect(err).NotTo(HaveOccurred()) 177 178 Expect(jobURL).To(BeEquivalentTo("fake-job-url")) 179 Expect(warnings).To(ConsistOf(Warnings{"this is a warning"})) 180 }) 181 }) 182 183 When("Cloud Controller returns errors and warnings", func() { 184 It("returns the error and all warnings", func() { 185 server.AppendHandlers( 186 CombineHandlers( 187 VerifyRequest(http.MethodPatch, "/v3/service_brokers/some-guid"), 188 RespondWith(http.StatusUnprocessableEntity, errorResponse, http.Header{"X-Cf-Warnings": {"this is another warning"}}), 189 ), 190 ) 191 192 _, warnings, err := client.UpdateResourceMetadataAsync("service-broker", "some-guid", Metadata{}) 193 194 Expect(err).To(MatchError(ccerror.UnprocessableEntityError{ 195 Message: "Metadata label key error: 'invalid*key' contains invalid characters", 196 })) 197 Expect(warnings).To(ConsistOf(Warnings{"this is another warning"})) 198 }) 199 }) 200 }) 201 202 When("updating metadata on an unsupported resource", func() { 203 It("returns an error", func() { 204 _, _, err := client.UpdateResourceMetadataAsync("anything", "fake-guid", Metadata{}) 205 Expect(err).To(MatchError("unknown async resource type (anything) requested")) 206 }) 207 }) 208 }) 209 })