fix: wire subscription service for yookassa hwid payments
This commit is contained in:
@@ -87,6 +87,7 @@ async def create_payment_route(request: web.Request) -> web.Response:
|
|||||||
return validation_error
|
return validation_error
|
||||||
method = str(payment_payload.method or "").strip().lower()
|
method = str(payment_payload.method or "").strip().lower()
|
||||||
settings: Settings = request.app["settings"]
|
settings: Settings = request.app["settings"]
|
||||||
|
subscription_service: SubscriptionService = request.app["subscription_service"]
|
||||||
cached = _get_cached_webapp_settings(request)
|
cached = _get_cached_webapp_settings(request)
|
||||||
tariffs_config = settings.tariffs_config
|
tariffs_config = settings.tariffs_config
|
||||||
traffic_mode = bool(settings.traffic_sale_mode)
|
traffic_mode = bool(settings.traffic_sale_mode)
|
||||||
|
|||||||
@@ -144,10 +144,12 @@ class YooKassaService:
|
|||||||
bot_username_for_default_return: Optional[str] = None,
|
bot_username_for_default_return: Optional[str] = None,
|
||||||
settings_obj: Optional[Settings] = None,
|
settings_obj: Optional[Settings] = None,
|
||||||
config: Optional[YooKassaConfig] = None,
|
config: Optional[YooKassaConfig] = None,
|
||||||
|
subscription_service: Optional[SubscriptionService] = None,
|
||||||
):
|
):
|
||||||
|
|
||||||
self.settings = settings_obj
|
self.settings = settings_obj
|
||||||
self.config = config or YooKassaConfig()
|
self.config = config or YooKassaConfig()
|
||||||
|
self.subscription_service = subscription_service
|
||||||
self._bot_username_for_default_return = bot_username_for_default_return
|
self._bot_username_for_default_return = bot_username_for_default_return
|
||||||
self._configured_return_url_override = configured_return_url
|
self._configured_return_url_override = configured_return_url
|
||||||
self._sdk_configured_for = (
|
self._sdk_configured_for = (
|
||||||
@@ -2680,6 +2682,7 @@ def create_service(ctx: ServiceFactoryContext) -> YooKassaService:
|
|||||||
bot_username_for_default_return=ctx.bot_username_for_default_return,
|
bot_username_for_default_return=ctx.bot_username_for_default_return,
|
||||||
settings_obj=ctx.settings,
|
settings_obj=ctx.settings,
|
||||||
config=config,
|
config=config,
|
||||||
|
subscription_service=ctx.subscription_service,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -104,6 +104,7 @@ class BuildServicesWiringTests(unittest.TestCase):
|
|||||||
self.assertIsInstance(yookassa, YooKassaService)
|
self.assertIsInstance(yookassa, YooKassaService)
|
||||||
# Identity check: the wired attribute must be the *same* instance.
|
# Identity check: the wired attribute must be the *same* instance.
|
||||||
self.assertIs(getattr(subscription, "yookassa_service", None), yookassa)
|
self.assertIs(getattr(subscription, "yookassa_service", None), yookassa)
|
||||||
|
self.assertIs(getattr(yookassa, "subscription_service", None), subscription)
|
||||||
|
|
||||||
def test_panel_webhook_service_can_reach_subscription_service(self):
|
def test_panel_webhook_service_can_reach_subscription_service(self):
|
||||||
"""The 24h pre-expiry handler in panel_webhook_service.handle_event
|
"""The 24h pre-expiry handler in panel_webhook_service.handle_event
|
||||||
|
|||||||
@@ -94,3 +94,105 @@ class WebAppDeviceTopupOptionsTests(IsolatedAsyncioTestCase):
|
|||||||
self.assertEqual(payload["extra_hwid_devices_valid_until_text"], "02.01.2099 03:04")
|
self.assertEqual(payload["extra_hwid_devices_valid_until_text"], "02.01.2099 03:04")
|
||||||
self.assertEqual(payload["plans"][0]["valid_from"], valid_from.isoformat())
|
self.assertEqual(payload["plans"][0]["valid_from"], valid_from.isoformat())
|
||||||
self.assertEqual(payload["plans"][0]["valid_until"], active_until.isoformat())
|
self.assertEqual(payload["plans"][0]["valid_until"], active_until.isoformat())
|
||||||
|
|
||||||
|
async def test_create_payment_route_quotes_hwid_with_app_subscription_service(self):
|
||||||
|
tariff = SimpleNamespace(
|
||||||
|
key="standard",
|
||||||
|
billing_model="period",
|
||||||
|
enabled_periods=[1],
|
||||||
|
hwid_device_packages=SimpleNamespace(
|
||||||
|
rub=[SimpleNamespace(count=1)],
|
||||||
|
stars=[],
|
||||||
|
),
|
||||||
|
)
|
||||||
|
settings = SimpleNamespace(
|
||||||
|
traffic_sale_mode=False,
|
||||||
|
tariffs_config=SimpleNamespace(require=lambda key: tariff),
|
||||||
|
DEFAULT_LANGUAGE="en",
|
||||||
|
DEFAULT_CURRENCY_SYMBOL="RUB",
|
||||||
|
ADMIN_IDS=[],
|
||||||
|
)
|
||||||
|
quote = {
|
||||||
|
"price": 25,
|
||||||
|
"valid_from": datetime(2099, 1, 1, tzinfo=timezone.utc),
|
||||||
|
"valid_until": datetime(2099, 4, 1, tzinfo=timezone.utc),
|
||||||
|
"pricing_period_months": 3,
|
||||||
|
"proration_ratio": 1.0,
|
||||||
|
"full_price": 25,
|
||||||
|
}
|
||||||
|
subscription_service = SimpleNamespace(
|
||||||
|
quote_hwid_device_topup=AsyncMock(return_value=quote)
|
||||||
|
)
|
||||||
|
request = SimpleNamespace(
|
||||||
|
app={
|
||||||
|
"settings": settings,
|
||||||
|
"async_session_factory": _SessionFactory(),
|
||||||
|
"subscription_service": subscription_service,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
db_user = SimpleNamespace(
|
||||||
|
is_banned=False,
|
||||||
|
panel_user_uuid="panel-user",
|
||||||
|
language_code="en",
|
||||||
|
telegram_id=42,
|
||||||
|
)
|
||||||
|
sub = SimpleNamespace(tariff_key="standard")
|
||||||
|
|
||||||
|
async def _fake_create_payment(**kwargs):
|
||||||
|
return billing_module.web.json_response(
|
||||||
|
{
|
||||||
|
"ok": True,
|
||||||
|
"price": kwargs["price"],
|
||||||
|
"hwid_valid_until": kwargs["hwid_quote"]["valid_until"].isoformat(),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
with (
|
||||||
|
patch.object(billing_module, "_require_user_id", return_value=42),
|
||||||
|
patch.object(
|
||||||
|
billing_module,
|
||||||
|
"_enforce_webapp_rate_limit",
|
||||||
|
AsyncMock(return_value=None),
|
||||||
|
),
|
||||||
|
patch.object(
|
||||||
|
billing_module,
|
||||||
|
"_read_json",
|
||||||
|
AsyncMock(
|
||||||
|
return_value={
|
||||||
|
"method": "yookassa",
|
||||||
|
"months": 1,
|
||||||
|
"device_count": 1,
|
||||||
|
"tariff_key": "standard",
|
||||||
|
"sale_mode": "hwid_devices",
|
||||||
|
}
|
||||||
|
),
|
||||||
|
),
|
||||||
|
patch.object(
|
||||||
|
billing_module,
|
||||||
|
"_get_cached_webapp_settings",
|
||||||
|
return_value={"subscription_options": {}, "stars_subscription_options": {}},
|
||||||
|
),
|
||||||
|
patch.object(
|
||||||
|
billing_module.user_dal,
|
||||||
|
"get_user_by_id",
|
||||||
|
AsyncMock(return_value=db_user),
|
||||||
|
),
|
||||||
|
patch.object(
|
||||||
|
billing_module.subscription_dal,
|
||||||
|
"get_active_subscription_by_user_id",
|
||||||
|
AsyncMock(return_value=sub),
|
||||||
|
),
|
||||||
|
patch.object(
|
||||||
|
billing_module,
|
||||||
|
"_create_subscription_payment",
|
||||||
|
AsyncMock(side_effect=_fake_create_payment),
|
||||||
|
) as create_payment,
|
||||||
|
):
|
||||||
|
response = await billing_module.create_payment_route(request)
|
||||||
|
|
||||||
|
self.assertEqual(response.status, 200)
|
||||||
|
payload = json.loads(response.text)
|
||||||
|
self.assertTrue(payload["ok"])
|
||||||
|
self.assertEqual(payload["price"], 25)
|
||||||
|
subscription_service.quote_hwid_device_topup.assert_awaited_once()
|
||||||
|
create_payment.assert_awaited_once()
|
||||||
|
|||||||
Reference in New Issue
Block a user