fix: address code review findings — duplicate fixture, JWT key length, async deprecation
- Remove duplicate mock_extract_factory fixture in conftest.py - Use 32+ char JWT_SECRET_KEY everywhere (was 15 chars, triggered warnings) - Replace deprecated asyncio.get_event_loop() with asyncio.run() - Unify WebhookEventFactory sign methods (consistent json.dumps)
This commit is contained in:
parent
12480b8c35
commit
863453b2e2
5 changed files with 9 additions and 33 deletions
|
|
@ -10,7 +10,7 @@ import pytest
|
|||
# Set at import time so every worker process picks up the same values
|
||||
# before any module-level code in app.auth.jwt caches the secret.
|
||||
os.environ.setdefault("TESTING", "1")
|
||||
os.environ.setdefault("JWT_SECRET_KEY", "test-secret-e2e")
|
||||
os.environ.setdefault("JWT_SECRET_KEY", "test-secret-key-minimum-32-characters!!")
|
||||
|
||||
# Ensure directories exist for modules with module-level FileHandlers.
|
||||
# bot.py creates FileHandler(config.BOT_LOG_FILE) at import time.
|
||||
|
|
@ -27,7 +27,7 @@ os.makedirs(os.path.join(os.environ["DATA_DIR"], "state"), exist_ok=True)
|
|||
def e2e_env(tmp_path, monkeypatch):
|
||||
"""Set up complete E2E environment with DATA_DIR, create dirs."""
|
||||
monkeypatch.setenv("DATA_DIR", str(tmp_path))
|
||||
monkeypatch.setenv("JWT_SECRET_KEY", "test-secret-e2e")
|
||||
monkeypatch.setenv("JWT_SECRET_KEY", "test-secret-key-minimum-32-characters!!")
|
||||
|
||||
(tmp_path / "extracts").mkdir()
|
||||
(tmp_path / "analytics").mkdir()
|
||||
|
|
@ -103,31 +103,6 @@ def write_test_parquet(path: str, data: list[dict]):
|
|||
conn.close()
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def mock_extract_factory(e2e_env):
|
||||
"""Factory fixture: returns callable that creates mock extract.duckdb files.
|
||||
|
||||
Usage:
|
||||
mock_extract_factory(source_name, tables_list)
|
||||
"""
|
||||
def _factory(source_name: str, tables: list, remote_attach=None):
|
||||
db_path = create_mock_extract(e2e_env["extracts_dir"], source_name, tables)
|
||||
if remote_attach:
|
||||
import duckdb as _duckdb
|
||||
conn = _duckdb.connect(str(db_path))
|
||||
conn.execute("""CREATE TABLE IF NOT EXISTS _remote_attach (
|
||||
alias VARCHAR, extension VARCHAR, url VARCHAR, token_env VARCHAR
|
||||
)""")
|
||||
for row in remote_attach:
|
||||
conn.execute(
|
||||
"INSERT INTO _remote_attach VALUES (?, ?, ?, ?)",
|
||||
[row["alias"], row["extension"], row["url"], row["token_env"]],
|
||||
)
|
||||
conn.close()
|
||||
return db_path
|
||||
return _factory
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def seeded_app(e2e_env):
|
||||
"""FastAPI TestClient with seeded admin + analyst users, JWT tokens."""
|
||||
|
|
|
|||
|
|
@ -105,7 +105,8 @@ class WebhookEventFactory:
|
|||
|
||||
@staticmethod
|
||||
def sign_payload(payload: dict[str, Any], secret: str) -> str:
|
||||
body = json.dumps(payload, sort_keys=True, separators=(",", ":")).encode()
|
||||
"""Sign payload with HMAC-SHA256. Uses default json.dumps() to match production."""
|
||||
body = json.dumps(payload).encode()
|
||||
sig = hmac.new(secret.encode(), body, hashlib.sha256).hexdigest()
|
||||
return f"sha256={sig}"
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ class TestInstanceConfig:
|
|||
def test_missing_config_returns_defaults(self, tmp_path, monkeypatch):
|
||||
monkeypatch.setenv("DATA_DIR", str(tmp_path))
|
||||
monkeypatch.setenv("TESTING", "1")
|
||||
monkeypatch.setenv("JWT_SECRET_KEY", "test-secret-e2e")
|
||||
monkeypatch.setenv("JWT_SECRET_KEY", "test-secret-key-minimum-32-characters!!")
|
||||
from app.instance_config import get_instance_name
|
||||
name = get_instance_name()
|
||||
assert isinstance(name, str)
|
||||
|
|
@ -15,7 +15,7 @@ class TestInstanceConfig:
|
|||
"""get_instance_name should read instance.name from YAML, not flat instance_name."""
|
||||
monkeypatch.setenv("DATA_DIR", str(tmp_path))
|
||||
monkeypatch.setenv("TESTING", "1")
|
||||
monkeypatch.setenv("JWT_SECRET_KEY", "test-secret-e2e")
|
||||
monkeypatch.setenv("JWT_SECRET_KEY", "test-secret-key-minimum-32-characters!!")
|
||||
|
||||
state_dir = tmp_path / "state"
|
||||
state_dir.mkdir(exist_ok=True)
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ from fastapi.testclient import TestClient
|
|||
@pytest.fixture
|
||||
def client(tmp_path, monkeypatch):
|
||||
monkeypatch.setenv("DATA_DIR", str(tmp_path))
|
||||
monkeypatch.setenv("JWT_SECRET_KEY", "test-secret-e2e")
|
||||
monkeypatch.setenv("JWT_SECRET_KEY", "test-secret-key-minimum-32-characters!!")
|
||||
monkeypatch.setenv("SCRIPT_TIMEOUT", "5")
|
||||
|
||||
from app.main import create_app
|
||||
|
|
@ -287,7 +287,7 @@ class TestAuthSecurity:
|
|||
def viewer_client(tmp_path, monkeypatch):
|
||||
"""TestClient with a viewer-role user seeded."""
|
||||
monkeypatch.setenv("DATA_DIR", str(tmp_path))
|
||||
monkeypatch.setenv("JWT_SECRET_KEY", "test-secret-e2e")
|
||||
monkeypatch.setenv("JWT_SECRET_KEY", "test-secret-key-minimum-32-characters!!")
|
||||
monkeypatch.setenv("SCRIPT_TIMEOUT", "5")
|
||||
|
||||
from app.main import create_app
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ def _make_message(text: str, chat_id: int = 10) -> dict:
|
|||
|
||||
def _run(coro):
|
||||
"""Run a coroutine synchronously."""
|
||||
return asyncio.get_event_loop().run_until_complete(coro)
|
||||
return asyncio.run(coro)
|
||||
|
||||
|
||||
class TestHandleMessage:
|
||||
|
|
|
|||
Loading…
Reference in a new issue