chore: incomplete product setup error handling

This commit is contained in:
Livio Bieri 2023-11-20 16:36:00 +01:00 committed by Christian Cueni
parent 809c45235f
commit 33bea6c08a
3 changed files with 57 additions and 12 deletions

View File

@ -11,7 +11,6 @@ from vbv_lernwelt.shop.models import (
Product,
VV_PRODUCT_SKU,
)
from vbv_lernwelt.shop.services import get_payment_url
USER_USERNAME = "testuser"
USER_EMAIL = "test@example.com"
@ -33,8 +32,10 @@ TEST_ADDRESS_DATA = {
"company_country": "Test Company Country",
}
REDIRECT_URL = "http://testserver/redirect-url"
class CheckoutAPIView(APITestCase):
class CheckoutAPITestCase(APITestCase):
def setUp(self) -> None:
Product.objects.create(
sku=VV_PRODUCT_SKU,
@ -53,17 +54,16 @@ class CheckoutAPIView(APITestCase):
self.client.login(username=USER_USERNAME, password=USER_PASSWORD)
@patch("vbv_lernwelt.shop.views.init_transaction")
def test_checkout(self, mock_init_transaction):
def test_checkout_happy_case(self, mock_init_transaction):
# GIVEN
mock_init_transaction.return_value = "1234567890"
redirect_url = "http://testserver/redirect-url"
# WHEN
response = self.client.post(
path=reverse("checkout-vv"),
format="json",
data={
"redirect_url": redirect_url,
"redirect_url": REDIRECT_URL,
"address": TEST_ADDRESS_DATA,
},
)
@ -71,8 +71,8 @@ class CheckoutAPIView(APITestCase):
# THEN
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertEqual(
f"https://pay.sandbox.datatrans.com/v1/start/1234567890",
response.json()["next_step_url"],
get_payment_url("1234567890"),
)
self.assertTrue(
@ -82,3 +82,38 @@ class CheckoutAPIView(APITestCase):
state=CheckoutState.INITIALIZED.value,
).exists()
)
mock_init_transaction.assert_called_once_with(
user=self.user,
amount_chf_centimes=300_00,
redirect_url_success=f"{REDIRECT_URL}/onboarding/vv/checkout/complete",
redirect_url_error=f"{REDIRECT_URL}/onboarding/vv/checkout/address?error",
redirect_url_cancel=f"{REDIRECT_URL}/",
webhook_url=f"{REDIRECT_URL}/api/shop/transaction/webhook/",
)
@patch("vbv_lernwelt.shop.views.init_transaction")
def test_incomplete_setup(self, mock_init_transaction):
# GIVEN
Product.objects.all().delete()
mock_init_transaction.return_value = "1234567890"
# WHEN
response = self.client.post(
path=reverse("checkout-vv"),
format="json",
data={
"redirect_url": REDIRECT_URL,
"address": TEST_ADDRESS_DATA,
},
)
# THEN
self.assertEqual(response.status_code, status.HTTP_200_OK)
expected = (
f"{REDIRECT_URL}/onboarding/vv/checkout/address?error&"
f"message=vv_product_does_not_exist_needs_to_be_created"
)
self.assertEqual(expected, response.json()["next_step_url"])

View File

@ -3,7 +3,7 @@ from unittest import TestCase
from vbv_lernwelt.shop.services import is_signature_valid
class DatatransWebhookSigning(TestCase):
class DatatransWebhookSigningTestCase(TestCase):
# Key is from their example in the docs, not ours! :D
HMAC_KEY_FROM_THE_DOCS_NOT_HAZARDOUS = (
"861bbfc01e089259091927d6ad7f71c8"

View File

@ -107,12 +107,18 @@ def checkout_vv(request):
"""
sku = VV_PRODUCT_SKU
logger.info(f"Checkout requested: sku={sku}", user_id=request.user.id)
base_redirect_url = request.data["redirect_url"]
try:
product = Product.objects.get(sku=sku)
except Product.DoesNotExist:
raise Exception(
f"Required Product not found: {sku} must be created in the admin interface first.",
return JsonResponse(
{
"next_step_url": checkout_error_url(
base_url=base_redirect_url,
message="vv_product_does_not_exist_needs_to_be_created",
)
},
)
checkouts = CheckoutInformation.objects.filter(
@ -131,7 +137,6 @@ def checkout_vv(request):
return JsonResponse({"next_step_url": get_payment_url(checkout.transaction_id)})
# not yet initialized at all, or canceled/failed
base_redirect_url = request.data["redirect_url"]
transaction_id = init_transaction(
user=request.user,
amount_chf_centimes=product.price,
@ -162,8 +167,13 @@ def webhook_url(base_url: str) -> str:
return f"{base_url}/api/shop/transaction/webhook/"
def checkout_error_url(base_url: str) -> str:
return f"{base_url}/onboarding/vv/checkout/address?error"
def checkout_error_url(base_url: str, message: str | None = None) -> str:
url = f"{base_url}/onboarding/vv/checkout/address?error"
if message:
url += f"&message={message}"
return url
def checkout_cancel_url(base_url: str) -> str: