network/pkg/httputil/errors_test.go
2026-01-20 10:03:55 +02:00

183 lines
4.2 KiB
Go

package httputil
import (
"net/http"
"net/http/httptest"
"testing"
)
func TestHTTPError(t *testing.T) {
err := NewHTTPError(http.StatusBadRequest, "invalid input")
expected := "HTTP 400: invalid input"
if err.Error() != expected {
t.Errorf("HTTPError.Error() = %v, want %v", err.Error(), expected)
}
}
func TestCheckMethod(t *testing.T) {
tests := []struct {
name string
method string
expected string
wantResult bool
wantStatus int
}{
{
name: "matching method",
method: http.MethodPost,
expected: http.MethodPost,
wantResult: true,
wantStatus: 0, // No error written
},
{
name: "non-matching method",
method: http.MethodGet,
expected: http.MethodPost,
wantResult: false,
wantStatus: http.StatusMethodNotAllowed,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
req := httptest.NewRequest(tt.method, "/", nil)
w := httptest.NewRecorder()
result := CheckMethod(w, req, tt.expected)
if result != tt.wantResult {
t.Errorf("CheckMethod() = %v, want %v", result, tt.wantResult)
}
if tt.wantStatus > 0 && w.Code != tt.wantStatus {
t.Errorf("CheckMethod() status = %v, want %v", w.Code, tt.wantStatus)
}
})
}
}
func TestCheckMethodOneOf(t *testing.T) {
tests := []struct {
name string
method string
allowed []string
wantResult bool
wantStatus int
}{
{
name: "method in list",
method: http.MethodPost,
allowed: []string{http.MethodGet, http.MethodPost},
wantResult: true,
wantStatus: 0,
},
{
name: "method not in list",
method: http.MethodDelete,
allowed: []string{http.MethodGet, http.MethodPost},
wantResult: false,
wantStatus: http.StatusMethodNotAllowed,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
req := httptest.NewRequest(tt.method, "/", nil)
w := httptest.NewRecorder()
result := CheckMethodOneOf(w, req, tt.allowed...)
if result != tt.wantResult {
t.Errorf("CheckMethodOneOf() = %v, want %v", result, tt.wantResult)
}
if tt.wantStatus > 0 && w.Code != tt.wantStatus {
t.Errorf("CheckMethodOneOf() status = %v, want %v", w.Code, tt.wantStatus)
}
})
}
}
func TestRequireNotEmpty(t *testing.T) {
tests := []struct {
name string
value string
fieldName string
wantResult bool
wantStatus int
}{
{
name: "non-empty value",
value: "test",
fieldName: "username",
wantResult: true,
wantStatus: 0,
},
{
name: "empty value",
value: "",
fieldName: "username",
wantResult: false,
wantStatus: http.StatusBadRequest,
},
{
name: "whitespace only",
value: " ",
fieldName: "username",
wantResult: false,
wantStatus: http.StatusBadRequest,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
w := httptest.NewRecorder()
result := RequireNotEmpty(w, tt.value, tt.fieldName)
if result != tt.wantResult {
t.Errorf("RequireNotEmpty() = %v, want %v", result, tt.wantResult)
}
if tt.wantStatus > 0 && w.Code != tt.wantStatus {
t.Errorf("RequireNotEmpty() status = %v, want %v", w.Code, tt.wantStatus)
}
})
}
}
func TestCommonErrors(t *testing.T) {
tests := []struct {
name string
err *HTTPError
code int
}{
{"BadRequest", ErrBadRequest, http.StatusBadRequest},
{"Unauthorized", ErrUnauthorized, http.StatusUnauthorized},
{"Forbidden", ErrForbidden, http.StatusForbidden},
{"NotFound", ErrNotFound, http.StatusNotFound},
{"MethodNotAllowed", ErrMethodNotAllowed, http.StatusMethodNotAllowed},
{"Conflict", ErrConflict, http.StatusConflict},
{"InternalServerError", ErrInternalServerError, http.StatusInternalServerError},
{"ServiceUnavailable", ErrServiceUnavailable, http.StatusServiceUnavailable},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if tt.err.Code != tt.code {
t.Errorf("%s.Code = %v, want %v", tt.name, tt.err.Code, tt.code)
}
})
}
}
func TestWriteHTTPError(t *testing.T) {
w := httptest.NewRecorder()
err := NewHTTPError(http.StatusNotFound, "resource not found")
WriteHTTPError(w, err)
if w.Code != http.StatusNotFound {
t.Errorf("WriteHTTPError() status = %v, want %v", w.Code, http.StatusNotFound)
}
}