http_assertions.go 5.4 KB

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