func (m *MockRender) Header() http.Header { r := httptest.ResponseRecorder{} m.Called() return r.Header() }
func recorderToResponse(recorder *httptest.ResponseRecorder) *http.Response { return &http.Response{ StatusCode: recorder.Code, Body: jsh.CreateReadCloser(recorder.Body.Bytes()), Header: recorder.Header(), } }
// checkIndex is like assertIndex but returns an error func checkIndex(resp *httptest.ResponseRecorder) error { header := resp.Header().Get("X-Consul-Index") if header == "" || header == "0" { return fmt.Errorf("Bad: %v", header) } return nil }
func testContentType(t *testing.T, r *http.Request, rec *httptest.ResponseRecorder, expected string) { ct := rec.Header().Get("content-type") if !strings.EqualFold(ct, expected) { t.Errorf("Unexpected content-type for %q: %s, expected: %s", r.URL.String(), ct, expected) } }
func TestHandleFunc(t *testing.T) { wfe := setupWFE(t) var mux *http.ServeMux var rw *httptest.ResponseRecorder var stubCalled bool runWrappedHandler := func(req *http.Request, allowed ...string) { mux = http.NewServeMux() rw = httptest.NewRecorder() stubCalled = false wfe.HandleFunc(mux, "/test", func(http.ResponseWriter, *http.Request) { stubCalled = true }, allowed...) req.URL = mustParseURL("/test") mux.ServeHTTP(rw, req) } // Plain requests (no CORS) type testCase struct { allowed []string reqMethod string shouldSucceed bool } var lastNonce string for _, c := range []testCase{ {[]string{"GET", "POST"}, "GET", true}, {[]string{"GET", "POST"}, "POST", true}, {[]string{"GET"}, "", false}, {[]string{"GET"}, "POST", false}, {[]string{"GET"}, "OPTIONS", false}, // TODO, #469 {[]string{"GET"}, "MAKE-COFFEE", false}, // 405, or 418? } { runWrappedHandler(&http.Request{Method: c.reqMethod}, c.allowed...) test.AssertEquals(t, stubCalled, c.shouldSucceed) if c.shouldSucceed { test.AssertEquals(t, rw.Code, http.StatusOK) } else { test.AssertEquals(t, rw.Code, http.StatusMethodNotAllowed) test.AssertEquals(t, sortHeader(rw.Header().Get("Allow")), strings.Join(c.allowed, ", ")) test.AssertEquals(t, rw.Body.String(), `{"type":"urn:acme:error:malformed","detail":"Method not allowed"}`) } nonce := rw.Header().Get("Replay-Nonce") test.AssertNotEquals(t, nonce, lastNonce) lastNonce = nonce } // Disallowed method returns error JSON in body runWrappedHandler(&http.Request{Method: "PUT"}, "GET", "POST") test.AssertEquals(t, rw.Header().Get("Content-Type"), "application/problem+json") test.AssertEquals(t, rw.Body.String(), `{"type":"urn:acme:error:malformed","detail":"Method not allowed"}`) test.AssertEquals(t, sortHeader(rw.Header().Get("Allow")), "GET, POST") // Disallowed method special case: response to HEAD has got no body runWrappedHandler(&http.Request{Method: "HEAD"}, "GET", "POST") test.AssertEquals(t, stubCalled, false) test.AssertEquals(t, rw.Body.String(), "") test.AssertEquals(t, sortHeader(rw.Header().Get("Allow")), "GET, POST") }
func ReadHeadersFromResponse(writer *httptest.ResponseRecorder) map[string]string { headers := map[string]string{} for k, v := range writer.Header() { log.Println(k, v) headers[k] = strings.Join(v, " ") } return headers }
func (s *Stack) Write(response *Response, rec *httptest.ResponseRecorder) { for key, values := range rec.Header() { for _, value := range values { response.header.Add(key, value) } } response.buffer.Write(rec.Body.Bytes()) response.code = rec.Code }
// respFromRecorder builds an http response from a httptest recorder func respFromRecorder(w *httptest.ResponseRecorder) *http.Response { resp := http.Response{} resp.StatusCode = w.Code resp.Header = w.Header() // TODO: fill in the rest of response b := w.Body.Bytes() resp.Body = ioutil.NopCloser(bytes.NewReader(b)) return &resp }
func assertResponseWithStatusAndMessage(t *testing.T, res *httptest.ResponseRecorder, code int, status, message string) { var apiMessage responses.APIMessage json.NewDecoder(res.Body).Decode(&apiMessage) assert.Equal(t, code, res.Code) assert.Equal(t, "application/json; charset=UTF-8", res.Header().Get("Content-Type")) assert.Equal(t, status, apiMessage.Status) assert.Equal(t, message, apiMessage.Message) }
// Test that the headers and body match. func assertHttpMatchRecorder(t *testing.T, recorder *httptest.ResponseRecorder, expectedStatus int, expectedHeaders http.Header, expectedBody string) { assert.Equal(t, expectedStatus, recorder.Code) // Verify that headers match. Order shouldn't matter. assert.Equal(t, recorder.Header(), expectedHeaders) // Convert the body to a string. assert.Equal(t, expectedBody, recorder.Body.String()) }
func assertJSONResponse(t *testing.T, expectedCode int, expectedResponse string, w *httptest.ResponseRecorder) { assert.Equal(t, expectedCode, w.Code) assert.Equal(t, "application/json", w.Header().Get("content-type")) var expected, actual interface{} require.NoError(t, json.Unmarshal([]byte(expectedResponse), &expected)) require.NoError(t, json.Unmarshal(w.Body.Bytes(), &actual)) assert.Equal(t, expected, actual) }
// getIndex parses X-Consul-Index func getIndex(t *testing.T, resp *httptest.ResponseRecorder) uint64 { header := resp.Header().Get("X-Consul-Index") if header == "" { t.Fatalf("Bad: %v", header) } val, err := strconv.Atoi(header) if err != nil { t.Fatalf("Bad: %v", header) } return uint64(val) }
// copyResponse copies all relevant info from rec to rw. func copyResponse(rw http.ResponseWriter, rec *httptest.ResponseRecorder) { // copy the headers for k, v := range rec.Header() { rw.Header()[k] = v } // copy the code rw.WriteHeader(rec.Code) // copy the body rw.Write(rec.Body.Bytes()) }
func ReadHeadersFromResponse(writer *httptest.ResponseRecorder) (map[string]string, []models.YaagAnnotationHeader) { headers := map[string]string{} yaagAnnotations := []models.YaagAnnotationHeader{} for k, v := range writer.Header() { if strings.HasPrefix(k, "Yaag-Annotation") { yaagAnnotations = append(yaagAnnotations, annotations.New(k, strings.Join(v, " "))) } else { headers[k] = strings.Join(v, " ") } } return headers, yaagAnnotations }
func (m mockCacher) Put(key string, r *httptest.ResponseRecorder) *CachedResponse { specHeaders := make(map[string]string) for k, v := range r.Header() { specHeaders[k] = strings.Join(v, ", ") } m.data[key] = &CachedResponse{ StatusCode: r.Code, Body: r.Body.Bytes(), Headers: specHeaders, } return m.data[key] }
func compressedRequest(w *httptest.ResponseRecorder, compression string) { CompressHandler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Length", strconv.Itoa(9*1024)) for i := 0; i < 1024; i++ { io.WriteString(w, "Gorilla!\n") } })).ServeHTTP(w, &http.Request{ Method: "GET", Header: http.Header{ "Accept-Encoding": []string{compression}, }, }) }
func checkResponseRecorder(t *testing.T, rr *httptest.ResponseRecorder, code int, header map[string][]string, body string) { if !rr.Flushed { t.Fatal("ResponseRecorder not flushed") } if a, e := rr.Code, code; a != e { t.Error(a, "!=", e) } if a, e := map[string][]string(rr.Header()), header; !reflect.DeepEqual(a, e) { t.Error(a, "!=", e) } if a, e := rr.Body.Bytes(), []byte(body); !bytes.Equal(a, e) { t.Error(a, "!=", e) } }
func checkHeaders(t *testing.T, res *httptest.ResponseRecorder, requiredHeaders map[string]string) { for headerKey, expectedHeaderValue := range requiredHeaders { actualHeaderValue := res.Header().Get(headerKey) if actualHeaderValue != expectedHeaderValue { // N.B. the http library does not distinguish between header // entries that have an empty "" value, and non-existing entries if expectedHeaderValue != "" { t.Errorf("Expected header %q to be %q but it was %q", headerKey, expectedHeaderValue, actualHeaderValue) t.Logf("Full headers: %q", res.Header()) } else { t.Errorf("Expected header %q to not be present, or to be an empty string (\"\"), but it was %q", headerKey, actualHeaderValue) } } } }
// AssertJSONResponse asserts that the given response recorder has // recorded the given HTTP status, response body and content type. If // expectBody is of type BodyAsserter it will be called with the response // body to ensure the response is correct. func AssertJSONResponse(c *gc.C, rec *httptest.ResponseRecorder, expectStatus int, expectBody interface{}) { c.Assert(rec.Code, gc.Equals, expectStatus, gc.Commentf("body: %s", rec.Body.Bytes())) // Ensure the response includes the expected body. if expectBody == nil { c.Assert(rec.Body.Bytes(), gc.HasLen, 0) return } c.Assert(rec.Header().Get("Content-Type"), gc.Equals, "application/json") if assertBody, ok := expectBody.(BodyAsserter); ok { var data json.RawMessage err := json.Unmarshal(rec.Body.Bytes(), &data) c.Assert(err, jc.ErrorIsNil, gc.Commentf("body: %s", rec.Body.Bytes())) assertBody(c, data) return } c.Assert(rec.Body.String(), jc.JSONEquals, expectBody) }
func checkStatusCode(t *testing.T, res *httptest.ResponseRecorder, statusCode int) { respBody, err := ioutil.ReadAll(res.Body) if err != nil { t.Fatalf("Could not read response body: %v", err) } // make sure we get at least a few bytes of a response body... // even http 303 should have some body, see // https://tools.ietf.org/html/rfc7231#section-6.4.4 if len(respBody) < 20 { t.Error("Expected a response body (at least 20 bytes), but get less (or none).") t.Logf("Headers: %s", res.Header()) t.Logf("Response received:\n%s", string(respBody)) } if res.Code != statusCode { t.Errorf("Expected status code %v but got %v", statusCode, res.Code) t.Logf("Headers: %s", res.Header()) t.Logf("Response received:\n%s", string(respBody)) } }
func NewResponse(resp *httptest.ResponseRecorder) *Response { content := resp.Body.Bytes() contentType := resp.Header().Get("Content-Type") contentEncoding := resp.Header().Get("Content-Encoding") return &Response{ StatusCode: resp.Code, Header: NewHeader(resp.Header()), Body: NewBody(content, contentType, contentEncoding), } }
// Put stores a CachedResponse for a given key and response func (c DiskCacher) Put(key string, resp *httptest.ResponseRecorder) *CachedResponse { c.mutex.Lock() defer c.mutex.Unlock() skipDisk := resp.Header().Get("_chameleon-seeded-skip-disk") != "" if skipDisk { resp.Header().Del("_chameleon-seeded-skip-disk") } skipDisk = skipDisk || c.memory specHeaders := make(map[string]string) for k, v := range resp.Header() { specHeaders[k] = strings.Join(v, ", ") } if !skipDisk { specs := c.loadSpecs() newSpec := Spec{ Key: key, SpecResponse: SpecResponse{ StatusCode: resp.Code, ContentFile: key, Headers: specHeaders, }, } specs = append(specs, newSpec) contentFilePath := path.Join(c.dataDir, key) err := c.FileSystem.WriteFile(contentFilePath, resp.Body.Bytes()) if err != nil { panic(err) } specBytes, err := json.MarshalIndent(specs, "", " ") err = c.FileSystem.WriteFile(c.specPath, specBytes) if err != nil { panic(err) } } c.cache[key] = &CachedResponse{ StatusCode: resp.Code, Headers: specHeaders, Body: resp.Body.Bytes(), } return c.cache[key] }
It("404s", func() { req, err := http.NewRequest("GET", "/v1/posts/23", nil) Expect(err).To(BeNil()) api.Handler().ServeHTTP(rec, req) Expect(rec.Code).To(Equal(http.StatusNotFound)) errorJSON := []byte(`{"errors":[{"status":"404","title":"post not found"}]}`) Expect(rec.Body.Bytes()).To(MatchJSON(errorJSON)) }) It("POSTSs new objects", func() { reqBody := strings.NewReader(`{"data": [{"attributes":{"title": "New Post" }, "type": "posts"}]}`) req, err := http.NewRequest("POST", "/v1/posts", reqBody) Expect(err).To(BeNil()) api.Handler().ServeHTTP(rec, req) Expect(rec.Code).To(Equal(http.StatusCreated)) Expect(rec.Header().Get("Location")).To(Equal("/v1/posts/4")) var result map[string]interface{} Expect(json.Unmarshal(rec.Body.Bytes(), &result)).To(BeNil()) Expect(result).To(Equal(map[string]interface{}{ "data": map[string]interface{}{ "id": "4", "type": "posts", "attributes": map[string]interface{}{ "title": "New Post", "value": nil, }, "relationships": map[string]interface{}{ "author": map[string]interface{}{ "data": nil, "links": map[string]interface{}{ "self": "/v1/posts/4/relationships/author",
"name": "some-sender" }`)) Expect(sendersCollection.GetCall.Receives.SenderID).To(Equal("some-sender-id")) Expect(sendersCollection.GetCall.Receives.ClientID).To(Equal("some-client-id")) }) Context("failure cases", func() { It("returns a 301 when the sender id is missing", func() { var err error request, err = http.NewRequest("GET", "/senders/", nil) Expect(err).NotTo(HaveOccurred()) handler.ServeHTTP(writer, request, context) Expect(writer.Code).To(Equal(http.StatusMovedPermanently)) headers := writer.Header() Expect(headers.Get("Location")).To(Equal("/senders")) Expect(writer.Body.String()).To(BeEmpty()) }) It("returns a 401 when the client id is missing", func() { context.Set("client_id", "") handler.ServeHTTP(writer, request, context) Expect(writer.Code).To(Equal(http.StatusUnauthorized)) Expect(writer.Body.String()).To(MatchJSON(`{ "errors": [ "missing client id" ] }`)) })
Describe("WriteJSON", func() { var rw *httptest.ResponseRecorder BeforeEach(func() { rw = httptest.NewRecorder() }) Context("given an empty string", func() { It("responds correctly", func() { util.WriteJSON("", rw) got, err := ioutil.ReadAll(rw.Body) Expect(err).To(BeNil()) Expect(got).To(Equal([]byte("\"\""))) Expect(rw.Code).To(Equal(http.StatusOK)) Expect(rw.Header().Get("Content-Type")).To(Equal("application/json")) }) }) Context("given nil", func() { It("responds correctly", func() { util.WriteJSON(nil, rw) got, err := ioutil.ReadAll(rw.Body) Expect(err).To(BeNil()) Expect(got).To(Equal([]byte("null"))) Expect(rw.Code).To(Equal(http.StatusOK)) Expect(rw.Header().Get("Content-Type")).To(Equal("application/json")) }) }) Context("given an empty slice", func() { It("responds correctly", func() { util.WriteJSON(make([]int, 0), rw)
// assertIndex tests that X-Consul-Index is set and non-zero func assertIndex(t *testing.T, resp *httptest.ResponseRecorder) { header := resp.Header().Get("X-Consul-Index") if header == "" || header == "0" { t.Fatalf("Bad: %v", header) } }
//Check the specific header value func checkHeader(t *testing.T, response *httptest.ResponseRecorder, header string, value string) { if response.Header().Get(header) != value { t.Fatalf("Header: %s, get:%s expected:%s", header, response.Header().Get(header), value) } }
func TestFlashes(t *testing.T) { var req *http.Request var rsp *httptest.ResponseRecorder var hdr http.Header var err error var ok bool var cookies []string var session *Session var flashes []interface{} store := NewCookieStore([]byte("secret-key")) // Round 1 ---------------------------------------------------------------- req, _ = http.NewRequest("GET", "http://localhost:8080/", nil) rsp = NewRecorder() // Get a session. if session, err = store.Get(req, "session-key"); err != nil { t.Fatalf("Error getting session: %v", err) } // Get a flash. flashes = session.Flashes() if len(flashes) != 0 { t.Errorf("Expected empty flashes; Got %v", flashes) } // Add some flashes. session.AddFlash("foo") session.AddFlash("bar") // Custom key. session.AddFlash("baz", "custom_key") // Save. if err = Save(req, rsp); err != nil { t.Fatalf("Error saving session: %v", err) } hdr = rsp.Header() cookies, ok = hdr["Set-Cookie"] if !ok || len(cookies) != 1 { t.Fatal("No cookies. Header:", hdr) } if _, err = store.Get(req, "session:key"); err.Error() != "sessions: invalid character in cookie name: session:key" { t.Fatalf("Expected error due to invalid cookie name") } // Round 2 ---------------------------------------------------------------- req, _ = http.NewRequest("GET", "http://localhost:8080/", nil) req.Header.Add("Cookie", cookies[0]) rsp = NewRecorder() // Get a session. if session, err = store.Get(req, "session-key"); err != nil { t.Fatalf("Error getting session: %v", err) } // Check all saved values. flashes = session.Flashes() if len(flashes) != 2 { t.Fatalf("Expected flashes; Got %v", flashes) } if flashes[0] != "foo" || flashes[1] != "bar" { t.Errorf("Expected foo,bar; Got %v", flashes) } flashes = session.Flashes() if len(flashes) != 0 { t.Errorf("Expected dumped flashes; Got %v", flashes) } // Custom key. flashes = session.Flashes("custom_key") if len(flashes) != 1 { t.Errorf("Expected flashes; Got %v", flashes) } else if flashes[0] != "baz" { t.Errorf("Expected baz; Got %v", flashes) } flashes = session.Flashes("custom_key") if len(flashes) != 0 { t.Errorf("Expected dumped flashes; Got %v", flashes) } // Round 3 ---------------------------------------------------------------- // Custom type req, _ = http.NewRequest("GET", "http://localhost:8080/", nil) rsp = NewRecorder() // Get a session. if session, err = store.Get(req, "session-key"); err != nil { t.Fatalf("Error getting session: %v", err) } // Get a flash. flashes = session.Flashes() if len(flashes) != 0 { t.Errorf("Expected empty flashes; Got %v", flashes) } // Add some flashes. session.AddFlash(&FlashMessage{42, "foo"}) // Save. if err = Save(req, rsp); err != nil { t.Fatalf("Error saving session: %v", err) } hdr = rsp.Header() cookies, ok = hdr["Set-Cookie"] if !ok || len(cookies) != 1 { t.Fatal("No cookies. Header:", hdr) } // Round 4 ---------------------------------------------------------------- // Custom type req, _ = http.NewRequest("GET", "http://localhost:8080/", nil) req.Header.Add("Cookie", cookies[0]) rsp = NewRecorder() // Get a session. if session, err = store.Get(req, "session-key"); err != nil { t.Fatalf("Error getting session: %v", err) } // Check all saved values. flashes = session.Flashes() if len(flashes) != 1 { t.Fatalf("Expected flashes; Got %v", flashes) } custom := flashes[0].(FlashMessage) if custom.Type != 42 || custom.Message != "foo" { t.Errorf("Expected %#v, got %#v", FlashMessage{42, "foo"}, custom) } }
func setCookie(rr *httptest.ResponseRecorder, r *http.Request) { r.Header.Set("Cookie", rr.Header().Get("Set-Cookie")) }