github.com/willmadison/cli@v6.40.1-0.20181018160101-29d5937903ff+incompatible/cf/api/curl_test.go (about) 1 package api_test 2 3 import ( 4 "net/http" 5 "strings" 6 "time" 7 8 "code.cloudfoundry.org/cli/cf/api/apifakes" 9 "code.cloudfoundry.org/cli/cf/configuration/coreconfig" 10 "code.cloudfoundry.org/cli/cf/net" 11 "code.cloudfoundry.org/cli/cf/terminal/terminalfakes" 12 testconfig "code.cloudfoundry.org/cli/cf/util/testhelpers/configuration" 13 testnet "code.cloudfoundry.org/cli/cf/util/testhelpers/net" 14 15 . "code.cloudfoundry.org/cli/cf/api" 16 "code.cloudfoundry.org/cli/cf/trace/tracefakes" 17 . "code.cloudfoundry.org/cli/cf/util/testhelpers/matchers" 18 . "github.com/onsi/ginkgo" 19 . "github.com/onsi/gomega" 20 "github.com/onsi/gomega/ghttp" 21 ) 22 23 var _ = Describe("CloudControllerCurlRepository ", func() { 24 var ( 25 headers string 26 body string 27 apiErr error 28 ) 29 30 Describe("GET requests", func() { 31 BeforeEach(func() { 32 req := apifakes.NewCloudControllerTestRequest(testnet.TestRequest{ 33 Method: "GET", 34 Path: "/v2/endpoint", 35 Response: testnet.TestResponse{ 36 Status: http.StatusOK, 37 Body: expectedJSONResponse}, 38 }) 39 ts, handler := testnet.NewServer([]testnet.TestRequest{req}) 40 defer ts.Close() 41 42 deps := newCurlDependencies() 43 deps.config.SetAPIEndpoint(ts.URL) 44 45 repo := NewCloudControllerCurlRepository(deps.config, deps.gateway) 46 headers, body, apiErr = repo.Request("GET", "/v2/endpoint", "", "") 47 48 Expect(handler).To(HaveAllRequestsCalled()) 49 Expect(apiErr).NotTo(HaveOccurred()) 50 }) 51 52 It("returns headers with the status code", func() { 53 Expect(headers).To(ContainSubstring("200")) 54 }) 55 56 It("returns the header content type", func() { 57 Expect(headers).To(ContainSubstring("Content-Type")) 58 Expect(headers).To(ContainSubstring("text/plain")) 59 }) 60 61 It("returns the body as a JSON-encoded string", func() { 62 Expect(removeWhitespace(body)).To(Equal(removeWhitespace(expectedJSONResponse))) 63 }) 64 }) 65 66 Describe("POST requests", func() { 67 BeforeEach(func() { 68 req := apifakes.NewCloudControllerTestRequest(testnet.TestRequest{ 69 Method: "POST", 70 Path: "/v2/endpoint", 71 Matcher: testnet.RequestBodyMatcher(`{"key":"val"}`), 72 Response: testnet.TestResponse{ 73 Status: http.StatusOK, 74 Body: expectedJSONResponse}, 75 }) 76 77 ts, handler := testnet.NewServer([]testnet.TestRequest{req}) 78 defer ts.Close() 79 80 deps := newCurlDependencies() 81 deps.config.SetAPIEndpoint(ts.URL) 82 83 repo := NewCloudControllerCurlRepository(deps.config, deps.gateway) 84 headers, body, apiErr = repo.Request("POST", "/v2/endpoint", "", `{"key":"val"}`) 85 Expect(handler).To(HaveAllRequestsCalled()) 86 }) 87 88 It("does not return an error", func() { 89 Expect(apiErr).NotTo(HaveOccurred()) 90 }) 91 92 Context("when the server returns a 400 Bad Request header", func() { 93 BeforeEach(func() { 94 req := apifakes.NewCloudControllerTestRequest(testnet.TestRequest{ 95 Method: "POST", 96 Path: "/v2/endpoint", 97 Matcher: testnet.RequestBodyMatcher(`{"key":"val"}`), 98 Response: testnet.TestResponse{ 99 Status: http.StatusBadRequest, 100 Body: expectedJSONResponse}, 101 }) 102 103 ts, handler := testnet.NewServer([]testnet.TestRequest{req}) 104 defer ts.Close() 105 106 deps := newCurlDependencies() 107 deps.config.SetAPIEndpoint(ts.URL) 108 109 repo := NewCloudControllerCurlRepository(deps.config, deps.gateway) 110 _, body, apiErr = repo.Request("POST", "/v2/endpoint", "", `{"key":"val"}`) 111 Expect(handler).To(HaveAllRequestsCalled()) 112 }) 113 114 It("returns the response body", func() { 115 Expect(removeWhitespace(body)).To(Equal(removeWhitespace(expectedJSONResponse))) 116 }) 117 118 It("does not return an error", func() { 119 Expect(apiErr).NotTo(HaveOccurred()) 120 }) 121 }) 122 123 Context("when provided with invalid headers", func() { 124 It("returns an error", func() { 125 deps := newCurlDependencies() 126 repo := NewCloudControllerCurlRepository(deps.config, deps.gateway) 127 _, _, apiErr := repo.Request("POST", "/v2/endpoint", "not-valid", "") 128 Expect(apiErr).To(HaveOccurred()) 129 Expect(apiErr.Error()).To(ContainSubstring("headers")) 130 }) 131 }) 132 133 Context("when provided with valid headers", func() { 134 It("sends them along with the POST body", func() { 135 req := apifakes.NewCloudControllerTestRequest(testnet.TestRequest{ 136 Method: "POST", 137 Path: "/v2/endpoint", 138 Matcher: func(req *http.Request) { 139 Expect(req.Header.Get("content-type")).To(Equal("ascii/cats")) 140 Expect(req.Header.Get("x-something-else")).To(Equal("5")) 141 }, 142 Response: testnet.TestResponse{ 143 Status: http.StatusOK, 144 Body: expectedJSONResponse}, 145 }) 146 ts, handler := testnet.NewServer([]testnet.TestRequest{req}) 147 defer ts.Close() 148 149 deps := newCurlDependencies() 150 deps.config.SetAPIEndpoint(ts.URL) 151 152 headers := "content-type: ascii/cats\nx-something-else:5" 153 repo := NewCloudControllerCurlRepository(deps.config, deps.gateway) 154 _, _, apiErr := repo.Request("POST", "/v2/endpoint", headers, "") 155 Expect(handler).To(HaveAllRequestsCalled()) 156 Expect(apiErr).NotTo(HaveOccurred()) 157 }) 158 }) 159 }) 160 161 It("uses POST as the default method when a body is provided", func() { 162 ccServer := ghttp.NewServer() 163 ccServer.AppendHandlers( 164 ghttp.VerifyRequest("POST", "/v2/endpoint"), 165 ) 166 167 deps := newCurlDependencies() 168 deps.config.SetAPIEndpoint(ccServer.URL()) 169 170 repo := NewCloudControllerCurlRepository(deps.config, deps.gateway) 171 _, _, err := repo.Request("", "/v2/endpoint", "", "body") 172 Expect(err).NotTo(HaveOccurred()) 173 174 Expect(ccServer.ReceivedRequests()).To(HaveLen(1)) 175 }) 176 177 It("uses GET as the default method when a body is not provided", func() { 178 ccServer := ghttp.NewServer() 179 ccServer.AppendHandlers( 180 ghttp.VerifyRequest("GET", "/v2/endpoint"), 181 ) 182 183 deps := newCurlDependencies() 184 deps.config.SetAPIEndpoint(ccServer.URL()) 185 186 repo := NewCloudControllerCurlRepository(deps.config, deps.gateway) 187 _, _, err := repo.Request("", "/v2/endpoint", "", "") 188 Expect(err).NotTo(HaveOccurred()) 189 190 Expect(ccServer.ReceivedRequests()).To(HaveLen(1)) 191 }) 192 }) 193 194 const expectedJSONResponse = ` 195 {"resources": [ 196 { 197 "metadata": { "guid": "my-quota-guid" }, 198 "entity": { "name": "my-remote-quota", "memory_limit": 1024 } 199 } 200 ]} 201 ` 202 203 type curlDependencies struct { 204 config coreconfig.ReadWriter 205 gateway net.Gateway 206 } 207 208 func newCurlDependencies() (deps curlDependencies) { 209 deps.config = testconfig.NewRepository() 210 deps.config.SetAccessToken("BEARER my_access_token") 211 deps.gateway = net.NewCloudControllerGateway(deps.config, time.Now, new(terminalfakes.FakeUI), new(tracefakes.FakePrinter), "") 212 return 213 } 214 215 func removeWhitespace(body string) string { 216 body = strings.Replace(body, " ", "", -1) 217 body = strings.Replace(body, "\n", "", -1) 218 body = strings.Replace(body, "\r", "", -1) 219 body = strings.Replace(body, "\t", "", -1) 220 return body 221 }