""" Test: Basic App Import and Route Tests (pytest-compatible) ========================================================== Tests module imports and all GET routes without requiring Oracle. Converted from api/test_app_basic.py. Run: pytest api/tests/test_app_basic.py -v """ import os import sys import tempfile import pytest # --- Marker: all tests here are unit (no Oracle) --- pytestmark = pytest.mark.unit # --- Set env vars BEFORE any app import --- _tmpdir = tempfile.mkdtemp() _sqlite_path = os.path.join(_tmpdir, "test_import.db") os.environ["FORCE_THIN_MODE"] = "true" os.environ["SQLITE_DB_PATH"] = _sqlite_path os.environ["ORACLE_DSN"] = "dummy" os.environ["ORACLE_USER"] = "dummy" os.environ["ORACLE_PASSWORD"] = "dummy" os.environ.setdefault("JSON_OUTPUT_DIR", _tmpdir) # Add api/ to path so we can import app _api_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) if _api_dir not in sys.path: sys.path.insert(0, _api_dir) # ------------------------------------------------------- # Section 1: Module Import Checks # ------------------------------------------------------- MODULES = [ "app.config", "app.database", "app.main", "app.routers.health", "app.routers.dashboard", "app.routers.mappings", "app.routers.sync", "app.routers.validation", "app.routers.articles", "app.services.sqlite_service", "app.services.scheduler_service", "app.services.mapping_service", "app.services.article_service", "app.services.validation_service", "app.services.import_service", "app.services.sync_service", "app.services.order_reader", ] @pytest.mark.parametrize("module_name", MODULES) def test_module_import(module_name): """Each app module should import without errors.""" __import__(module_name) # ------------------------------------------------------- # Section 2: Route Tests via TestClient # ------------------------------------------------------- # (path, expected_status_codes, is_known_oracle_failure) GET_ROUTES = [ ("/health", [200], False), ("/", [200, 500], False), ("/missing-skus", [200, 500], False), ("/mappings", [200, 500], False), ("/logs", [200, 500], False), ("/api/mappings", [200, 503], True), ("/api/mappings/export-csv", [200, 503], True), ("/api/mappings/csv-template", [200], False), ("/api/sync/status", [200], False), ("/api/sync/history", [200], False), ("/api/sync/schedule", [200], False), ("/api/validate/missing-skus", [200], False), ("/api/validate/missing-skus?page=1&per_page=10", [200], False), ("/api/sync/run/nonexistent/log", [200, 404], False), ("/api/articles/search?q=ab", [200, 503], True), ("/settings", [200, 500], False), ] @pytest.fixture(scope="module") def client(): """Create a TestClient with lifespan for all route tests.""" from fastapi.testclient import TestClient from app.main import app with TestClient(app, raise_server_exceptions=False) as c: yield c @pytest.mark.parametrize( "path,expected_codes,is_oracle_route", GET_ROUTES, ids=[p for p, _, _ in GET_ROUTES], ) def test_route(client, path, expected_codes, is_oracle_route): """Each GET route should return an expected status code.""" resp = client.get(path) assert resp.status_code in expected_codes, ( f"GET {path} returned {resp.status_code}, expected one of {expected_codes}. " f"Body: {resp.text[:300]}" )