fix(gitea): address review feedback on diff size limiting
PR Ready Gate / clear-labels (pull_request) Successful in 2s
CI / test (pull_request) Successful in 17s
CI / review (anthropic--claude-4.6-sonnet, sonnet, SONNET_REVIEW_TOKEN) (pull_request) Successful in 28s
CI / review (gpt-5, security, ., rodin/security-patterns, SECURITY_REVIEW.md, SECURITY_REVIEW_TOKEN) (pull_request) Successful in 1m34s
CI / review (gpt-5, gpt, GPT_REVIEW_TOKEN) (pull_request) Successful in 1m34s
PR Ready Gate / clear-labels (pull_request) Successful in 2s
CI / test (pull_request) Successful in 17s
CI / review (anthropic--claude-4.6-sonnet, sonnet, SONNET_REVIEW_TOKEN) (pull_request) Successful in 28s
CI / review (gpt-5, security, ., rodin/security-patterns, SECURITY_REVIEW.md, SECURITY_REVIEW_TOKEN) (pull_request) Successful in 1m34s
CI / review (gpt-5, gpt, GPT_REVIEW_TOKEN) (pull_request) Successful in 1m34s
- Add concurrency safety note to MaxDiffSize field documentation, mirroring the existing note on RetryBackoff - Consolidate six individual test functions into a single table-driven test (TestGetPullRequestDiff_SizeLimits) reducing repetition - Add //nolint:errcheck annotation to test handler w.Write calls
This commit is contained in:
@@ -71,6 +71,9 @@ type Client struct {
|
|||||||
|
|
||||||
// MaxDiffSize is the maximum number of bytes allowed when fetching a PR diff.
|
// MaxDiffSize is the maximum number of bytes allowed when fetching a PR diff.
|
||||||
// If zero, defaults to DefaultMaxDiffSize (10 MB). Set to any negative value to disable the limit.
|
// If zero, defaults to DefaultMaxDiffSize (10 MB). Set to any negative value to disable the limit.
|
||||||
|
//
|
||||||
|
// This field must be configured before the first request is made.
|
||||||
|
// Modifying it while requests are in flight is not safe.
|
||||||
MaxDiffSize int64
|
MaxDiffSize int64
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+75
-128
@@ -10,134 +10,81 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestGetPullRequestDiff_ExceedsMaxSize(t *testing.T) {
|
func TestGetPullRequestDiff_SizeLimits(t *testing.T) {
|
||||||
// Create a diff that exceeds a small limit
|
tests := []struct {
|
||||||
largeDiff := strings.Repeat("+ added line\n", 1000) // ~13 KB
|
name string
|
||||||
|
diff string
|
||||||
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
maxDiffSize int64
|
||||||
w.Write([]byte(largeDiff))
|
wantErr error
|
||||||
}))
|
wantDiff string
|
||||||
defer server.Close()
|
}{
|
||||||
|
{
|
||||||
client := NewClient(server.URL, "test-token")
|
name: "exceeds max size",
|
||||||
client.MaxDiffSize = 100 // 100 bytes limit
|
diff: strings.Repeat("+ added line\n", 1000), // ~13 KB
|
||||||
client.RetryBackoff = []time.Duration{} // no delay in tests
|
maxDiffSize: 100,
|
||||||
|
wantErr: ErrDiffTooLarge,
|
||||||
_, err := client.GetPullRequestDiff(context.Background(), "owner", "repo", 1)
|
},
|
||||||
if err == nil {
|
{
|
||||||
t.Fatal("expected error for oversized diff, got nil")
|
name: "within max size",
|
||||||
|
diff: "diff --git a/f.go b/f.go\n--- a/f.go\n+++ b/f.go\n@@ -1 +1 @@\n-old\n+new\n",
|
||||||
|
maxDiffSize: 1024,
|
||||||
|
wantDiff: "diff --git a/f.go b/f.go\n--- a/f.go\n+++ b/f.go\n@@ -1 +1 @@\n-old\n+new\n",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "exactly at limit",
|
||||||
|
diff: strings.Repeat("x", 50),
|
||||||
|
maxDiffSize: 50,
|
||||||
|
wantDiff: strings.Repeat("x", 50),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "one byte over limit",
|
||||||
|
diff: strings.Repeat("x", 51),
|
||||||
|
maxDiffSize: 50,
|
||||||
|
wantErr: ErrDiffTooLarge,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "disabled limit",
|
||||||
|
diff: strings.Repeat("x", 10000),
|
||||||
|
maxDiffSize: -1,
|
||||||
|
wantDiff: strings.Repeat("x", 10000),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "default limit",
|
||||||
|
diff: "diff content",
|
||||||
|
maxDiffSize: 0, // zero means use DefaultMaxDiffSize
|
||||||
|
wantDiff: "diff content",
|
||||||
|
},
|
||||||
}
|
}
|
||||||
if !errors.Is(err, ErrDiffTooLarge) {
|
|
||||||
t.Errorf("expected ErrDiffTooLarge, got: %v", err)
|
for _, tt := range tests {
|
||||||
}
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
}
|
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
w.Write([]byte(tt.diff)) //nolint:errcheck // test handler
|
||||||
func TestGetPullRequestDiff_WithinMaxSize(t *testing.T) {
|
}))
|
||||||
smallDiff := "diff --git a/f.go b/f.go\n--- a/f.go\n+++ b/f.go\n@@ -1 +1 @@\n-old\n+new\n"
|
defer server.Close()
|
||||||
|
|
||||||
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
client := NewClient(server.URL, "test-token")
|
||||||
w.Write([]byte(smallDiff))
|
client.MaxDiffSize = tt.maxDiffSize
|
||||||
}))
|
client.RetryBackoff = []time.Duration{}
|
||||||
defer server.Close()
|
|
||||||
|
got, err := client.GetPullRequestDiff(context.Background(), "owner", "repo", 1)
|
||||||
client := NewClient(server.URL, "test-token")
|
|
||||||
client.MaxDiffSize = 1024 // 1 KB limit — more than enough
|
if tt.wantErr != nil {
|
||||||
client.RetryBackoff = []time.Duration{}
|
if err == nil {
|
||||||
|
t.Fatal("expected error, got nil")
|
||||||
got, err := client.GetPullRequestDiff(context.Background(), "owner", "repo", 1)
|
}
|
||||||
if err != nil {
|
if !errors.Is(err, tt.wantErr) {
|
||||||
t.Fatalf("unexpected error: %v", err)
|
t.Errorf("expected %v, got: %v", tt.wantErr, err)
|
||||||
}
|
}
|
||||||
if got != smallDiff {
|
return
|
||||||
t.Errorf("expected diff %q, got %q", smallDiff, got)
|
}
|
||||||
}
|
|
||||||
}
|
if err != nil {
|
||||||
|
t.Fatalf("unexpected error: %v", err)
|
||||||
func TestGetPullRequestDiff_ExactlyAtLimit(t *testing.T) {
|
}
|
||||||
// A diff that is exactly at the limit should succeed
|
if got != tt.wantDiff {
|
||||||
exactDiff := strings.Repeat("x", 50)
|
t.Errorf("diff mismatch: got length %d, want length %d", len(got), len(tt.wantDiff))
|
||||||
|
}
|
||||||
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
})
|
||||||
w.Write([]byte(exactDiff))
|
|
||||||
}))
|
|
||||||
defer server.Close()
|
|
||||||
|
|
||||||
client := NewClient(server.URL, "test-token")
|
|
||||||
client.MaxDiffSize = 50 // exactly the size of the diff
|
|
||||||
client.RetryBackoff = []time.Duration{}
|
|
||||||
|
|
||||||
got, err := client.GetPullRequestDiff(context.Background(), "owner", "repo", 1)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("unexpected error for diff at exact limit: %v", err)
|
|
||||||
}
|
|
||||||
if got != exactDiff {
|
|
||||||
t.Errorf("expected diff to match, got length %d", len(got))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestGetPullRequestDiff_OneByteOverLimit(t *testing.T) {
|
|
||||||
// A diff that is one byte over the limit should fail
|
|
||||||
overDiff := strings.Repeat("x", 51)
|
|
||||||
|
|
||||||
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
w.Write([]byte(overDiff))
|
|
||||||
}))
|
|
||||||
defer server.Close()
|
|
||||||
|
|
||||||
client := NewClient(server.URL, "test-token")
|
|
||||||
client.MaxDiffSize = 50
|
|
||||||
client.RetryBackoff = []time.Duration{}
|
|
||||||
|
|
||||||
_, err := client.GetPullRequestDiff(context.Background(), "owner", "repo", 1)
|
|
||||||
if err == nil {
|
|
||||||
t.Fatal("expected error for diff one byte over limit")
|
|
||||||
}
|
|
||||||
if !errors.Is(err, ErrDiffTooLarge) {
|
|
||||||
t.Errorf("expected ErrDiffTooLarge, got: %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestGetPullRequestDiff_DisabledLimit(t *testing.T) {
|
|
||||||
// When MaxDiffSize is -1, no limit is enforced
|
|
||||||
largeDiff := strings.Repeat("x", 10000)
|
|
||||||
|
|
||||||
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
w.Write([]byte(largeDiff))
|
|
||||||
}))
|
|
||||||
defer server.Close()
|
|
||||||
|
|
||||||
client := NewClient(server.URL, "test-token")
|
|
||||||
client.MaxDiffSize = -1 // disabled
|
|
||||||
client.RetryBackoff = []time.Duration{}
|
|
||||||
|
|
||||||
got, err := client.GetPullRequestDiff(context.Background(), "owner", "repo", 1)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("unexpected error with disabled limit: %v", err)
|
|
||||||
}
|
|
||||||
if got != largeDiff {
|
|
||||||
t.Errorf("expected full diff with disabled limit, got length %d", len(got))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestGetPullRequestDiff_DefaultLimit(t *testing.T) {
|
|
||||||
// With zero MaxDiffSize (default), should use DefaultMaxDiffSize.
|
|
||||||
// A small diff should succeed without setting MaxDiffSize.
|
|
||||||
smallDiff := "diff content"
|
|
||||||
|
|
||||||
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
w.Write([]byte(smallDiff))
|
|
||||||
}))
|
|
||||||
defer server.Close()
|
|
||||||
|
|
||||||
client := NewClient(server.URL, "test-token")
|
|
||||||
// MaxDiffSize is zero (default) — should use DefaultMaxDiffSize (10 MB)
|
|
||||||
client.RetryBackoff = []time.Duration{}
|
|
||||||
|
|
||||||
got, err := client.GetPullRequestDiff(context.Background(), "owner", "repo", 1)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("unexpected error with default limit: %v", err)
|
|
||||||
}
|
|
||||||
if got != smallDiff {
|
|
||||||
t.Errorf("expected diff %q, got %q", smallDiff, got)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user