feat(browser): auto-commit con 178 cambios

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-20 18:22:23 +02:00
parent 7d100e7f3e
commit 763e06c127
178 changed files with 19917 additions and 317 deletions
+103
View File
@@ -0,0 +1,103 @@
package browser
import (
"reflect"
"testing"
)
func TestParseCaptchaSignals(t *testing.T) {
tests := []struct {
name string
raw string
wantDetected bool
wantTypes []string
wantURL string
wantErr bool
}{
{
name: "recaptcha detectado",
raw: `{"detected":true,"types":["recaptcha"],"url":"https://x.test/login"}`,
wantDetected: true,
wantTypes: []string{"recaptcha"},
wantURL: "https://x.test/login",
},
{
name: "hcaptcha detectado",
raw: `{"detected":true,"types":["hcaptcha"],"url":"https://y.test/signup"}`,
wantDetected: true,
wantTypes: []string{"hcaptcha"},
wantURL: "https://y.test/signup",
},
{
name: "turnstile detectado",
raw: `{"detected":true,"types":["turnstile"],"url":"https://z.test/"}`,
wantDetected: true,
wantTypes: []string{"turnstile"},
wantURL: "https://z.test/",
},
{
name: "challenge por texto",
raw: `{"detected":true,"types":["challenge"],"url":"https://cf.test/"}`,
wantDetected: true,
wantTypes: []string{"challenge"},
wantURL: "https://cf.test/",
},
{
name: "multiples senales",
raw: `{"detected":true,"types":["turnstile","challenge"],"url":"https://cf.test/"}`,
wantDetected: true,
wantTypes: []string{"turnstile", "challenge"},
wantURL: "https://cf.test/",
},
{
name: "ninguno",
raw: `{"detected":false,"types":[],"url":"https://clean.test/"}`,
wantDetected: false,
wantTypes: []string{},
wantURL: "https://clean.test/",
},
{
name: "campo error best-effort no rompe",
raw: `{"detected":false,"types":[],"url":"https://err.test/","error":"boom"}`,
wantDetected: false,
wantTypes: []string{},
wantURL: "https://err.test/",
},
{
name: "types ausente se normaliza a slice vacio",
raw: `{"detected":false,"url":"https://n.test/"}`,
wantDetected: false,
wantTypes: []string{},
wantURL: "https://n.test/",
},
{
name: "json invalido devuelve error",
raw: `not-json`,
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
detected, types, url, err := parseCaptchaSignals(tt.raw)
if tt.wantErr {
if err == nil {
t.Fatalf("esperaba error, got nil")
}
return
}
if err != nil {
t.Fatalf("error inesperado: %v", err)
}
if detected != tt.wantDetected {
t.Errorf("detected: got %v, want %v", detected, tt.wantDetected)
}
if !reflect.DeepEqual(types, tt.wantTypes) {
t.Errorf("types: got %v, want %v", types, tt.wantTypes)
}
if url != tt.wantURL {
t.Errorf("url: got %q, want %q", url, tt.wantURL)
}
})
}
}