import uuid
from unittest.mock import Mock

import pytest
from pytest_mock import MockFixture
from src.__types.errors import ResourceNotFoundError
from src.__types.index import TenantAuthInfo
from src.infrastructure.repositories.tenant_repository import TenantRepository
from src.usecases.tenant_auth_info_usecase import TenantAuthInfoUseCase


class TestTenantAuthInfoUseCase:
    @pytest.fixture
    def mock_tenant_repository(self, mocker: MockFixture) -> Mock:
        return mocker.Mock(spec=TenantRepository)

    @pytest.fixture
    def usecase(self, mock_tenant_repository: Mock) -> TenantAuthInfoUseCase:
        return TenantAuthInfoUseCase(tenant_repository=mock_tenant_repository)

    class TestGetByName:
        def test_get(
            self,
            usecase: TenantAuthInfoUseCase,
            mock_tenant_repository: Mock,
        ) -> None:
            """指定したテナント名のユーザー認証情報を取得できることを確認する。"""
            # Arrange
            expected_auth_info = TenantAuthInfo(
                tenant_id=uuid.uuid4(),
                user_application_client_id="user_application_client#dummy",
            )
            mock_tenant_repository.get_auth_info_by_name.return_value = expected_auth_info

            # Act
            actual = usecase.get(name="dummy_tenant")

            # Assert
            assert actual == expected_auth_info
            mock_tenant_repository.get_auth_info_by_name.assert_called_once_with(name="dummy_tenant")

        def test_tenant_not_found(
            self,
            usecase: TenantAuthInfoUseCase,
            mock_tenant_repository: Mock,
        ) -> None:
            """対象テナントが存在しない場合に例外をそのまま返すことを確認する。"""
            # Arrange
            mock_tenant_repository.get_auth_info_by_name.side_effect = ResourceNotFoundError("not found")

            # Act / Assert
            with pytest.raises(ResourceNotFoundError):
                usecase.get(name="missing_tenant")

            mock_tenant_repository.get_auth_info_by_name.assert_called_once_with(name="missing_tenant")
