11 "github.com/golang/protobuf/proto"
12 "github.com/onsi/gomega/gbytes"
13 "github.com/onsi/gomega/ghttp/protobuf"
15 . "github.com/onsi/ginkgo"
16 . "github.com/onsi/gomega"
17 . "github.com/onsi/gomega/ghttp"
20 var _ = Describe("TestServer", func() {
35 Describe("Resetting the server", func() {
37 s.RouteToHandler("GET", "/", func(w http.ResponseWriter, req *http.Request) {})
38 s.AppendHandlers(func(w http.ResponseWriter, req *http.Request) {})
39 http.Get(s.URL() + "/")
41 Ω(s.ReceivedRequests()).Should(HaveLen(1))
44 It("clears all handlers and call counts", func() {
46 Ω(s.ReceivedRequests()).Should(HaveLen(0))
47 Ω(func() { s.GetHandler(0) }).Should(Panic())
51 Describe("closing client connections", func() {
53 s.RouteToHandler("GET", "/",
54 func(w http.ResponseWriter, req *http.Request) {
55 io.WriteString(w, req.RemoteAddr)
58 client := http.Client{Transport: &http.Transport{DisableKeepAlives: true}}
59 resp, err := client.Get(s.URL())
60 Ω(err).ShouldNot(HaveOccurred())
61 Ω(resp.StatusCode).Should(Equal(200))
63 body, err := ioutil.ReadAll(resp.Body)
65 Ω(err).ShouldNot(HaveOccurred())
67 s.CloseClientConnections()
69 resp, err = client.Get(s.URL())
70 Ω(err).ShouldNot(HaveOccurred())
71 Ω(resp.StatusCode).Should(Equal(200))
73 body2, err := ioutil.ReadAll(resp.Body)
75 Ω(err).ShouldNot(HaveOccurred())
77 Ω(body2).ShouldNot(Equal(body))
81 Describe("closing server mulitple times", func() {
82 It("should not fail", func() {
84 Ω(s.Close).ShouldNot(Panic())
88 Describe("allowing unhandled requests", func() {
89 Context("when true", func() {
91 s.AllowUnhandledRequests = true
92 s.UnhandledRequestStatusCode = http.StatusForbidden
93 resp, err = http.Get(s.URL() + "/foo")
94 Ω(err).ShouldNot(HaveOccurred())
97 It("should allow unhandled requests and respond with the passed in status code", func() {
98 Ω(err).ShouldNot(HaveOccurred())
99 Ω(resp.StatusCode).Should(Equal(http.StatusForbidden))
101 data, err := ioutil.ReadAll(resp.Body)
102 Ω(err).ShouldNot(HaveOccurred())
103 Ω(data).Should(BeEmpty())
106 It("should record the requests", func() {
107 Ω(s.ReceivedRequests()).Should(HaveLen(1))
108 Ω(s.ReceivedRequests()[0].URL.Path).Should(Equal("/foo"))
112 Context("when false", func() {
113 It("should fail when attempting a request", func() {
114 failures := InterceptGomegaFailures(func() {
115 http.Get(s.URL() + "/foo")
118 Ω(failures[0]).Should(ContainSubstring("Received Unhandled Request"))
123 Describe("Managing Handlers", func() {
127 s.RouteToHandler("GET", "/routed", func(w http.ResponseWriter, req *http.Request) {
128 called = append(called, "r1")
130 s.RouteToHandler("POST", regexp.MustCompile(`/routed\d`), func(w http.ResponseWriter, req *http.Request) {
131 called = append(called, "r2")
133 s.AppendHandlers(func(w http.ResponseWriter, req *http.Request) {
134 called = append(called, "A")
135 }, func(w http.ResponseWriter, req *http.Request) {
136 called = append(called, "B")
140 It("should prefer routed handlers if there is a match", func() {
141 http.Get(s.URL() + "/routed")
142 http.Post(s.URL()+"/routed7", "application/json", nil)
143 http.Get(s.URL() + "/foo")
144 http.Get(s.URL() + "/routed")
145 http.Post(s.URL()+"/routed9", "application/json", nil)
146 http.Get(s.URL() + "/bar")
148 failures := InterceptGomegaFailures(func() {
149 http.Get(s.URL() + "/foo")
150 http.Get(s.URL() + "/routed/not/a/match")
151 http.Get(s.URL() + "/routed7")
152 http.Post(s.URL()+"/routed", "application/json", nil)
155 Ω(failures[0]).Should(ContainSubstring("Received Unhandled Request"))
156 Ω(failures).Should(HaveLen(4))
158 http.Post(s.URL()+"/routed3", "application/json", nil)
160 Ω(called).Should(Equal([]string{"r1", "r2", "A", "r1", "r2", "B", "r2"}))
163 It("should override routed handlers when reregistered", func() {
164 s.RouteToHandler("GET", "/routed", func(w http.ResponseWriter, req *http.Request) {
165 called = append(called, "r3")
167 s.RouteToHandler("POST", regexp.MustCompile(`/routed\d`), func(w http.ResponseWriter, req *http.Request) {
168 called = append(called, "r4")
171 http.Get(s.URL() + "/routed")
172 http.Post(s.URL()+"/routed7", "application/json", nil)
174 Ω(called).Should(Equal([]string{"r3", "r4"}))
177 It("should call the appended handlers, in order, as requests come in", func() {
178 http.Get(s.URL() + "/foo")
179 Ω(called).Should(Equal([]string{"A"}))
181 http.Get(s.URL() + "/foo")
182 Ω(called).Should(Equal([]string{"A", "B"}))
184 failures := InterceptGomegaFailures(func() {
185 http.Get(s.URL() + "/foo")
188 Ω(failures[0]).Should(ContainSubstring("Received Unhandled Request"))
191 Describe("Overwriting an existing handler", func() {
193 s.SetHandler(0, func(w http.ResponseWriter, req *http.Request) {
194 called = append(called, "C")
198 It("should override the specified handler", func() {
199 http.Get(s.URL() + "/foo")
200 http.Get(s.URL() + "/foo")
201 Ω(called).Should(Equal([]string{"C", "B"}))
205 Describe("Getting an existing handler", func() {
206 It("should return the handler func", func() {
207 s.GetHandler(1)(nil, nil)
208 Ω(called).Should(Equal([]string{"B"}))
212 Describe("Wrapping an existing handler", func() {
214 s.WrapHandler(0, func(w http.ResponseWriter, req *http.Request) {
215 called = append(called, "C")
219 It("should wrap the existing handler in a new handler", func() {
220 http.Get(s.URL() + "/foo")
221 http.Get(s.URL() + "/foo")
222 Ω(called).Should(Equal([]string{"A", "C", "B"}))
227 Describe("When a handler fails", func() {
229 s.UnhandledRequestStatusCode = http.StatusForbidden //just to be clear that 500s aren't coming from unhandled requests
232 Context("because the handler has panicked", func() {
234 s.AppendHandlers(func(w http.ResponseWriter, req *http.Request) {
239 It("should respond with a 500 and make a failing assertion", func() {
240 var resp *http.Response
243 failures := InterceptGomegaFailures(func() {
244 resp, err = http.Get(s.URL())
247 Ω(err).ShouldNot(HaveOccurred())
248 Ω(resp.StatusCode).Should(Equal(http.StatusInternalServerError))
249 Ω(failures).Should(ConsistOf(ContainSubstring("Handler Panicked")))
253 Context("because an assertion has failed", func() {
255 s.AppendHandlers(func(w http.ResponseWriter, req *http.Request) {
256 // Ω(true).Should(BeFalse()) <-- would be nice to do it this way, but the test just can't be written this way
258 By("We're cheating a bit here -- we're throwing a GINKGO_PANIC which simulates a failed assertion")
263 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() {
264 resp, err := http.Get(s.URL())
266 Ω(err).ShouldNot(HaveOccurred())
267 Ω(resp.StatusCode).Should(Equal(http.StatusInternalServerError))
272 Describe("Logging to the Writer", func() {
273 var buf *gbytes.Buffer
275 buf = gbytes.NewBuffer()
277 s.AppendHandlers(func(w http.ResponseWriter, req *http.Request) {})
278 s.AppendHandlers(func(w http.ResponseWriter, req *http.Request) {})
281 It("should write to the buffer when a request comes in", func() {
282 http.Get(s.URL() + "/foo")
283 Ω(buf).Should(gbytes.Say("GHTTP Received Request: GET - /foo\n"))
285 http.Post(s.URL()+"/bar", "", nil)
286 Ω(buf).Should(gbytes.Say("GHTTP Received Request: POST - /bar\n"))
290 Describe("Request Handlers", func() {
291 Describe("VerifyRequest", func() {
293 s.AppendHandlers(VerifyRequest("GET", "/foo"))
296 It("should verify the method, path", func() {
297 resp, err = http.Get(s.URL() + "/foo?baz=bar")
298 Ω(err).ShouldNot(HaveOccurred())
301 It("should verify the method, path", func() {
302 failures := InterceptGomegaFailures(func() {
303 http.Get(s.URL() + "/foo2")
305 Ω(failures).Should(HaveLen(1))
308 It("should verify the method, path", func() {
309 failures := InterceptGomegaFailures(func() {
310 http.Post(s.URL()+"/foo", "application/json", nil)
312 Ω(failures).Should(HaveLen(1))
315 Context("when passed a rawQuery", func() {
316 It("should also be possible to verify the rawQuery", func() {
317 s.SetHandler(0, VerifyRequest("GET", "/foo", "baz=bar"))
318 resp, err = http.Get(s.URL() + "/foo?baz=bar")
319 Ω(err).ShouldNot(HaveOccurred())
322 It("should match irregardless of query parameter ordering", func() {
323 s.SetHandler(0, VerifyRequest("GET", "/foo", "type=get&name=money"))
324 u, _ := url.Parse(s.URL() + "/foo")
325 u.RawQuery = url.Values{
326 "type": []string{"get"},
327 "name": []string{"money"},
330 resp, err = http.Get(u.String())
331 Ω(err).ShouldNot(HaveOccurred())
335 Context("when passed a matcher for path", func() {
336 It("should apply the matcher", func() {
337 s.SetHandler(0, VerifyRequest("GET", MatchRegexp(`/foo/[a-f]*/3`)))
338 resp, err = http.Get(s.URL() + "/foo/abcdefa/3")
339 Ω(err).ShouldNot(HaveOccurred())
344 Describe("VerifyContentType", func() {
346 s.AppendHandlers(CombineHandlers(
347 VerifyRequest("GET", "/foo"),
348 VerifyContentType("application/octet-stream"),
352 It("should verify the content type", func() {
353 req, err := http.NewRequest("GET", s.URL()+"/foo", nil)
354 Ω(err).ShouldNot(HaveOccurred())
355 req.Header.Set("Content-Type", "application/octet-stream")
357 resp, err = http.DefaultClient.Do(req)
358 Ω(err).ShouldNot(HaveOccurred())
361 It("should verify the content type", func() {
362 req, err := http.NewRequest("GET", s.URL()+"/foo", nil)
363 Ω(err).ShouldNot(HaveOccurred())
364 req.Header.Set("Content-Type", "application/json")
366 failures := InterceptGomegaFailures(func() {
367 http.DefaultClient.Do(req)
369 Ω(failures).Should(HaveLen(1))
373 Describe("Verify BasicAuth", func() {
375 s.AppendHandlers(CombineHandlers(
376 VerifyRequest("GET", "/foo"),
377 VerifyBasicAuth("bob", "password"),
381 It("should verify basic auth", func() {
382 req, err := http.NewRequest("GET", s.URL()+"/foo", nil)
383 Ω(err).ShouldNot(HaveOccurred())
384 req.SetBasicAuth("bob", "password")
386 resp, err = http.DefaultClient.Do(req)
387 Ω(err).ShouldNot(HaveOccurred())
390 It("should verify basic auth", func() {
391 req, err := http.NewRequest("GET", s.URL()+"/foo", nil)
392 Ω(err).ShouldNot(HaveOccurred())
393 req.SetBasicAuth("bob", "bassword")
395 failures := InterceptGomegaFailures(func() {
396 http.DefaultClient.Do(req)
398 Ω(failures).Should(HaveLen(1))
401 It("should require basic auth header", func() {
402 req, err := http.NewRequest("GET", s.URL()+"/foo", nil)
403 Ω(err).ShouldNot(HaveOccurred())
405 failures := InterceptGomegaFailures(func() {
406 http.DefaultClient.Do(req)
408 Ω(failures).Should(ContainElement(ContainSubstring("Authorization header must be specified")))
412 Describe("VerifyHeader", func() {
414 s.AppendHandlers(CombineHandlers(
415 VerifyRequest("GET", "/foo"),
416 VerifyHeader(http.Header{
417 "accept": []string{"jpeg", "png"},
418 "cache-control": []string{"omicron"},
419 "Return-Path": []string{"hobbiton"},
424 It("should verify the headers", func() {
425 req, err := http.NewRequest("GET", s.URL()+"/foo", nil)
426 Ω(err).ShouldNot(HaveOccurred())
427 req.Header.Add("Accept", "jpeg")
428 req.Header.Add("Accept", "png")
429 req.Header.Add("Cache-Control", "omicron")
430 req.Header.Add("return-path", "hobbiton")
432 resp, err = http.DefaultClient.Do(req)
433 Ω(err).ShouldNot(HaveOccurred())
436 It("should verify the headers", func() {
437 req, err := http.NewRequest("GET", s.URL()+"/foo", nil)
438 Ω(err).ShouldNot(HaveOccurred())
439 req.Header.Add("Schmaccept", "jpeg")
440 req.Header.Add("Schmaccept", "png")
441 req.Header.Add("Cache-Control", "omicron")
442 req.Header.Add("return-path", "hobbiton")
444 failures := InterceptGomegaFailures(func() {
445 http.DefaultClient.Do(req)
447 Ω(failures).Should(HaveLen(1))
451 Describe("VerifyHeaderKV", func() {
453 s.AppendHandlers(CombineHandlers(
454 VerifyRequest("GET", "/foo"),
455 VerifyHeaderKV("accept", "jpeg", "png"),
456 VerifyHeaderKV("cache-control", "omicron"),
457 VerifyHeaderKV("Return-Path", "hobbiton"),
461 It("should verify the headers", func() {
462 req, err := http.NewRequest("GET", s.URL()+"/foo", nil)
463 Ω(err).ShouldNot(HaveOccurred())
464 req.Header.Add("Accept", "jpeg")
465 req.Header.Add("Accept", "png")
466 req.Header.Add("Cache-Control", "omicron")
467 req.Header.Add("return-path", "hobbiton")
469 resp, err = http.DefaultClient.Do(req)
470 Ω(err).ShouldNot(HaveOccurred())
473 It("should verify the headers", func() {
474 req, err := http.NewRequest("GET", s.URL()+"/foo", nil)
475 Ω(err).ShouldNot(HaveOccurred())
476 req.Header.Add("Accept", "jpeg")
477 req.Header.Add("Cache-Control", "omicron")
478 req.Header.Add("return-path", "hobbiton")
480 failures := InterceptGomegaFailures(func() {
481 http.DefaultClient.Do(req)
483 Ω(failures).Should(HaveLen(1))
487 Describe("VerifyBody", func() {
489 s.AppendHandlers(CombineHandlers(
490 VerifyRequest("POST", "/foo"),
491 VerifyBody([]byte("some body")),
495 It("should verify the body", func() {
496 resp, err = http.Post(s.URL()+"/foo", "", bytes.NewReader([]byte("some body")))
497 Ω(err).ShouldNot(HaveOccurred())
500 It("should verify the body", func() {
501 failures := InterceptGomegaFailures(func() {
502 http.Post(s.URL()+"/foo", "", bytes.NewReader([]byte("wrong body")))
504 Ω(failures).Should(HaveLen(1))
508 Describe("VerifyJSON", func() {
510 s.AppendHandlers(CombineHandlers(
511 VerifyRequest("POST", "/foo"),
512 VerifyJSON(`{"a":3, "b":2}`),
516 It("should verify the json body and the content type", func() {
517 resp, err = http.Post(s.URL()+"/foo", "application/json", bytes.NewReader([]byte(`{"b":2, "a":3}`)))
518 Ω(err).ShouldNot(HaveOccurred())
521 It("should verify the json body and the content type", func() {
522 failures := InterceptGomegaFailures(func() {
523 http.Post(s.URL()+"/foo", "application/json", bytes.NewReader([]byte(`{"b":2, "a":4}`)))
525 Ω(failures).Should(HaveLen(1))
528 It("should verify the json body and the content type", func() {
529 failures := InterceptGomegaFailures(func() {
530 http.Post(s.URL()+"/foo", "application/not-json", bytes.NewReader([]byte(`{"b":2, "a":3}`)))
532 Ω(failures).Should(HaveLen(1))
536 Describe("VerifyJSONRepresenting", func() {
538 s.AppendHandlers(CombineHandlers(
539 VerifyRequest("POST", "/foo"),
540 VerifyJSONRepresenting([]int{1, 3, 5}),
544 It("should verify the json body and the content type", func() {
545 resp, err = http.Post(s.URL()+"/foo", "application/json", bytes.NewReader([]byte(`[1,3,5]`)))
546 Ω(err).ShouldNot(HaveOccurred())
549 It("should verify the json body and the content type", func() {
550 failures := InterceptGomegaFailures(func() {
551 http.Post(s.URL()+"/foo", "application/json", bytes.NewReader([]byte(`[1,3]`)))
553 Ω(failures).Should(HaveLen(1))
557 Describe("VerifyForm", func() {
558 var formValues url.Values
561 formValues = make(url.Values)
562 formValues.Add("users", "user1")
563 formValues.Add("users", "user2")
564 formValues.Add("group", "users")
567 Context("when encoded in the URL", func() {
569 s.AppendHandlers(CombineHandlers(
570 VerifyRequest("GET", "/foo"),
571 VerifyForm(url.Values{
572 "users": []string{"user1", "user2"},
573 "group": []string{"users"},
578 It("should verify form values", func() {
579 resp, err = http.Get(s.URL() + "/foo?" + formValues.Encode())
580 Ω(err).ShouldNot(HaveOccurred())
583 It("should ignore extra values", func() {
584 formValues.Add("extra", "value")
585 resp, err = http.Get(s.URL() + "/foo?" + formValues.Encode())
586 Ω(err).ShouldNot(HaveOccurred())
589 It("fail on missing values", func() {
590 formValues.Del("group")
591 failures := InterceptGomegaFailures(func() {
592 resp, err = http.Get(s.URL() + "/foo?" + formValues.Encode())
594 Ω(failures).Should(HaveLen(1))
597 It("fail on incorrect values", func() {
598 formValues.Set("group", "wheel")
599 failures := InterceptGomegaFailures(func() {
600 resp, err = http.Get(s.URL() + "/foo?" + formValues.Encode())
602 Ω(failures).Should(HaveLen(1))
606 Context("when present in the body", func() {
608 s.AppendHandlers(CombineHandlers(
609 VerifyRequest("POST", "/foo"),
610 VerifyForm(url.Values{
611 "users": []string{"user1", "user2"},
612 "group": []string{"users"},
617 It("should verify form values", func() {
618 resp, err = http.PostForm(s.URL()+"/foo", formValues)
619 Ω(err).ShouldNot(HaveOccurred())
622 It("should ignore extra values", func() {
623 formValues.Add("extra", "value")
624 resp, err = http.PostForm(s.URL()+"/foo", formValues)
625 Ω(err).ShouldNot(HaveOccurred())
628 It("fail on missing values", func() {
629 formValues.Del("group")
630 failures := InterceptGomegaFailures(func() {
631 resp, err = http.PostForm(s.URL()+"/foo", formValues)
633 Ω(failures).Should(HaveLen(1))
636 It("fail on incorrect values", func() {
637 formValues.Set("group", "wheel")
638 failures := InterceptGomegaFailures(func() {
639 resp, err = http.PostForm(s.URL()+"/foo", formValues)
641 Ω(failures).Should(HaveLen(1))
646 Describe("VerifyFormKV", func() {
647 Context("when encoded in the URL", func() {
649 s.AppendHandlers(CombineHandlers(
650 VerifyRequest("GET", "/foo"),
651 VerifyFormKV("users", "user1", "user2"),
655 It("verifies the form value", func() {
656 resp, err = http.Get(s.URL() + "/foo?users=user1&users=user2")
657 Ω(err).ShouldNot(HaveOccurred())
660 It("verifies the form value", func() {
661 failures := InterceptGomegaFailures(func() {
662 resp, err = http.Get(s.URL() + "/foo?users=user1")
664 Ω(failures).Should(HaveLen(1))
668 Context("when present in the body", func() {
670 s.AppendHandlers(CombineHandlers(
671 VerifyRequest("POST", "/foo"),
672 VerifyFormKV("users", "user1", "user2"),
676 It("verifies the form value", func() {
677 resp, err = http.PostForm(s.URL()+"/foo", url.Values{"users": []string{"user1", "user2"}})
678 Ω(err).ShouldNot(HaveOccurred())
681 It("verifies the form value", func() {
682 failures := InterceptGomegaFailures(func() {
683 resp, err = http.PostForm(s.URL()+"/foo", url.Values{"users": []string{"user1"}})
685 Ω(failures).Should(HaveLen(1))
690 Describe("VerifyProtoRepresenting", func() {
691 var message *protobuf.SimpleMessage
694 message = new(protobuf.SimpleMessage)
695 message.Description = proto.String("A description")
696 message.Id = proto.Int32(0)
698 s.AppendHandlers(CombineHandlers(
699 VerifyRequest("POST", "/proto"),
700 VerifyProtoRepresenting(message),
704 It("verifies the proto body and the content type", func() {
705 serialized, err := proto.Marshal(message)
706 Ω(err).ShouldNot(HaveOccurred())
708 resp, err = http.Post(s.URL()+"/proto", "application/x-protobuf", bytes.NewReader(serialized))
709 Ω(err).ShouldNot(HaveOccurred())
712 It("should verify the proto body and the content type", func() {
713 serialized, err := proto.Marshal(&protobuf.SimpleMessage{
714 Description: proto.String("A description"),
716 Metadata: proto.String("some metadata"),
718 Ω(err).ShouldNot(HaveOccurred())
720 failures := InterceptGomegaFailures(func() {
721 http.Post(s.URL()+"/proto", "application/x-protobuf", bytes.NewReader(serialized))
723 Ω(failures).Should(HaveLen(1))
726 It("should verify the proto body and the content type", func() {
727 serialized, err := proto.Marshal(message)
728 Ω(err).ShouldNot(HaveOccurred())
730 failures := InterceptGomegaFailures(func() {
731 http.Post(s.URL()+"/proto", "application/not-x-protobuf", bytes.NewReader(serialized))
733 Ω(failures).Should(HaveLen(1))
737 Describe("RespondWith", func() {
738 Context("without headers", func() {
740 s.AppendHandlers(CombineHandlers(
741 VerifyRequest("POST", "/foo"),
742 RespondWith(http.StatusCreated, "sweet"),
744 VerifyRequest("POST", "/foo"),
745 RespondWith(http.StatusOK, []byte("sour")),
749 It("should return the response", func() {
750 resp, err = http.Post(s.URL()+"/foo", "application/json", nil)
751 Ω(err).ShouldNot(HaveOccurred())
753 Ω(resp.StatusCode).Should(Equal(http.StatusCreated))
755 body, err := ioutil.ReadAll(resp.Body)
756 Ω(err).ShouldNot(HaveOccurred())
757 Ω(body).Should(Equal([]byte("sweet")))
759 resp, err = http.Post(s.URL()+"/foo", "application/json", nil)
760 Ω(err).ShouldNot(HaveOccurred())
762 Ω(resp.StatusCode).Should(Equal(http.StatusOK))
764 body, err = ioutil.ReadAll(resp.Body)
765 Ω(err).ShouldNot(HaveOccurred())
766 Ω(body).Should(Equal([]byte("sour")))
770 Context("with headers", func() {
772 s.AppendHandlers(CombineHandlers(
773 VerifyRequest("POST", "/foo"),
774 RespondWith(http.StatusCreated, "sweet", http.Header{"X-Custom-Header": []string{"my header"}}),
778 It("should return the headers too", func() {
779 resp, err = http.Post(s.URL()+"/foo", "application/json", nil)
780 Ω(err).ShouldNot(HaveOccurred())
782 Ω(resp.StatusCode).Should(Equal(http.StatusCreated))
783 Ω(ioutil.ReadAll(resp.Body)).Should(Equal([]byte("sweet")))
784 Ω(resp.Header.Get("X-Custom-Header")).Should(Equal("my header"))
789 Describe("RespondWithPtr", func() {
792 var stringBody string
795 byteBody = []byte("sweet")
798 s.AppendHandlers(CombineHandlers(
799 VerifyRequest("POST", "/foo"),
800 RespondWithPtr(&code, &byteBody),
802 VerifyRequest("POST", "/foo"),
803 RespondWithPtr(&code, &stringBody),
807 It("should return the response", func() {
808 code = http.StatusCreated
809 byteBody = []byte("tasty")
812 resp, err = http.Post(s.URL()+"/foo", "application/json", nil)
813 Ω(err).ShouldNot(HaveOccurred())
815 Ω(resp.StatusCode).Should(Equal(http.StatusCreated))
817 body, err := ioutil.ReadAll(resp.Body)
818 Ω(err).ShouldNot(HaveOccurred())
819 Ω(body).Should(Equal([]byte("tasty")))
821 resp, err = http.Post(s.URL()+"/foo", "application/json", nil)
822 Ω(err).ShouldNot(HaveOccurred())
824 Ω(resp.StatusCode).Should(Equal(http.StatusCreated))
826 body, err = ioutil.ReadAll(resp.Body)
827 Ω(err).ShouldNot(HaveOccurred())
828 Ω(body).Should(Equal([]byte("treat")))
831 Context("when passed a nil body", func() {
833 s.SetHandler(0, CombineHandlers(
834 VerifyRequest("POST", "/foo"),
835 RespondWithPtr(&code, nil),
839 It("should return an empty body and not explode", func() {
840 resp, err = http.Post(s.URL()+"/foo", "application/json", nil)
842 Ω(err).ShouldNot(HaveOccurred())
843 Ω(resp.StatusCode).Should(Equal(http.StatusOK))
844 body, err := ioutil.ReadAll(resp.Body)
845 Ω(err).ShouldNot(HaveOccurred())
846 Ω(body).Should(BeEmpty())
848 Ω(s.ReceivedRequests()).Should(HaveLen(1))
853 Describe("RespondWithJSON", func() {
854 Context("when no optional headers are set", func() {
856 s.AppendHandlers(CombineHandlers(
857 VerifyRequest("POST", "/foo"),
858 RespondWithJSONEncoded(http.StatusCreated, []int{1, 2, 3}),
862 It("should return the response", func() {
863 resp, err = http.Post(s.URL()+"/foo", "application/json", nil)
864 Ω(err).ShouldNot(HaveOccurred())
866 Ω(resp.StatusCode).Should(Equal(http.StatusCreated))
868 body, err := ioutil.ReadAll(resp.Body)
869 Ω(err).ShouldNot(HaveOccurred())
870 Ω(body).Should(MatchJSON("[1,2,3]"))
873 It("should set the Content-Type header to application/json", func() {
874 resp, err = http.Post(s.URL()+"/foo", "application/json", nil)
875 Ω(err).ShouldNot(HaveOccurred())
877 Ω(resp.Header["Content-Type"]).Should(Equal([]string{"application/json"}))
881 Context("when optional headers are set", func() {
882 var headers http.Header
884 headers = http.Header{"Stuff": []string{"things"}}
887 JustBeforeEach(func() {
888 s.AppendHandlers(CombineHandlers(
889 VerifyRequest("POST", "/foo"),
890 RespondWithJSONEncoded(http.StatusCreated, []int{1, 2, 3}, headers),
894 It("should preserve those headers", func() {
895 resp, err = http.Post(s.URL()+"/foo", "application/json", nil)
896 Ω(err).ShouldNot(HaveOccurred())
898 Ω(resp.Header["Stuff"]).Should(Equal([]string{"things"}))
901 It("should set the Content-Type header to application/json", func() {
902 resp, err = http.Post(s.URL()+"/foo", "application/json", nil)
903 Ω(err).ShouldNot(HaveOccurred())
905 Ω(resp.Header["Content-Type"]).Should(Equal([]string{"application/json"}))
908 Context("when setting the Content-Type explicitly", func() {
910 headers["Content-Type"] = []string{"not-json"}
913 It("should use the Content-Type header that was explicitly set", func() {
914 resp, err = http.Post(s.URL()+"/foo", "application/json", nil)
915 Ω(err).ShouldNot(HaveOccurred())
917 Ω(resp.Header["Content-Type"]).Should(Equal([]string{"not-json"}))
923 Describe("RespondWithJSONPtr", func() {
924 type testObject struct {
930 var object testObject
932 Context("when no optional headers are set", func() {
935 object = testObject{}
936 s.AppendHandlers(CombineHandlers(
937 VerifyRequest("POST", "/foo"),
938 RespondWithJSONEncodedPtr(&code, &object),
942 It("should return the response", func() {
943 code = http.StatusCreated
948 resp, err = http.Post(s.URL()+"/foo", "application/json", nil)
949 Ω(err).ShouldNot(HaveOccurred())
951 Ω(resp.StatusCode).Should(Equal(http.StatusCreated))
953 body, err := ioutil.ReadAll(resp.Body)
954 Ω(err).ShouldNot(HaveOccurred())
955 Ω(body).Should(MatchJSON(`{"Key": "Jim", "Value": "Codes"}`))
958 It("should set the Content-Type header to application/json", func() {
959 resp, err = http.Post(s.URL()+"/foo", "application/json", nil)
960 Ω(err).ShouldNot(HaveOccurred())
962 Ω(resp.Header["Content-Type"]).Should(Equal([]string{"application/json"}))
966 Context("when optional headers are set", func() {
967 var headers http.Header
969 headers = http.Header{"Stuff": []string{"things"}}
972 JustBeforeEach(func() {
974 object = testObject{}
975 s.AppendHandlers(CombineHandlers(
976 VerifyRequest("POST", "/foo"),
977 RespondWithJSONEncodedPtr(&code, &object, headers),
981 It("should preserve those headers", func() {
982 resp, err = http.Post(s.URL()+"/foo", "application/json", nil)
983 Ω(err).ShouldNot(HaveOccurred())
985 Ω(resp.Header["Stuff"]).Should(Equal([]string{"things"}))
988 It("should set the Content-Type header to application/json", func() {
989 resp, err = http.Post(s.URL()+"/foo", "application/json", nil)
990 Ω(err).ShouldNot(HaveOccurred())
992 Ω(resp.Header["Content-Type"]).Should(Equal([]string{"application/json"}))
995 Context("when setting the Content-Type explicitly", func() {
997 headers["Content-Type"] = []string{"not-json"}
1000 It("should use the Content-Type header that was explicitly set", func() {
1001 resp, err = http.Post(s.URL()+"/foo", "application/json", nil)
1002 Ω(err).ShouldNot(HaveOccurred())
1004 Ω(resp.Header["Content-Type"]).Should(Equal([]string{"not-json"}))
1010 Describe("RespondWithProto", func() {
1011 var message *protobuf.SimpleMessage
1014 message = new(protobuf.SimpleMessage)
1015 message.Description = proto.String("A description")
1016 message.Id = proto.Int32(99)
1019 Context("when no optional headers are set", func() {
1021 s.AppendHandlers(CombineHandlers(
1022 VerifyRequest("POST", "/proto"),
1023 RespondWithProto(http.StatusCreated, message),
1027 It("should return the response", func() {
1028 resp, err = http.Post(s.URL()+"/proto", "application/x-protobuf", nil)
1029 Ω(err).ShouldNot(HaveOccurred())
1031 Ω(resp.StatusCode).Should(Equal(http.StatusCreated))
1033 var received protobuf.SimpleMessage
1034 body, err := ioutil.ReadAll(resp.Body)
1035 err = proto.Unmarshal(body, &received)
1036 Ω(err).ShouldNot(HaveOccurred())
1039 It("should set the Content-Type header to application/x-protobuf", func() {
1040 resp, err = http.Post(s.URL()+"/proto", "application/x-protobuf", nil)
1041 Ω(err).ShouldNot(HaveOccurred())
1043 Ω(resp.Header["Content-Type"]).Should(Equal([]string{"application/x-protobuf"}))
1047 Context("when optional headers are set", func() {
1048 var headers http.Header
1050 headers = http.Header{"Stuff": []string{"things"}}
1053 JustBeforeEach(func() {
1054 s.AppendHandlers(CombineHandlers(
1055 VerifyRequest("POST", "/proto"),
1056 RespondWithProto(http.StatusCreated, message, headers),
1060 It("should preserve those headers", func() {
1061 resp, err = http.Post(s.URL()+"/proto", "application/x-protobuf", nil)
1062 Ω(err).ShouldNot(HaveOccurred())
1064 Ω(resp.Header["Stuff"]).Should(Equal([]string{"things"}))
1067 It("should set the Content-Type header to application/x-protobuf", func() {
1068 resp, err = http.Post(s.URL()+"/proto", "application/x-protobuf", nil)
1069 Ω(err).ShouldNot(HaveOccurred())
1071 Ω(resp.Header["Content-Type"]).Should(Equal([]string{"application/x-protobuf"}))
1074 Context("when setting the Content-Type explicitly", func() {
1076 headers["Content-Type"] = []string{"not-x-protobuf"}
1079 It("should use the Content-Type header that was explicitly set", func() {
1080 resp, err = http.Post(s.URL()+"/proto", "application/x-protobuf", nil)
1081 Ω(err).ShouldNot(HaveOccurred())
1083 Ω(resp.Header["Content-Type"]).Should(Equal([]string{"not-x-protobuf"}))