Primer commit

This commit is contained in:
2026-05-30 14:31:19 -06:00
commit a35d26fac0
277 changed files with 265240 additions and 0 deletions
+120
View File
@@ -0,0 +1,120 @@
# -*- coding: utf-8 -*-
"""Test puntual del fallback post-UPDATE en workflow Marca->Sucursal V2.
Escenario:
- Crear contacto en SUCURSAL (con CF autoref).
- Crear contacto en MARCA SIN CF, mismo phone.
- Disparar webhook Marca->Sucursal.
- El workflow va por cascada phone, encuentra contacto sucursal, UPDATE.
- Tras UPDATE, el nuevo IF detecta cfValue vacio -> autoenlace.
- Verificar:
* CF en MARCA queda poblado con id del contacto sucursal.
* CF en SUCURSAL queda con autoref.
- Cleanup.
"""
import os
import sys
import time
import datetime
ROOT_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.insert(0, ROOT_DIR)
sys.path.insert(0, os.path.join(ROOT_DIR, "scripts"))
from scripts import n8n_e2e_test as t
def log(msg):
ts = datetime.datetime.now().strftime("%H:%M:%S")
print(f"[{ts}] {msg}", flush=True)
def main():
cleanup = t.Cleanup()
try:
phone = "+5219991122334"
email = "fbpost@e3.local"
# 1) Resolver field_id CF en sucursal (varia por sucursal)
cf_id_branch = t.resolve_cf_id_in_location(t.PINOTEPA_LOCATION_ID, t.CF_KEY)
log(f"CF field_id en PINOTEPA: {cf_id_branch}")
# 2) Crear contacto SUCURSAL con autoref CF
payload_branch = t._new_contact_payload("FBPU", phone=phone, email=email)
branch_id = t.create_contact(t.PINOTEPA_LOCATION_ID, payload_branch)
cleanup.register(t.PINOTEPA_LOCATION_ID, branch_id, "fbpost branch")
log(f"Branch creado: {branch_id}")
# Poblar CF autoref en sucursal
t.update_contact(t.PINOTEPA_LOCATION_ID, branch_id, {
"customFields": [
{"id": cf_id_branch, "key": t.CF_KEY, "field_value": branch_id}
]
})
# 2b) Esperar a que GHL indexe el email en sucursal (el workflow va por cascada mail)
log("Esperando indexacion del email en sucursal...")
suc_token = t.get_token(t.PINOTEPA_LOCATION_ID)
import time as _t
deadline = _t.time() + 30
indexed = False
while _t.time() < deadline:
try:
r = t.gc._request("POST", "/contacts/search", suc_token, json={
"locationId": t.PINOTEPA_LOCATION_ID, "pageLimit": 5, "query": email
})
if any(c.get("id") == branch_id for c in (r.get("contacts") or [])):
indexed = True
break
except Exception:
pass
_t.sleep(2)
log(f" email indexado: {indexed}")
assert indexed, "El email no se indexo en sucursal a tiempo"
# 3) Crear contacto MARCA SIN CF, mismo phone
payload_brand = t._new_contact_payload("FBPU", phone=phone, email=email)
brand_id = t.create_contact(t.BRAND_LOCATION_ID, payload_brand)
cleanup.register(t.BRAND_LOCATION_ID, brand_id, "fbpost brand")
log(f"Brand creado (sin CF): {brand_id}")
# 4) Sanity: confirmar CF Marca vacio
cm0 = t.get_contact(t.BRAND_LOCATION_ID, brand_id)
cf_brand_0 = t.cf_value_of(cm0, t.CF_ID_BRAND)
log(f"CF Marca pre-webhook: {cf_brand_0!r} (esperado: vacio)")
assert not cf_brand_0, f"CF Marca deberia estar vacio, valor={cf_brand_0!r}"
# 5) Disparar webhook Marca->Sucursal
brand_obj = t.get_contact(t.BRAND_LOCATION_ID, brand_id)
webhook_payload = t.build_webhook_payload_marca_to_suc(brand_obj)
s, body = t.fire_webhook(t.WEBHOOK_URL_MARCA_TO_SUC, webhook_payload)
log(f"Webhook status: {s} body: {body[:100]}")
assert s == 200, f"Webhook fallo: {s}"
log("Esperando 18s para que el workflow complete (cascada + UPDATE + autoenlace)...")
time.sleep(18)
# 6) Verificar: CF en MARCA ahora poblado con branch_id
cm1 = t.get_contact(t.BRAND_LOCATION_ID, brand_id)
cf_brand_1 = t.cf_value_of(cm1, t.CF_ID_BRAND)
log(f"CF Marca post-webhook: {cf_brand_1!r}")
if cf_brand_1 == branch_id:
log("[OK] Fallback post-UPDATE: CF Marca quedo enlazado al branch_id.")
else:
log(f"[FAIL] CF Marca = {cf_brand_1!r}, esperaba {branch_id!r}")
sys.exit(2)
# 7) Verificar: CF en SUCURSAL sigue siendo autoref (era branch_id desde antes)
cb1 = t.get_contact(t.PINOTEPA_LOCATION_ID, branch_id)
cf_branch_1 = t.cf_value_of(cb1, cf_id_branch)
log(f"CF Sucursal post-webhook: {cf_branch_1!r}")
if cf_branch_1 == branch_id:
log("[OK] CF Sucursal mantiene autoref.")
else:
log(f"[WARN] CF Sucursal cambio a {cf_branch_1!r}")
finally:
cleanup.run()
if __name__ == "__main__":
main()