"""Tests for api module.""" import os import pytest from unittest.mock import patch, MagicMock from factsdb.config import DatabaseConfig @pytest.fixture def app(tmp_path, monkeypatch): """Create a Flask test app with in-memory DB and mocked config.""" db_path = str(tmp_path / "test.db") monkeypatch.setenv("DATABASE_PATH", db_path) monkeypatch.setenv("AI_ENDPOINT_URL", "http://localhost:8000/v1") monkeypatch.setenv("AI_ENDPOINT_TOKEN", "tok") monkeypatch.setenv("FTP_USERNAME", "u") monkeypatch.setenv("FTP_PASSWORD", "p") monkeypatch.setenv("API_KEY", "test-key") from factsdb.api import create_app return create_app() @pytest.fixture def client(app): return app.test_client() class TestHealth: def test_health(self, client): resp = client.get("/health") assert resp.status_code == 200 data = resp.get_json() assert data["status"] == "healthy" assert data["service"] == "FactsDB" class TestVersion: def test_version(self, client): resp = client.get("/version") assert resp.status_code == 200 data = resp.get_json() assert "version" in data class TestGetTables: def test_without_api_key(self, client): resp = client.get("/tables") assert resp.status_code == 401 def test_with_api_key(self, client): resp = client.get("/tables", headers={"X-API-Key": "test-key"}) assert resp.status_code == 200 data = resp.get_json() assert "tables" in data assert "total_tables" in data class TestGetTableData: def test_without_api_key(self, client): resp = client.get("/tables/nonexistent") assert resp.status_code == 401 def test_with_api_key(self, client): resp = client.get("/tables/nonexistent", headers={"X-API-Key": "test-key"}) assert resp.status_code == 200 data = resp.get_json() assert "facts" in data class TestQueryTable: def test_without_api_key(self, client): resp = client.post("/tables/t1/query") assert resp.status_code == 401 def test_with_api_key(self, client): resp = client.post( "/tables/t1/query", headers={"X-API-Key": "test-key"}, json={"query": "test"} ) assert resp.status_code == 200 class TestGetTableCount: def test_without_api_key(self, client): resp = client.get("/tables/t1/count") assert resp.status_code == 401 def test_with_api_key(self, client): resp = client.get("/tables/t1/count", headers={"X-API-Key": "test-key"}) assert resp.status_code == 200 data = resp.get_json() assert "count" in data class TestGetFact: def test_without_api_key(self, client): resp = client.get("/fact/1") assert resp.status_code == 401 def test_not_found(self, client): resp = client.get("/fact/999", headers={"X-API-Key": "test-key"}) assert resp.status_code == 404 class TestSearch: def test_without_api_key(self, client): resp = client.get("/search") assert resp.status_code == 401 def test_missing_query(self, client): resp = client.get("/search", headers={"X-API-Key": "test-key"}) assert resp.status_code == 400 def test_with_query(self, client): resp = client.get("/search?q=test", headers={"X-API-Key": "test-key"}) assert resp.status_code == 200 class TestMetrics: def test_metrics_prometheus(self, client): resp = client.get("/metrics") assert resp.status_code == 200 def test_metrics_json(self, client): resp = client.get("/metrics/json") assert resp.status_code == 200 data = resp.get_json() assert "metrics" in data class TestStats: def test_without_api_key(self, client): resp = client.get("/stats") assert resp.status_code == 401 def test_with_api_key(self, client): resp = client.get("/stats", headers={"X-API-Key": "test-key"}) assert resp.status_code == 200 class TestNoApiKeyRequired: """Test endpoints that work when API_KEY env var is empty.""" def test_tables_open(self, tmp_path, monkeypatch): db_path = str(tmp_path / "test.db") monkeypatch.setenv("DATABASE_PATH", db_path) monkeypatch.setenv("AI_ENDPOINT_URL", "http://localhost:8000/v1") monkeypatch.setenv("AI_ENDPOINT_TOKEN", "tok") monkeypatch.setenv("FTP_USERNAME", "u") monkeypatch.setenv("FTP_PASSWORD", "p") monkeypatch.setenv("API_KEY", "") from factsdb.api import create_app app = create_app() c = app.test_client() resp = c.get("/tables") assert resp.status_code == 200