Curatare globala a comentariilor si docstring-urilor (app, tools, teste, scripturi): eliminate referintele la PRD-uri, US-xxx, task-uri istorice si review-uri; pastrata doar informatia functionala, formulata scurt. Regula adaugata in CLAUDE.md (sectiunea Stil). Fara modificari de cod sau comportament. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
140 lines
6.1 KiB
Python
140 lines
6.1 KiB
Python
"""Configurare pytest la nivel de suita: izoleaza testele de `.env`-ul de dezvoltare.
|
|
|
|
In working-dir exista un `.env` pentru probe live (ex. `AUTOPASS_REQUIRE_API_KEY=true`,
|
|
`AUTOPASS_WORKER_USE_TEST_CREDS=true`, creds RAR de test) care e citit automat de
|
|
pydantic Settings. Fara izolare, acele flag-uri ar regla tacit comportamentul
|
|
testelor: 401 pe rutele protejate si creds <test> in loc de fallback-ul pe cont.
|
|
|
|
Fixam un default sigur pe variabilele de mediu — care au PRECEDENTA peste fisierul
|
|
`.env` in pydantic-settings — deci neutralizam doar valorile din fisier, nu si o
|
|
variabila exportata explicit in shell. Testele care chiar verifica enforcement-ul
|
|
(auth pornit, creds <test>) il seteaza punctual prin `monkeypatch`/`object.__setattr__`.
|
|
"""
|
|
|
|
import hashlib
|
|
import os
|
|
|
|
import pytest
|
|
|
|
os.environ.setdefault("AUTOPASS_REQUIRE_API_KEY", "false")
|
|
os.environ.setdefault("AUTOPASS_WORKER_USE_TEST_CREDS", "false")
|
|
# Embeddings e ON implicit in app (config.py), dar in teste il lasam OFF ca sa nu
|
|
# lazy-load-eze modelul de ~230MB la fiecare test care atinge editorul de mapari
|
|
# (suita rapida, fara download in CI). Testele de embeddings il pornesc punctual.
|
|
os.environ.setdefault("AUTOPASS_EMBEDDINGS_ENABLED", "false")
|
|
# Seed-ul de operatii etichetate e ON in app, dar OFF in teste: multe teste presupun
|
|
# mapping_suggestions GOL la init_db. Testele care au nevoie de el il pornesc punctual
|
|
# (object.__setattr__ pe settings sau apel direct la seeder).
|
|
os.environ.setdefault("AUTOPASS_SEED_OPERATII_ENABLED", "false")
|
|
|
|
|
|
# Referinta la init_db-ul REAL (nemodificat), capturata O SINGURA DATA la prima rulare a
|
|
# fixturii de mai jos. Wrapper-ul o refoloseste ca sa nu se auto-imbrace recursiv.
|
|
_REAL_INIT_DB = None
|
|
|
|
|
|
@pytest.fixture(autouse=True)
|
|
def _auto_send_on_default_account(request, monkeypatch):
|
|
"""Contul default id=1 (seed schema.sql, INSERT OR IGNORE) porneste pe
|
|
`auto_send_enabled=0` (Auto OFF) — corect in productie (nimic nu pleaca fara confirmare).
|
|
|
|
Dar suita exercita lantul `POST -> claim_one -> sent` pe contul id=1
|
|
(test_import_e2e, test_creds_delivery, test_live_rar): cu Auto OFF, ingestia ar marca
|
|
`held=1` si worker-ul (`claim_one ... AND held=0`) nu ar mai lua randul
|
|
-> testele ar stagna tacit. E un fix de STARE DB, nu env var (coloana e per-rand in
|
|
`accounts`), deci il aplicam wraparind `init_db` (contul id=1 NU e creat de `create_account`
|
|
-> un patch pe factory NU l-ar acoperi).
|
|
|
|
Wrapam `init_db` astfel incat orice DB de test creat sa aiba id=1 pe Auto ON (held=0 la
|
|
ingestie), pastrand suita verde ca inainte de 5.19. Conturile create explicit de teste
|
|
(`create_account`) raman pe default OFF -> testele care VOR Auto OFF il primesc corect.
|
|
|
|
Testele care verifica DEFAULT-ul brut (id=1 == 0 imediat dupa init_db) se exclud cu
|
|
markerul `no_auto_send_seed`.
|
|
"""
|
|
global _REAL_INIT_DB
|
|
import sys
|
|
|
|
import app.db as _db
|
|
|
|
if _REAL_INIT_DB is None:
|
|
_REAL_INIT_DB = _db.init_db
|
|
|
|
if request.node.get_closest_marker("no_auto_send_seed"):
|
|
yield
|
|
return
|
|
|
|
def _init_db_auto_on():
|
|
_REAL_INIT_DB()
|
|
conn = _db.get_connection()
|
|
try:
|
|
conn.execute("UPDATE accounts SET auto_send_enabled=1 WHERE id=1")
|
|
conn.commit()
|
|
finally:
|
|
conn.close()
|
|
|
|
# app.db.init_db: acopera fixturile care fac `from app.db import init_db` in corpul lor
|
|
# (importul ruleaza DUPA acest patch -> primeste wrapper-ul) + apelurile `app.db.init_db()`.
|
|
monkeypatch.setattr(_db, "init_db", _init_db_auto_on)
|
|
# app.main.init_db: lifespan-ul TestClient cheama numele importat la nivel de modul
|
|
# (`from .db import init_db`); daca app.main e deja importat, patch-uim si referinta lui.
|
|
# Daca NU e inca importat, primul `from app.main import app` din test il va lega la
|
|
# wrapper-ul de mai sus automat (citeste app.db.init_db la momentul importului).
|
|
_main = sys.modules.get("app.main")
|
|
if _main is not None:
|
|
monkeypatch.setattr(_main, "init_db", _init_db_auto_on, raising=False)
|
|
yield
|
|
# Anti-leak: daca app.main a fost importat IN timpul testului (legand wrapper-ul la
|
|
# import, nu prin monkeypatch), readu-l la init_db-ul real ca sa nu ramana wrapat global.
|
|
_main = sys.modules.get("app.main")
|
|
if _main is not None and getattr(_main, "init_db", None) is _init_db_auto_on:
|
|
_main.init_db = _REAL_INIT_DB
|
|
|
|
|
|
@pytest.fixture(autouse=True)
|
|
def _reset_embeddings_singleton():
|
|
"""Reseteaza singleton-ul global de embeddings intre teste (izolare de ordine).
|
|
|
|
`enrich_suggestions` foloseste `embeddings.has_corpus()` ca poarta; un test care
|
|
indexeaza corpusul pe singleton-ul global (ex. test_module_level_index_corpus)
|
|
altfel l-ar lasa populat -> teste ulterioare care cheama pending_unmapped ar primi
|
|
sugestii embedding spurioase. Resetam la None inainte si dupa fiecare test.
|
|
"""
|
|
try:
|
|
import app.embeddings as _emb
|
|
_emb._engine = None
|
|
except Exception:
|
|
pass
|
|
yield
|
|
try:
|
|
import app.embeddings as _emb
|
|
_emb._engine = None
|
|
except Exception:
|
|
pass
|
|
|
|
|
|
def make_test_cui(seed: str = "") -> str:
|
|
"""Factory centralizat: genereaza un CUI de test unic din seed.
|
|
|
|
Folosit de fixture-urile de test care creeaza conturi via /signup sau create_account
|
|
si au nevoie de un CUI unic per test (altfel unicitatea CUI-ului bloca al doilea signup
|
|
cu acelasi seed in acelasi DB de test).
|
|
|
|
Formatul 'ROTE' + 8 hex-uri e suficient de unic per DB de test (izolata per test).
|
|
"""
|
|
h = hashlib.md5(seed.encode()).hexdigest()[:8].upper()
|
|
return f"ROTE{h}"
|
|
|
|
|
|
def pytest_configure(config):
|
|
"""Markeri custom. `live` = teste care ating endpoint-ul real RAR (opt-in,
|
|
skip implicit; vezi tests/test_live_rar.py). Excludere: `-m 'not live'`."""
|
|
config.addinivalue_line(
|
|
"markers", "live: test live pe RAR test (necesita AUTOPASS_LIVE_RAR=1 + creds reale)"
|
|
)
|
|
config.addinivalue_line(
|
|
"markers",
|
|
"no_auto_send_seed: dezactiveaza fixtura autouse care pune id=1 pe Auto ON "
|
|
"(teste care verifica default-ul brut auto_send_enabled=0 al contului id=1)",
|
|
)
|