lolly/internal/utils/utils_test.go

208 lines
5.6 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// Package utils 提供工具函数的测试。
//
// 该文件测试工具模块的各项功能,包括:
// - HTTPError 结构体和预定义错误
// - SendError 函数
// - SendErrorWithDetail 函数
// - 内部重定向相关函数
//
// 作者xfy
package utils
import (
"testing"
"github.com/valyala/fasthttp"
)
// TestHTTPErrorPredefined 测试预定义的 HTTP 错误
func TestHTTPErrorPredefined(t *testing.T) {
tests := []struct {
name string
err HTTPError
wantMsg string
wantStatus int
}{
{"NotFound", ErrNotFound, "Not Found", fasthttp.StatusNotFound},
{"Forbidden", ErrForbidden, "Forbidden", fasthttp.StatusForbidden},
{"Unauthorized", ErrUnauthorized, "Unauthorized", fasthttp.StatusUnauthorized},
{"BadGateway", ErrBadGateway, "Bad Gateway", fasthttp.StatusBadGateway},
{"GatewayTimeout", ErrGatewayTimeout, "Gateway Timeout", fasthttp.StatusGatewayTimeout},
{"InternalError", ErrInternalError, "Internal Server Error", fasthttp.StatusInternalServerError},
{"TooManyRequests", ErrTooManyRequests, "Too Many Requests", fasthttp.StatusTooManyRequests},
{"ServiceUnavailable", ErrServiceUnavailable, "Service Unavailable", fasthttp.StatusServiceUnavailable},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if tt.err.Message != tt.wantMsg {
t.Errorf("message = %q, want %q", tt.err.Message, tt.wantMsg)
}
if tt.err.StatusCode != tt.wantStatus {
t.Errorf("status = %d, want %d", tt.err.StatusCode, tt.wantStatus)
}
})
}
}
// TestSendError 测试 SendError 函数
func TestSendError(t *testing.T) {
tests := []struct {
name string
err HTTPError
wantBody string
wantStatus int
}{
{
name: "not_found",
err: ErrNotFound,
wantBody: "Not Found",
wantStatus: fasthttp.StatusNotFound,
},
{
name: "internal_error",
err: ErrInternalError,
wantBody: "Internal Server Error",
wantStatus: fasthttp.StatusInternalServerError,
},
{
name: "custom_error",
err: HTTPError{Message: "Custom Error", StatusCode: 418},
wantBody: "Custom Error",
wantStatus: 418,
},
{
name: "empty_message",
err: HTTPError{Message: "", StatusCode: 200},
wantBody: "",
wantStatus: 200,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
ctx := &fasthttp.RequestCtx{}
ctx.Request.SetRequestURI("/test")
SendError(ctx, tt.err)
if ctx.Response.StatusCode() != tt.wantStatus {
t.Errorf("status = %d, want %d", ctx.Response.StatusCode(), tt.wantStatus)
}
if body := string(ctx.Response.Body()); body != tt.wantBody {
t.Errorf("body = %q, want %q", body, tt.wantBody)
}
})
}
}
// TestSendErrorWithDetail 测试 SendErrorWithDetail 函数
func TestSendErrorWithDetail(t *testing.T) {
tests := []struct {
name string
err HTTPError
detail string
wantBody string
wantStatus int
}{
{
name: "with_detail",
err: ErrNotFound,
detail: "resource missing",
wantBody: "Not Found: resource missing",
wantStatus: fasthttp.StatusNotFound,
},
{
name: "empty_detail",
err: ErrForbidden,
detail: "",
wantBody: "Forbidden",
wantStatus: fasthttp.StatusForbidden,
},
{
name: "detail_with_special_chars",
err: ErrBadGateway,
detail: "upstream: http://backend:8080 (connection refused)",
wantBody: "Bad Gateway: upstream: http://backend:8080 (connection refused)",
wantStatus: fasthttp.StatusBadGateway,
},
{
name: "detail_with_chinese",
err: ErrForbidden,
detail: "权限不足",
wantBody: "Forbidden: 权限不足",
wantStatus: fasthttp.StatusForbidden,
},
{
name: "custom_error_with_detail",
err: HTTPError{Message: "Custom", StatusCode: 418},
detail: "I'm a teapot",
wantBody: "Custom: I'm a teapot",
wantStatus: 418,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
ctx := &fasthttp.RequestCtx{}
ctx.Request.SetRequestURI("/test")
SendErrorWithDetail(ctx, tt.err, tt.detail)
if ctx.Response.StatusCode() != tt.wantStatus {
t.Errorf("status = %d, want %d", ctx.Response.StatusCode(), tt.wantStatus)
}
if body := string(ctx.Response.Body()); body != tt.wantBody {
t.Errorf("body = %q, want %q", body, tt.wantBody)
}
})
}
}
// TestInternalRedirectKey 测试内部重定向常量
func TestInternalRedirectKey(t *testing.T) {
if InternalRedirectKey != "__internal_redirect__" {
t.Errorf("InternalRedirectKey = %q, want %q", InternalRedirectKey, "__internal_redirect__")
}
}
// TestHTTPError_CustomErrors 测试自定义 HTTPError
func TestHTTPError_CustomErrors(t *testing.T) {
tests := []struct {
name string
err HTTPError
wantMsg string
wantStatus int
}{
{
name: "teapot",
err: HTTPError{Message: "I'm a teapot", StatusCode: 418},
wantMsg: "I'm a teapot",
wantStatus: 418,
},
{
name: "rate_limit",
err: HTTPError{Message: "Rate limit exceeded", StatusCode: 429},
wantMsg: "Rate limit exceeded",
wantStatus: 429,
},
{
name: "empty_message",
err: HTTPError{Message: "", StatusCode: 500},
wantMsg: "",
wantStatus: 500,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if tt.err.Message != tt.wantMsg {
t.Errorf("Message = %q, want %q", tt.err.Message, tt.wantMsg)
}
if tt.err.StatusCode != tt.wantStatus {
t.Errorf("StatusCode = %d, want %d", tt.err.StatusCode, tt.wantStatus)
}
})
}
}