"""
Tests for view executor module
"""

import pytest
from django.contrib.auth.models import User
from rest_framework import generics, serializers, status
from rest_framework.response import Response
from rest_framework.test import APIRequestFactory

from drf_mcp.executor import ViewInvoker


class SimpleSerializer(serializers.Serializer):
    """Simple test serializer"""
    name = serializers.CharField(max_length=100)
    email = serializers.EmailField()


class SimpleAPIView(generics.GenericAPIView):
    """Simple test API view"""
    serializer_class = SimpleSerializer

    def get(self, request):
        """GET method"""
        return Response({"message": "test"})

    def post(self, request):
        """POST method"""
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        return Response(serializer.data, status=status.HTTP_201_CREATED)


@pytest.mark.django_db
@pytest.mark.asyncio
class TestViewInvoker:
    """Test async view executor"""

    @pytest.fixture
    def invoker(self):
        """Provide invoker instance"""
        return ViewInvoker()

    @pytest.fixture
    def test_user(self):
        """Create test user"""
        return User.objects.create_user(
            username="testuser",
            email="test@example.com",
            password="testpass",
        )

    async def test_invoker_initialization(self, invoker):
        """Test invoker can be initialized"""
        assert invoker is not None
        assert invoker.factory is not None

    async def test_invoke_get_request(self, invoker):
        """Test invoking GET request"""
        response = await invoker.invoke(
            SimpleAPIView,
            "GET",
            "/test/",
        )
        assert response == {"message": "test"}

    async def test_invoke_with_user(self, invoker, test_user):
        """Test invoking with authenticated user"""
        response = await invoker.invoke(
            SimpleAPIView,
            "GET",
            "/test/",
            user=test_user,
        )
        assert response == {"message": "test"}

    async def test_invalid_http_method(self, invoker):
        """Test invalid HTTP method raises error"""
        with pytest.raises(ValueError):
            await invoker.invoke(
                SimpleAPIView,
                "INVALID",
                "/test/",
            )
