Files
coder/aibridge/intercept/apidump/headers_internal_test.go
T
Ethan c650aabbef chore: standardize on *_internal_test.go for white-box tests (#25601)
My agent added `//nolint:testpackage` to a test file on one of my PRs.
Again. This PR cleans it up across the entire repo and updates the
in-repo conventions so future agents stop doing it.

The repo already has a precedent for white-box tests that need to touch
unexported symbols: `*_internal_test.go` (145+ existing files). The
`testpackage` linter's default `skip-regexp` exempts that filename
suffix, so the `//nolint:testpackage` directive is unnecessary in every
case where someone reached for it. This PR renames 51 such files to
`*_internal_test.go` via `git mv` so blame and history follow, and
strips the dead directive from 2 files that were already correctly named
(`coderd/oauth2provider/authorize_internal_test.go`,
`coderd/x/chatd/advisor_internal_test.go`).

`.claude/docs/TESTING.md` now documents the rule explicitly under *Test
Package Naming*, which is imported into the root `AGENTS.md` via
`@.claude/docs/TESTING.md`. The rule: prefer `package foo_test`; if you
need internal access, rename the file to `*_internal_test.go` rather
than adding a nolint directive.
2026-05-22 20:24:38 +10:00

115 lines
2.7 KiB
Go

package apidump
import (
"bytes"
"net/http"
"testing"
"github.com/google/uuid"
"github.com/stretchr/testify/require"
"cdr.dev/slog/v3"
"github.com/coder/quartz"
)
func TestSensitiveHeaderLists(t *testing.T) {
t.Parallel()
// Verify all expected sensitive request headers are in the list
expectedRequestHeaders := []string{
"Authorization",
"X-Api-Key",
"Api-Key",
"X-Auth-Token",
"Cookie",
"Proxy-Authorization",
"X-Amz-Security-Token",
}
for _, h := range expectedRequestHeaders {
_, ok := sensitiveRequestHeaders[h]
require.True(t, ok, "expected %q to be in sensitiveRequestHeaders", h)
}
// Verify all expected sensitive response headers are in the list
// Note: header names use Go's canonical form (http.CanonicalHeaderKey)
expectedResponseHeaders := []string{
"Set-Cookie",
"Www-Authenticate",
"Proxy-Authenticate",
}
for _, h := range expectedResponseHeaders {
_, ok := sensitiveResponseHeaders[h]
require.True(t, ok, "expected %q to be in sensitiveResponseHeaders", h)
}
}
func TestWriteRedactedHeaders(t *testing.T) {
t.Parallel()
d := &Dumper{
dumpPath: interceptDumpPath("/tmp", "test", "test", uuid.New(), quartz.NewMock(t)),
logger: slog.Make(),
}
tests := []struct {
name string
headers http.Header
sensitive map[string]struct{}
overrides map[string]string
expected string
}{
{
name: "empty headers",
headers: http.Header{},
expected: "",
},
{
name: "single header",
headers: http.Header{"Content-Type": {"application/json"}},
expected: "Content-Type: application/json\r\n",
},
{
name: "sorted alphabetically",
headers: http.Header{
"Zebra": {"last"},
"Alpha": {"first"},
},
expected: "Alpha: first\r\nZebra: last\r\n",
},
{
name: "override applied",
headers: http.Header{"Content-Length": {"100"}},
overrides: map[string]string{"Content-Length": "200"},
expected: "Content-Length: 200\r\n",
},
{
name: "sensitive header redacted",
headers: http.Header{"Set-Cookie": {"session=abcdefghij"}},
sensitive: sensitiveResponseHeaders,
expected: "Set-Cookie: se...ij\r\n",
},
{
name: "multi-value header",
headers: http.Header{
"Accept": {"text/html", "application/json"},
},
expected: "Accept: text/html\r\nAccept: application/json\r\n",
},
{
name: "override for non-existent header",
headers: http.Header{},
overrides: map[string]string{"Host": "example.com"},
expected: "Host: example.com\r\n",
},
}
for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
t.Parallel()
var buf bytes.Buffer
d.writeRedactedHeaders(&buf, tc.headers, tc.sensitive, tc.overrides)
require.Equal(t, tc.expected, buf.String())
})
}
}