"""Pay-page integration tests (ticket 014). Validate short-lived JWT token signing/verification and HTML rendering with and without billing enabled. """ from __future__ import annotations import uuid import httpx import pytest import respx from contract_check.api.billing.pay_page import verify_pay_token from contract_check.core.billing.pay_tokens import create_pay_token from contract_check.core.config import get_settings pytestmark = pytest.mark.integration async def test_pay_page_token_roundtrip() -> None: invoice_id = uuid.uuid4() token = create_pay_token(invoice_id) assert verify_pay_token(token) == invoice_id async def test_pay_page_invalid_token_403(client: httpx.AsyncClient) -> None: r = await client.get(f"/pay/{uuid.uuid4()}?token=invalid-token") assert r.status_code == 403 async def test_pay_page_missing_token_403(client: httpx.AsyncClient) -> None: r = await client.get(f"/pay/{uuid.uuid4()}") assert r.status_code == 403 async def test_pay_page_mismatch_token_403(client: httpx.AsyncClient) -> None: token = create_pay_token(uuid.uuid4()) r = await client.get(f"/pay/{uuid.uuid4()}?token={token}") assert r.status_code == 403 async def test_pay_page_renders_pending_invoice( client: httpx.AsyncClient, infra: dict[str, str], ) -> None: import os os.environ["YOOKASSA_ENABLED"] = "true" os.environ["YOOKASSA_SHOP_ID"] = "123456" os.environ["YOOKASSA_SECRET_KEY"] = "test-secret" os.environ["BILLING_RETURN_JWT_SECRET"] = "pay-secret" get_settings.cache_clear() from tests.integration.conftest import user_token tg = abs(int(uuid.uuid4().int % 900000000000)) + 100000000000 token = await user_token(client, infra, tg) with respx.mock: respx.post("https://api.yookassa.ru/v3/payments").mock( return_value=httpx.Response( 200, json={ "id": "pay-page-1", "status": "pending", "confirmation": {"confirmation_url": "https://yoo.test/p1"}, }, ) ) r = await client.post( "/api/v1/billing/checkout", json={"kind": "topup", "credits": 1}, headers={"Authorization": f"Bearer {token}"}, ) assert r.status_code == 201, r.text invoice_id = uuid.UUID(r.json()["invoice_id"]) pay_token = create_pay_token(invoice_id) page = await client.get(f"/pay/{invoice_id}?token={pay_token}") assert page.status_code == 200 assert "Ожидание оплаты" in page.text assert str(invoice_id)[:8] in page.text # Clean env. os.environ.pop("YOOKASSA_ENABLED", None) os.environ.pop("BILLING_RETURN_JWT_SECRET", None) get_settings.cache_clear()