package main import ( "testing" "time" ) func TestDestinoSeguro(t *testing.T) { casos := map[string]string{ "/pedir/nueva?fecha=2026-10-09": "/pedir/nueva?fecha=2026-10-09", "/pedir/mis-fechas": "/pedir/mis-fechas", "": "", "/": "", "/index.html": "", "//evil.example/pedir/": "", "https://evil.example/pedir/": "", "/\\evil.example/pedir/": "", "/pedir/\r\nSet-Cookie: x=1": "", "javascript:alert(1)": "", } for entrada, quiero := range casos { if got := destinoSeguro(entrada); got != quiero { t.Errorf("destinoSeguro(%q) = %q, quiero %q", entrada, got, quiero) } } } func TestDestinoSeguroSinPuntos(t *testing.T) { for _, sig := range []string{"/pedir/../index.html", "/pedir/./nueva", "/pedir//nueva", "/pedir/x/../../evil"} { if got := destinoSeguro(sig); got != "" { t.Errorf("destinoSeguro(%q) = %q, quiero vacío", sig, got) } } if got := destinoSeguro("/pedir/"); got != "/pedir/" { t.Errorf("destinoSeguro(/pedir/) = %q", got) } } func TestCerrojoApuntaAntesDeCalcular(t *testing.T) { c := NuevoCerrojo(5, time.Minute, time.Minute) pasan := 0 for i := 0; i < 50; i++ { if ok, _ := c.Intentar("ip:1.2.3.4"); ok { pasan++ } } if pasan != 5 { t.Fatalf("pasaron %d intentos, quiero 5", pasan) } } func TestArgonParametrosAcotados(t *testing.T) { // Un hash manipulado que pide 4 GiB de memoria no se calcula. malo := "$argon2id$v=19$m=4194304,t=3,p=4$c2FsdHNhbHRzYWx0$aGFzaGhhc2hoYXNoaGFzaGhhc2hoYXNoaGFzaGhhc2g" if VerificarClave(malo, "loquesea") { t.Fatal("no deberia verificar") } } func TestConfigEjemploValida(t *testing.T) { c, err := CargarConfig("../despliegue/config.ejemplo.json") if err != nil { t.Fatalf("despliegue/config.ejemplo.json no carga: %v", err) } if !c.CookieSegura || c.Local { t.Fatal("el ejemplo de producción tiene que llevar cookie_segura y no local") } }