backend/tests/test_marketplace_service.py
Rama master · réplica de lectura del repositorio original.
"""Tests for SHA256 integrity verification in the marketplace service."""
import hashlib
import io
import zipfile
from unittest.mock import MagicMock, patch
import pytest
def make_zip_bytes() -> bytes:
buf = io.BytesIO()
with zipfile.ZipFile(buf, "w") as zf:
zf.writestr("provider.py", "class P: pass")
return buf.getvalue()
def test_sha256_passes_on_match():
from services.marketplace import verify_zip_sha256
data = make_zip_bytes()
expected = hashlib.sha256(data).hexdigest()
assert verify_zip_sha256(data, expected) is True
def test_sha256_fails_on_mismatch():
from services.marketplace import verify_zip_sha256
data = make_zip_bytes()
assert verify_zip_sha256(data, "wrong") is False
def test_sha256_skipped_when_empty():
from services.marketplace import verify_zip_sha256
assert verify_zip_sha256(b"anything", "") is True
def test_sha256_case_insensitive():
from services.marketplace import verify_zip_sha256
data = make_zip_bytes()
expected = hashlib.sha256(data).hexdigest().upper()
assert verify_zip_sha256(data, expected) is True
def test_install_raises_on_sha256_mismatch(tmp_path):
from services.marketplace import PluginMarketplace
data = make_zip_bytes()
with patch("requests.get") as mock_get:
resp = MagicMock()
resp.content = data
resp.raise_for_status = MagicMock()
resp.is_redirect = False
mock_get.return_value = resp
marketplace = PluginMarketplace()
with pytest.raises(RuntimeError, match="SHA256 mismatch"):
marketplace.install_plugin_from_zip(
plugin_name="test",
zip_url="https://example.com/plugin.zip",
expected_sha256="0" * 64,
plugins_dir=str(tmp_path),
)
def test_install_succeeds_on_correct_sha256(tmp_path):
from services.marketplace import PluginMarketplace
data = make_zip_bytes()
correct_sha = hashlib.sha256(data).hexdigest()
with patch("requests.get") as mock_get:
resp = MagicMock()
resp.content = data
resp.raise_for_status = MagicMock()
resp.is_redirect = False
mock_get.return_value = resp
with patch("services.marketplace.safe_zip_extract"):
marketplace = PluginMarketplace()
result = marketplace.install_plugin_from_zip(
plugin_name="test",
zip_url="https://example.com/plugin.zip",
expected_sha256=correct_sha,
plugins_dir=str(tmp_path),
)
assert result["status"] == "installed"
assert "test" in result["path"]
def test_install_refuses_an_empty_sha256(tmp_path):
"""No hash, no install: the index supplies one for every plugin (#71)."""
from services.marketplace import PluginMarketplace
with patch("requests.get") as mock_get:
marketplace = PluginMarketplace()
with pytest.raises(RuntimeError, match="SHA256 is required"):
marketplace.install_plugin_from_zip(
plugin_name="test",
zip_url="https://example.com/plugin.zip",
expected_sha256="",
plugins_dir=str(tmp_path),
)
mock_get.assert_not_called()