Ctrl K
ComunidadGuías…

backend/tests/test_marketplace_service.py

Rama master · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
"""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()