# tests/senarios/test_edge_cases.py

import pytest
from unittest.mock import MagicMock
from beautyspot import Spot
from beautyspot.db import SQLiteTaskDB
from beautyspot.storage import LocalStorage


def test_path_traversal_prevention(tmp_path):
    """Test that LocalStorage prevents path traversal attacks."""
    storage = LocalStorage(str(tmp_path))

    with pytest.raises(ValueError, match="Invalid key"):
        storage.save("../malicious", b"data")

    with pytest.raises(ValueError, match="Invalid key"):
        storage.save("subdir/malicious", b"data")


def test_storage_failure_handling(tmp_path):
    """Test that spot handles storage failures gracefully (or raises as expected)."""
    # In the current implementation, spot doesn't catch storage errors during save,
    # so we expect it to propagate. This test documents that behavior.

    spot = Spot(
        name="test_proj",
        db=SQLiteTaskDB(tmp_path / "test.db"),
        storage_backend=LocalStorage(tmp_path / "blobs"),
    )

    # Mock storage.save to fail
    spot.cache.storage.save = MagicMock(side_effect=PermissionError("Disk full"))

    @spot.mark(save_blob=True)
    def my_task():
        return "data"

    with pytest.raises(PermissionError):
        my_task()


def test_db_failure_handling(tmp_path):
    """Test behavior when DB fails."""
    spot = Spot(name="test_proj", db=SQLiteTaskDB(tmp_path / "test.db"))

    # Mock db.save to fail
    spot.cache.db.save = MagicMock(side_effect=Exception("DB Connection Lost"))

    @spot.mark
    def my_task():
        return "data"

    # Currently expected to propagate
    with pytest.raises(Exception, match="DB Connection Lost"):
        my_task()


def test_invalid_json_serialization(tmp_path):
    """Test behavior when unserializable object is returned."""
    from beautyspot.serializer import SerializationError

    spot = Spot(name="test_proj", db=SQLiteTaskDB(tmp_path / "test.db"))

    class Unserializable:
        pass

    @spot.mark(save_blob=False)
    def bad_task():
        return Unserializable()

    with pytest.raises(SerializationError):
        bad_task()
