"""Spanish negation tests (round-3 point 4): merchants write in Spanish; negations like 'nunca', 'lamentablemente' or 'no podemos' must veto `approval` exactly like their English counterparts. Veto rule unchanged: when in doubt -> needs_review.""" from __future__ import annotations import pytest from cayceops.components.maild import classify as clf from cayceops.models import MailClassification APPROVAL_ONLY = MailClassification.APPROVAL def _never_approval(cfg_factory, text: str) -> None: kind, _ = clf.classify(text, cfg_factory()) assert kind is not APPROVAL_ONLY, f"{text!r} classified as APPROVAL" def test_english_baseline_still_works(cfg): config = cfg() kind, _ = clf.classify("Your application was approved, welcome to the program", config) assert kind is APPROVAL_ONLY @pytest.mark.parametrize( "text", [ # 1. rejection stem "Lamentamos informarle que su solicitud fue rechazada", # 2. nunca "Nunca aceptamos negocios de criptomonedas", # 3. jamás "Jamás hemos trabajado con affiliates externos", # 4. tampoco "No podemos aceptar su sitio, tampoco podemos ofrecerle otro acuerdo", # 5. ningún/ninguna "En este momento no tenemos ningún hueco para nuevos partners", # 6. no podemos (multi-word) "Su propuesta es interesante pero no podemos proceder", # 7. no es posible (multi-word) "Gracias por escribir, pero no es posible colaborar este trimestre", # 8. lamentablemente "Lamentablemente su aplicación no ha sido aprobada", # 9. no aceptamos "Por política interna no aceptamos sitios de viajes", # 10. mixed spanish/english: negation in spanish, approval word in english "Thanks for reaching out! Lamentablemente we cannot approve your site", # 11. mixed: approval in spanish, negation in english "Apreciamos su interés, but we are not accepting new partners", # 12. nadie / nada "Aquí nadie decidiría eso, así que no hay nada que aprobar", ], ) def test_spanish_and_mixed_negations_veto_approval(cfg, text): _never_approval(cfg, text) def test_spanish_pure_approval_still_approves(cfg): """A clean Spanish approval WITHOUT any negation must still classify approval — the veto must not over-fire.""" config = cfg() kind, confidence = clf.classify( "Su solicitud fue aprobada. Bienvenido al programa, estamos encantados " "de trabajar con ustedes.", config, ) assert kind is APPROVAL_ONLY assert confidence >= 0.5 def test_spanish_rejection_classifies_rejection(cfg): config = cfg() kind, conf = clf.classify( "Lamentamos informarle que su solicitud fue rechazada por el comité", config, ) assert kind is MailClassification.REJECTION assert conf >= 0.9