mirror of
https://github.com/bellingcat/auto-archiver-api.git
synced 2026-06-12 21:48:35 +03:00
default endpoints tested
This commit is contained in:
3
.gitignore
vendored
3
.gitignore
vendored
@@ -18,4 +18,5 @@ wit*
|
|||||||
src/crawls
|
src/crawls
|
||||||
.coverage
|
.coverage
|
||||||
.pytest_cache/*
|
.pytest_cache/*
|
||||||
htmlcov
|
htmlcov
|
||||||
|
local_archive
|
||||||
11
Pipfile
Normal file
11
Pipfile
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
[[source]]
|
||||||
|
url = "https://pypi.org/simple"
|
||||||
|
verify_ssl = true
|
||||||
|
name = "pypi"
|
||||||
|
|
||||||
|
[packages]
|
||||||
|
|
||||||
|
[dev-packages]
|
||||||
|
|
||||||
|
[requires]
|
||||||
|
python_version = "3.10"
|
||||||
@@ -12,7 +12,6 @@ from security import get_user_auth, bearer_security
|
|||||||
|
|
||||||
default_router = APIRouter()
|
default_router = APIRouter()
|
||||||
|
|
||||||
|
|
||||||
@default_router.get("/")
|
@default_router.get("/")
|
||||||
async def home(request: Request):
|
async def home(request: Request):
|
||||||
# TODO: maybe split into 2 routes: one non authenticated and one authenticated for the groups info only
|
# TODO: maybe split into 2 routes: one non authenticated and one authenticated for the groups info only
|
||||||
@@ -27,7 +26,7 @@ async def home(request: Request):
|
|||||||
|
|
||||||
|
|
||||||
@default_router.get("/health")
|
@default_router.get("/health")
|
||||||
async def health(request: Request):
|
async def health():
|
||||||
return JSONResponse({"status": "ok"})
|
return JSONResponse({"status": "ok"})
|
||||||
|
|
||||||
@default_router.get("/groups", response_model=list[str])
|
@default_router.get("/groups", response_model=list[str])
|
||||||
|
|||||||
15
src/main.py
15
src/main.py
@@ -50,11 +50,16 @@ app.include_router(interoperability_router)
|
|||||||
# prometheus exposed in /metrics with authentication
|
# prometheus exposed in /metrics with authentication
|
||||||
Instrumentator(should_group_status_codes=False, excluded_handlers=["/metrics"]).instrument(app).expose(app, dependencies=[Depends(token_api_key_auth)])
|
Instrumentator(should_group_status_codes=False, excluded_handlers=["/metrics"]).instrument(app).expose(app, dependencies=[Depends(token_api_key_auth)])
|
||||||
|
|
||||||
# used mostly for development in combination with local_archive
|
def setup_local_archive_serve():
|
||||||
SERVE_LOCAL_ARCHIVE = os.environ.get("SERVE_LOCAL_ARCHIVE", "")
|
# if env SERVE_LOCAL_ARCHIVE is set it serves files from that dir, useful for development and using local_archive
|
||||||
if len(SERVE_LOCAL_ARCHIVE) > 1 and os.path.isdir(SERVE_LOCAL_ARCHIVE):
|
SERVE_LOCAL_ARCHIVE = os.environ.get("SERVE_LOCAL_ARCHIVE", "")
|
||||||
logger.info(f"mounting local archive {SERVE_LOCAL_ARCHIVE}")
|
local_dir = SERVE_LOCAL_ARCHIVE
|
||||||
app.mount(SERVE_LOCAL_ARCHIVE, StaticFiles(directory=SERVE_LOCAL_ARCHIVE), name=SERVE_LOCAL_ARCHIVE)
|
if not os.path.isdir(local_dir) and os.path.isdir(local_dir.replace("/app", ".")):
|
||||||
|
local_dir = local_dir.replace("/app", ".")
|
||||||
|
if len(SERVE_LOCAL_ARCHIVE) > 1 and os.path.isdir(local_dir):
|
||||||
|
logger.warning(f"MOUNTing local archive {SERVE_LOCAL_ARCHIVE}")
|
||||||
|
app.mount(SERVE_LOCAL_ARCHIVE, StaticFiles(directory=local_dir), name=SERVE_LOCAL_ARCHIVE)
|
||||||
|
setup_local_archive_serve()
|
||||||
|
|
||||||
|
|
||||||
app.middleware("http")(logging_middleware)
|
app.middleware("http")(logging_middleware)
|
||||||
|
|||||||
@@ -8,8 +8,6 @@ from core.config import CHROME_APP_IDS, BLOCKED_EMAILS
|
|||||||
assert len(CHROME_APP_IDS) > 0, "CHROME_APP_IDS env variable not properly set, it's a csv"
|
assert len(CHROME_APP_IDS) > 0, "CHROME_APP_IDS env variable not properly set, it's a csv"
|
||||||
for app_id in CHROME_APP_IDS:
|
for app_id in CHROME_APP_IDS:
|
||||||
assert len(app_id) > 10, f"CHROME_APP_IDS got invalid id: {app_id} env variable not set"
|
assert len(app_id) > 10, f"CHROME_APP_IDS got invalid id: {app_id} env variable not set"
|
||||||
logger.info(f"{CHROME_APP_IDS=}")
|
|
||||||
logger.info(f"{len(BLOCKED_EMAILS)=}")
|
|
||||||
|
|
||||||
# Auth logic
|
# Auth logic
|
||||||
bearer_security = HTTPBearer()
|
bearer_security = HTTPBearer()
|
||||||
|
|||||||
79
src/tests/endpoints/test_default.py
Normal file
79
src/tests/endpoints/test_default.py
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
from unittest.mock import AsyncMock, patch
|
||||||
|
from fastapi.testclient import TestClient
|
||||||
|
from core.config import VERSION
|
||||||
|
|
||||||
|
|
||||||
|
def test_endpoint_home():
|
||||||
|
from main import app
|
||||||
|
client = TestClient(app)
|
||||||
|
|
||||||
|
r = client.get("/")
|
||||||
|
assert r.status_code == 200
|
||||||
|
j = r.json()
|
||||||
|
assert "version" in j and j["version"] == VERSION
|
||||||
|
assert "breakingChanges" in j
|
||||||
|
assert "groups" not in j
|
||||||
|
|
||||||
|
|
||||||
|
@patch("endpoints.default.bearer_security", new_callable=AsyncMock)
|
||||||
|
@patch("endpoints.default.get_user_auth", new_callable=AsyncMock, return_value="test@example.com")
|
||||||
|
@patch("endpoints.default.crud.get_user_groups", return_value=["group1", "group2"])
|
||||||
|
def test_endpoint_home_with_groups(m1, m2, m3):
|
||||||
|
from main import app
|
||||||
|
client = TestClient(app)
|
||||||
|
|
||||||
|
r = client.get("/")
|
||||||
|
assert r.status_code == 200
|
||||||
|
j = r.json()
|
||||||
|
assert "version" in j and j["version"] == VERSION
|
||||||
|
assert "breakingChanges" in j
|
||||||
|
assert "groups" in j
|
||||||
|
assert j["groups"] == ["group1", "group2"]
|
||||||
|
|
||||||
|
|
||||||
|
def test_endpoint_health():
|
||||||
|
from main import app
|
||||||
|
client = TestClient(app)
|
||||||
|
|
||||||
|
r = client.get("/health")
|
||||||
|
assert r.status_code == 200
|
||||||
|
assert r.json() == {"status": "ok"}
|
||||||
|
|
||||||
|
|
||||||
|
def test_endpoint_groups_403():
|
||||||
|
from main import app
|
||||||
|
client = TestClient(app)
|
||||||
|
r = client.get("/groups")
|
||||||
|
assert r.status_code == 403
|
||||||
|
|
||||||
|
|
||||||
|
@patch("endpoints.default.crud.get_user_groups", return_value=["group1", "group2"])
|
||||||
|
def test_endpoint_groups(m1):
|
||||||
|
async def mock_get_user_auth(): return True
|
||||||
|
from main import app
|
||||||
|
from security import get_user_auth
|
||||||
|
app.dependency_overrides[get_user_auth] = mock_get_user_auth
|
||||||
|
|
||||||
|
client = TestClient(app)
|
||||||
|
r = client.get("/groups")
|
||||||
|
|
||||||
|
assert r.status_code == 200
|
||||||
|
j = r.json()
|
||||||
|
assert j == ["group1", "group2"]
|
||||||
|
|
||||||
|
|
||||||
|
def test_no_serve_local_archive_by_default():
|
||||||
|
from main import app
|
||||||
|
client = TestClient(app)
|
||||||
|
|
||||||
|
r = client.get("/app/local_archive_test/temp.txt")
|
||||||
|
assert r.status_code == 404
|
||||||
|
|
||||||
|
|
||||||
|
def test_favicon():
|
||||||
|
from main import app
|
||||||
|
client = TestClient(app)
|
||||||
|
|
||||||
|
r = client.get("/favicon.ico")
|
||||||
|
assert r.status_code == 200
|
||||||
|
assert r.headers["content-type"] == "image/vnd.microsoft.icon"
|
||||||
22
src/tests/test_main.py
Normal file
22
src/tests/test_main.py
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
import os
|
||||||
|
from fastapi.testclient import TestClient
|
||||||
|
|
||||||
|
|
||||||
|
def test_serve_local_archive_logic():
|
||||||
|
os.environ["SERVE_LOCAL_ARCHIVE"] = "/app/local_archive_test"
|
||||||
|
|
||||||
|
# create a test file
|
||||||
|
os.makedirs("local_archive_test", exist_ok=True)
|
||||||
|
with open("local_archive_test/temp.txt", "w") as f:
|
||||||
|
f.write("test")
|
||||||
|
|
||||||
|
from main import app, setup_local_archive_serve
|
||||||
|
setup_local_archive_serve()
|
||||||
|
client = TestClient(app)
|
||||||
|
|
||||||
|
r = client.get("/app/local_archive_test/temp.txt")
|
||||||
|
assert r.status_code == 200
|
||||||
|
assert r.text == "test"
|
||||||
|
|
||||||
|
os.remove("local_archive_test/temp.txt")
|
||||||
|
os.rmdir("local_archive_test")
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
import pytest
|
|
||||||
from fastapi.testclient import TestClient
|
|
||||||
from core.config import VERSION
|
|
||||||
|
|
||||||
def test_mock_logger():
|
|
||||||
from main import app
|
|
||||||
|
|
||||||
client = TestClient(app)
|
|
||||||
|
|
||||||
response = client.get("/")
|
|
||||||
assert response.status_code == 200
|
|
||||||
r = response.json()
|
|
||||||
assert "version" in r and r["version"] == VERSION
|
|
||||||
Reference in New Issue
Block a user