Files
ds2api/internal/devcapture/store_test.go

111 lines
3.1 KiB
Go

package devcapture
import (
"io"
"strings"
"testing"
"unicode/utf8"
)
func TestNewFromEnvDefaults(t *testing.T) {
t.Setenv("DS2API_DEV_PACKET_CAPTURE_LIMIT", "")
t.Setenv("DS2API_DEV_PACKET_CAPTURE_MAX_BODY_BYTES", "")
t.Setenv("VERCEL", "")
t.Setenv("NOW_REGION", "")
s := NewFromEnv()
if s.Limit() != 20 {
t.Fatalf("expected default limit 20, got %d", s.Limit())
}
if s.MaxBodyBytes() != 5*1024*1024 {
t.Fatalf("expected default max body bytes 5MB, got %d", s.MaxBodyBytes())
}
}
func TestNewFromEnvHonorsOverrides(t *testing.T) {
t.Setenv("DS2API_DEV_PACKET_CAPTURE_LIMIT", "7")
t.Setenv("DS2API_DEV_PACKET_CAPTURE_MAX_BODY_BYTES", "8192")
t.Setenv("VERCEL", "")
t.Setenv("NOW_REGION", "")
s := NewFromEnv()
if s.Limit() != 7 {
t.Fatalf("expected override limit 7, got %d", s.Limit())
}
if s.MaxBodyBytes() != 8192 {
t.Fatalf("expected override max body bytes 8192, got %d", s.MaxBodyBytes())
}
}
func TestStorePushKeepsNewestWithinLimit(t *testing.T) {
s := &Store{enabled: true, limit: 2, maxBodyBytes: 1024}
for i := 0; i < 3; i++ {
session := s.Start("test", "http://x", "", map[string]any{"seq": i})
if session == nil {
t.Fatal("expected session")
}
rc := session.WrapBody(io.NopCloser(strings.NewReader("ok")), 200)
_, _ = io.ReadAll(rc)
_ = rc.Close()
}
items := s.Snapshot()
if len(items) != 2 {
t.Fatalf("expected 2 items, got %d", len(items))
}
if !strings.Contains(items[0].RequestBody, `"seq":2`) {
t.Fatalf("expected newest first, got %#v", items[0].RequestBody)
}
if !strings.Contains(items[1].RequestBody, `"seq":1`) {
t.Fatalf("expected second newest, got %#v", items[1].RequestBody)
}
}
func TestWrapBodyTruncatesByLimit(t *testing.T) {
s := &Store{enabled: true, limit: 5, maxBodyBytes: 4}
session := s.Start("test", "http://x", "acc1", map[string]any{"x": 1})
if session == nil {
t.Fatal("expected session")
}
rc := session.WrapBody(io.NopCloser(strings.NewReader("abcdef")), 200)
_, _ = io.ReadAll(rc)
_ = rc.Close()
items := s.Snapshot()
if len(items) != 1 {
t.Fatalf("expected 1 item, got %d", len(items))
}
if items[0].ResponseBody != "abcd" {
t.Fatalf("expected truncated body, got %q", items[0].ResponseBody)
}
if !items[0].ResponseTruncated {
t.Fatal("expected truncated flag true")
}
if items[0].AccountID != "acc1" {
t.Fatalf("expected account id, got %q", items[0].AccountID)
}
}
func TestWrapBodyTruncatesUTF8WithoutBreakingRune(t *testing.T) {
s := &Store{enabled: true, limit: 5, maxBodyBytes: 5}
session := s.Start("test", "http://x", "acc1", map[string]any{"x": 1})
if session == nil {
t.Fatal("expected session")
}
rc := session.WrapBody(io.NopCloser(strings.NewReader("😀xy")), 200)
_, _ = io.ReadAll(rc)
_ = rc.Close()
items := s.Snapshot()
if len(items) != 1 {
t.Fatalf("expected 1 item, got %d", len(items))
}
if !utf8.ValidString(items[0].ResponseBody) {
t.Fatalf("expected valid utf-8 response body, got %q", items[0].ResponseBody)
}
if items[0].ResponseBody != "😀x" {
t.Fatalf("expected rune-safe truncation, got %q", items[0].ResponseBody)
}
if !items[0].ResponseTruncated {
t.Fatal("expected truncated flag true")
}
}