mirror of
https://github.com/codeflash-ai/codeflash-agent.git
synced 2026-05-04 18:25:19 +00:00
* fix: resolve all ruff lint errors across repo Auto-fixed 31 errors (unused imports, formatting, simplifications). Manually fixed 14 remaining: - EXE001: removed shebangs from non-executable bench scripts - C417: replaced map(lambda) with generator expression - C901/PLR0915: extracted _write_and_instrument_tests from generate_ai_tests - C901/PLR0912: extracted _parse_toml_addopts and _ini_section_name from modify_addopts - RUF001/RUF002: replaced ambiguous Unicode chars (en dash, multiplication sign) - FBT002: made boolean params keyword-only in report functions - E402: moved `import re` to top of file in security reports * fix: resolve pre-existing mypy errors across packages - _testgen.py: annotate `generated` as `str` to avoid no-any-return - _test_runner.py: use str() for TimeoutExpired stdout/stderr (bytes|str), remove unused type: ignore on proc.kill() - _candidate_eval.py: annotate `speedup` as `float` to avoid no-any-return from lazy-loaded performance_gain
87 lines
2.2 KiB
Python
87 lines
2.2 KiB
Python
"""Tests for GitHub App authentication."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import httpx
|
|
import jwt as pyjwt
|
|
import respx
|
|
from helpers import WEBHOOK_SECRET
|
|
|
|
from github_app.auth import (
|
|
generate_jwt,
|
|
get_installation_token,
|
|
verify_signature,
|
|
)
|
|
|
|
|
|
def test_generate_jwt_structure(mock_config):
|
|
token = generate_jwt(mock_config)
|
|
# Should be a 3-part JWT.
|
|
parts = token.split(".")
|
|
assert len(parts) == 3
|
|
|
|
|
|
def test_generate_jwt_claims(mock_config):
|
|
token = generate_jwt(mock_config)
|
|
claims = pyjwt.decode(
|
|
token,
|
|
options={"verify_signature": False},
|
|
algorithms=["RS256"],
|
|
)
|
|
# PyJWT requires iss as string; Config.app_id is int, converted in generate_jwt.
|
|
assert claims["iss"] == "12345"
|
|
assert "iat" in claims
|
|
assert "exp" in claims
|
|
# 660 = 600s expiry + 60s backdate.
|
|
assert claims["exp"] - claims["iat"] == 660
|
|
|
|
|
|
def test_verify_signature_valid():
|
|
payload = b"test payload"
|
|
import hashlib
|
|
import hmac
|
|
|
|
sig = hmac.new(
|
|
WEBHOOK_SECRET.encode(),
|
|
payload,
|
|
hashlib.sha256,
|
|
).hexdigest()
|
|
assert verify_signature(payload, f"sha256={sig}", WEBHOOK_SECRET)
|
|
|
|
|
|
def test_verify_signature_invalid():
|
|
assert not verify_signature(b"payload", "sha256=wrong", WEBHOOK_SECRET)
|
|
|
|
|
|
def test_verify_signature_bad_prefix():
|
|
assert not verify_signature(b"payload", "md5=abc", WEBHOOK_SECRET)
|
|
|
|
|
|
@respx.mock
|
|
async def test_get_installation_token_fetches(mock_config):
|
|
respx.post(
|
|
"https://api.github.com/app/installations/99/access_tokens",
|
|
).respond(json={"token": "ghs_test123"})
|
|
|
|
async with httpx.AsyncClient() as client:
|
|
token = await get_installation_token(
|
|
mock_config,
|
|
99,
|
|
client=client,
|
|
)
|
|
|
|
assert token == "ghs_test123"
|
|
|
|
|
|
@respx.mock
|
|
async def test_get_installationtoken_caches(mock_config):
|
|
route = respx.post(
|
|
"https://api.github.com/app/installations/99/access_tokens",
|
|
).respond(json={"token": "ghs_cached"})
|
|
|
|
async with httpx.AsyncClient() as client:
|
|
t1 = await get_installation_token(mock_config, 99, client=client)
|
|
t2 = await get_installation_token(mock_config, 99, client=client)
|
|
|
|
assert t1 == t2 == "ghs_cached"
|
|
assert route.call_count == 1
|