""" Real sync test: GoMag API → validate → import into Oracle (MARIUSM_AUTO). Requires: - App running on localhost:5003 - GOMAG_API_KEY set in api/.env - Oracle configured (MARIUSM_AUTO_AUTO) """ import os import time from datetime import datetime, timedelta from pathlib import Path import httpx import pytest from dotenv import load_dotenv pytestmark = pytest.mark.sync # Load .env once at module level for API key check _env_path = Path(__file__).parents[2] / ".env" load_dotenv(str(_env_path), override=True) _GOMAG_API_KEY = os.environ.get("GOMAG_API_KEY", "") _GOMAG_API_SHOP = os.environ.get("GOMAG_API_SHOP", "") if not _GOMAG_API_KEY: pytestmark = [pytest.mark.sync, pytest.mark.skip(reason="GOMAG_API_KEY not set")] @pytest.fixture(scope="module") def client(base_url): with httpx.Client(base_url=base_url, timeout=30.0) as c: yield c @pytest.fixture(scope="module") def gomag_api_key(): if not _GOMAG_API_KEY: pytest.skip("GOMAG_API_KEY is empty or not set") return _GOMAG_API_KEY @pytest.fixture(scope="module") def gomag_api_shop(): if not _GOMAG_API_SHOP: pytest.skip("GOMAG_API_SHOP is empty or not set") return _GOMAG_API_SHOP def _wait_for_sync(client, timeout=60): """Poll sync status until it stops running. Returns final status dict.""" deadline = time.monotonic() + timeout while time.monotonic() < deadline: r = client.get("/api/sync/status") assert r.status_code == 200, f"sync/status returned {r.status_code}" data = r.json() if data.get("status") != "running": return data time.sleep(2) raise TimeoutError(f"Sync did not finish within {timeout}s") def test_gomag_api_connection(gomag_api_key, gomag_api_shop): """Verify direct GoMag API connectivity and order presence.""" seven_days_ago = (datetime.now() - timedelta(days=7)).strftime("%Y-%m-%d") # GoMag API uses a central endpoint, not the shop URL url = "https://api.gomag.ro/api/v1/order/read/json" params = {"startDate": seven_days_ago, "page": 1, "limit": 5} headers = {"X-Oc-Restadmin-Id": gomag_api_key} with httpx.Client(timeout=30.0, follow_redirects=True) as c: r = c.get(url, params=params, headers=headers) assert r.status_code == 200, f"GoMag API returned {r.status_code}: {r.text[:200]}" data = r.json() # GoMag returns either a list or a dict with orders key if isinstance(data, dict): assert "orders" in data or len(data) > 0, "GoMag API returned empty response" else: assert isinstance(data, list), f"Unexpected GoMag response type: {type(data)}" def test_app_sync_start(client, gomag_api_key): """Trigger a real sync via the app API and wait for completion.""" r = client.post("/api/sync/start") assert r.status_code == 200, f"sync/start returned {r.status_code}: {r.text[:200]}" final_status = _wait_for_sync(client, timeout=60) assert final_status.get("status") != "running", ( f"Sync still running after timeout: {final_status}" ) def test_sync_results(client): """Verify the latest sync run processed at least one order.""" r = client.get("/api/sync/history", params={"per_page": 1}) assert r.status_code == 200, f"sync/history returned {r.status_code}" data = r.json() runs = data.get("runs", []) assert len(runs) > 0, "No sync runs found in history" latest = runs[0] assert latest.get("total_orders", 0) > 0, ( f"Latest sync run has 0 orders: {latest}" ) def test_sync_idempotent(client, gomag_api_key): """Re-running sync should result in ALREADY_IMPORTED, not double imports.""" r = client.post("/api/sync/start") assert r.status_code == 200, f"sync/start returned {r.status_code}" _wait_for_sync(client, timeout=60) r = client.get("/api/sync/history", params={"per_page": 1}) assert r.status_code == 200 data = r.json() runs = data.get("runs", []) assert len(runs) > 0, "No sync runs found after second sync" latest = runs[0] total = latest.get("total_orders", 0) already_imported = latest.get("already_imported", 0) imported = latest.get("imported", 0) # Most orders should be ALREADY_IMPORTED on second run if total > 0: assert already_imported >= imported, ( f"Expected mostly ALREADY_IMPORTED on second run, " f"got imported={imported}, already_imported={already_imported}, total={total}" )