http_assertions.go raw

   1  package assert
   2  
   3  import (
   4  	"fmt"
   5  	"net/http"
   6  	"net/http/httptest"
   7  	"net/url"
   8  	"strings"
   9  )
  10  
  11  // httpCode is a helper that returns HTTP code of the response. It returns -1 and
  12  // an error if building a new request fails.
  13  func httpCode(handler http.HandlerFunc, method, url string, values url.Values) (int, error) {
  14  	w := httptest.NewRecorder()
  15  	req, err := http.NewRequest(method, url, http.NoBody)
  16  	if err != nil {
  17  		return -1, err
  18  	}
  19  	req.URL.RawQuery = values.Encode()
  20  	handler(w, req)
  21  	return w.Code, nil
  22  }
  23  
  24  // HTTPSuccess asserts that a specified handler returns a success status code.
  25  //
  26  //	assert.HTTPSuccess(t, myHandler, "POST", "http://www.google.com", nil)
  27  //
  28  // Returns whether the assertion was successful (true) or not (false).
  29  func HTTPSuccess(t TestingT, handler http.HandlerFunc, method, url string, values url.Values, msgAndArgs ...interface{}) bool {
  30  	if h, ok := t.(tHelper); ok {
  31  		h.Helper()
  32  	}
  33  	code, err := httpCode(handler, method, url, values)
  34  	if err != nil {
  35  		Fail(t, fmt.Sprintf("Failed to build test request, got error: %s", err), msgAndArgs...)
  36  	}
  37  
  38  	isSuccessCode := code >= http.StatusOK && code <= http.StatusPartialContent
  39  	if !isSuccessCode {
  40  		Fail(t, fmt.Sprintf("Expected HTTP success status code for %q but received %d", url+"?"+values.Encode(), code), msgAndArgs...)
  41  	}
  42  
  43  	return isSuccessCode
  44  }
  45  
  46  // HTTPRedirect asserts that a specified handler returns a redirect status code.
  47  //
  48  //	assert.HTTPRedirect(t, myHandler, "GET", "/a/b/c", url.Values{"a": []string{"b", "c"}}
  49  //
  50  // Returns whether the assertion was successful (true) or not (false).
  51  func HTTPRedirect(t TestingT, handler http.HandlerFunc, method, url string, values url.Values, msgAndArgs ...interface{}) bool {
  52  	if h, ok := t.(tHelper); ok {
  53  		h.Helper()
  54  	}
  55  	code, err := httpCode(handler, method, url, values)
  56  	if err != nil {
  57  		Fail(t, fmt.Sprintf("Failed to build test request, got error: %s", err), msgAndArgs...)
  58  	}
  59  
  60  	isRedirectCode := code >= http.StatusMultipleChoices && code <= http.StatusTemporaryRedirect
  61  	if !isRedirectCode {
  62  		Fail(t, fmt.Sprintf("Expected HTTP redirect status code for %q but received %d", url+"?"+values.Encode(), code), msgAndArgs...)
  63  	}
  64  
  65  	return isRedirectCode
  66  }
  67  
  68  // HTTPError asserts that a specified handler returns an error status code.
  69  //
  70  //	assert.HTTPError(t, myHandler, "POST", "/a/b/c", url.Values{"a": []string{"b", "c"}}
  71  //
  72  // Returns whether the assertion was successful (true) or not (false).
  73  func HTTPError(t TestingT, handler http.HandlerFunc, method, url string, values url.Values, msgAndArgs ...interface{}) bool {
  74  	if h, ok := t.(tHelper); ok {
  75  		h.Helper()
  76  	}
  77  	code, err := httpCode(handler, method, url, values)
  78  	if err != nil {
  79  		Fail(t, fmt.Sprintf("Failed to build test request, got error: %s", err), msgAndArgs...)
  80  	}
  81  
  82  	isErrorCode := code >= http.StatusBadRequest
  83  	if !isErrorCode {
  84  		Fail(t, fmt.Sprintf("Expected HTTP error status code for %q but received %d", url+"?"+values.Encode(), code), msgAndArgs...)
  85  	}
  86  
  87  	return isErrorCode
  88  }
  89  
  90  // HTTPStatusCode asserts that a specified handler returns a specified status code.
  91  //
  92  //	assert.HTTPStatusCode(t, myHandler, "GET", "/notImplemented", nil, 501)
  93  //
  94  // Returns whether the assertion was successful (true) or not (false).
  95  func HTTPStatusCode(t TestingT, handler http.HandlerFunc, method, url string, values url.Values, statuscode int, msgAndArgs ...interface{}) bool {
  96  	if h, ok := t.(tHelper); ok {
  97  		h.Helper()
  98  	}
  99  	code, err := httpCode(handler, method, url, values)
 100  	if err != nil {
 101  		Fail(t, fmt.Sprintf("Failed to build test request, got error: %s", err), msgAndArgs...)
 102  	}
 103  
 104  	successful := code == statuscode
 105  	if !successful {
 106  		Fail(t, fmt.Sprintf("Expected HTTP status code %d for %q but received %d", statuscode, url+"?"+values.Encode(), code), msgAndArgs...)
 107  	}
 108  
 109  	return successful
 110  }
 111  
 112  // HTTPBody is a helper that returns HTTP body of the response. It returns
 113  // empty string if building a new request fails.
 114  func HTTPBody(handler http.HandlerFunc, method, url string, values url.Values) string {
 115  	w := httptest.NewRecorder()
 116  	if len(values) > 0 {
 117  		url += "?" + values.Encode()
 118  	}
 119  	req, err := http.NewRequest(method, url, http.NoBody)
 120  	if err != nil {
 121  		return ""
 122  	}
 123  	handler(w, req)
 124  	return w.Body.String()
 125  }
 126  
 127  // HTTPBodyContains asserts that a specified handler returns a
 128  // body that contains a string.
 129  //
 130  //	assert.HTTPBodyContains(t, myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky")
 131  //
 132  // Returns whether the assertion was successful (true) or not (false).
 133  func HTTPBodyContains(t TestingT, handler http.HandlerFunc, method, url string, values url.Values, str interface{}, msgAndArgs ...interface{}) bool {
 134  	if h, ok := t.(tHelper); ok {
 135  		h.Helper()
 136  	}
 137  	body := HTTPBody(handler, method, url, values)
 138  
 139  	contains := strings.Contains(body, fmt.Sprint(str))
 140  	if !contains {
 141  		Fail(t, fmt.Sprintf("Expected response body for %q to contain %q but found %q", url+"?"+values.Encode(), str, body), msgAndArgs...)
 142  	}
 143  
 144  	return contains
 145  }
 146  
 147  // HTTPBodyNotContains asserts that a specified handler returns a
 148  // body that does not contain a string.
 149  //
 150  //	assert.HTTPBodyNotContains(t, myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky")
 151  //
 152  // Returns whether the assertion was successful (true) or not (false).
 153  func HTTPBodyNotContains(t TestingT, handler http.HandlerFunc, method, url string, values url.Values, str interface{}, msgAndArgs ...interface{}) bool {
 154  	if h, ok := t.(tHelper); ok {
 155  		h.Helper()
 156  	}
 157  	body := HTTPBody(handler, method, url, values)
 158  
 159  	contains := strings.Contains(body, fmt.Sprint(str))
 160  	if contains {
 161  		Fail(t, fmt.Sprintf("Expected response body for %q to NOT contain %q but found %q", url+"?"+values.Encode(), str, body), msgAndArgs...)
 162  	}
 163  
 164  	return !contains
 165  }
 166