Files
remnawave-bedolaga-telegram…/tests/services/test_yookassa_service_adapter.py
2025-10-12 10:13:32 +03:00

180 lines
6.1 KiB
Python

"""Тесты низкоуровневого сервиса YooKassaService."""
from __future__ import annotations
import asyncio
from datetime import datetime
from pathlib import Path
import sys
from types import SimpleNamespace
import pytest
ROOT_DIR = Path(__file__).resolve().parents[2]
if str(ROOT_DIR) not in sys.path:
sys.path.insert(0, str(ROOT_DIR))
from yookassa import Configuration, Payment as YooKassaPayment # type: ignore # noqa: E402
from app.config import settings # noqa: E402
from app.services.yookassa_service import YooKassaService # noqa: E402
@pytest.fixture
def anyio_backend() -> str:
return "asyncio"
class DummyLoop:
async def run_in_executor(self, _executor, func):
return func()
def _prepare_config(monkeypatch: pytest.MonkeyPatch) -> None:
monkeypatch.setattr(settings, "YOOKASSA_SHOP_ID", "shop123", raising=False)
monkeypatch.setattr(settings, "YOOKASSA_SECRET_KEY", "secret123", raising=False)
monkeypatch.setattr(settings, "YOOKASSA_RETURN_URL", "https://example.com/return", raising=False)
monkeypatch.setattr(settings, "YOOKASSA_VAT_CODE", 1, raising=False)
monkeypatch.setattr(settings, "YOOKASSA_PAYMENT_MODE", "full_payment", raising=False)
monkeypatch.setattr(settings, "YOOKASSA_PAYMENT_SUBJECT", "service", raising=False)
def test_init_without_credentials(monkeypatch: pytest.MonkeyPatch) -> None:
monkeypatch.setattr(settings, "YOOKASSA_SHOP_ID", "", raising=False)
monkeypatch.setattr(settings, "YOOKASSA_SECRET_KEY", "", raising=False)
service = YooKassaService()
assert service.configured is False
assert service.return_url == "https://t.me/"
@pytest.mark.anyio("asyncio")
async def test_create_payment_success(monkeypatch: pytest.MonkeyPatch) -> None:
_prepare_config(monkeypatch)
monkeypatch.setattr(settings, "YOOKASSA_DEFAULT_RECEIPT_EMAIL", None, raising=False)
monkeypatch.setattr(asyncio, "get_running_loop", lambda: DummyLoop(), raising=False)
captured_config: dict[str, tuple[str, str]] = {}
def fake_configure(shop_id: str, secret_key: str) -> None:
captured_config["values"] = (shop_id, secret_key)
monkeypatch.setattr(Configuration, "configure", fake_configure, raising=False)
response_obj = SimpleNamespace(
id="yk_1",
status="pending",
paid=False,
confirmation=SimpleNamespace(confirmation_url="https://yk/confirm"),
metadata={"meta": "value"},
amount=SimpleNamespace(value="140.00", currency="RUB"),
refundable=True,
created_at=datetime(2024, 1, 1, 12, 0, 0),
description="Desc",
test=False,
)
monkeypatch.setattr(
YooKassaPayment,
"create",
staticmethod(lambda payload, key: response_obj),
raising=False,
)
service = YooKassaService()
monkeypatch.setattr(settings, "YOOKASSA_DEFAULT_RECEIPT_EMAIL", "fallback@example.com", raising=False)
result = await service.create_payment(
amount=140.0,
currency="RUB",
description="Пополнение",
metadata={"order": "1"},
receipt_email="user@example.com",
)
assert service.configured is True
assert captured_config["values"] == ("shop123", "secret123")
assert result is not None
assert result["id"] == "yk_1"
assert result["confirmation_url"] == "https://yk/confirm"
assert result["amount_value"] == 140.0
assert result["status"] == "pending"
@pytest.mark.anyio("asyncio")
async def test_create_payment_without_contacts(monkeypatch: pytest.MonkeyPatch) -> None:
_prepare_config(monkeypatch)
monkeypatch.setattr(settings, "YOOKASSA_DEFAULT_RECEIPT_EMAIL", None, raising=False)
monkeypatch.setattr(Configuration, "configure", lambda *args, **kwargs: None, raising=False)
monkeypatch.setattr(asyncio, "get_running_loop", lambda: DummyLoop(), raising=False)
monkeypatch.setattr(
YooKassaPayment,
"create",
staticmethod(lambda payload, key: SimpleNamespace()),
raising=False,
)
service = YooKassaService()
result = await service.create_payment(
amount=10,
currency="RUB",
description="desc",
metadata={},
)
assert result is not None
assert result.get("error") is True
@pytest.mark.anyio("asyncio")
async def test_create_payment_returns_none_when_not_configured(monkeypatch: pytest.MonkeyPatch) -> None:
monkeypatch.setattr(settings, "YOOKASSA_SHOP_ID", "", raising=False)
monkeypatch.setattr(settings, "YOOKASSA_SECRET_KEY", "", raising=False)
service = YooKassaService()
result = await service.create_payment(
amount=10,
currency="RUB",
description="desc",
metadata={},
)
assert result is None
@pytest.mark.anyio("asyncio")
async def test_create_sbp_payment_success(monkeypatch: pytest.MonkeyPatch) -> None:
_prepare_config(monkeypatch)
monkeypatch.setattr(asyncio, "get_running_loop", lambda: DummyLoop(), raising=False)
monkeypatch.setattr(Configuration, "configure", lambda *args, **kwargs: None, raising=False)
monkeypatch.setattr(settings, "YOOKASSA_DEFAULT_RECEIPT_EMAIL", "fallback@example.com", raising=False)
response_obj = SimpleNamespace(
id="sbp_001",
status="pending",
paid=False,
confirmation=SimpleNamespace(confirmation_url="https://sbp/confirm"),
metadata={"meta": "value"},
amount=SimpleNamespace(value="200.00", currency="RUB"),
refundable=False,
created_at=datetime(2024, 2, 1, 9, 0, 0),
description="SBP payment",
test=True,
)
monkeypatch.setattr(
YooKassaPayment,
"create",
staticmethod(lambda payload, key: response_obj),
raising=False,
)
service = YooKassaService()
result = await service.create_sbp_payment(
amount=200.0,
currency="rub",
description="Оплата",
metadata={"type": "sbp"},
receipt_phone="+70000000000",
)
assert result is not None
assert result["id"] == "sbp_001"
assert result["confirmation_url"] == "https://sbp/confirm"
assert result["status"] == "pending"