diff --git a/checks/http.go b/checks/http.go index 72e2b7d..c994292 100644 --- a/checks/http.go +++ b/checks/http.go @@ -157,15 +157,25 @@ func prettyPrintHTTPTest(test api.HTTPRequestTest, variables map[string]string) interpolated := InterpolateVariables(*test.BodyContainsNone, variables) return fmt.Sprintf("Expecting response body to not contain: %s", interpolated) } + if test.HeadersEqual != nil { + interpolatedKey := InterpolateVariables(test.HeadersEqual.Key, variables) + interpolatedValue := InterpolateVariables(test.HeadersEqual.Value, variables) + return fmt.Sprintf("Expecting header to equal: '%s: %v'", interpolatedKey, interpolatedValue) + } if test.HeadersContain != nil { interpolatedKey := InterpolateVariables(test.HeadersContain.Key, variables) interpolatedValue := InterpolateVariables(test.HeadersContain.Value, variables) - return fmt.Sprintf("Expecting headers to contain: '%s: %v'", interpolatedKey, interpolatedValue) + return fmt.Sprintf("Expecting header to contain: '%s: %v'", interpolatedKey, interpolatedValue) + } + if test.TrailersEqual != nil { + interpolatedKey := InterpolateVariables(test.TrailersEqual.Key, variables) + interpolatedValue := InterpolateVariables(test.TrailersEqual.Value, variables) + return fmt.Sprintf("Expecting trailer to equal: '%s: %v'", interpolatedKey, interpolatedValue) } if test.TrailersContain != nil { interpolatedKey := InterpolateVariables(test.TrailersContain.Key, variables) interpolatedValue := InterpolateVariables(test.TrailersContain.Value, variables) - return fmt.Sprintf("Expecting trailers to contain: '%s: %v'", interpolatedKey, interpolatedValue) + return fmt.Sprintf("Expecting trailer to contain: '%s: %v'", interpolatedKey, interpolatedValue) } if test.JSONValue != nil { var val any diff --git a/checks/local.go b/checks/local.go index 9c5f227..48606ce 100644 --- a/checks/local.go +++ b/checks/local.go @@ -131,8 +131,12 @@ func evaluateHTTPRequestTests(stepIndex int, req api.CLIStepHTTPRequest, result if strings.Contains(result.BodyString, needle) { err = fmt.Errorf("expected response body to not contain %q", needle) } + case test.HeadersEqual != nil: + err = evaluateHeaderEquals(result.ResponseHeaders, *test.HeadersEqual, result.Variables, "header") case test.HeadersContain != nil: err = evaluateHeaderContains(result.ResponseHeaders, *test.HeadersContain, result.Variables, "header") + case test.TrailersEqual != nil: + err = evaluateHeaderEquals(result.ResponseTrailers, *test.TrailersEqual, result.Variables, "trailer") case test.TrailersContain != nil: err = evaluateHeaderContains(result.ResponseTrailers, *test.TrailersContain, result.Variables, "trailer") case test.JSONValue != nil: @@ -185,6 +189,21 @@ func evaluateHTTPRequestTests(stepIndex int, req api.CLIStepHTTPRequest, result return nil } +func evaluateHeaderEquals(headers map[string]string, test api.HTTPRequestTestHeader, variables map[string]string, label string) error { + key := InterpolateVariables(test.Key, variables) + want := InterpolateVariables(test.Value, variables) + + got, ok := findHeaderValue(headers, key) + if !ok { + return fmt.Errorf("expected %s %q to exist", label, key) + } + if !strings.EqualFold(got, want) { + return fmt.Errorf("expected %s %q to equal %q, got %q", label, key, want, got) + } + + return nil +} + func evaluateHeaderContains(headers map[string]string, test api.HTTPRequestTestHeader, variables map[string]string, label string) error { key := InterpolateVariables(test.Key, variables) want := InterpolateVariables(test.Value, variables) @@ -193,7 +212,7 @@ func evaluateHeaderContains(headers map[string]string, test api.HTTPRequestTestH if !ok { return fmt.Errorf("expected %s %q to exist", label, key) } - if !strings.Contains(got, want) { + if !strings.Contains(strings.ToLower(got), strings.ToLower(want)) { return fmt.Errorf("expected %s %q to contain %q, got %q", label, key, want, got) } diff --git a/checks/local_test.go b/checks/local_test.go index a679905..a377a7e 100644 --- a/checks/local_test.go +++ b/checks/local_test.go @@ -14,6 +14,7 @@ func TestLocalSubmissionEventPassesCLIAndHTTPResults(t *testing.T) { }}}, {HTTPRequest: &api.CLIStepHTTPRequest{Tests: []api.HTTPRequestTest{ {StatusCode: intPtr(200)}, + {HeadersEqual: &api.HTTPRequestTestHeader{Key: "Set-Cookie", Value: "session_id=abc123; Path=/"}}, {HeadersContain: &api.HTTPRequestTestHeader{Key: "Set-Cookie", Value: "session_id="}}, {JSONValue: &api.HTTPRequestTestJSONValue{ Path: ".app", diff --git a/client/lessons.go b/client/lessons.go index dedb834..c51ece0 100644 --- a/client/lessons.go +++ b/client/lessons.go @@ -125,7 +125,9 @@ type HTTPRequestTest struct { StatusCode *int `yaml:"statusCode"` BodyContains *string `yaml:"bodyContains"` BodyContainsNone *string `yaml:"bodyContainsNone"` + HeadersEqual *HTTPRequestTestHeader `yaml:"headersEqual"` HeadersContain *HTTPRequestTestHeader `yaml:"headersContain"` + TrailersEqual *HTTPRequestTestHeader `yaml:"trailersEqual"` TrailersContain *HTTPRequestTestHeader `yaml:"trailersContain"` JSONValue *HTTPRequestTestJSONValue `yaml:"jsonValue"` } diff --git a/render/http.go b/render/http.go index 45eec68..925b835 100644 --- a/render/http.go +++ b/render/http.go @@ -21,10 +21,14 @@ func printHTTPRequestResult(result api.HTTPRequestResult) string { filteredHeaders := make(map[string]string) for respK, respV := range result.ResponseHeaders { for _, test := range result.Request.Tests { - if test.HeadersContain == nil { + testHeader := test.HeadersEqual + if testHeader == nil { + testHeader = test.HeadersContain + } + if testHeader == nil { continue } - interpolatedTestHeaderKey := checks.InterpolateVariables(test.HeadersContain.Key, result.Variables) + interpolatedTestHeaderKey := checks.InterpolateVariables(testHeader.Key, result.Variables) if strings.EqualFold(respK, interpolatedTestHeaderKey) { filteredHeaders[respK] = respV } @@ -34,11 +38,15 @@ func printHTTPRequestResult(result api.HTTPRequestResult) string { filteredTrailers := make(map[string]string) for respK, respV := range result.ResponseTrailers { for _, test := range result.Request.Tests { - if test.TrailersContain == nil { + testTrailer := test.TrailersEqual + if testTrailer == nil { + testTrailer = test.TrailersContain + } + if testTrailer == nil { continue } - interpolatedTestTrailerKey := checks.InterpolateVariables(test.TrailersContain.Key, result.Variables) + interpolatedTestTrailerKey := checks.InterpolateVariables(testTrailer.Key, result.Variables) if strings.EqualFold(respK, interpolatedTestTrailerKey) { filteredTrailers[respK] = respV } diff --git a/render/variables.go b/render/variables.go index fedf01a..034651e 100644 --- a/render/variables.go +++ b/render/variables.go @@ -131,10 +131,18 @@ func availableVariablesForHTTPResult(result api.HTTPRequestResult) (entries []va if test.BodyContainsNone != nil { addInterpolationNames(*test.BodyContainsNone, "Body Excludes Test") } + if test.HeadersEqual != nil { + addInterpolationNames(test.HeadersEqual.Key, "Header Test Key") + addInterpolationNames(test.HeadersEqual.Value, "Header Test Value") + } if test.HeadersContain != nil { addInterpolationNames(test.HeadersContain.Key, "Header Test Key") addInterpolationNames(test.HeadersContain.Value, "Header Test Value") } + if test.TrailersEqual != nil { + addInterpolationNames(test.TrailersEqual.Key, "Trailer Test Key") + addInterpolationNames(test.TrailersEqual.Value, "Trailer Test Value") + } if test.TrailersContain != nil { addInterpolationNames(test.TrailersContain.Key, "Trailer Test Key") addInterpolationNames(test.TrailersContain.Value, "Trailer Test Value") diff --git a/version.txt b/version.txt index 085dad9..6d101d3 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -v1.31.1 +v1.32.0