first commit
This commit is contained in:
commit
34ea15a54d
246 changed files with 18660 additions and 0 deletions
97
backend/tests/test_payments.py
Normal file
97
backend/tests/test_payments.py
Normal file
|
|
@ -0,0 +1,97 @@
|
|||
import hashlib
|
||||
import hmac
|
||||
import json
|
||||
from app.core.config import get_settings
|
||||
from app.services.payments.gateway import MockPaymentGateway, get_payment_gateway
|
||||
from tests.helpers import auth_headers, client, create_pending_order
|
||||
|
||||
|
||||
def _mock_signature(body: bytes) -> str:
|
||||
secret = get_settings().payment_mock_secret
|
||||
return hmac.new(secret.encode(), body, hashlib.sha256).hexdigest()
|
||||
|
||||
|
||||
def test_verify_payment_issues_tickets() -> None:
|
||||
token, checkout = create_pending_order()
|
||||
assert checkout["status"] == "pending"
|
||||
payment = checkout["payment"]
|
||||
assert payment["provider"] == "mock"
|
||||
|
||||
gateway = get_payment_gateway()
|
||||
assert isinstance(gateway, MockPaymentGateway)
|
||||
payment_id = f"mock_pay_{checkout['id']}"
|
||||
signature = gateway.build_mock_checkout_signature(payment["provider_order_id"], payment_id)
|
||||
|
||||
verify = client.post(
|
||||
f"/api/orders/{checkout['id']}/payment/verify",
|
||||
headers=auth_headers(token),
|
||||
json={
|
||||
"provider_order_id": payment["provider_order_id"],
|
||||
"provider_payment_id": payment_id,
|
||||
"signature": signature,
|
||||
},
|
||||
)
|
||||
assert verify.status_code == 200
|
||||
assert verify.json()["status"] == "paid"
|
||||
|
||||
tickets = client.get("/api/tickets/my", headers=auth_headers(token)).json()
|
||||
assert any(t["order_id"] == checkout["id"] for t in tickets)
|
||||
|
||||
|
||||
def test_rejects_invalid_signature() -> None:
|
||||
token, checkout = create_pending_order()
|
||||
payment = checkout["payment"]
|
||||
verify = client.post(
|
||||
f"/api/orders/{checkout['id']}/payment/verify",
|
||||
headers=auth_headers(token),
|
||||
json={
|
||||
"provider_order_id": payment["provider_order_id"],
|
||||
"provider_payment_id": "mock_pay_bad",
|
||||
"signature": "not-valid",
|
||||
},
|
||||
)
|
||||
assert verify.status_code == 400
|
||||
|
||||
|
||||
def test_webhook_idempotent() -> None:
|
||||
token, checkout = create_pending_order()
|
||||
payment = checkout["payment"]
|
||||
payment_id = f"mock_pay_wh_{checkout['id']}"
|
||||
import uuid
|
||||
|
||||
event_id = f"evt_duplicate_{uuid.uuid4().hex}"
|
||||
payload = {
|
||||
"id": event_id,
|
||||
"event": "payment.captured",
|
||||
"payload": {
|
||||
"payment": {
|
||||
"entity": {
|
||||
"id": payment_id,
|
||||
"order_id": payment["provider_order_id"],
|
||||
"amount": checkout["total_paise"],
|
||||
"currency": "INR",
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
body = json.dumps(payload).encode()
|
||||
signature = _mock_signature(body)
|
||||
headers = {"X-Mock-Signature": signature}
|
||||
|
||||
first = client.post("/api/webhooks/mock", content=body, headers=headers)
|
||||
assert first.status_code == 200
|
||||
assert first.json()["status"] == "paid"
|
||||
|
||||
second = client.post("/api/webhooks/mock", content=body, headers=headers)
|
||||
assert second.status_code == 200
|
||||
assert second.json()["status"] == "duplicate_ignored"
|
||||
|
||||
tickets = client.get("/api/tickets/my", headers=auth_headers(token)).json()
|
||||
assert len([t for t in tickets if t["order_id"] == checkout["id"]]) == 1
|
||||
|
||||
|
||||
def test_cancel_pending_order_releases_inventory() -> None:
|
||||
token, checkout = create_pending_order()
|
||||
cancel = client.post(f"/api/orders/{checkout['id']}/cancel", headers=auth_headers(token))
|
||||
assert cancel.status_code == 200
|
||||
assert cancel.json()["status"] == "cancelled"
|
||||
Loading…
Add table
Add a link
Reference in a new issue