github.com/wanddynosios/cli/v8@v8.7.9-0.20240221182337-1a92e3a7017f/api/cloudcontroller/ccv3/application_feature_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("Application", func() { 16 var client *Client 17 18 BeforeEach(func() { 19 client, _ = NewTestClient() 20 }) 21 22 Describe("UpdateAppFeature", func() { 23 var ( 24 warnings Warnings 25 executeErr error 26 appGUID = "some-app-guid" 27 enabled = false 28 ) 29 Context("Updating SSH", func() { 30 JustBeforeEach(func() { 31 warnings, executeErr = client.UpdateAppFeature(appGUID, enabled, "ssh") 32 }) 33 34 When("the app exists", func() { 35 BeforeEach(func() { 36 response1 := fmt.Sprintf(`{ 37 "name": "ssh", 38 "description": "Enable SSHing into the app.", 39 "enabled": false 40 }`) 41 42 server.AppendHandlers( 43 CombineHandlers( 44 VerifyRequest(http.MethodPatch, fmt.Sprintf("/v3/apps/%s/features/ssh", appGUID)), 45 VerifyBody([]byte(fmt.Sprintf(`{"enabled":%t}`, enabled))), 46 RespondWith(http.StatusOK, response1, http.Header{"X-Cf-Warnings": {"this is a warning"}}), 47 ), 48 ) 49 }) 50 51 It("returns all warnings", func() { 52 Expect(executeErr).NotTo(HaveOccurred()) 53 54 Expect(warnings).To(ConsistOf("this is a warning")) 55 }) 56 }) 57 58 When("the cloud controller returns errors and warnings", func() { 59 BeforeEach(func() { 60 updateResponse := `{ 61 "errors": [ 62 { 63 "code": 10008, 64 "detail": "The request is semantically invalid: command presence", 65 "title": "CF-UnprocessableEntity" 66 }, 67 { 68 "code": 10010, 69 "detail": "Org not found", 70 "title": "CF-ResourceNotFound" 71 } 72 ] 73 }` 74 server.AppendHandlers( 75 CombineHandlers( 76 VerifyRequest(http.MethodPatch, fmt.Sprintf("/v3/apps/%s/features/ssh", appGUID)), 77 RespondWith(http.StatusTeapot, updateResponse, http.Header{"X-Cf-Warnings": {"this is a warning"}}), 78 ), 79 ) 80 }) 81 82 It("returns the error and all warnings", func() { 83 Expect(executeErr).To(MatchError(ccerror.MultiError{ 84 ResponseCode: http.StatusTeapot, 85 Errors: []ccerror.V3Error{ 86 { 87 Code: 10008, 88 Detail: "The request is semantically invalid: command presence", 89 Title: "CF-UnprocessableEntity", 90 }, 91 { 92 Code: 10010, 93 Detail: "Org not found", 94 Title: "CF-ResourceNotFound", 95 }, 96 }, 97 })) 98 Expect(warnings).To(ConsistOf("this is a warning")) 99 }) 100 }) 101 }) 102 }) 103 104 Describe("GetAppFeature", func() { 105 var ( 106 warnings Warnings 107 executeErr error 108 appGUID = "some-app-guid" 109 applicationFeature resources.ApplicationFeature 110 ) 111 112 Context("Getting SSH", func() { 113 JustBeforeEach(func() { 114 applicationFeature, warnings, executeErr = client.GetAppFeature(appGUID, "ssh") 115 }) 116 117 When("the app exists", func() { 118 BeforeEach(func() { 119 getResponse := fmt.Sprintf(`{ 120 "name": "ssh", 121 "description": "Enable SSHing into the app.", 122 "enabled": false 123 }`) 124 125 server.AppendHandlers( 126 CombineHandlers( 127 VerifyRequest(http.MethodGet, fmt.Sprintf("/v3/apps/%s/features/ssh", appGUID)), 128 RespondWith(http.StatusOK, getResponse, http.Header{"X-Cf-Warnings": {"this is a warning"}}), 129 ), 130 ) 131 }) 132 133 It("returns an app feature and all warnings", func() { 134 Expect(executeErr).NotTo(HaveOccurred()) 135 136 Expect(warnings).To(ConsistOf("this is a warning")) 137 Expect(applicationFeature.Name).To(Equal("ssh")) 138 Expect(applicationFeature.Enabled).To(Equal(false)) 139 }) 140 }) 141 142 When("the cloud controller returns errors and warnings", func() { 143 BeforeEach(func() { 144 response := `{ 145 "errors": [ 146 { 147 "code": 10008, 148 "detail": "The request is semantically invalid: command presence", 149 "title": "CF-UnprocessableEntity" 150 }, 151 { 152 "code": 10010, 153 "detail": "Org not found", 154 "title": "CF-ResourceNotFound" 155 } 156 ] 157 }` 158 server.AppendHandlers( 159 CombineHandlers( 160 VerifyRequest(http.MethodGet, fmt.Sprintf("/v3/apps/%s/features/ssh", appGUID)), 161 RespondWith(http.StatusTeapot, response, http.Header{"X-Cf-Warnings": {"this is a warning"}}), 162 ), 163 ) 164 }) 165 166 It("returns the error and all warnings", func() { 167 Expect(executeErr).To(MatchError(ccerror.MultiError{ 168 ResponseCode: http.StatusTeapot, 169 Errors: []ccerror.V3Error{ 170 { 171 Code: 10008, 172 Detail: "The request is semantically invalid: command presence", 173 Title: "CF-UnprocessableEntity", 174 }, 175 { 176 Code: 10010, 177 Detail: "Org not found", 178 Title: "CF-ResourceNotFound", 179 }, 180 }, 181 })) 182 Expect(warnings).To(ConsistOf("this is a warning")) 183 }) 184 }) 185 }) 186 }) 187 188 Describe("GetSSHEnabled", func() { 189 190 var ( 191 warnings Warnings 192 executeErr error 193 appGUID = "some-app-guid" 194 sshEnabled SSHEnabled 195 ) 196 197 JustBeforeEach(func() { 198 sshEnabled, warnings, executeErr = client.GetSSHEnabled(appGUID) 199 }) 200 201 When("no error occurs", func() { 202 203 BeforeEach(func() { 204 getResponse := fmt.Sprintf(`{ 205 "enabled": false, 206 "reason": "Disabled for space some-space" 207 }`) 208 209 server.AppendHandlers( 210 CombineHandlers( 211 VerifyRequest(http.MethodGet, fmt.Sprintf("/v3/apps/%s/ssh_enabled", appGUID)), 212 RespondWith(http.StatusOK, getResponse, http.Header{"X-Cf-Warnings": {"this is a warning"}}), 213 ), 214 ) 215 }) 216 217 It("returns the SSHEnabled boolean", func() { 218 219 Expect(executeErr).NotTo(HaveOccurred()) 220 221 Expect(warnings).To(ConsistOf("this is a warning")) 222 Expect(sshEnabled.Enabled).To(Equal(false)) 223 Expect(sshEnabled.Reason).To(Equal("Disabled for space some-space")) 224 }) 225 }) 226 227 When("the cloud controller returns errors and warnings", func() { 228 BeforeEach(func() { 229 response := `{ 230 "errors": [ 231 { 232 "code": 10008, 233 "detail": "The request is semantically invalid: command presence", 234 "title": "CF-UnprocessableEntity" 235 }, 236 { 237 "code": 10010, 238 "detail": "Org not found", 239 "title": "CF-ResourceNotFound" 240 } 241 ] 242 }` 243 server.AppendHandlers( 244 CombineHandlers( 245 VerifyRequest(http.MethodGet, fmt.Sprintf("/v3/apps/%s/ssh_enabled", appGUID)), 246 RespondWith(http.StatusTeapot, response, http.Header{"X-Cf-Warnings": {"this is a warning"}}), 247 ), 248 ) 249 }) 250 251 It("returns the error and all warnings", func() { 252 Expect(executeErr).To(MatchError(ccerror.MultiError{ 253 ResponseCode: http.StatusTeapot, 254 Errors: []ccerror.V3Error{ 255 { 256 Code: 10008, 257 Detail: "The request is semantically invalid: command presence", 258 Title: "CF-UnprocessableEntity", 259 }, 260 { 261 Code: 10010, 262 Detail: "Org not found", 263 Title: "CF-ResourceNotFound", 264 }, 265 }, 266 })) 267 Expect(warnings).To(ConsistOf("this is a warning")) 268 }) 269 }) 270 }) 271 })