Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
vendor/*
!vendor/vendor.json
coverage.out
coverage.html
count.out
test
profile.out
Expand Down
120 changes: 120 additions & 0 deletions context_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
"os"
"path/filepath"
"reflect"
"runtime"
"strconv"
"strings"
"sync"
Expand Down Expand Up @@ -179,6 +180,20 @@
assert.Nil(t, f)
}

func TestContextFormFileParseMultipartFormFailed(t *testing.T) {
c, _ := CreateTestContext(httptest.NewRecorder())
// Create a request with invalid multipart form data
body := strings.NewReader("invalid multipart data")
c.Request, _ = http.NewRequest(http.MethodPost, "/", body)
c.Request.Header.Set("Content-Type", "multipart/form-data; boundary=invalid")
c.engine.MaxMultipartMemory = 8 << 20

// This should trigger the error handling in FormFile when ParseMultipartForm fails
f, err := c.FormFile("file")
require.Error(t, err)
assert.Nil(t, f)
}

func TestContextMultipartForm(t *testing.T) {
buf := new(bytes.Buffer)
mw := multipart.NewWriter(buf)
Expand Down Expand Up @@ -273,6 +288,43 @@
require.Error(t, c.SaveUploadedFile(f, "test/permission_test", mode))
}

func TestSaveUploadedFileChmodFailed(t *testing.T) {
if runtime.GOOS == "windows" {
t.Skip("chmod test not applicable on Windows")
}

Check failure on line 295 in context_test.go

View workflow job for this annotation

GitHub Actions / lint

File is not properly formatted (gci)
buf := new(bytes.Buffer)
mw := multipart.NewWriter(buf)
w, err := mw.CreateFormFile("file", "chmod_test")
require.NoError(t, err)
_, err = w.Write([]byte("chmod_test"))
require.NoError(t, err)
mw.Close()
c, _ := CreateTestContext(httptest.NewRecorder())
c.Request, _ = http.NewRequest(http.MethodPost, "/", buf)
c.Request.Header.Set("Content-Type", mw.FormDataContentType())
f, err := c.FormFile("file")
require.NoError(t, err)
assert.Equal(t, "chmod_test", f.Filename)

// Create a temporary directory with restricted permissions
tmpDir := t.TempDir()
restrictedDir := filepath.Join(tmpDir, "restricted")
require.NoError(t, os.MkdirAll(restrictedDir, 0o755))
// Make the directory read-only to trigger chmod failure
require.NoError(t, os.Chmod(restrictedDir, 0o444))
t.Cleanup(func() {
// Restore permissions for cleanup
os.Chmod(restrictedDir, 0o755)

Check failure on line 318 in context_test.go

View workflow job for this annotation

GitHub Actions / lint

Error return value of `os.Chmod` is not checked (errcheck)
})

// Try to save file with different permissions - this should fail on chmod
var mode fs.FileMode = 0o755
err = c.SaveUploadedFile(f, filepath.Join(restrictedDir, "subdir", "chmod_test"), mode)
// This might fail on MkdirAll or Chmod depending on the system
assert.Error(t, err)
}

func TestContextReset(t *testing.T) {
router := New()
c := router.allocateContext(0)
Expand Down Expand Up @@ -883,6 +935,20 @@
assert.Empty(t, dicts)
}

func TestContextInitFormCacheError(t *testing.T) {
c, _ := CreateTestContext(httptest.NewRecorder())
// Create a request with invalid multipart form data
body := strings.NewReader("invalid multipart data")
c.Request, _ = http.NewRequest(http.MethodPost, "/", body)
c.Request.Header.Set("Content-Type", "multipart/form-data; boundary=invalid")
c.engine.MaxMultipartMemory = 8 << 20

// This should trigger the error handling in initFormCache
values, ok := c.GetPostFormArray("foo")
assert.False(t, ok)
assert.Empty(t, values)
}

func TestContextPostFormMultipart(t *testing.T) {
c, _ := CreateTestContext(httptest.NewRecorder())
c.Request = createMultipartRequest()
Expand Down Expand Up @@ -2364,6 +2430,31 @@
assert.False(t, c.IsAborted())
}

func TestContextShouldBindBodyWithReadError(t *testing.T) {
w := httptest.NewRecorder()
c, _ := CreateTestContext(w)

// Create a request with a body that will cause read error
c.Request, _ = http.NewRequest(http.MethodPost, "/", &errorReader{})

type testStruct struct {
Foo string `json:"foo"`
}
obj := testStruct{}

// This should trigger the error handling in ShouldBindBodyWith
err := c.ShouldBindBodyWith(&obj, binding.JSON)
assert.Error(t, err)

Check failure on line 2447 in context_test.go

View workflow job for this annotation

GitHub Actions / lint

require-error: for error assertions use require (testifylint)
assert.Contains(t, err.Error(), "read error")
}

// errorReader is a helper struct that always returns an error when Read is called
type errorReader struct{}

func (e *errorReader) Read(p []byte) (n int, err error) {
return 0, errors.New("read error")
}

func TestContextShouldBindBodyWith(t *testing.T) {
type typeA struct {
Foo string `json:"foo" xml:"foo" binding:"required"`
Expand Down Expand Up @@ -2834,6 +2925,17 @@
assert.Equal(t, "Fetch binary post data", string(data))
}

func TestContextGetRawDataNilBody(t *testing.T) {
c, _ := CreateTestContext(httptest.NewRecorder())
c.Request, _ = http.NewRequest(http.MethodPost, "/", nil)
c.Request.Body = nil

data, err := c.GetRawData()
assert.Error(t, err)

Check failure on line 2934 in context_test.go

View workflow job for this annotation

GitHub Actions / lint

require-error: for error assertions use require (testifylint)
assert.Nil(t, data)
assert.Contains(t, err.Error(), "cannot read nil body")
}

func TestContextRenderDataFromReader(t *testing.T) {
w := httptest.NewRecorder()
c, _ := CreateTestContext(w)
Expand Down Expand Up @@ -3422,6 +3524,24 @@
setCookie := c.Writer.Header().Get("Set-Cookie")
assert.Contains(t, setCookie, "SameSite=None")
})

// Test that SameSiteDefaultMode uses context's sameSite setting
t.Run("SameSite=Default uses context setting", func(t *testing.T) {
c, _ := CreateTestContext(httptest.NewRecorder())
c.SetSameSite(http.SameSiteStrictMode)
cookie := &http.Cookie{
Name: "user",
Value: "gin",
Path: "/",
Domain: "localhost",
Secure: true,
HttpOnly: true,
SameSite: http.SameSiteDefaultMode,
}
c.SetCookieData(cookie)
setCookie := c.Writer.Header().Get("Set-Cookie")
assert.Contains(t, setCookie, "SameSite=Strict")
})
}

func TestGetMapFromFormData(t *testing.T) {
Expand Down
53 changes: 53 additions & 0 deletions debug_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,59 @@
}
}

func TestDebugPrintWARNINGDefaultLowGoVersion(t *testing.T) {
// Test the Go version warning branch by testing getMinVer with different inputs
// and then testing the logic directly

Check failure on line 118 in debug_test.go

View workflow job for this annotation

GitHub Actions / lint

File is not properly formatted (gci)
// First test getMinVer with a version that would trigger the warning
v, err := getMinVer("go1.22.1")
require.NoError(t, err)
assert.Equal(t, uint64(22), v)

// Test that version 22 is less than ginSupportMinGoVer (23)
assert.True(t, v < ginSupportMinGoVer)

Check failure on line 125 in debug_test.go

View workflow job for this annotation

GitHub Actions / lint

compares: use assert.Less (testifylint)

// Test the warning message directly by capturing debugPrint output
re := captureOutput(t, func() {
SetMode(DebugMode)
// Simulate the condition that would trigger the warning
if v < ginSupportMinGoVer {
debugPrint(`[WARNING] Now Gin requires Go 1.23+.

`)
}
debugPrint(`[WARNING] Creating an Engine instance with the Logger and Recovery middleware already attached.

`)
SetMode(TestMode)
})

assert.Equal(t, "[GIN-debug] [WARNING] Now Gin requires Go 1.23+.\n\n[GIN-debug] [WARNING] Creating an Engine instance with the Logger and Recovery middleware already attached.\n\n", re)
}

func TestDebugPrintWithCustomFunc(t *testing.T) {
// Test debugPrint with custom DebugPrintFunc
originalFunc := DebugPrintFunc
defer func() {
DebugPrintFunc = originalFunc
}()

var capturedFormat string
var capturedValues []any
DebugPrintFunc = func(format string, values ...any) {
capturedFormat = format
capturedValues = values
}

SetMode(DebugMode)
debugPrint("test %s %d", "message", 42)
SetMode(TestMode)

// debugPrint automatically adds \n if not present
assert.Equal(t, "test %s %d", capturedFormat)
assert.Equal(t, []any{"message", 42}, capturedValues)
}

func TestDebugPrintWARNINGNew(t *testing.T) {
re := captureOutput(t, func() {
SetMode(DebugMode)
Expand Down
Loading