Skip to content

Commit

Permalink
Add WithHeader enhancement to the Serve matcher to check for a return…
Browse files Browse the repository at this point in the history
…ed header
  • Loading branch information
joshuatcasey authored and ryanmoran committed Sep 19, 2022
1 parent b6f0805 commit 0c9b3dd
Show file tree
Hide file tree
Showing 2 changed files with 100 additions and 0 deletions.
34 changes: 34 additions & 0 deletions matchers/serve.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ import (
"io"
"net/http"
"reflect"
"sort"
"strconv"
"strings"

"github.com/onsi/gomega/types"
"github.com/paketo-buildpacks/occam"
Expand All @@ -32,6 +34,18 @@ type ServeMatcher struct {
client *http.Client
}

type Header struct {
key string
value string
}

func WithHeader(key, value string) Header {
return Header{
key: key,
value: value,
}
}

// OnPort sets the container port that is expected to be exposed.
func (sm *ServeMatcher) OnPort(port int) *ServeMatcher {
sm.port = port
Expand Down Expand Up @@ -96,6 +110,12 @@ func (sm *ServeMatcher) Match(actual interface{}) (success bool, err error) {
}

if response != nil {
if header, ok := sm.expected.(Header); ok {
formatHeaders(sm, response)
sm.expected = fmt.Sprintf("Header '%s=%s'", header.key, header.value)
return response.Header.Get(header.key) == header.value, nil
}

defer response.Body.Close()
content, err := io.ReadAll(response.Body)
if err != nil {
Expand All @@ -116,6 +136,20 @@ func (sm *ServeMatcher) Match(actual interface{}) (success bool, err error) {
return false, nil
}

func formatHeaders(sm *ServeMatcher, response *http.Response) {
var keys []string
for key := range response.Header {
keys = append(keys, key)
}
sort.Strings(keys)

sm.response = ""
for _, key := range keys {
sm.response += fmt.Sprintf("Header '%s=%s'\n\t", key, strings.Join(response.Header.Values(key), ", "))
}
sm.response = strings.TrimSpace(sm.response)
}

func (sm *ServeMatcher) compare(actual string, expected interface{}) (bool, error) {
if m, ok := expected.(types.GomegaMatcher); ok {
match, err := m.Match(actual)
Expand Down
66 changes: 66 additions & 0 deletions matchers/serve_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ func testServe(t *testing.T, context spec.G, it spec.S) {
return
}

w.Header().Set("Date", "Sat, 17 Sep 2022 03:28:54 GMT")

switch req.URL.Path {
case "/":
w.WriteHeader(http.StatusOK)
Expand Down Expand Up @@ -240,6 +242,30 @@ func testServe(t *testing.T, context spec.G, it spec.S) {
})
})
})

context("WithHeader", func() {
it("returns true with the header is found", func() {
matcher = matchers.Serve(matchers.WithHeader("Content-Type", "text/plain; charset=utf-8"))

result, err := matcher.Match(occam.Container{
Ports: map[string]string{"8080": port},
Env: map[string]string{"PORT": "8080"},
})
Expect(err).NotTo(HaveOccurred())
Expect(result).To(BeTrue())
})

it("returns false with the header is not found", func() {
matcher = matchers.Serve(matchers.WithHeader("Content-Type", "other"))

result, err := matcher.Match(occam.Container{
Ports: map[string]string{"8080": port},
Env: map[string]string{"PORT": "8080"},
})
Expect(err).NotTo(HaveOccurred())
Expect(result).To(BeFalse())
})
})
})

context("when the matcher fails", func() {
Expand Down Expand Up @@ -284,6 +310,26 @@ Container logs:
some logs
`)))
})

it("returns a useful error message for WithHeader", func() {
matcher = matchers.Serve(matchers.WithHeader("Content-Type", "other"))
_, _ = matcher.Match(occam.Container{
Ports: map[string]string{"8080": port},
Env: map[string]string{"PORT": "8080"},
})

message := matcher.FailureMessage(actual)
Expect(message).To(ContainSubstring(strings.TrimSpace(`
Expected the response from docker container some-container-id:
Header 'Content-Length=11'
Header 'Content-Type=text/plain; charset=utf-8'
Header 'Date=Sat, 17 Sep 2022 03:28:54 GMT'
to contain:
Header 'Content-Type=other'`)))
})
})

context("NegatedFailureMessage", func() {
Expand All @@ -304,5 +350,25 @@ some logs
`)))
})
})

it("returns a useful error message for WithHeader", func() {
matcher = matchers.Serve(matchers.WithHeader("Content-Type", "other"))
_, _ = matcher.Match(occam.Container{
Ports: map[string]string{"8080": port},
Env: map[string]string{"PORT": "8080"},
})

message := matcher.NegatedFailureMessage(actual)
Expect(message).To(ContainSubstring(strings.TrimSpace(`
Expected the response from docker container some-container-id:
Header 'Content-Length=11'
Header 'Content-Type=text/plain; charset=utf-8'
Header 'Date=Sat, 17 Sep 2022 03:28:54 GMT'
not to contain:
Header 'Content-Type=other'`)))
})
})
}

0 comments on commit 0c9b3dd

Please sign in to comment.