mirror of
https://github.com/lukaszraczylo/claude-mnemonic.git
synced 2026-06-11 00:09:28 +00:00
214 lines
4.7 KiB
Go
214 lines
4.7 KiB
Go
package privacy
|
|
|
|
import (
|
|
"testing"
|
|
)
|
|
|
|
func TestContainsSecrets(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
input string
|
|
expected bool
|
|
}{
|
|
{
|
|
name: "empty string",
|
|
input: "",
|
|
expected: false,
|
|
},
|
|
{
|
|
name: "normal text",
|
|
input: "This is just some regular text about a bug fix",
|
|
expected: false,
|
|
},
|
|
{
|
|
name: "API key pattern",
|
|
input: "api_key=abc123def456ghi789jkl012mno345pqr678",
|
|
expected: true,
|
|
},
|
|
{
|
|
name: "api-key with dash",
|
|
input: `api-key: "abc123def456ghi789jkl012mno"`,
|
|
expected: true,
|
|
},
|
|
{
|
|
name: "password in config",
|
|
input: `password="super_secret_password_123"`,
|
|
expected: true,
|
|
},
|
|
{
|
|
name: "OpenAI key format",
|
|
input: "sk-abc123def456ghi789jkl012mno345pqr678",
|
|
expected: true,
|
|
},
|
|
{
|
|
name: "Anthropic key format",
|
|
input: "sk-ant-api03-abc123def456ghi789jkl012mno345",
|
|
expected: true,
|
|
},
|
|
{
|
|
name: "GitHub PAT",
|
|
input: "ghp_1234567890abcdefghijklmnopqrstuvwxyz",
|
|
expected: true,
|
|
},
|
|
{
|
|
name: "GitHub PAT new format",
|
|
input: "github_pat_12ABCDEFGHIJ3456789abc_defghijklmno",
|
|
expected: true,
|
|
},
|
|
{
|
|
name: "AWS access key",
|
|
input: "AKIAIOSFODNN7EXAMPLE",
|
|
expected: true,
|
|
},
|
|
{
|
|
name: "Private key header",
|
|
input: "-----BEGIN RSA PRIVATE KEY-----",
|
|
expected: true,
|
|
},
|
|
{
|
|
name: "JWT token",
|
|
input: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIn0.dozjgNryP4J3jVmNHl0w5N_XgL0n3I9PlFUP0THsR8U",
|
|
expected: true,
|
|
},
|
|
{
|
|
name: "bearer token",
|
|
input: "Bearer abc123def456ghi789jkl012mno345",
|
|
expected: true,
|
|
},
|
|
{
|
|
name: "secret_key in code",
|
|
input: `secret_key = "my_super_secret_token_here"`,
|
|
expected: true,
|
|
},
|
|
{
|
|
name: "short password is not detected",
|
|
input: `password="short"`,
|
|
expected: false, // Too short to trigger
|
|
},
|
|
{
|
|
name: "word password in sentence",
|
|
input: "The password field should be validated",
|
|
expected: false,
|
|
},
|
|
{
|
|
name: "word api in code",
|
|
input: "The API returns JSON data",
|
|
expected: false,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
result := ContainsSecrets(tt.input)
|
|
if result != tt.expected {
|
|
t.Errorf("ContainsSecrets(%q) = %v, want %v", tt.input, result, tt.expected)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestRedactSecrets(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
input string
|
|
expected string
|
|
}{
|
|
{
|
|
name: "empty string",
|
|
input: "",
|
|
expected: "",
|
|
},
|
|
{
|
|
name: "no secrets",
|
|
input: "This is safe text",
|
|
expected: "This is safe text",
|
|
},
|
|
{
|
|
name: "API key gets redacted",
|
|
input: "api_key=abc123def456ghi789jkl012mno345pqr678",
|
|
expected: "api_key=[REDACTED]",
|
|
},
|
|
{
|
|
name: "OpenAI key gets redacted",
|
|
input: "The key is sk-abc123def456ghi789jkl012mno345pqr678",
|
|
expected: "The key is sk-a...[REDACTED]",
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
result := RedactSecrets(tt.input)
|
|
if result != tt.expected {
|
|
t.Errorf("RedactSecrets(%q) = %q, want %q", tt.input, result, tt.expected)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestSanitizeObservation(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
narrative string
|
|
facts []string
|
|
expected bool
|
|
}{
|
|
{
|
|
name: "clean observation",
|
|
narrative: "Fixed a bug in the login flow",
|
|
facts: []string{"Users can now log in", "Session management improved"},
|
|
expected: false,
|
|
},
|
|
{
|
|
name: "secret in narrative",
|
|
narrative: "Set API key api_key=abc123def456ghi789jkl012mno345",
|
|
facts: []string{"Configuration updated"},
|
|
expected: true,
|
|
},
|
|
{
|
|
name: "secret in facts",
|
|
narrative: "Updated configuration",
|
|
facts: []string{"Added api_key=abc123def456ghi789jkl012mno345"},
|
|
expected: true,
|
|
},
|
|
{
|
|
name: "empty facts",
|
|
narrative: "Clean narrative",
|
|
facts: []string{},
|
|
expected: false,
|
|
},
|
|
{
|
|
name: "nil facts",
|
|
narrative: "Clean narrative",
|
|
facts: nil,
|
|
expected: false,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
result := SanitizeObservation(tt.narrative, tt.facts)
|
|
if result != tt.expected {
|
|
t.Errorf("SanitizeObservation() = %v, want %v", result, tt.expected)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func BenchmarkContainsSecrets(b *testing.B) {
|
|
text := "This is a normal piece of text that does not contain any secrets or sensitive information"
|
|
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
ContainsSecrets(text)
|
|
}
|
|
}
|
|
|
|
func BenchmarkContainsSecretsWithSecret(b *testing.B) {
|
|
text := "api_key=abc123def456ghi789jkl012mno345pqr678"
|
|
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
ContainsSecrets(text)
|
|
}
|
|
}
|