feat: улучшить agentic-readiness — добавить CI, проверки конфигурации и тесты

This commit is contained in:
Marat Kharitonov
2026-07-06 22:18:12 +03:00
parent 2b695aed82
commit 3818c2db29
6 changed files with 251 additions and 133 deletions
+34 -13
View File
@@ -109,60 +109,76 @@ class TestPaginationE2e:
"""End-to-end tests for pagination functionality."""
@pytest.mark.asyncio
async def test_e2e_scans_pagination(self, e2e_client):
async def test_e2e_scans_pagination(self, e2e_client, sample_e2e_scan):
"""Verify that scan list pagination works."""
# First page
resp1 = await e2e_client.get("/api/v1/scans?limit=10&offset=0")
assert resp1.status_code == 200
data1 = resp1.json()
assert data1["limit"] == 10
assert data1["offset"] == 0
assert data1["total"] >= 1
assert len(data1["scans"]) >= 1
assert any(p["package_name"] == "test-e2e-pkg" for p in data1["scans"])
# Second page
resp2 = await e2e_client.get("/api/v1/scans?limit=10&offset=10")
assert resp2.status_code == 200
data2 = resp2.json()
assert data2["limit"] == 10
assert data2["offset"] == 10
assert data2["total"] >= 0
@pytest.mark.asyncio
async def test_e2e_packages_pagination(self, e2e_client):
async def test_e2e_packages_pagination(self, e2e_client, sample_e2e_scan):
"""Verify that package list pagination works."""
resp1 = await e2e_client.get("/api/v1/packages?limit=5&offset=0")
assert resp1.status_code == 200
data1 = resp1.json()
assert data1["limit"] == 5
assert data1["offset"] == 0
assert data1["total"] >= 1
assert any(p["name"] == "test-e2e-pkg" for p in data1["packages"])
class TestFilteringE2e:
"""End-to-end tests for filtering functionality."""
@pytest.mark.asyncio
async def test_e2e_scan_filter_by_status(self, e2e_client):
async def test_e2e_scan_filter_by_status(self, e2e_client, sample_e2e_scan):
"""Verify that scans can be filtered by status."""
resp = await e2e_client.get("/api/v1/scans?status=completed")
assert resp.status_code == 200
data = resp.json()
assert data["total"] >= 1
assert all(s["status"] == "completed" for s in data["scans"])
assert any(s["package_name"] == "test-e2e-pkg" for s in data["scans"])
@pytest.mark.asyncio
async def test_e2e_scan_filter_by_flagged(self, e2e_client):
async def test_e2e_scan_filter_by_flagged(self, e2e_client, sample_e2e_scan):
"""Verify that scans can be filtered by flagged status."""
resp = await e2e_client.get("/api/v1/scans?flagged=true")
assert resp.status_code == 200
data = resp.json()
assert data["total"] >= 1
assert all(s["flagged"] is True for s in data["scans"])
assert any(s["package_name"] == "test-e2e-pkg" for s in data["scans"])
@pytest.mark.asyncio
async def test_e2e_scan_filter_by_search(self, e2e_client):
async def test_e2e_scan_filter_by_search(self, e2e_client, e2e_db_session, sample_e2e_scan):
"""Verify that scans can be filtered by search term."""
resp = await e2e_client.get("/api/v1/scans?search=e2e")
assert resp.status_code == 200
data = resp.json()
# If there are matching scans, they should contain the search term
if data["scans"]:
assert any("e2e" in s["package_name"] for s in data["scans"])
assert data["total"] >= 1
assert all("e2e" in scan["package_name"] for scan in data["scans"])
@pytest.mark.asyncio
async def test_e2e_scan_filter_no_match_returns_empty(self, e2e_client, e2e_db_session):
"""Verify that filter with no matches returns empty list."""
resp = await e2e_client.get("/api/v1/scans?search=zzznotfound")
assert resp.status_code == 200
data = resp.json()
assert data["total"] == 0
assert data["scans"] == []
class TestErrorHandlingE2e:
@@ -220,16 +236,21 @@ class TestWebsocketFragmentE2e:
"""E2E tests for HTMX fragment responses."""
@pytest.mark.asyncio
async def test_e2e_scans_fragment_response(self, e2e_client):
async def test_e2e_scans_fragment_response(self, e2e_client, sample_e2e_scan):
"""Verify that scans page returns fragment when HX-Request header is set."""
resp = await e2e_client.get("/scans", headers={"HX-Request": "true"})
assert resp.status_code == 200
# Fragment should not include full HTML structure
assert "<!DOCTYPE" not in resp.text
assert "<table" in resp.text
assert "scans-table-container" in resp.text
assert "test-e2e-pkg" in resp.text
@pytest.mark.asyncio
async def test_e2e_packages_fragment_response(self, e2e_client):
async def test_e2e_packages_fragment_response(self, e2e_client, sample_e2e_scan):
"""Verify that packages page returns fragment when HX-Request header is set."""
resp = await e2e_client.get("/packages", headers={"HX-Request": "true"})
assert resp.status_code == 200
assert "<!DOCTYPE" not in resp.text
assert "<table" in resp.text
assert "packages-table-container" in resp.text
assert "test-e2e-pkg" in resp.text
+21 -2
View File
@@ -71,6 +71,10 @@ class TestWebhookToScanFlow:
assert resp.status_code == 200
data = resp.json()
assert data["status"] == "accepted"
assert data["asset"] == "/" + e2e_go_webhook_payload["asset"]["name"].strip("/")
assert data["action"] == "UPDATED"
assert data["asset"] == "/packages/github.com/e2e/test-go/@v/v1.0.0.zip"
assert data["action"] == "UPDATED"
@pytest.mark.asyncio
async def test_e2e_webhook_accepts_npm_asset(
@@ -102,6 +106,10 @@ class TestWebhookToScanFlow:
assert resp.status_code == 200
data = resp.json()
assert data["status"] == "accepted"
assert data["asset"] == e2e_npm_webhook_payload["asset"]["name"]
assert data["action"] == "UPDATED"
assert data["asset"] == "/packages/e2e-test-npm/-/e2e-test-npm-1.0.0.tgz"
assert data["action"] == "UPDATED"
@pytest.mark.asyncio
async def test_e2e_webhook_accepts_scoped_npm_asset(self, e2e_client, e2e_db_session):
@@ -139,7 +147,10 @@ class TestWebhookToScanFlow:
resp = await e2e_client.post("/webhooks/nexus", json=payload)
assert resp.status_code == 200
assert resp.json()["status"] == "accepted"
data = resp.json()
assert data["status"] == "accepted"
assert data["asset"] == "/packages/@angular/core/-/core-18.0.0.tgz"
assert data["action"] == "UPDATED"
class TestWebhookSignatureValidation:
@@ -167,8 +178,11 @@ class TestWebhookSignatureValidation:
headers={"X-Nexus-Webhook-Signature": signature, "Content-Type": "application/json"},
)
# Should be accepted (signature matches)
assert resp.status_code == 200
data = resp.json()
assert data["status"] == "accepted"
assert data["asset"] == e2e_webhook_payload["asset"]["name"]
assert data["action"] == "UPDATED"
config.webhook_secret = original_secret
@@ -237,6 +251,10 @@ class TestApiIntegration:
assert resp.status_code == 200
data = resp.json()
assert data["total"] >= 2
assert len(data["findings"]) >= 2
rules = {f["rule"] for f in data["findings"]}
assert "shady-links" in rules
assert "exec-base64" in rules
@pytest.mark.asyncio
async def test_e2e_api_findings_filter_by_rule(self, e2e_client, sample_e2e_scan):
@@ -281,6 +299,7 @@ class TestWebUiIntegration:
resp = await e2e_client.get("/packages")
assert resp.status_code == 200
assert "Packages" in resp.text or "Пакеты" in resp.text
assert "test-e2e-pkg" in resp.text
@pytest.mark.asyncio
async def test_e2e_package_detail_page(self, e2e_client, sample_e2e_scan):