{
  "steward": "python-test-steward",
  "project": "Azure-AI-RAG-CSharp-Semantic-Kernel-Functions",
  "runDate": "2026-03-22",
  "runId": "2026-03-22T00-00-00",
  "findings": [
    {
      "id": "PYTS-COVER-001",
      "title": "Zero test coverage across all Python modules",
      "severity": "critical",
      "category": "COVER",
      "file": "src/DocumentLoaderFunction/function_app.py",
      "description": "No test files exist in the repository. Every production Python module — the blob trigger handler, the search index loader, the HTML parser, and the infrastructure script — has zero test coverage. There is no way to verify correctness of blob processing, HTML parsing, or search index population without manual deployment to Azure.",
      "recommendation": "Create a tests/ directory alongside src/DocumentLoaderFunction/. Add pytest, pytest-mock, and coverage to a requirements-dev.txt. Implement a minimum test suite covering: html_to_json with valid and invalid HTML, AISearchIndexLoader.populate_search_index with mocked search clients, and Loader handler with a mocked InputStream and all Azure clients mocked.",
      "status": "open"
    },
    {
      "id": "PYTS-CONFIG-001",
      "title": "No pytest configuration",
      "severity": "critical",
      "category": "CONFIG",
      "file": "src/DocumentLoaderFunction/",
      "description": "There is no pytest configuration file (pytest.ini, pyproject.toml, or setup.cfg). Without this, CI runners cannot discover or execute tests reliably. Test paths, asyncio mode, and coverage reporting are unspecified.",
      "recommendation": "Add a pyproject.toml (or pytest.ini) at the DocumentLoaderFunction root with at minimum: testpaths = [\"tests\"], addopts = \"--tb=short\", and asyncio_mode = \"auto\" if async tests are introduced.",
      "status": "open"
    },
    {
      "id": "PYTS-COVER-002",
      "title": "Blob trigger handler Loader has no test coverage",
      "severity": "critical",
      "category": "COVER",
      "file": "src/DocumentLoaderFunction/function_app.py",
      "line": 99,
      "description": "The Loader function is the production entry point for all document ingestion. It contains multiple failure modes, including a reference to blob_service_client at lines 99-100 that is outside the try block, meaning an UnboundLocalError will occur if any exception is raised during the setup phase before that variable is assigned. This bug cannot be caught without a test that exercises the failure path.",
      "recommendation": "Write a test test_should_raise_unbound_error_when_exception_occurs_before_blob_client_assigned to confirm and document the behavior. Then fix the scoping issue in the production code.",
      "status": "open"
    },
    {
      "id": "PYTS-COVER-003",
      "title": "AISearchIndexLoader.populate_search_index has no test coverage",
      "severity": "critical",
      "category": "COVER",
      "file": "src/DocumentLoaderFunction/function_app.py",
      "line": 114,
      "description": "The index creation and document upload logic is entirely untested. The function makes three external service calls (index check, optional index creation, document upload) and raises exceptions on embedding or upload failure. No test verifies any of these paths.",
      "recommendation": "Add tests with mocked SearchIndexClient and SearchClient covering: index exists path, index does not exist path, successful document upload, and upload exception propagation.",
      "status": "open"
    },
    {
      "id": "PYTS-MOCK-001",
      "title": "No mocking infrastructure for Azure SDK or LangChain",
      "severity": "notable",
      "category": "MOCK",
      "file": "src/DocumentLoaderFunction/requirements.txt",
      "description": "The requirements.txt contains no test dependencies (pytest-mock, coverage). Any test that instantiates production code as-is would invoke real Azure services, breaking CI in environments without credentials.",
      "recommendation": "Create a requirements-dev.txt (or requirements-test.txt) containing pytest, pytest-mock, pytest-cov, and any Azure SDK test helpers. Document in the project README how to run tests locally.",
      "status": "open"
    },
    {
      "id": "PYTS-COVER-004",
      "title": "html_to_json has no tests despite being purely functional",
      "severity": "notable",
      "category": "COVER",
      "file": "src/DocumentLoaderFunction/function_app.py",
      "line": 188,
      "description": "html_to_json takes bytes input and returns a (dict, str) tuple with no external dependencies. It is the easiest function in the codebase to unit test. The lack of tests means that edge cases (missing HTML tags, empty input, malformed HTML) are unverified, and refactoring this function carries no safety net.",
      "recommendation": "Add a TestHtmlToJson class with at minimum: valid HTML happy path, HTML missing <title>, HTML missing all optional sections, and empty bytes input.",
      "status": "open"
    },
    {
      "id": "PYTS-ISOLATE-001",
      "title": "Global os.environ mutation in Loader will cause test pollution",
      "severity": "notable",
      "category": "ISOLATE",
      "file": "src/DocumentLoaderFunction/function_app.py",
      "line": 49,
      "description": "Lines 49-54 write directly to os.environ at runtime (OPENAI_API_TYPE, OPENAI_API_KEY, AZURE_OPENAI_AD_TOKEN). If tests invoke Loader without isolating the environment, these mutations will leak into other tests and affect global process state.",
      "recommendation": "Wrap all test invocations of Loader with unittest.mock.patch.dict(os.environ, {}, clear=True) or use a pytest fixture that saves/restores environment variables. Consider using the monkeypatch fixture for cleaner isolation.",
      "status": "open"
    },
    {
      "id": "PYTS-COVER-005",
      "title": "DirectoryZipper utility has no tests",
      "severity": "minor",
      "category": "COVER",
      "file": "infra/scripts/directory_zipper.py",
      "description": "infra/scripts/directory_zipper.py defines a DirectoryZipper class used in the deployment pipeline. It performs file system operations with no error handling. No tests verify exclusion logic, ZIP creation, or temp directory cleanup.",
      "recommendation": "Add tests using the tmp_path pytest fixture: verify files are copied, excluded dirs are skipped, excluded file extensions are skipped, and the temp directory is cleaned up after create_zip.",
      "status": "open"
    },
    {
      "id": "PYTS-INFO-001",
      "title": "html_to_json is well-structured for unit testing",
      "severity": "info",
      "category": "COVER",
      "file": "src/DocumentLoaderFunction/function_app.py",
      "line": 188,
      "description": "html_to_json has a clean signature, no side effects, and no external dependencies. It is an ideal starting point for introducing the test suite — low mocking overhead and high value as a regression baseline.",
      "recommendation": "Prioritize html_to_json tests as the first step to establish a test baseline for the project.",
      "status": "open"
    },
    {
      "id": "PYTS-INFO-002",
      "title": ".funcignore references a test directory, indicating test intent",
      "severity": "info",
      "category": "CONFIG",
      "file": "src/DocumentLoaderFunction/.funcignore",
      "description": "The .funcignore file lists 'test' as an exclusion from Azure Functions deployment packages. This confirms the team intended to add tests. The directory itself does not exist yet.",
      "recommendation": "Create the tests/ directory and populate it following the recommended test additions in the review document.",
      "status": "open"
    }
  ],
  "summary": {
    "critical": 4,
    "notable": 3,
    "minor": 1,
    "info": 2,
    "total": 10
  }
}
