[🤖] Add Unit-Tests
Build Docker and Deploy / Run goext test-suite (push) Successful in 1m34s

This commit is contained in:
2026-04-27 10:46:08 +02:00
parent dad0e3240d
commit 02d6894ec6
116 changed files with 18795 additions and 1 deletions
+320
View File
@@ -0,0 +1,320 @@
package ginext
import (
"bytes"
"net/http"
"net/http/httptest"
"testing"
"github.com/gin-gonic/gin"
)
func init() {
gin.SetMode(gin.TestMode)
}
func newTestCtx() (*gin.Context, *httptest.ResponseRecorder) {
rec := httptest.NewRecorder()
c, _ := gin.CreateTestContext(rec)
c.Request = httptest.NewRequest(http.MethodGet, "/", nil)
return c, rec
}
func TestJSONResponse_Basics(t *testing.T) {
r := JSON(http.StatusOK, map[string]any{"a": 1})
if !r.IsSuccess() {
t.Fatalf("expected IsSuccess true for 200")
}
ir, ok := r.(InspectableHTTPResponse)
if !ok {
t.Fatalf("expected InspectableHTTPResponse")
}
if ir.Statuscode() != http.StatusOK {
t.Fatalf("statuscode mismatch: %d", ir.Statuscode())
}
if ir.ContentType() != "application/json" {
t.Fatalf("expected content-type application/json, got %q", ir.ContentType())
}
}
func TestJSONResponse_Write(t *testing.T) {
c, rec := newTestCtx()
r := JSON(http.StatusCreated, map[string]any{"hello": "world"})
r.Write(c)
if rec.Code != http.StatusCreated {
t.Fatalf("expected 201, got %d", rec.Code)
}
if !bytes.Contains(rec.Body.Bytes(), []byte("\"hello\":\"world\"")) {
t.Fatalf("unexpected body: %s", rec.Body.String())
}
}
func TestJSONResponse_BodyString(t *testing.T) {
c, _ := newTestCtx()
r := JSON(http.StatusOK, map[string]any{"x": 42})
ir := r.(InspectableHTTPResponse)
body := ir.BodyString(c)
if body == nil {
t.Fatalf("expected body, got nil")
}
if !bytes.Contains([]byte(*body), []byte("\"x\":42")) {
t.Fatalf("unexpected body: %q", *body)
}
}
func TestJSONResponse_FilterFromContext(t *testing.T) {
c, _ := newTestCtx()
SetJSONFilter(c, "abc")
r := JSON(http.StatusOK, map[string]any{"x": 1})
body := r.(InspectableHTTPResponse).BodyString(c)
if body == nil {
t.Fatalf("expected body")
}
}
func TestJSONResponse_FilterOverride(t *testing.T) {
c, _ := newTestCtx()
SetJSONFilter(c, "abc")
r := JSONWithFilter(http.StatusOK, map[string]any{"x": 1}, "override")
if r == nil {
t.Fatalf("expected response")
}
if !r.IsSuccess() {
t.Fatalf("expected success")
}
body := r.(InspectableHTTPResponse).BodyString(c)
if body == nil {
t.Fatalf("expected body")
}
}
func TestResponse_IsSuccessRanges(t *testing.T) {
cases := []struct {
code int
ok bool
}{
{100, false},
{199, false},
{200, true},
{201, true},
{299, true},
{300, true},
{399, true},
{400, false},
{500, false},
}
for _, tc := range cases {
r := JSON(tc.code, nil)
if r.IsSuccess() != tc.ok {
t.Errorf("status %d: expected IsSuccess=%v", tc.code, tc.ok)
}
r2 := Status(tc.code)
if r2.IsSuccess() != tc.ok {
t.Errorf("Status(%d): expected IsSuccess=%v", tc.code, tc.ok)
}
r3 := Text(tc.code, "x")
if r3.IsSuccess() != tc.ok {
t.Errorf("Text(%d): expected IsSuccess=%v", tc.code, tc.ok)
}
r4 := Data(tc.code, "text/plain", []byte("x"))
if r4.IsSuccess() != tc.ok {
t.Errorf("Data(%d): expected IsSuccess=%v", tc.code, tc.ok)
}
}
}
func TestResponse_WithHeader(t *testing.T) {
r := JSON(http.StatusOK, nil).
WithHeader("X-Foo", "bar").
WithHeader("X-Baz", "qux")
headers := r.(InspectableHTTPResponse).Headers()
if len(headers) != 2 {
t.Fatalf("expected 2 headers, got %d", len(headers))
}
if headers[0] != "X-Foo=bar" || headers[1] != "X-Baz=qux" {
t.Fatalf("headers wrong: %v", headers)
}
}
func TestResponse_WithCookie_DoesNotPanic(t *testing.T) {
r := JSON(http.StatusOK, nil).
WithCookie("session", "abc", 3600, "/", "example.com", true, true)
if r == nil {
t.Fatalf("expected response")
}
c, rec := newTestCtx()
r.Write(c)
if rec.Code != http.StatusOK {
t.Fatalf("expected 200, got %d", rec.Code)
}
cookies := rec.Result().Cookies()
if len(cookies) != 1 {
t.Fatalf("expected 1 cookie, got %d", len(cookies))
}
if cookies[0].Name != "session" || cookies[0].Value != "abc" {
t.Fatalf("cookie wrong: %+v", cookies[0])
}
}
func TestTextResponse(t *testing.T) {
c, rec := newTestCtx()
r := Text(http.StatusOK, "hello")
if r.(InspectableHTTPResponse).ContentType() != "text/plain" {
t.Fatalf("expected text/plain")
}
body := r.(InspectableHTTPResponse).BodyString(c)
if body == nil || *body != "hello" {
t.Fatalf("body mismatch")
}
r.Write(c)
if rec.Body.String() != "hello" {
t.Fatalf("write body mismatch: %q", rec.Body.String())
}
}
func TestDataResponse(t *testing.T) {
c, rec := newTestCtx()
payload := []byte{0x01, 0x02, 0x03}
r := Data(http.StatusOK, "application/octet-stream", payload)
if r.(InspectableHTTPResponse).ContentType() != "application/octet-stream" {
t.Fatalf("contenttype mismatch")
}
r.Write(c)
if !bytes.Equal(rec.Body.Bytes(), payload) {
t.Fatalf("body mismatch")
}
body := r.(InspectableHTTPResponse).BodyString(c)
if body == nil || *body != string(payload) {
t.Fatalf("BodyString mismatch")
}
}
func TestStatusResponse(t *testing.T) {
c, rec := newTestCtx()
r := Status(http.StatusNoContent)
if r.(InspectableHTTPResponse).ContentType() != "" {
t.Fatalf("expected empty content type")
}
if r.(InspectableHTTPResponse).BodyString(c) != nil {
t.Fatalf("expected nil body")
}
r.Write(c)
if c.Writer.Status() != http.StatusNoContent {
t.Fatalf("expected 204, got %d", c.Writer.Status())
}
_ = rec
}
func TestRedirectResponse(t *testing.T) {
c, rec := newTestCtx()
r := Redirect(http.StatusFound, "/elsewhere")
if r.(InspectableHTTPResponse).Statuscode() != http.StatusFound {
t.Fatalf("status mismatch")
}
if r.(InspectableHTTPResponse).ContentType() != "" {
t.Fatalf("expected empty content type")
}
if r.(InspectableHTTPResponse).BodyString(c) != nil {
t.Fatalf("expected nil body")
}
r.Write(c)
if rec.Code != http.StatusFound {
t.Fatalf("expected 302, got %d", rec.Code)
}
if rec.Header().Get("Location") != "/elsewhere" {
t.Fatalf("expected Location header")
}
}
func TestNotImplemented(t *testing.T) {
r := NotImplemented()
if r == nil {
t.Fatalf("expected response")
}
if r.IsSuccess() {
t.Fatalf("NotImplemented must not be success")
}
}
func TestError_NotSuccess(t *testing.T) {
r := Error(http.ErrAbortHandler)
if r.IsSuccess() {
t.Fatalf("error response must not be success")
}
herr, ok := r.(HTTPErrorResponse)
if !ok {
t.Fatalf("expected HTTPErrorResponse")
}
if herr.Error() == nil {
t.Fatalf("expected non-nil err")
}
}
func TestError_ContentTypeJSON(t *testing.T) {
r := Error(http.ErrAbortHandler)
if r.(InspectableHTTPResponse).ContentType() != "application/json" {
t.Fatalf("expected application/json")
}
}
func TestDownloadData(t *testing.T) {
c, rec := newTestCtx()
payload := []byte("file content")
r := DownloadData(http.StatusOK, "text/plain", "f.txt", payload)
if r.(InspectableHTTPResponse).ContentType() != "text/plain" {
t.Fatalf("contenttype mismatch")
}
if r.(InspectableHTTPResponse).Statuscode() != http.StatusOK {
t.Fatalf("status mismatch")
}
body := r.(InspectableHTTPResponse).BodyString(c)
if body == nil || *body != string(payload) {
t.Fatalf("body mismatch")
}
r.Write(c)
if rec.Header().Get("Content-Disposition") == "" {
t.Fatalf("expected Content-Disposition header")
}
if !bytes.Contains([]byte(rec.Header().Get("Content-Disposition")), []byte("f.txt")) {
t.Fatalf("Content-Disposition does not contain filename: %q", rec.Header().Get("Content-Disposition"))
}
}
func TestSeekable(t *testing.T) {
r := Seekable("foo.bin", "application/octet-stream", bytes.NewReader([]byte("xyz")))
if !r.IsSuccess() {
t.Fatalf("seekable must be success")
}
ir := r.(InspectableHTTPResponse)
if ir.Statuscode() != 200 {
t.Fatalf("expected 200")
}
if ir.ContentType() != "application/octet-stream" {
t.Fatalf("contenttype mismatch")
}
body := ir.BodyString(nil)
if body == nil || *body != "(seekable)" {
t.Fatalf("BodyString mismatch")
}
}
func TestFile_Builders(t *testing.T) {
r := File("text/plain", "/tmp/this-file-should-not-exist-xyz")
if !r.IsSuccess() {
t.Fatalf("File must IsSuccess true")
}
if r.(InspectableHTTPResponse).Statuscode() != 200 {
t.Fatalf("expected 200")
}
if r.(InspectableHTTPResponse).ContentType() != "text/plain" {
t.Fatalf("contenttype mismatch")
}
r2 := Download("application/pdf", "/tmp/this-file-should-not-exist-xyz", "doc.pdf")
if r2.(InspectableHTTPResponse).ContentType() != "application/pdf" {
t.Fatalf("contenttype mismatch")
}
body := r.(InspectableHTTPResponse).BodyString(nil)
if body != nil {
t.Fatalf("expected nil body for nonexistent file")
}
}