refactor: реструктуризация — core/, db/, routes/, web/
guarddog_nexus/ ├── core/ scanner, harvester, nexus, llm ├── db/ engine, models, queries ├── routes/ webhooks, api_*, web └── web/ templates + static - 11 файлов перемещено (git mv — сохранена история) - Все импорты обновлены (~15 файлов) - main.py, tests — исправлены пути - 50/50 тестов, ruff clean
This commit is contained in:
+2
-2
@@ -18,9 +18,9 @@ os.environ["LOG_SYSLOG_HOST"] = ""
|
||||
os.environ["TEMP_DIR"] = "/tmp/guarddog-nexus-test"
|
||||
|
||||
from guarddog_nexus.constants import DEFAULT_ECOSYSTEM, SEVERITY_WARNING # noqa: E402
|
||||
from guarddog_nexus.database import Base, get_session # noqa: E402
|
||||
from guarddog_nexus.db.engine import Base, get_session # noqa: E402
|
||||
from guarddog_nexus.db.models import Finding, Scan, ScanStatus # noqa: E402
|
||||
from guarddog_nexus.main import app # noqa: E402
|
||||
from guarddog_nexus.models import Finding, Scan, ScanStatus # noqa: E402
|
||||
|
||||
|
||||
@pytest_asyncio.fixture
|
||||
|
||||
+21
-21
@@ -5,16 +5,16 @@ from unittest.mock import patch
|
||||
import pytest
|
||||
from sqlalchemy import select
|
||||
|
||||
from guarddog_nexus.harvester import harvest
|
||||
from guarddog_nexus.models import Finding
|
||||
from guarddog_nexus.core.harvester import harvest
|
||||
from guarddog_nexus.db.models import Finding
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_harvest_new_package(db_session, guarddog_normalized_flagged):
|
||||
with (
|
||||
patch("guarddog_nexus.harvester.download_asset") as mock_dl,
|
||||
patch("guarddog_nexus.harvester.compute_sha256") as mock_sha,
|
||||
patch("guarddog_nexus.harvester.scan_package") as mock_scan,
|
||||
patch("guarddog_nexus.core.harvester.download_asset") as mock_dl,
|
||||
patch("guarddog_nexus.core.harvester.compute_sha256") as mock_sha,
|
||||
patch("guarddog_nexus.core.harvester.scan_package") as mock_scan,
|
||||
):
|
||||
mock_dl.return_value = "/tmp/test-package.tar.gz"
|
||||
mock_sha.return_value = "abc123"
|
||||
@@ -50,9 +50,9 @@ async def test_harvest_new_package(db_session, guarddog_normalized_flagged):
|
||||
async def test_harvest_same_sha256_skips(db_session, guarddog_normalized_flagged):
|
||||
"""Same SHA256 as existing scan → skip, don't re-scan."""
|
||||
with (
|
||||
patch("guarddog_nexus.harvester.download_asset") as mock_dl,
|
||||
patch("guarddog_nexus.harvester.compute_sha256") as mock_sha,
|
||||
patch("guarddog_nexus.harvester.scan_package") as mock_scan,
|
||||
patch("guarddog_nexus.core.harvester.download_asset") as mock_dl,
|
||||
patch("guarddog_nexus.core.harvester.compute_sha256") as mock_sha,
|
||||
patch("guarddog_nexus.core.harvester.scan_package") as mock_scan,
|
||||
):
|
||||
mock_dl.return_value = "/tmp/test.tar.gz"
|
||||
mock_sha.return_value = "deadbeef"
|
||||
@@ -86,9 +86,9 @@ async def test_harvest_same_sha256_skips(db_session, guarddog_normalized_flagged
|
||||
async def test_harvest_different_sha256_scans_again(db_session, guarddog_normalized_flagged):
|
||||
"""Same name/version, different SHA256 → new scan."""
|
||||
with (
|
||||
patch("guarddog_nexus.harvester.download_asset") as mock_dl,
|
||||
patch("guarddog_nexus.harvester.compute_sha256") as mock_sha,
|
||||
patch("guarddog_nexus.harvester.scan_package") as mock_scan,
|
||||
patch("guarddog_nexus.core.harvester.download_asset") as mock_dl,
|
||||
patch("guarddog_nexus.core.harvester.compute_sha256") as mock_sha,
|
||||
patch("guarddog_nexus.core.harvester.scan_package") as mock_scan,
|
||||
):
|
||||
mock_dl.return_value = "/tmp/test.tar.gz"
|
||||
mock_scan.return_value = guarddog_normalized_flagged
|
||||
@@ -123,9 +123,9 @@ async def test_harvest_different_sha256_scans_again(db_session, guarddog_normali
|
||||
async def test_harvest_skips_active_scan_same_url(db_session, guarddog_normalized_flagged):
|
||||
"""Concurrent webhooks for same URL: first proceeding, second skips as PENDING."""
|
||||
with (
|
||||
patch("guarddog_nexus.harvester.download_asset") as mock_dl,
|
||||
patch("guarddog_nexus.harvester.compute_sha256") as mock_sha,
|
||||
patch("guarddog_nexus.harvester.scan_package") as mock_scan,
|
||||
patch("guarddog_nexus.core.harvester.download_asset") as mock_dl,
|
||||
patch("guarddog_nexus.core.harvester.compute_sha256") as mock_sha,
|
||||
patch("guarddog_nexus.core.harvester.scan_package") as mock_scan,
|
||||
):
|
||||
mock_dl.return_value = "/tmp/test.tar.gz"
|
||||
mock_sha.return_value = "aaa"
|
||||
@@ -147,9 +147,9 @@ async def test_harvest_skips_active_scan_same_url(db_session, guarddog_normalize
|
||||
async def test_harvest_same_url_sha256_dedup(db_session, guarddog_normalized_flagged):
|
||||
"""Same URL twice: second run hits SHA256 dedup (first already completed)."""
|
||||
with (
|
||||
patch("guarddog_nexus.harvester.download_asset") as mock_dl,
|
||||
patch("guarddog_nexus.harvester.compute_sha256") as mock_sha,
|
||||
patch("guarddog_nexus.harvester.scan_package") as mock_scan,
|
||||
patch("guarddog_nexus.core.harvester.download_asset") as mock_dl,
|
||||
patch("guarddog_nexus.core.harvester.compute_sha256") as mock_sha,
|
||||
patch("guarddog_nexus.core.harvester.scan_package") as mock_scan,
|
||||
):
|
||||
mock_dl.return_value = "/tmp/test.tar.gz"
|
||||
mock_sha.return_value = "ccc"
|
||||
@@ -182,9 +182,9 @@ async def test_harvest_same_url_sha256_dedup(db_session, guarddog_normalized_fla
|
||||
@pytest.mark.asyncio
|
||||
async def test_harvest_clean_package(db_session, guarddog_normalized_clean):
|
||||
with (
|
||||
patch("guarddog_nexus.harvester.download_asset") as mock_dl,
|
||||
patch("guarddog_nexus.harvester.compute_sha256") as mock_sha,
|
||||
patch("guarddog_nexus.harvester.scan_package") as mock_scan,
|
||||
patch("guarddog_nexus.core.harvester.download_asset") as mock_dl,
|
||||
patch("guarddog_nexus.core.harvester.compute_sha256") as mock_sha,
|
||||
patch("guarddog_nexus.core.harvester.scan_package") as mock_scan,
|
||||
):
|
||||
mock_dl.return_value = "/tmp/test.tar.gz"
|
||||
mock_sha.return_value = "abc"
|
||||
@@ -205,7 +205,7 @@ async def test_harvest_clean_package(db_session, guarddog_normalized_clean):
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_harvest_download_failure(db_session):
|
||||
with patch("guarddog_nexus.harvester.download_asset") as mock_dl:
|
||||
with patch("guarddog_nexus.core.harvester.download_asset") as mock_dl:
|
||||
mock_dl.return_value = None
|
||||
|
||||
scan = await harvest(
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
"""Tests for GuardDog scanner integration."""
|
||||
|
||||
from guarddog_nexus.scanner import _normalize_output
|
||||
from guarddog_nexus.core.scanner import _normalize_output
|
||||
|
||||
|
||||
def test_normalize_clean_output(guarddog_output_clean):
|
||||
|
||||
@@ -34,7 +34,7 @@ async def test_webhook_ignores_created_action(client, sample_nexus_webhook):
|
||||
@pytest.mark.asyncio
|
||||
async def test_webhook_accepts_asset_updated(client, sample_nexus_webhook):
|
||||
sample_nexus_webhook["action"] = "UPDATED"
|
||||
with patch("guarddog_nexus.webhooks._scan_in_background") as _mock:
|
||||
with patch("guarddog_nexus.routes.webhooks._scan_in_background") as _mock:
|
||||
resp = await client.post("/webhooks/nexus", json=sample_nexus_webhook)
|
||||
assert resp.status_code == 200
|
||||
assert resp.json()["status"] == "accepted"
|
||||
@@ -68,7 +68,7 @@ async def test_webhook_no_asset_or_component(client):
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_webhook_accepts_component(client, sample_nexus_component_webhook):
|
||||
with patch("guarddog_nexus.webhooks._scan_component") as _mock:
|
||||
with patch("guarddog_nexus.routes.webhooks._scan_component") as _mock:
|
||||
resp = await client.post("/webhooks/nexus", json=sample_nexus_component_webhook)
|
||||
assert resp.status_code == 200
|
||||
data = resp.json()
|
||||
|
||||
Reference in New Issue
Block a user