131 lines
4.7 KiB
Python
131 lines
4.7 KiB
Python
from __future__ import annotations
|
|
|
|
import hashlib
|
|
import hmac
|
|
import json
|
|
|
|
from fastapi.testclient import TestClient
|
|
|
|
from app import main as main_module
|
|
from app.gitea import GiteaClient
|
|
from app.models import Repository
|
|
from app.store import ScanStore
|
|
|
|
|
|
def test_repository_catalog_and_durable_scan_job_contract(tmp_path) -> None:
|
|
main_module.store = ScanStore(str(tmp_path / "history.db"))
|
|
main_module.job_runner = None
|
|
main_module.gitea_client = GiteaClient("http://gitea.local", "test-token", transport=lambda *_: (500, b""))
|
|
repository = Repository(
|
|
id="gitea:64",
|
|
provider="gitea",
|
|
provider_repository_id="64",
|
|
owner="Jens",
|
|
name="RepoPulse",
|
|
full_name="Jens/RepoPulse",
|
|
default_branch="main",
|
|
latest_revision="0123456789abcdef0123456789abcdef01234567",
|
|
)
|
|
main_module.store.upsert_repository(repository)
|
|
client = TestClient(main_module.app)
|
|
|
|
catalog = client.get("/api/v1/repositories")
|
|
assert catalog.status_code == 200
|
|
assert catalog.json()[0]["id"] == "gitea:64"
|
|
assert "latest_scan" not in catalog.json()[0]
|
|
|
|
queued = client.post("/api/v1/repositories/gitea%3A64/scans", json={"force": False})
|
|
assert queued.status_code == 202
|
|
job = queued.json()
|
|
assert job["repository_id"] == "gitea:64"
|
|
assert job["status"] == "queued"
|
|
|
|
duplicate = client.post("/api/v1/repositories/gitea%3A64/scans", json={"force": False})
|
|
assert duplicate.status_code == 202
|
|
assert duplicate.json()["id"] == job["id"]
|
|
assert duplicate.json()["deduplicated"] is True
|
|
|
|
detail = client.get("/api/v1/repositories/gitea%3A64")
|
|
assert detail.status_code == 200
|
|
assert detail.json()["latest_scan"] is None
|
|
assert client.get(f"/api/v1/scan-jobs/{job['id']}").json()["status"] == "queued"
|
|
|
|
|
|
def test_signed_gitea_webhook_only_schedules_default_branch_push(
|
|
tmp_path, monkeypatch
|
|
) -> None:
|
|
main_module.store = ScanStore(str(tmp_path / "history.db"))
|
|
main_module.job_runner = None
|
|
main_module.gitea_client = GiteaClient("http://gitea.local", "test-token", transport=lambda *_: (500, b""))
|
|
repository = Repository(
|
|
id="gitea:64",
|
|
provider="gitea",
|
|
provider_repository_id="64",
|
|
owner="Jens",
|
|
name="RepoPulse",
|
|
full_name="Jens/RepoPulse",
|
|
default_branch="main",
|
|
latest_revision="0123456789abcdef0123456789abcdef01234567",
|
|
)
|
|
main_module.store.upsert_repository(repository)
|
|
monkeypatch.setenv("REPOPULSE_GITEA_WEBHOOK_SECRET", "webhook-secret")
|
|
payload = {
|
|
"repository": {"id": 64},
|
|
"ref": "refs/heads/main",
|
|
"after": "abcdef0123456789abcdef0123456789abcdef01",
|
|
}
|
|
body = json.dumps(payload).encode()
|
|
signature = hmac.new(b"webhook-secret", body, hashlib.sha256).hexdigest()
|
|
client = TestClient(main_module.app)
|
|
|
|
response = client.post(
|
|
"/api/v1/webhooks/gitea",
|
|
content=body,
|
|
headers={"X-Gitea-Signature": signature, "X-Gitea-Event": "push"},
|
|
)
|
|
assert response.status_code == 200
|
|
assert response.json()["job_id"]
|
|
assert main_module.store.get_repository("gitea:64").latest_revision == payload["after"]
|
|
|
|
wrong_signature = client.post(
|
|
"/api/v1/webhooks/gitea",
|
|
content=body,
|
|
headers={"X-Gitea-Signature": "0" * 64, "X-Gitea-Event": "push"},
|
|
)
|
|
assert wrong_signature.status_code == 401
|
|
|
|
feature_payload = payload | {"ref": "refs/heads/feature"}
|
|
feature_body = json.dumps(feature_payload).encode()
|
|
feature_signature = hmac.new(b"webhook-secret", feature_body, hashlib.sha256).hexdigest()
|
|
feature = client.post(
|
|
"/api/v1/webhooks/gitea",
|
|
content=feature_body,
|
|
headers={"X-Gitea-Signature": feature_signature, "X-Gitea-Event": "push"},
|
|
)
|
|
assert feature.status_code == 200
|
|
assert feature.json()["job_id"] is None
|
|
|
|
|
|
def test_meta_exposes_operational_counts_without_connector_token(tmp_path) -> None:
|
|
main_module.store = ScanStore(str(tmp_path / "history.db"))
|
|
main_module.job_runner = None
|
|
main_module.gitea_client = GiteaClient("http://gitea.local", "never-return-this-token")
|
|
main_module.store.upsert_repository(
|
|
Repository(
|
|
id="gitea:64",
|
|
provider="gitea",
|
|
provider_repository_id="64",
|
|
owner="Jens",
|
|
name="RepoPulse",
|
|
full_name="Jens/RepoPulse",
|
|
latest_revision="0123456789abcdef0123456789abcdef01234567",
|
|
)
|
|
)
|
|
|
|
response = TestClient(main_module.app).get("/api/v1/meta")
|
|
|
|
assert response.status_code == 200
|
|
assert response.json()["repository_count"] == 1
|
|
assert response.json()["repository_states"]["never_scanned"] == 1
|
|
assert "never-return-this-token" not in response.text
|