# tests/unit/api/test_get_resolved_store_code.py
"""
Unit tests for get_resolved_store_code dependency.

Tests the store code resolution logic that supports both:
- Path-based routing: /store/{store_code}/dashboard (store_code in URL)
- Subdomain/custom domain: /store/dashboard (store resolved by middleware)
"""

from unittest.mock import MagicMock, Mock

import pytest
from fastapi import HTTPException

from app.api.deps import get_resolved_store_code


@pytest.mark.unit
@pytest.mark.stores
class TestGetResolvedStoreCode:
    """Test suite for get_resolved_store_code dependency."""

    @pytest.mark.asyncio
    async def test_returns_store_code_from_path_params(self):
        """When store_code is in path params (path-based routing), return it."""
        request = Mock()
        request.path_params = {"store_code": "ACME"}
        request.state = MagicMock()

        result = await get_resolved_store_code(request)

        assert result == "ACME"

    @pytest.mark.asyncio
    async def test_returns_store_code_from_middleware_state(self):
        """When no path param but middleware resolved store, return store.store_code."""
        mock_store = Mock()
        mock_store.store_code = "ORION"

        request = Mock()
        request.path_params = {}
        request.state = MagicMock()
        request.state.store = mock_store

        result = await get_resolved_store_code(request)

        assert result == "ORION"

    @pytest.mark.asyncio
    async def test_path_param_takes_priority_over_middleware(self):
        """Path param should be preferred even if middleware also resolved a store."""
        mock_store = Mock()
        mock_store.store_code = "MIDDLEWARE_STORE"

        request = Mock()
        request.path_params = {"store_code": "PATH_STORE"}
        request.state = MagicMock()
        request.state.store = mock_store

        result = await get_resolved_store_code(request)

        assert result == "PATH_STORE"

    @pytest.mark.asyncio
    async def test_raises_404_when_no_store_found(self):
        """When neither path param nor middleware provides store, raise 404."""
        request = Mock()
        request.path_params = {}
        request.state = MagicMock()
        request.state.store = None

        with pytest.raises(HTTPException) as exc_info:
            await get_resolved_store_code(request)

        assert exc_info.value.status_code == 404
        assert "Store not found" in str(exc_info.value.detail)

    @pytest.mark.asyncio
    async def test_empty_string_path_param_falls_through(self):
        """Empty string path param should fall through to middleware."""
        mock_store = Mock()
        mock_store.store_code = "FALLBACK"

        request = Mock()
        request.path_params = {"store_code": ""}
        request.state = MagicMock()
        request.state.store = mock_store

        result = await get_resolved_store_code(request)

        assert result == "FALLBACK"

    @pytest.mark.asyncio
    async def test_no_path_params_key_falls_through(self):
        """When path_params doesn't contain store_code, fall through to middleware."""
        mock_store = Mock()
        mock_store.store_code = "WIDGET"

        request = Mock()
        request.path_params = {"order_id": "123"}
        request.state = MagicMock()
        request.state.store = mock_store

        result = await get_resolved_store_code(request)

        assert result == "WIDGET"

    @pytest.mark.asyncio
    async def test_raises_404_when_no_state_store_attribute(self):
        """When request.state has no store attribute at all, raise 404."""
        request = Mock()
        request.path_params = {}
        # Simulate missing attribute
        request.state = MagicMock(spec=[])

        with pytest.raises(HTTPException) as exc_info:
            await get_resolved_store_code(request)

        assert exc_info.value.status_code == 404
