""" 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}" )