feat(service-auto): săpt 3-phase2 — toate ipotezele confirmate + modul funcțional
Backend: - service_auto module complet: router, service, schemas, 5 teste suites (22/22 passed) - 5 endpoints: GET /ping, /firme, /tip-deviz, /masini, POST /comenzi - SP_CREEAZA_COMANDA_PROTOTIP creat în MARIUSM_AUTO (VALID, 5.9ms) - oracle_pool.py: session_callback backward-compat patch - ROA_WEB user: grants SP-only confirmate (H3), mariusm_test pool switchat - pyproject.toml: integration pytest marker înregistrat Frontend: - ComandaNoua.vue: date reale din Oracle (firme/tip-deviz/masini), nu hardcodate - src/modules/service-auto/services/api.js: axios service cu Bearer token - src/router/index.js: rută /service-auto/comanda-noua Docs: - decision-log.md: verdict MERGE, toate 6 ipoteze CONFIRMED - learnings.md: 7 patterns reutilizabile - grants-audit.md: arhitectura multi-tenant + proxy auth analysis + V_NOM_FIRME loop - template-modul-oracle.md: rețetă completă pentru module Oracle noi - TODO-phase2.md: 7 items concrete Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
109
backend/modules/service_auto/tests/test_diacritice_encoding.py
Normal file
109
backend/modules/service_auto/tests/test_diacritice_encoding.py
Normal file
@@ -0,0 +1,109 @@
|
||||
"""
|
||||
Integration test — Hypothesis #4: diacritice encoding end-to-end.
|
||||
|
||||
Verifies that RAISE_APPLICATION_ERROR(-20001, 'mesaj cu ă î ș ț â') flows correctly
|
||||
through the full chain: Oracle → oracledb → _handle_oracle_error → HTTPException.detail
|
||||
|
||||
Two layers tested:
|
||||
L1 (live Oracle) — PL/SQL anonymous block raises ORA-20001 with diacritice;
|
||||
oracledb.DatabaseError.args[0].message must contain them intact.
|
||||
L2 (_handle_oracle_error) — the HTTPException.detail must contain diacritice,
|
||||
ORA prefix stripped.
|
||||
|
||||
No HTTP server needed. Requires live Oracle connection (mariusm_test pool credentials).
|
||||
|
||||
Run:
|
||||
cd /workspace/roa2web
|
||||
python -m pytest backend/modules/service_auto/tests/test_diacritice_encoding.py -v -m integration
|
||||
"""
|
||||
import os
|
||||
import sys
|
||||
import pytest
|
||||
import oracledb
|
||||
from fastapi import HTTPException
|
||||
|
||||
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', '..', '..', '..'))
|
||||
|
||||
from backend.modules.service_auto.services.comanda_service import _handle_oracle_error
|
||||
|
||||
HOST = "10.0.20.121"
|
||||
PORT = 1521
|
||||
SERVICE_NAME = "ROA"
|
||||
SECRETS_FILE = os.path.join(
|
||||
os.path.dirname(__file__), '..', '..', '..', 'secrets', 'mariusm_test.oracle_pass'
|
||||
)
|
||||
USER = "ROA_WEB"
|
||||
|
||||
# Romanian diacritice in error message — full set
|
||||
DIACRITICE_MSG = "Client invalid: ă î ș ț â Ă Î Ș Ț Â"
|
||||
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
def oracle_conn():
|
||||
"""Live connection as ROA_WEB for the duration of this test module."""
|
||||
with open(SECRETS_FILE) as f:
|
||||
pwd = f.read().strip()
|
||||
conn = oracledb.connect(user=USER, password=pwd, host=HOST, port=PORT, service_name=SERVICE_NAME)
|
||||
yield conn
|
||||
conn.close()
|
||||
|
||||
|
||||
@pytest.mark.integration
|
||||
def test_l1_oracle_encodes_diacritice_in_raise_application_error(oracle_conn):
|
||||
"""
|
||||
L1: Oracle sends diacritice in RAISE_APPLICATION_ERROR message.
|
||||
oracledb decodes them correctly through the NLS chain.
|
||||
"""
|
||||
raised = None
|
||||
with oracle_conn.cursor() as cur:
|
||||
try:
|
||||
cur.execute(
|
||||
f"BEGIN RAISE_APPLICATION_ERROR(-20001, :msg); END;",
|
||||
{"msg": DIACRITICE_MSG},
|
||||
)
|
||||
except oracledb.DatabaseError as e:
|
||||
raised = e
|
||||
|
||||
assert raised is not None, "Expected ORA-20001 to be raised"
|
||||
err = raised.args[0]
|
||||
assert err.code == 20001, f"Expected code 20001, got {err.code}"
|
||||
|
||||
# Every Romanian diacritic character must survive the Oracle → Python round-trip
|
||||
for char in "ăîșțâĂÎȘȚÂ":
|
||||
assert char in err.message, (
|
||||
f"Diacritic '{char}' lost in Oracle→oracledb encoding. "
|
||||
f"Full message: {err.message!r}"
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.integration
|
||||
def test_l2_handle_oracle_error_preserves_diacritice_in_http_detail(oracle_conn):
|
||||
"""
|
||||
L2: _handle_oracle_error strips ORA prefix and passes diacritice into HTTPException.detail.
|
||||
"""
|
||||
raised_db = None
|
||||
with oracle_conn.cursor() as cur:
|
||||
try:
|
||||
cur.execute(
|
||||
"BEGIN RAISE_APPLICATION_ERROR(-20001, :msg); END;",
|
||||
{"msg": DIACRITICE_MSG},
|
||||
)
|
||||
except oracledb.DatabaseError as e:
|
||||
raised_db = e
|
||||
|
||||
assert raised_db is not None
|
||||
|
||||
# Pass through the same handler used in production
|
||||
with pytest.raises(HTTPException) as exc_info:
|
||||
_handle_oracle_error(raised_db)
|
||||
|
||||
http_exc = exc_info.value
|
||||
assert http_exc.status_code == 422
|
||||
assert not http_exc.detail.startswith("ORA-"), (
|
||||
f"ORA prefix not stripped from detail: {http_exc.detail!r}"
|
||||
)
|
||||
for char in "ăîșțâĂÎȘȚÂ":
|
||||
assert char in http_exc.detail, (
|
||||
f"Diacritic '{char}' lost in _handle_oracle_error. "
|
||||
f"detail: {http_exc.detail!r}"
|
||||
)
|
||||
Reference in New Issue
Block a user