Files
comun/utile/Teste/partener_anaf/mock_anaf_verificare.prg
Marius Mutu 95cf54e447 Verificare ANAF: raspunsul 404 citit, intrerupator cand serviciul nu raspunde
Serviciul ANAF intoarce HTTP 404 cu corp complet pentru codurile inexistente
({"found":[],"notFound":[...]}), iar wrapper-ul citea corpul doar pe 200 - deci
verdictul "cod inexistent" nu aparea niciodata. Corpul se citeste acum la orice
status, iar verdictul se da doar cand notFound contine chiar codul interogat;
orice alt corp neinteles inseamna "nu a raspuns", nu acuzatie.

Timeout-uri reale pe apelurile web (2/2/3/3): garda Pemstatus din jurul lui
SetTimeouts intoarce .F. pe obiectul COM legat tarziu, deci timeout-urile nu se
aplicau, iar o gazda care inghite pachetele bloca interfata ~21 s per rand.
Aceleasi timeout-uri si pe drumul batch. Fallback-ul Microsoft.XMLHTTP, fara
timeout, a fost scos de pe calea single.

Cand serviciul nu raspunde, verificarile se opresc 10 minute si banda arata ca
au fost sarite, in loc sa taca. La deschiderea formularului pleaca o sonda
asincrona de disponibilitate, cu termen de viata, guard de reintrare si Abort()
la inchidere; randul care asteapta verdictul nu face apel propriu. Cache doar pe
rezultate pozitive. Codul fiscal nenumeric primeste mesaj propriu, in banda si
in detaliile F4.

ParseJsonANAFv8 restaureaza formatul datei si pe calea de eroare (o exceptie
lasa toata sesiunea pe YMD).

Teste: suita headless 70/70, cu sonda si clasele de esec mock-uite (fara retea)
si fixture peste corpurile 404 masurate pe serviciul real.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DhJwsrFFe1ZNAAtS8Twuti
2026-07-27 16:25:02 +03:00

90 lines
4.2 KiB
Plaintext

