feat: add portal recharge page
This commit is contained in:
+113
-1
@@ -9,7 +9,7 @@ from django.test import Client, TestCase, override_settings
|
||||
from django.utils import timezone
|
||||
from rest_framework.test import APIClient
|
||||
|
||||
from apps.billing.models import CallRecord, PointsLedger, RechargeOrder
|
||||
from apps.billing.models import CallRecord, ExchangeRate, PointsLedger, RechargeOrder
|
||||
from apps.users.models import ApiKey, UserWallet
|
||||
|
||||
|
||||
@@ -434,3 +434,115 @@ class PortalAccountFlowTests(TestCase):
|
||||
self.assertContains(response, "15")
|
||||
self.assertNotContains(response, "other-alias")
|
||||
self.assertNotContains(response, other_key.key_prefix)
|
||||
|
||||
def test_recharge_page_requires_login_and_shows_form(self):
|
||||
user = self.create_verified_user()
|
||||
UserWallet.objects.create(user=user, points_balance=25)
|
||||
|
||||
anonymous_response = self.client.get("/recharge")
|
||||
self.assertEqual(anonymous_response.status_code, 302)
|
||||
self.assertTrue(anonymous_response["Location"].startswith("/login?next="))
|
||||
|
||||
self.client.force_login(user)
|
||||
response = self.client.get("/recharge")
|
||||
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertEqual(response.context["balance"].points_balance, 25)
|
||||
self.assertContains(response, "充值金额")
|
||||
self.assertContains(response, "创建订单")
|
||||
self.assertContains(response, "qrcode@1.5.4")
|
||||
self.assertContains(response, "QRCode.toCanvas")
|
||||
|
||||
def test_recharge_page_post_creates_pending_order_without_crediting_wallet_or_ledger(self):
|
||||
user = self.create_verified_user()
|
||||
UserWallet.objects.create(user=user, points_balance=5)
|
||||
ExchangeRate.objects.create(
|
||||
currency="CNY",
|
||||
points_per_unit=Decimal("10.0000"),
|
||||
effective_from=timezone.now(),
|
||||
)
|
||||
self.client.force_login(user)
|
||||
|
||||
response = self.client.post(
|
||||
"/recharge",
|
||||
{"amount": "20.00", "pay_method": RechargeOrder.PayMethod.WEIXIN},
|
||||
)
|
||||
|
||||
self.assertEqual(response.status_code, 302)
|
||||
self.assertTrue(response["Location"].startswith("/recharge?order_no="))
|
||||
order = RechargeOrder.objects.get(user=user)
|
||||
self.assertEqual(order.amount_money, Decimal("20.00"))
|
||||
self.assertEqual(order.exchange_rate, Decimal("10.0000"))
|
||||
self.assertEqual(order.points_granted, 200)
|
||||
self.assertEqual(order.status, RechargeOrder.Status.PENDING)
|
||||
self.assertTrue(order.code_url.startswith("weixin://wxpay/cmhub-mock"))
|
||||
self.assertIsNotNone(order.expires_at)
|
||||
wallet = UserWallet.objects.get(user=user)
|
||||
self.assertEqual(wallet.points_balance, 5)
|
||||
self.assertFalse(
|
||||
PointsLedger.objects.filter(
|
||||
user=user,
|
||||
ref_order_id=order.id,
|
||||
).exists()
|
||||
)
|
||||
|
||||
follow_response = self.client.get(response["Location"])
|
||||
|
||||
self.assertEqual(follow_response.status_code, 200)
|
||||
self.assertEqual(follow_response.context["current_order"], order)
|
||||
self.assertContains(follow_response, order.order_no)
|
||||
self.assertContains(follow_response, "weixin://wxpay/cmhub-mock")
|
||||
self.assertContains(follow_response, 'data-status-url="/api/v1/recharge/status"')
|
||||
self.assertContains(follow_response, "data-recharge-order")
|
||||
|
||||
def test_recharge_page_current_order_only_shows_current_user_order(self):
|
||||
user = self.create_verified_user()
|
||||
other_user = self.create_verified_user()
|
||||
UserWallet.objects.create(user=user, points_balance=0)
|
||||
other_order = self.create_recharge_order(
|
||||
other_user,
|
||||
order_no="R-OTHER-RECHARGE-PAGE-504",
|
||||
amount="50.00",
|
||||
points=500,
|
||||
status=RechargeOrder.Status.PENDING,
|
||||
)
|
||||
self.client.force_login(user)
|
||||
|
||||
response = self.client.get(f"/recharge?order_no={other_order.order_no}")
|
||||
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertIsNone(response.context["current_order"])
|
||||
self.assertNotContains(response, other_order.order_no)
|
||||
|
||||
@override_settings(RECHARGE_MAX_AMOUNT_CNY="100.00")
|
||||
def test_recharge_page_rejects_amount_above_configured_maximum(self):
|
||||
user = self.create_verified_user()
|
||||
UserWallet.objects.create(user=user, points_balance=0)
|
||||
ExchangeRate.objects.create(
|
||||
currency="CNY",
|
||||
points_per_unit=Decimal("10.0000"),
|
||||
effective_from=timezone.now(),
|
||||
)
|
||||
self.client.force_login(user)
|
||||
|
||||
response = self.client.post(
|
||||
"/recharge",
|
||||
{"amount": "100.01", "pay_method": RechargeOrder.PayMethod.ALIPAY},
|
||||
)
|
||||
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertContains(response, "单笔充值金额不能超过 100.00 CNY")
|
||||
self.assertFalse(RechargeOrder.objects.filter(user=user).exists())
|
||||
|
||||
def test_recharge_page_post_is_csrf_protected(self):
|
||||
user = self.create_verified_user()
|
||||
csrf_client = Client(enforce_csrf_checks=True)
|
||||
csrf_client.force_login(user)
|
||||
|
||||
response = csrf_client.post(
|
||||
"/recharge",
|
||||
{"amount": "20.00", "pay_method": RechargeOrder.PayMethod.WEIXIN},
|
||||
)
|
||||
|
||||
self.assertEqual(response.status_code, 403)
|
||||
self.assertFalse(RechargeOrder.objects.filter(user=user).exists())
|
||||
|
||||
Reference in New Issue
Block a user