From db36155cf3397cee0fedc9d7010c071f9b24a8d4 Mon Sep 17 00:00:00 2001 From: julianajlk Date: Wed, 27 Mar 2024 17:34:14 -0400 Subject: [PATCH] test: Update tests move create new PI --- .../test_stripe_test_payment_flow.json | 8 +- .../payment/tests/views/test_stripe.py | 74 +++++++++++++------ 2 files changed, 57 insertions(+), 25 deletions(-) diff --git a/ecommerce/extensions/payment/tests/views/fixtures/test_stripe_test_payment_flow.json b/ecommerce/extensions/payment/tests/views/fixtures/test_stripe_test_payment_flow.json index 411ed622d8e..f2ec8a0f1d3 100644 --- a/ecommerce/extensions/payment/tests/views/fixtures/test_stripe_test_payment_flow.json +++ b/ecommerce/extensions/payment/tests/views/fixtures/test_stripe_test_payment_flow.json @@ -418,7 +418,7 @@ "source": null, "statement_descriptor": null, "statement_descriptor_suffix": null, - "status": "requires_payment_method", + "status": "requires_action", "transfer_data": null, "transfer_group": null }, @@ -478,7 +478,7 @@ "transfer_group": null }, "cancel_resp": { - "id": "pi_3LsftNIadiFyUl1x2TWxaADZ", + "id": "pi_3OqcQ5H4caH7G0X11y8NKNa4", "object": "payment_intent", "amount": 14900, "amount_capturable": 0, @@ -502,9 +502,9 @@ ], "has_more": false, "total_count": 0, - "url": "/v1/charges?payment_intent=pi_3LsftNIadiFyUl1x2TWxaADZ" + "url": "/v1/charges?payment_intent=pi_3OqcQ5H4caH7G0X11y8NKNa4" }, - "client_secret": "pi_3LsftNIadiFyUl1x2TWxaADZ_secret_VxRx7Y1skyp0jKtq7Gdu80Xnh", + "client_secret": "pi_3OqcQ5H4caH7G0X11y8NKNa4_secret_kbBQP5DZGLccIESMInIq5GECO", "confirmation_method": "automatic", "created": 1709561818, "currency": "usd", diff --git a/ecommerce/extensions/payment/tests/views/test_stripe.py b/ecommerce/extensions/payment/tests/views/test_stripe.py index 52ac0120cf6..e2165391ad8 100644 --- a/ecommerce/extensions/payment/tests/views/test_stripe.py +++ b/ecommerce/extensions/payment/tests/views/test_stripe.py @@ -16,6 +16,7 @@ ) from ecommerce.courses.tests.factories import CourseFactory from ecommerce.entitlements.utils import create_or_update_course_entitlement +from ecommerce.extensions.basket.constants import PAYMENT_INTENT_ID_ATTRIBUTE from ecommerce.extensions.checkout.utils import get_receipt_page_url from ecommerce.extensions.order.constants import PaymentEventTypeName from ecommerce.extensions.payment.constants import STRIPE_CARD_TYPE_MAP @@ -105,19 +106,11 @@ def payment_flow_with_mocked_stripe_calls( mock_modify.side_effect = modify_side_effect else: mock_modify.side_effect = [fixture_data['modify_resp']] - # If Payment Intent gets into 'requires_action' status without confirmation from the BNPL, - # we create a new Payment Intent for retry payment in the MFE - with mock.patch('stripe.PaymentIntent.cancel') as mock_cancel: - if in_progress_payment is not None: - mock_cancel.side_effect = [fixture_data['cancel_resp']] - with mock.patch('stripe.PaymentIntent.create') as mock_create: - if in_progress_payment is not None: - mock_create.side_effect = [fixture_data['create_resp_in_progress']] - # make your call - return self.client.post( - url, - data=data - ) + # make your call + return self.client.post( + url, + data=data + ) def assert_successful_order_response(self, response, order_number): assert response.status_code == 201 @@ -385,6 +378,49 @@ def test_capture_context_large_characters_basket(self): # The metadata must be less than 500 characters assert len(mock_create.call_args.kwargs['metadata']['courses']) < 500 + @file_data('fixtures/test_stripe_test_payment_flow.json') + def test_capture_context_in_progress_payment( + self, + confirm_resp, # pylint: disable=unused-argument + confirm_resp_in_progress, # pylint: disable=unused-argument + create_resp, + create_resp_in_progress, + modify_resp, # pylint: disable=unused-argument + cancel_resp, + refund_resp, # pylint: disable=unused-argument + retrieve_addr_resp): # pylint: disable=unused-argument + """ + Verify that hitting capture-context with a Payment Intent that already exists but it's + in 'requires_action' state, that a new Payment Intent is created and associated to the basket. + """ + basket = self.create_basket(product_class=SEAT_PRODUCT_CLASS_NAME) + + with mock.patch('stripe.PaymentIntent.create') as mock_create: + mock_create.return_value = create_resp_in_progress + # If Payment Intent gets into 'requires_action' status without confirmation from the BNPL, + # we create a new Payment Intent for retry payment in the MFE + with mock.patch('stripe.PaymentIntent.cancel') as mock_cancel: + mock_cancel.return_value = cancel_resp + with mock.patch('stripe.PaymentIntent.create') as mock_create_new: + mock_create_new.return_value = create_resp + response = self.client.get(self.capture_context_url) + + # Basket should have the new Payment Intent ID + mock_create_new.assert_called_once() + payment_intent_id = BasketAttribute.objects.get( + basket=basket, + attribute_type__name=PAYMENT_INTENT_ID_ATTRIBUTE + ).value_text + assert payment_intent_id == mock_create_new.return_value['id'] + + # Response should have the same order_number and new client secret + assert response.json() == { + 'capture_context': { + 'key_id': mock_create_new.return_value['client_secret'], + 'order_id': basket.order_number, + } + } + def test_payment_error_no_basket(self): """ Verify view redirects to error page if no basket exists for payment_intent_id. @@ -449,7 +485,7 @@ def test_payment_check_sdn_returns_hits(self): def test_payment_handle_payment_intent_in_progress(self): """ Verify the POST endpoint handles a Payment Intent that is not succeeded yet, - with a 'requires_action' status without confirmation from the BNPL payment. + with a 'requires_action' for a BNPL payment, which will be handled in the MFE. """ basket = self.create_basket(product_class=SEAT_PRODUCT_CLASS_NAME) @@ -464,13 +500,9 @@ def test_payment_handle_payment_intent_in_progress(self): ) assert response.status_code == 201 - # A new Payment Intent was created for retry payment - assert response.json() == { - 'status': 'requires_payment_method', - 'transaction_id': 'pi_3OqcQ5H4caH7G0X11y8NKNa4', - 'confirmation_client_secret': 'pi_3OqcQ5H4caH7G0X11y8NKNa4_secret_kbBQP5DZGLccIESMInIq5GECO', - 'payment_method': None, - } + # Should return 'requires_action' to the MFE with the same Payment Intent + assert response.json()['status'] == 'requires_action' + assert response.json()['transaction_id'] == 'pi_3LsftNIadiFyUl1x2TWxaADZ' def test_handle_payment_fails_with_carderror(self): """