* mock_anaf_verificare.prg - inlocuieste FUNCTION ANAF_VerificaCuiSingle (validare.prg) cu raspunsuri
* preconfigurate, ca testul UI sa NU faca apeluri reale la serviciul ANAF (lent/nedeterminist).
* Se incarca cu SET PROCEDURE ... ADDITIVE INAINTEA lui test_init_env_auto (care incarca validare.prg
* real) - la nume duplicat de FUNCTION, VFP foloseste fisierul cautat PRIMUL (verificat empiric,
* vezi COMUN\docs\testare-ui-vfp.md capcana g). NormalizeazaCUI (validare.prg) NU e suprascrisa -
* se foloseste cea reala.
* IMPORTANT: goANAFMockData (Collection cu raspunsuri, cheie 'C'+cui normalizat) si gnANAFCallCount
* (contor apeluri reale, nu din cache) se construiesc INLINE in programul principal al testului,
* NU aici si NU intr-o PROCEDURE - vezi capcana l din depanare_testare_vfp.md (CREATEOBJECT/
* ADDPROPERTY apelate dintr-o PROCEDURA se comporta gresit in acest runtime headless; SET PROCEDURE
* nici nu executa codul de top-level al acestui fisier, doar inregistreaza FUNCTION-ul de mai jos).
* Contor apeluri: gnANAFCallCount creste doar cand mock-ul e efectiv apelat (ANAF_StarePartener
* verifica intai goCacheANAF_Sesiune - cache-hit NU ajunge aici).
* runda 12: tdData (data documentului, trimisa de ANAF_StarePartener) e retinuta in gdANAFUltimaData,
* ca testul sa poata verifica ca data ajunge efectiv la wrapper.
* T7/lane E (handoff_anaf_404.md): al 4-lea parametru tcClasaEsec, prin referinta, identic cu wrapper-ul
* real ('' / 'FARA_RASPUNS' / 'RASPUNS_NEINTELES'). Simulare clasa de esec: daca valoarea din
* goANAFMockData pentru o cheie e STRING (nu obiect), e tratata ca nume de clasa de esec - mock-ul
* intoarce .NULL. cu tcClasaEsec = acea valoare, fara sa atinga tlNegasit (ramane .F., ca la wrapper-ul
* real pe caile FARA_RASPUNS/RASPUNS_NEINTELES). Restul (CUI neconfigurat = "cod inexistent" simulat) e
* neschimbat.
FUNCTION ANAF_VerificaCuiSingle
LPARAMETERS tcCui, tdData, tlNegasit, tcClasaEsec
LOCAL lcCui, lcKey, luItem
tlNegasit = .F.
tcClasaEsec = ''
IF TYPE('goANAFMockData') <> 'O'
RETURN .NULL.
ENDIF
IF TYPE('gnANAFCallCount') = 'N'
gnANAFCallCount = gnANAFCallCount + 1
ENDIF
IF VARTYPE(m.tdData) = 'D'
gdANAFUltimaData = m.tdData
ENDIF
lcCui = NormalizeazaCUI(m.tcCui)
lcKey = 'C' + m.lcCui
IF goANAFMockData.GetKey(m.lcKey) = 0
tlNegasit = .T. && CUI neconfigurat - simuleaza raspunsul ANAF "cod inexistent"
RETURN .NULL.
ENDIF
luItem = goANAFMockData.Item(m.lcKey)
IF VARTYPE(m.luItem) = 'C'
tcClasaEsec = m.luItem && simuleaza esecul wrapper-ului (FARA_RASPUNS / RASPUNS_NEINTELES)
RETURN .NULL.
ENDIF
RETURN m.luItem
ENDFUNC
* T7/lane E, dupa T5/sonda (handoff_anaf_404.md): mock peste sonda asincrona de disponibilitate
* (ANAF_SondaPorneste/AuSositRaspunsul/AReusit/Opreste, validare.prg) - fara mock, Activeaza()
* ar face un apel HTTP real (winHTTP async) la fiecare test cu starea NECUNOSCUT. Globalele de
* control (gcMockSondaModo, glMockSondaActiva, gnMockSondaPornireCount, glMockSondaGataManual,
* glMockSondaReusitaManual) se construiesc INLINE in programul principal (acelasi motiv ca mai sus).
* Mod 'AUTO' (implicit): sonda "raspunde" instant cu succes la primul ANAF_SondaVerifica() - transparent
* pentru scenariile care nu testeaza explicit sonda. Mod 'MANUAL': testul controleaza explicit daca/cand
* "a sosit raspunsul" (glMockSondaGataManual) si cu ce rezultat (glMockSondaReusitaManual) - foloseste
* pentru S2 (sonda in aer)/S3 (sonda reuseste)/S4 (sonda expira).
FUNCTION ANAF_SondaPorneste
IF TYPE('gnMockSondaPornireCount') = 'N'
gnMockSondaPornireCount = gnMockSondaPornireCount + 1
ENDIF
glMockSondaActiva = .T.
RETURN .T.
ENDFUNC
FUNCTION ANAF_SondaAuSositRaspunsul
IF TYPE('glMockSondaActiva') <> 'L' OR !glMockSondaActiva
RETURN .T.
ENDIF
IF TYPE('gcMockSondaModo') = 'C' AND gcMockSondaModo == 'MANUAL'
RETURN glMockSondaGataManual
ENDIF
RETURN .T. && AUTO: raspunde imediat
ENDFUNC
FUNCTION ANAF_SondaAReusit
IF TYPE('gcMockSondaModo') = 'C' AND gcMockSondaModo == 'MANUAL'
RETURN glMockSondaReusitaManual
ENDIF
RETURN .T. && AUTO: succes implicit
ENDFUNC
FUNCTION ANAF_SondaOpreste
LOCAL llOprita
llOprita = (TYPE('glMockSondaActiva') = 'L' AND glMockSondaActiva)
glMockSondaActiva = .F.
RETURN m.llOprita
ENDFUNC