aboutsummaryrefslogtreecommitdiffstats
path: root/vendor/github.com/onsi/gomega/ghttp/test_server_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/onsi/gomega/ghttp/test_server_test.go')
-rw-r--r--vendor/github.com/onsi/gomega/ghttp/test_server_test.go1089
1 files changed, 1089 insertions, 0 deletions
diff --git a/vendor/github.com/onsi/gomega/ghttp/test_server_test.go b/vendor/github.com/onsi/gomega/ghttp/test_server_test.go
new file mode 100644
index 0000000..88b3246
--- /dev/null
+++ b/vendor/github.com/onsi/gomega/ghttp/test_server_test.go
@@ -0,0 +1,1089 @@
+package ghttp_test
+
+import (
+ "bytes"
+ "io"
+ "io/ioutil"
+ "net/http"
+ "net/url"
+ "regexp"
+
+ "github.com/golang/protobuf/proto"
+ "github.com/onsi/gomega/gbytes"
+ "github.com/onsi/gomega/ghttp/protobuf"
+
+ . "github.com/onsi/ginkgo"
+ . "github.com/onsi/gomega"
+ . "github.com/onsi/gomega/ghttp"
+)
+
+var _ = Describe("TestServer", func() {
+ var (
+ resp *http.Response
+ err error
+ s *Server
+ )
+
+ BeforeEach(func() {
+ s = NewServer()
+ })
+
+ AfterEach(func() {
+ s.Close()
+ })
+
+ Describe("Resetting the server", func() {
+ BeforeEach(func() {
+ s.RouteToHandler("GET", "/", func(w http.ResponseWriter, req *http.Request) {})
+ s.AppendHandlers(func(w http.ResponseWriter, req *http.Request) {})
+ http.Get(s.URL() + "/")
+
+ Ω(s.ReceivedRequests()).Should(HaveLen(1))
+ })
+
+ It("clears all handlers and call counts", func() {
+ s.Reset()
+ Ω(s.ReceivedRequests()).Should(HaveLen(0))
+ Ω(func() { s.GetHandler(0) }).Should(Panic())
+ })
+ })
+
+ Describe("closing client connections", func() {
+ It("closes", func() {
+ s.RouteToHandler("GET", "/",
+ func(w http.ResponseWriter, req *http.Request) {
+ io.WriteString(w, req.RemoteAddr)
+ },
+ )
+ client := http.Client{Transport: &http.Transport{DisableKeepAlives: true}}
+ resp, err := client.Get(s.URL())
+ Ω(err).ShouldNot(HaveOccurred())
+ Ω(resp.StatusCode).Should(Equal(200))
+
+ body, err := ioutil.ReadAll(resp.Body)
+ resp.Body.Close()
+ Ω(err).ShouldNot(HaveOccurred())
+
+ s.CloseClientConnections()
+
+ resp, err = client.Get(s.URL())
+ Ω(err).ShouldNot(HaveOccurred())
+ Ω(resp.StatusCode).Should(Equal(200))
+
+ body2, err := ioutil.ReadAll(resp.Body)
+ resp.Body.Close()
+ Ω(err).ShouldNot(HaveOccurred())
+
+ Ω(body2).ShouldNot(Equal(body))
+ })
+ })
+
+ Describe("closing server mulitple times", func() {
+ It("should not fail", func() {
+ s.Close()
+ Ω(s.Close).ShouldNot(Panic())
+ })
+ })
+
+ Describe("allowing unhandled requests", func() {
+ Context("when true", func() {
+ BeforeEach(func() {
+ s.AllowUnhandledRequests = true
+ s.UnhandledRequestStatusCode = http.StatusForbidden
+ resp, err = http.Get(s.URL() + "/foo")
+ Ω(err).ShouldNot(HaveOccurred())
+ })
+
+ It("should allow unhandled requests and respond with the passed in status code", func() {
+ Ω(err).ShouldNot(HaveOccurred())
+ Ω(resp.StatusCode).Should(Equal(http.StatusForbidden))
+
+ data, err := ioutil.ReadAll(resp.Body)
+ Ω(err).ShouldNot(HaveOccurred())
+ Ω(data).Should(BeEmpty())
+ })
+
+ It("should record the requests", func() {
+ Ω(s.ReceivedRequests()).Should(HaveLen(1))
+ Ω(s.ReceivedRequests()[0].URL.Path).Should(Equal("/foo"))
+ })
+ })
+
+ Context("when false", func() {
+ It("should fail when attempting a request", func() {
+ failures := InterceptGomegaFailures(func() {
+ http.Get(s.URL() + "/foo")
+ })
+
+ Ω(failures[0]).Should(ContainSubstring("Received Unhandled Request"))
+ })
+ })
+ })
+
+ Describe("Managing Handlers", func() {
+ var called []string
+ BeforeEach(func() {
+ called = []string{}
+ s.RouteToHandler("GET", "/routed", func(w http.ResponseWriter, req *http.Request) {
+ called = append(called, "r1")
+ })
+ s.RouteToHandler("POST", regexp.MustCompile(`/routed\d`), func(w http.ResponseWriter, req *http.Request) {
+ called = append(called, "r2")
+ })
+ s.AppendHandlers(func(w http.ResponseWriter, req *http.Request) {
+ called = append(called, "A")
+ }, func(w http.ResponseWriter, req *http.Request) {
+ called = append(called, "B")
+ })
+ })
+
+ It("should prefer routed handlers if there is a match", func() {
+ http.Get(s.URL() + "/routed")
+ http.Post(s.URL()+"/routed7", "application/json", nil)
+ http.Get(s.URL() + "/foo")
+ http.Get(s.URL() + "/routed")
+ http.Post(s.URL()+"/routed9", "application/json", nil)
+ http.Get(s.URL() + "/bar")
+
+ failures := InterceptGomegaFailures(func() {
+ http.Get(s.URL() + "/foo")
+ http.Get(s.URL() + "/routed/not/a/match")
+ http.Get(s.URL() + "/routed7")
+ http.Post(s.URL()+"/routed", "application/json", nil)
+ })
+
+ Ω(failures[0]).Should(ContainSubstring("Received Unhandled Request"))
+ Ω(failures).Should(HaveLen(4))
+
+ http.Post(s.URL()+"/routed3", "application/json", nil)
+
+ Ω(called).Should(Equal([]string{"r1", "r2", "A", "r1", "r2", "B", "r2"}))
+ })
+
+ It("should override routed handlers when reregistered", func() {
+ s.RouteToHandler("GET", "/routed", func(w http.ResponseWriter, req *http.Request) {
+ called = append(called, "r3")
+ })
+ s.RouteToHandler("POST", regexp.MustCompile(`/routed\d`), func(w http.ResponseWriter, req *http.Request) {
+ called = append(called, "r4")
+ })
+
+ http.Get(s.URL() + "/routed")
+ http.Post(s.URL()+"/routed7", "application/json", nil)
+
+ Ω(called).Should(Equal([]string{"r3", "r4"}))
+ })
+
+ It("should call the appended handlers, in order, as requests come in", func() {
+ http.Get(s.URL() + "/foo")
+ Ω(called).Should(Equal([]string{"A"}))
+
+ http.Get(s.URL() + "/foo")
+ Ω(called).Should(Equal([]string{"A", "B"}))
+
+ failures := InterceptGomegaFailures(func() {
+ http.Get(s.URL() + "/foo")
+ })
+
+ Ω(failures[0]).Should(ContainSubstring("Received Unhandled Request"))
+ })
+
+ Describe("Overwriting an existing handler", func() {
+ BeforeEach(func() {
+ s.SetHandler(0, func(w http.ResponseWriter, req *http.Request) {
+ called = append(called, "C")
+ })
+ })
+
+ It("should override the specified handler", func() {
+ http.Get(s.URL() + "/foo")
+ http.Get(s.URL() + "/foo")
+ Ω(called).Should(Equal([]string{"C", "B"}))
+ })
+ })
+
+ Describe("Getting an existing handler", func() {
+ It("should return the handler func", func() {
+ s.GetHandler(1)(nil, nil)
+ Ω(called).Should(Equal([]string{"B"}))
+ })
+ })
+
+ Describe("Wrapping an existing handler", func() {
+ BeforeEach(func() {
+ s.WrapHandler(0, func(w http.ResponseWriter, req *http.Request) {
+ called = append(called, "C")
+ })
+ })
+
+ It("should wrap the existing handler in a new handler", func() {
+ http.Get(s.URL() + "/foo")
+ http.Get(s.URL() + "/foo")
+ Ω(called).Should(Equal([]string{"A", "C", "B"}))
+ })
+ })
+ })
+
+ Describe("When a handler fails", func() {
+ BeforeEach(func() {
+ s.UnhandledRequestStatusCode = http.StatusForbidden //just to be clear that 500s aren't coming from unhandled requests
+ })
+
+ Context("because the handler has panicked", func() {
+ BeforeEach(func() {
+ s.AppendHandlers(func(w http.ResponseWriter, req *http.Request) {
+ panic("bam")
+ })
+ })
+
+ It("should respond with a 500 and make a failing assertion", func() {
+ var resp *http.Response
+ var err error
+
+ failures := InterceptGomegaFailures(func() {
+ resp, err = http.Get(s.URL())
+ })
+
+ Ω(err).ShouldNot(HaveOccurred())
+ Ω(resp.StatusCode).Should(Equal(http.StatusInternalServerError))
+ Ω(failures).Should(ConsistOf(ContainSubstring("Handler Panicked")))
+ })
+ })
+
+ Context("because an assertion has failed", func() {
+ BeforeEach(func() {
+ s.AppendHandlers(func(w http.ResponseWriter, req *http.Request) {
+ // Ω(true).Should(BeFalse()) <-- would be nice to do it this way, but the test just can't be written this way
+
+ By("We're cheating a bit here -- we're throwing a GINKGO_PANIC which simulates a failed assertion")
+ panic(GINKGO_PANIC)
+ })
+ })
+
+ It("should respond with a 500 and *not* make a failing assertion, instead relying on Ginkgo to have already been notified of the error", func() {
+ resp, err := http.Get(s.URL())
+
+ Ω(err).ShouldNot(HaveOccurred())
+ Ω(resp.StatusCode).Should(Equal(http.StatusInternalServerError))
+ })
+ })
+ })
+
+ Describe("Logging to the Writer", func() {
+ var buf *gbytes.Buffer
+ BeforeEach(func() {
+ buf = gbytes.NewBuffer()
+ s.Writer = buf
+ s.AppendHandlers(func(w http.ResponseWriter, req *http.Request) {})
+ s.AppendHandlers(func(w http.ResponseWriter, req *http.Request) {})
+ })
+
+ It("should write to the buffer when a request comes in", func() {
+ http.Get(s.URL() + "/foo")
+ Ω(buf).Should(gbytes.Say("GHTTP Received Request: GET - /foo\n"))
+
+ http.Post(s.URL()+"/bar", "", nil)
+ Ω(buf).Should(gbytes.Say("GHTTP Received Request: POST - /bar\n"))
+ })
+ })
+
+ Describe("Request Handlers", func() {
+ Describe("VerifyRequest", func() {
+ BeforeEach(func() {
+ s.AppendHandlers(VerifyRequest("GET", "/foo"))
+ })
+
+ It("should verify the method, path", func() {
+ resp, err = http.Get(s.URL() + "/foo?baz=bar")
+ Ω(err).ShouldNot(HaveOccurred())
+ })
+
+ It("should verify the method, path", func() {
+ failures := InterceptGomegaFailures(func() {
+ http.Get(s.URL() + "/foo2")
+ })
+ Ω(failures).Should(HaveLen(1))
+ })
+
+ It("should verify the method, path", func() {
+ failures := InterceptGomegaFailures(func() {
+ http.Post(s.URL()+"/foo", "application/json", nil)
+ })
+ Ω(failures).Should(HaveLen(1))
+ })
+
+ Context("when passed a rawQuery", func() {
+ It("should also be possible to verify the rawQuery", func() {
+ s.SetHandler(0, VerifyRequest("GET", "/foo", "baz=bar"))
+ resp, err = http.Get(s.URL() + "/foo?baz=bar")
+ Ω(err).ShouldNot(HaveOccurred())
+ })
+
+ It("should match irregardless of query parameter ordering", func() {
+ s.SetHandler(0, VerifyRequest("GET", "/foo", "type=get&name=money"))
+ u, _ := url.Parse(s.URL() + "/foo")
+ u.RawQuery = url.Values{
+ "type": []string{"get"},
+ "name": []string{"money"},
+ }.Encode()
+
+ resp, err = http.Get(u.String())
+ Ω(err).ShouldNot(HaveOccurred())
+ })
+ })
+
+ Context("when passed a matcher for path", func() {
+ It("should apply the matcher", func() {
+ s.SetHandler(0, VerifyRequest("GET", MatchRegexp(`/foo/[a-f]*/3`)))
+ resp, err = http.Get(s.URL() + "/foo/abcdefa/3")
+ Ω(err).ShouldNot(HaveOccurred())
+ })
+ })
+ })
+
+ Describe("VerifyContentType", func() {
+ BeforeEach(func() {
+ s.AppendHandlers(CombineHandlers(
+ VerifyRequest("GET", "/foo"),
+ VerifyContentType("application/octet-stream"),
+ ))
+ })
+
+ It("should verify the content type", func() {
+ req, err := http.NewRequest("GET", s.URL()+"/foo", nil)
+ Ω(err).ShouldNot(HaveOccurred())
+ req.Header.Set("Content-Type", "application/octet-stream")
+
+ resp, err = http.DefaultClient.Do(req)
+ Ω(err).ShouldNot(HaveOccurred())
+ })
+
+ It("should verify the content type", func() {
+ req, err := http.NewRequest("GET", s.URL()+"/foo", nil)
+ Ω(err).ShouldNot(HaveOccurred())
+ req.Header.Set("Content-Type", "application/json")
+
+ failures := InterceptGomegaFailures(func() {
+ http.DefaultClient.Do(req)
+ })
+ Ω(failures).Should(HaveLen(1))
+ })
+ })
+
+ Describe("Verify BasicAuth", func() {
+ BeforeEach(func() {
+ s.AppendHandlers(CombineHandlers(
+ VerifyRequest("GET", "/foo"),
+ VerifyBasicAuth("bob", "password"),
+ ))
+ })
+
+ It("should verify basic auth", func() {
+ req, err := http.NewRequest("GET", s.URL()+"/foo", nil)
+ Ω(err).ShouldNot(HaveOccurred())
+ req.SetBasicAuth("bob", "password")
+
+ resp, err = http.DefaultClient.Do(req)
+ Ω(err).ShouldNot(HaveOccurred())
+ })
+
+ It("should verify basic auth", func() {
+ req, err := http.NewRequest("GET", s.URL()+"/foo", nil)
+ Ω(err).ShouldNot(HaveOccurred())
+ req.SetBasicAuth("bob", "bassword")
+
+ failures := InterceptGomegaFailures(func() {
+ http.DefaultClient.Do(req)
+ })
+ Ω(failures).Should(HaveLen(1))
+ })
+
+ It("should require basic auth header", func() {
+ req, err := http.NewRequest("GET", s.URL()+"/foo", nil)
+ Ω(err).ShouldNot(HaveOccurred())
+
+ failures := InterceptGomegaFailures(func() {
+ http.DefaultClient.Do(req)
+ })
+ Ω(failures).Should(ContainElement(ContainSubstring("Authorization header must be specified")))
+ })
+ })
+
+ Describe("VerifyHeader", func() {
+ BeforeEach(func() {
+ s.AppendHandlers(CombineHandlers(
+ VerifyRequest("GET", "/foo"),
+ VerifyHeader(http.Header{
+ "accept": []string{"jpeg", "png"},
+ "cache-control": []string{"omicron"},
+ "Return-Path": []string{"hobbiton"},
+ }),
+ ))
+ })
+
+ It("should verify the headers", func() {
+ req, err := http.NewRequest("GET", s.URL()+"/foo", nil)
+ Ω(err).ShouldNot(HaveOccurred())
+ req.Header.Add("Accept", "jpeg")
+ req.Header.Add("Accept", "png")
+ req.Header.Add("Cache-Control", "omicron")
+ req.Header.Add("return-path", "hobbiton")
+
+ resp, err = http.DefaultClient.Do(req)
+ Ω(err).ShouldNot(HaveOccurred())
+ })
+
+ It("should verify the headers", func() {
+ req, err := http.NewRequest("GET", s.URL()+"/foo", nil)
+ Ω(err).ShouldNot(HaveOccurred())
+ req.Header.Add("Schmaccept", "jpeg")
+ req.Header.Add("Schmaccept", "png")
+ req.Header.Add("Cache-Control", "omicron")
+ req.Header.Add("return-path", "hobbiton")
+
+ failures := InterceptGomegaFailures(func() {
+ http.DefaultClient.Do(req)
+ })
+ Ω(failures).Should(HaveLen(1))
+ })
+ })
+
+ Describe("VerifyHeaderKV", func() {
+ BeforeEach(func() {
+ s.AppendHandlers(CombineHandlers(
+ VerifyRequest("GET", "/foo"),
+ VerifyHeaderKV("accept", "jpeg", "png"),
+ VerifyHeaderKV("cache-control", "omicron"),
+ VerifyHeaderKV("Return-Path", "hobbiton"),
+ ))
+ })
+
+ It("should verify the headers", func() {
+ req, err := http.NewRequest("GET", s.URL()+"/foo", nil)
+ Ω(err).ShouldNot(HaveOccurred())
+ req.Header.Add("Accept", "jpeg")
+ req.Header.Add("Accept", "png")
+ req.Header.Add("Cache-Control", "omicron")
+ req.Header.Add("return-path", "hobbiton")
+
+ resp, err = http.DefaultClient.Do(req)
+ Ω(err).ShouldNot(HaveOccurred())
+ })
+
+ It("should verify the headers", func() {
+ req, err := http.NewRequest("GET", s.URL()+"/foo", nil)
+ Ω(err).ShouldNot(HaveOccurred())
+ req.Header.Add("Accept", "jpeg")
+ req.Header.Add("Cache-Control", "omicron")
+ req.Header.Add("return-path", "hobbiton")
+
+ failures := InterceptGomegaFailures(func() {
+ http.DefaultClient.Do(req)
+ })
+ Ω(failures).Should(HaveLen(1))
+ })
+ })
+
+ Describe("VerifyBody", func() {
+ BeforeEach(func() {
+ s.AppendHandlers(CombineHandlers(
+ VerifyRequest("POST", "/foo"),
+ VerifyBody([]byte("some body")),
+ ))
+ })
+
+ It("should verify the body", func() {
+ resp, err = http.Post(s.URL()+"/foo", "", bytes.NewReader([]byte("some body")))
+ Ω(err).ShouldNot(HaveOccurred())
+ })
+
+ It("should verify the body", func() {
+ failures := InterceptGomegaFailures(func() {
+ http.Post(s.URL()+"/foo", "", bytes.NewReader([]byte("wrong body")))
+ })
+ Ω(failures).Should(HaveLen(1))
+ })
+ })
+
+ Describe("VerifyJSON", func() {
+ BeforeEach(func() {
+ s.AppendHandlers(CombineHandlers(
+ VerifyRequest("POST", "/foo"),
+ VerifyJSON(`{"a":3, "b":2}`),
+ ))
+ })
+
+ It("should verify the json body and the content type", func() {
+ resp, err = http.Post(s.URL()+"/foo", "application/json", bytes.NewReader([]byte(`{"b":2, "a":3}`)))
+ Ω(err).ShouldNot(HaveOccurred())
+ })
+
+ It("should verify the json body and the content type", func() {
+ failures := InterceptGomegaFailures(func() {
+ http.Post(s.URL()+"/foo", "application/json", bytes.NewReader([]byte(`{"b":2, "a":4}`)))
+ })
+ Ω(failures).Should(HaveLen(1))
+ })
+
+ It("should verify the json body and the content type", func() {
+ failures := InterceptGomegaFailures(func() {
+ http.Post(s.URL()+"/foo", "application/not-json", bytes.NewReader([]byte(`{"b":2, "a":3}`)))
+ })
+ Ω(failures).Should(HaveLen(1))
+ })
+ })
+
+ Describe("VerifyJSONRepresenting", func() {
+ BeforeEach(func() {
+ s.AppendHandlers(CombineHandlers(
+ VerifyRequest("POST", "/foo"),
+ VerifyJSONRepresenting([]int{1, 3, 5}),
+ ))
+ })
+
+ It("should verify the json body and the content type", func() {
+ resp, err = http.Post(s.URL()+"/foo", "application/json", bytes.NewReader([]byte(`[1,3,5]`)))
+ Ω(err).ShouldNot(HaveOccurred())
+ })
+
+ It("should verify the json body and the content type", func() {
+ failures := InterceptGomegaFailures(func() {
+ http.Post(s.URL()+"/foo", "application/json", bytes.NewReader([]byte(`[1,3]`)))
+ })
+ Ω(failures).Should(HaveLen(1))
+ })
+ })
+
+ Describe("VerifyForm", func() {
+ var formValues url.Values
+
+ BeforeEach(func() {
+ formValues = make(url.Values)
+ formValues.Add("users", "user1")
+ formValues.Add("users", "user2")
+ formValues.Add("group", "users")
+ })
+
+ Context("when encoded in the URL", func() {
+ BeforeEach(func() {
+ s.AppendHandlers(CombineHandlers(
+ VerifyRequest("GET", "/foo"),
+ VerifyForm(url.Values{
+ "users": []string{"user1", "user2"},
+ "group": []string{"users"},
+ }),
+ ))
+ })
+
+ It("should verify form values", func() {
+ resp, err = http.Get(s.URL() + "/foo?" + formValues.Encode())
+ Ω(err).ShouldNot(HaveOccurred())
+ })
+
+ It("should ignore extra values", func() {
+ formValues.Add("extra", "value")
+ resp, err = http.Get(s.URL() + "/foo?" + formValues.Encode())
+ Ω(err).ShouldNot(HaveOccurred())
+ })
+
+ It("fail on missing values", func() {
+ formValues.Del("group")
+ failures := InterceptGomegaFailures(func() {
+ resp, err = http.Get(s.URL() + "/foo?" + formValues.Encode())
+ })
+ Ω(failures).Should(HaveLen(1))
+ })
+
+ It("fail on incorrect values", func() {
+ formValues.Set("group", "wheel")
+ failures := InterceptGomegaFailures(func() {
+ resp, err = http.Get(s.URL() + "/foo?" + formValues.Encode())
+ })
+ Ω(failures).Should(HaveLen(1))
+ })
+ })
+
+ Context("when present in the body", func() {
+ BeforeEach(func() {
+ s.AppendHandlers(CombineHandlers(
+ VerifyRequest("POST", "/foo"),
+ VerifyForm(url.Values{
+ "users": []string{"user1", "user2"},
+ "group": []string{"users"},
+ }),
+ ))
+ })
+
+ It("should verify form values", func() {
+ resp, err = http.PostForm(s.URL()+"/foo", formValues)
+ Ω(err).ShouldNot(HaveOccurred())
+ })
+
+ It("should ignore extra values", func() {
+ formValues.Add("extra", "value")
+ resp, err = http.PostForm(s.URL()+"/foo", formValues)
+ Ω(err).ShouldNot(HaveOccurred())
+ })
+
+ It("fail on missing values", func() {
+ formValues.Del("group")
+ failures := InterceptGomegaFailures(func() {
+ resp, err = http.PostForm(s.URL()+"/foo", formValues)
+ })
+ Ω(failures).Should(HaveLen(1))
+ })
+
+ It("fail on incorrect values", func() {
+ formValues.Set("group", "wheel")
+ failures := InterceptGomegaFailures(func() {
+ resp, err = http.PostForm(s.URL()+"/foo", formValues)
+ })
+ Ω(failures).Should(HaveLen(1))
+ })
+ })
+ })
+
+ Describe("VerifyFormKV", func() {
+ Context("when encoded in the URL", func() {
+ BeforeEach(func() {
+ s.AppendHandlers(CombineHandlers(
+ VerifyRequest("GET", "/foo"),
+ VerifyFormKV("users", "user1", "user2"),
+ ))
+ })
+
+ It("verifies the form value", func() {
+ resp, err = http.Get(s.URL() + "/foo?users=user1&users=user2")
+ Ω(err).ShouldNot(HaveOccurred())
+ })
+
+ It("verifies the form value", func() {
+ failures := InterceptGomegaFailures(func() {
+ resp, err = http.Get(s.URL() + "/foo?users=user1")
+ })
+ Ω(failures).Should(HaveLen(1))
+ })
+ })
+
+ Context("when present in the body", func() {
+ BeforeEach(func() {
+ s.AppendHandlers(CombineHandlers(
+ VerifyRequest("POST", "/foo"),
+ VerifyFormKV("users", "user1", "user2"),
+ ))
+ })
+
+ It("verifies the form value", func() {
+ resp, err = http.PostForm(s.URL()+"/foo", url.Values{"users": []string{"user1", "user2"}})
+ Ω(err).ShouldNot(HaveOccurred())
+ })
+
+ It("verifies the form value", func() {
+ failures := InterceptGomegaFailures(func() {
+ resp, err = http.PostForm(s.URL()+"/foo", url.Values{"users": []string{"user1"}})
+ })
+ Ω(failures).Should(HaveLen(1))
+ })
+ })
+ })
+
+ Describe("VerifyProtoRepresenting", func() {
+ var message *protobuf.SimpleMessage
+
+ BeforeEach(func() {
+ message = new(protobuf.SimpleMessage)
+ message.Description = proto.String("A description")
+ message.Id = proto.Int32(0)
+
+ s.AppendHandlers(CombineHandlers(
+ VerifyRequest("POST", "/proto"),
+ VerifyProtoRepresenting(message),
+ ))
+ })
+
+ It("verifies the proto body and the content type", func() {
+ serialized, err := proto.Marshal(message)
+ Ω(err).ShouldNot(HaveOccurred())
+
+ resp, err = http.Post(s.URL()+"/proto", "application/x-protobuf", bytes.NewReader(serialized))
+ Ω(err).ShouldNot(HaveOccurred())
+ })
+
+ It("should verify the proto body and the content type", func() {
+ serialized, err := proto.Marshal(&protobuf.SimpleMessage{
+ Description: proto.String("A description"),
+ Id: proto.Int32(0),
+ Metadata: proto.String("some metadata"),
+ })
+ Ω(err).ShouldNot(HaveOccurred())
+
+ failures := InterceptGomegaFailures(func() {
+ http.Post(s.URL()+"/proto", "application/x-protobuf", bytes.NewReader(serialized))
+ })
+ Ω(failures).Should(HaveLen(1))
+ })
+
+ It("should verify the proto body and the content type", func() {
+ serialized, err := proto.Marshal(message)
+ Ω(err).ShouldNot(HaveOccurred())
+
+ failures := InterceptGomegaFailures(func() {
+ http.Post(s.URL()+"/proto", "application/not-x-protobuf", bytes.NewReader(serialized))
+ })
+ Ω(failures).Should(HaveLen(1))
+ })
+ })
+
+ Describe("RespondWith", func() {
+ Context("without headers", func() {
+ BeforeEach(func() {
+ s.AppendHandlers(CombineHandlers(
+ VerifyRequest("POST", "/foo"),
+ RespondWith(http.StatusCreated, "sweet"),
+ ), CombineHandlers(
+ VerifyRequest("POST", "/foo"),
+ RespondWith(http.StatusOK, []byte("sour")),
+ ))
+ })
+
+ It("should return the response", func() {
+ resp, err = http.Post(s.URL()+"/foo", "application/json", nil)
+ Ω(err).ShouldNot(HaveOccurred())
+
+ Ω(resp.StatusCode).Should(Equal(http.StatusCreated))
+
+ body, err := ioutil.ReadAll(resp.Body)
+ Ω(err).ShouldNot(HaveOccurred())
+ Ω(body).Should(Equal([]byte("sweet")))
+
+ resp, err = http.Post(s.URL()+"/foo", "application/json", nil)
+ Ω(err).ShouldNot(HaveOccurred())
+
+ Ω(resp.StatusCode).Should(Equal(http.StatusOK))
+
+ body, err = ioutil.ReadAll(resp.Body)
+ Ω(err).ShouldNot(HaveOccurred())
+ Ω(body).Should(Equal([]byte("sour")))
+ })
+ })
+
+ Context("with headers", func() {
+ BeforeEach(func() {
+ s.AppendHandlers(CombineHandlers(
+ VerifyRequest("POST", "/foo"),
+ RespondWith(http.StatusCreated, "sweet", http.Header{"X-Custom-Header": []string{"my header"}}),
+ ))
+ })
+
+ It("should return the headers too", func() {
+ resp, err = http.Post(s.URL()+"/foo", "application/json", nil)
+ Ω(err).ShouldNot(HaveOccurred())
+
+ Ω(resp.StatusCode).Should(Equal(http.StatusCreated))
+ Ω(ioutil.ReadAll(resp.Body)).Should(Equal([]byte("sweet")))
+ Ω(resp.Header.Get("X-Custom-Header")).Should(Equal("my header"))
+ })
+ })
+ })
+
+ Describe("RespondWithPtr", func() {
+ var code int
+ var byteBody []byte
+ var stringBody string
+ BeforeEach(func() {
+ code = http.StatusOK
+ byteBody = []byte("sweet")
+ stringBody = "sour"
+
+ s.AppendHandlers(CombineHandlers(
+ VerifyRequest("POST", "/foo"),
+ RespondWithPtr(&code, &byteBody),
+ ), CombineHandlers(
+ VerifyRequest("POST", "/foo"),
+ RespondWithPtr(&code, &stringBody),
+ ))
+ })
+
+ It("should return the response", func() {
+ code = http.StatusCreated
+ byteBody = []byte("tasty")
+ stringBody = "treat"
+
+ resp, err = http.Post(s.URL()+"/foo", "application/json", nil)
+ Ω(err).ShouldNot(HaveOccurred())
+
+ Ω(resp.StatusCode).Should(Equal(http.StatusCreated))
+
+ body, err := ioutil.ReadAll(resp.Body)
+ Ω(err).ShouldNot(HaveOccurred())
+ Ω(body).Should(Equal([]byte("tasty")))
+
+ resp, err = http.Post(s.URL()+"/foo", "application/json", nil)
+ Ω(err).ShouldNot(HaveOccurred())
+
+ Ω(resp.StatusCode).Should(Equal(http.StatusCreated))
+
+ body, err = ioutil.ReadAll(resp.Body)
+ Ω(err).ShouldNot(HaveOccurred())
+ Ω(body).Should(Equal([]byte("treat")))
+ })
+
+ Context("when passed a nil body", func() {
+ BeforeEach(func() {
+ s.SetHandler(0, CombineHandlers(
+ VerifyRequest("POST", "/foo"),
+ RespondWithPtr(&code, nil),
+ ))
+ })
+
+ It("should return an empty body and not explode", func() {
+ resp, err = http.Post(s.URL()+"/foo", "application/json", nil)
+
+ Ω(err).ShouldNot(HaveOccurred())
+ Ω(resp.StatusCode).Should(Equal(http.StatusOK))
+ body, err := ioutil.ReadAll(resp.Body)
+ Ω(err).ShouldNot(HaveOccurred())
+ Ω(body).Should(BeEmpty())
+
+ Ω(s.ReceivedRequests()).Should(HaveLen(1))
+ })
+ })
+ })
+
+ Describe("RespondWithJSON", func() {
+ Context("when no optional headers are set", func() {
+ BeforeEach(func() {
+ s.AppendHandlers(CombineHandlers(
+ VerifyRequest("POST", "/foo"),
+ RespondWithJSONEncoded(http.StatusCreated, []int{1, 2, 3}),
+ ))
+ })
+
+ It("should return the response", func() {
+ resp, err = http.Post(s.URL()+"/foo", "application/json", nil)
+ Ω(err).ShouldNot(HaveOccurred())
+
+ Ω(resp.StatusCode).Should(Equal(http.StatusCreated))
+
+ body, err := ioutil.ReadAll(resp.Body)
+ Ω(err).ShouldNot(HaveOccurred())
+ Ω(body).Should(MatchJSON("[1,2,3]"))
+ })
+
+ It("should set the Content-Type header to application/json", func() {
+ resp, err = http.Post(s.URL()+"/foo", "application/json", nil)
+ Ω(err).ShouldNot(HaveOccurred())
+
+ Ω(resp.Header["Content-Type"]).Should(Equal([]string{"application/json"}))
+ })
+ })
+
+ Context("when optional headers are set", func() {
+ var headers http.Header
+ BeforeEach(func() {
+ headers = http.Header{"Stuff": []string{"things"}}
+ })
+
+ JustBeforeEach(func() {
+ s.AppendHandlers(CombineHandlers(
+ VerifyRequest("POST", "/foo"),
+ RespondWithJSONEncoded(http.StatusCreated, []int{1, 2, 3}, headers),
+ ))
+ })
+
+ It("should preserve those headers", func() {
+ resp, err = http.Post(s.URL()+"/foo", "application/json", nil)
+ Ω(err).ShouldNot(HaveOccurred())
+
+ Ω(resp.Header["Stuff"]).Should(Equal([]string{"things"}))
+ })
+
+ It("should set the Content-Type header to application/json", func() {
+ resp, err = http.Post(s.URL()+"/foo", "application/json", nil)
+ Ω(err).ShouldNot(HaveOccurred())
+
+ Ω(resp.Header["Content-Type"]).Should(Equal([]string{"application/json"}))
+ })
+
+ Context("when setting the Content-Type explicitly", func() {
+ BeforeEach(func() {
+ headers["Content-Type"] = []string{"not-json"}
+ })
+
+ It("should use the Content-Type header that was explicitly set", func() {
+ resp, err = http.Post(s.URL()+"/foo", "application/json", nil)
+ Ω(err).ShouldNot(HaveOccurred())
+
+ Ω(resp.Header["Content-Type"]).Should(Equal([]string{"not-json"}))
+ })
+ })
+ })
+ })
+
+ Describe("RespondWithJSONPtr", func() {
+ type testObject struct {
+ Key string
+ Value string
+ }
+
+ var code int
+ var object testObject
+
+ Context("when no optional headers are set", func() {
+ BeforeEach(func() {
+ code = http.StatusOK
+ object = testObject{}
+ s.AppendHandlers(CombineHandlers(
+ VerifyRequest("POST", "/foo"),
+ RespondWithJSONEncodedPtr(&code, &object),
+ ))
+ })
+
+ It("should return the response", func() {
+ code = http.StatusCreated
+ object = testObject{
+ Key: "Jim",
+ Value: "Codes",
+ }
+ resp, err = http.Post(s.URL()+"/foo", "application/json", nil)
+ Ω(err).ShouldNot(HaveOccurred())
+
+ Ω(resp.StatusCode).Should(Equal(http.StatusCreated))
+
+ body, err := ioutil.ReadAll(resp.Body)
+ Ω(err).ShouldNot(HaveOccurred())
+ Ω(body).Should(MatchJSON(`{"Key": "Jim", "Value": "Codes"}`))
+ })
+
+ It("should set the Content-Type header to application/json", func() {
+ resp, err = http.Post(s.URL()+"/foo", "application/json", nil)
+ Ω(err).ShouldNot(HaveOccurred())
+
+ Ω(resp.Header["Content-Type"]).Should(Equal([]string{"application/json"}))
+ })
+ })
+
+ Context("when optional headers are set", func() {
+ var headers http.Header
+ BeforeEach(func() {
+ headers = http.Header{"Stuff": []string{"things"}}
+ })
+
+ JustBeforeEach(func() {
+ code = http.StatusOK
+ object = testObject{}
+ s.AppendHandlers(CombineHandlers(
+ VerifyRequest("POST", "/foo"),
+ RespondWithJSONEncodedPtr(&code, &object, headers),
+ ))
+ })
+
+ It("should preserve those headers", func() {
+ resp, err = http.Post(s.URL()+"/foo", "application/json", nil)
+ Ω(err).ShouldNot(HaveOccurred())
+
+ Ω(resp.Header["Stuff"]).Should(Equal([]string{"things"}))
+ })
+
+ It("should set the Content-Type header to application/json", func() {
+ resp, err = http.Post(s.URL()+"/foo", "application/json", nil)
+ Ω(err).ShouldNot(HaveOccurred())
+
+ Ω(resp.Header["Content-Type"]).Should(Equal([]string{"application/json"}))
+ })
+
+ Context("when setting the Content-Type explicitly", func() {
+ BeforeEach(func() {
+ headers["Content-Type"] = []string{"not-json"}
+ })
+
+ It("should use the Content-Type header that was explicitly set", func() {
+ resp, err = http.Post(s.URL()+"/foo", "application/json", nil)
+ Ω(err).ShouldNot(HaveOccurred())
+
+ Ω(resp.Header["Content-Type"]).Should(Equal([]string{"not-json"}))
+ })
+ })
+ })
+ })
+
+ Describe("RespondWithProto", func() {
+ var message *protobuf.SimpleMessage
+
+ BeforeEach(func() {
+ message = new(protobuf.SimpleMessage)
+ message.Description = proto.String("A description")
+ message.Id = proto.Int32(99)
+ })
+
+ Context("when no optional headers are set", func() {
+ BeforeEach(func() {
+ s.AppendHandlers(CombineHandlers(
+ VerifyRequest("POST", "/proto"),
+ RespondWithProto(http.StatusCreated, message),
+ ))
+ })
+
+ It("should return the response", func() {
+ resp, err = http.Post(s.URL()+"/proto", "application/x-protobuf", nil)
+ Ω(err).ShouldNot(HaveOccurred())
+
+ Ω(resp.StatusCode).Should(Equal(http.StatusCreated))
+
+ var received protobuf.SimpleMessage
+ body, err := ioutil.ReadAll(resp.Body)
+ err = proto.Unmarshal(body, &received)
+ Ω(err).ShouldNot(HaveOccurred())
+ })
+
+ It("should set the Content-Type header to application/x-protobuf", func() {
+ resp, err = http.Post(s.URL()+"/proto", "application/x-protobuf", nil)
+ Ω(err).ShouldNot(HaveOccurred())
+
+ Ω(resp.Header["Content-Type"]).Should(Equal([]string{"application/x-protobuf"}))
+ })
+ })
+
+ Context("when optional headers are set", func() {
+ var headers http.Header
+ BeforeEach(func() {
+ headers = http.Header{"Stuff": []string{"things"}}
+ })
+
+ JustBeforeEach(func() {
+ s.AppendHandlers(CombineHandlers(
+ VerifyRequest("POST", "/proto"),
+ RespondWithProto(http.StatusCreated, message, headers),
+ ))
+ })
+
+ It("should preserve those headers", func() {
+ resp, err = http.Post(s.URL()+"/proto", "application/x-protobuf", nil)
+ Ω(err).ShouldNot(HaveOccurred())
+
+ Ω(resp.Header["Stuff"]).Should(Equal([]string{"things"}))
+ })
+
+ It("should set the Content-Type header to application/x-protobuf", func() {
+ resp, err = http.Post(s.URL()+"/proto", "application/x-protobuf", nil)
+ Ω(err).ShouldNot(HaveOccurred())
+
+ Ω(resp.Header["Content-Type"]).Should(Equal([]string{"application/x-protobuf"}))
+ })
+
+ Context("when setting the Content-Type explicitly", func() {
+ BeforeEach(func() {
+ headers["Content-Type"] = []string{"not-x-protobuf"}
+ })
+
+ It("should use the Content-Type header that was explicitly set", func() {
+ resp, err = http.Post(s.URL()+"/proto", "application/x-protobuf", nil)
+ Ω(err).ShouldNot(HaveOccurred())
+
+ Ω(resp.Header["Content-Type"]).Should(Equal([]string{"not-x-protobuf"}))
+ })
+ })
+ })
+ })
+ })
+})