mirror of
https://github.com/octoleo/syncthing.git
synced 2024-11-14 17:24:04 +00:00
65aaa607ab
Change made by: - running "gvt fetch" on each of the packages mentioned in Godeps/Godeps.json - `rm -rf Godeps` - tweaking the build scripts to not mention Godeps - tweaking the build scripts to test `./lib/...`, `./cmd/...` explicitly (to avoid testing vendor) - tweaking the build scripts to not juggle GOPATH for Godeps and instead set GO15VENDOREXPERIMENT. This also results in some updated packages at the same time I bet. Building with Go 1.3 and 1.4 still *works* but won't use our vendored dependencies - the user needs to have the actual packages in their GOPATH then, which they'll get with a normal "go get". Building with Go 1.6+ will get our vendored dependencies by default even when not using our build script, which is nice. By doing this we gain some freedom in that we can pick and choose manually what to include in vendor, as it's not based on just dependency analysis of our own code. This is also a risk as we might pick up dependencies we are unaware of, as the build may work locally with those packages present in GOPATH. On the other hand the build server will detect this as it has no packages in it's GOPATH beyond what is included in the repo. Recommended tool to manage dependencies is github.com/FiloSottile/gvt.
1083 lines
31 KiB
Go
1083 lines
31 KiB
Go
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)
|
|
},
|
|
)
|
|
|
|
resp, err := http.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 = http.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("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"}))
|
|
})
|
|
})
|
|
})
|
|
})
|
|
})
|
|
})
|