from __future__ import annotations from app.links import allowed_links, sanitize_links from app.models import KnowledgeSource # exact is the CANONICAL form produced by allowed_links (www/scheme/slash-less) EXACT = {"flexigobe.com", "flexigobe.com/catalogo.pdf"} HOSTS = {"flexigobe.com"} def test_sanitize_keeps_real_drops_fake_and_fixes_path(): # real allowlisted link kept exactly assert "https://flexigobe.com/catalogo.pdf" in sanitize_links( "Catálogo: https://flexigobe.com/catalogo.pdf", EXACT, HOSTS ) # invented path on the known store domain → downgraded to the real homepage out = sanitize_links("Más info: https://flexigobe.com/about", EXACT, HOSTS) assert "/about" not in out and "https://flexigobe.com" in out # www variant of a known host is recognized (not treated as foreign) out_www = sanitize_links("Web: https://www.flexigobe.com/inventado", EXACT, HOSTS) assert "flexigobe.com" in out_www and "/inventado" not in out_www # foreign/unknown domain → removed assert "evil.example.com" not in sanitize_links("Visita https://evil.example.com/x", EXACT, HOSTS) # markdown link with invented path → label kept, link fixed out3 = sanitize_links("Lee [Sobre nosotros](https://flexigobe.com/about) aquí", EXACT, HOSTS) assert "Sobre nosotros" in out3 and "/about" not in out3 def test_sanitize_noop_without_links(): assert sanitize_links("Sin enlaces aquí.", {"x"}, {"x"}) == "Sin enlaces aquí." def test_cart_permalink_survives_only_via_verbatim(): # The cart/checkout permalink lives on the myshopify domain, which is NOT # crawled, so it's NOT in the allowlist. Without help the guard DROPS it (the # real bug: customer saw "Aquí tienes el enlace:" with nothing -> "no funciona" # x15). The cart/reorder tools register it in ctx.web_urls -> verbatim-allowed. cart = "https://s.myshopify.com/cart/9:1" txt = f"Aquí tienes el enlace: {cart}" assert cart not in sanitize_links(txt, EXACT, HOSTS) # dropped when unknown assert cart in sanitize_links(txt, EXACT, HOSTS, extra_verbatim={cart}) # kept when registered async def test_allowed_links_built_from_source_urls(db_session): db_session.add( KnowledgeSource( tenant_id=7, kind="url", name="web", location="https://shop.example", urls=["https://shop.example", "https://shop.example/faq"], ) ) await db_session.flush() exact, hosts = await allowed_links(db_session, 7) assert "shop.example/faq" in exact # canonical form assert "shop.example" in hosts # another tenant's links must not leak in exact2, _ = await allowed_links(db_session, 999) assert exact2 == set() def test_extract_urls_from_text(): from app.rag.extract import extract_urls_from_text urls = extract_urls_from_text("Mira https://a.com/x y tambien https://a.com/y.pdf, gracias.") assert urls == ["https://a.com/x", "https://a.com/y.pdf"]