57 lines
2.3 KiB
Python

"""API tests using isolated SQLite files."""
import tempfile
import unittest
from pathlib import Path
from unittest.mock import patch
from fastapi.testclient import TestClient
from app.database import initialize, session
from app.main import app
class UsageApiTest(unittest.TestCase):
def setUp(self):
self.temp = tempfile.TemporaryDirectory()
self.db_path = Path(self.temp.name) / "usage.sqlite3"
initialize(self.db_path)
self.initialize_patch = patch("app.main.initialize", side_effect=lambda: initialize(self.db_path))
self.initialize_patch.start()
self.database_patch = patch("app.main.session", side_effect=lambda: session(self.db_path))
self.database_patch.start()
self.client_context = TestClient(app)
self.client = self.client_context.__enter__()
def tearDown(self):
self.client_context.__exit__(None, None, None)
self.database_patch.stop()
self.initialize_patch.stop()
self.temp.cleanup()
def test_health_and_empty_stats(self):
self.assertEqual(self.client.get("/api/health").json(), {"status": "ok"})
result = self.client.get("/api/stats").json()
self.assertEqual(result["total_clicks"], 0)
self.assertEqual({item["id"]: item["click_count"] for item in result["items"]}, {"risk": 0, "cost": 0})
def test_each_click_increments_once_and_persists(self):
self.assertEqual(self.client.post("/api/apps/risk/click", json={}).status_code, 201)
self.assertEqual(self.client.post("/api/apps/risk/click", json={}).status_code, 201)
self.assertEqual(self.client.post("/api/apps/cost/click", json={}).status_code, 201)
stats = self.client.get("/api/stats").json()
self.assertEqual(stats["total_clicks"], 3)
self.assertEqual({item["id"]: item["click_count"] for item in stats["items"]}, {"risk": 2, "cost": 1})
self.assertIsNotNone(stats["updated_at"])
def test_only_allowlisted_apps_can_be_counted(self):
self.assertEqual(self.client.post("/api/apps/unknown/click", json={}).status_code, 404)
def test_rejects_cross_origin_click(self):
response = self.client.post("/api/apps/risk/click", json={}, headers={"Origin": "https://untrusted.example"})
self.assertEqual(response.status_code, 403)
if __name__ == "__main__":
unittest.main()