57 lines
2.3 KiB
Python
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()
|