Cybersecurity-Projects/PROJECTS/beginner/c2-beacon/backend/tests/test_app.py

87 lines
2.4 KiB
Python

"""
AngelaMos | 2026
test_app.py
"""
from pathlib import Path
import pytest
from httpx import ASGITransport, AsyncClient
from beacon.registry import BeaconRegistry
from beacon.tasking import TaskManager
from database import init_db
from ops.manager import OpsManager
@pytest.fixture
async def client(tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> AsyncClient:
"""
Provide an async HTTP client with a test app using isolated database
"""
test_db_path = tmp_path / "test.db"
import config
monkeypatch.setattr(config.settings, "DATABASE_PATH", test_db_path)
monkeypatch.setattr(config.settings, "APP_NAME", "C2 Beacon Server")
import database
monkeypatch.setattr(database, "settings", config.settings)
await init_db()
from app.__main__ import create_app
test_app = create_app()
test_app.state.registry = BeaconRegistry()
test_app.state.task_manager = TaskManager()
test_app.state.ops_manager = OpsManager()
transport = ASGITransport(app=test_app)
async with AsyncClient(transport=transport, base_url="http://test") as ac:
yield ac
class TestHealthAndRoot:
"""
Verify health check and root information endpoints
"""
async def test_health_returns_200(self, client: AsyncClient) -> None:
"""
Health endpoint responds with 200 and status healthy
"""
response = await client.get("/health")
assert response.status_code == 200
assert response.json()["status"] == "healthy"
async def test_root_returns_app_info(self, client: AsyncClient) -> None:
"""
Root endpoint returns application name and version
"""
response = await client.get("/")
data = response.json()
assert "name" in data
assert "version" in data
class TestBeaconEndpoints:
"""
Verify REST beacon listing endpoints
"""
async def test_list_beacons_empty(self, client: AsyncClient) -> None:
"""
Beacons list returns empty array with no registered beacons
"""
response = await client.get("/beacons")
assert response.status_code == 200
assert response.json() == []
async def test_get_beacon_not_found(self, client: AsyncClient) -> None:
"""
Non-existent beacon ID returns 404
"""
response = await client.get("/beacons/nonexistent")
assert response.status_code == 404