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