Skip to content

Commit

Permalink
feat(registration): check refund status from a new endpoint
Browse files Browse the repository at this point in the history
Refs: LINK-2112
  • Loading branch information
harriris-vincit committed Sep 13, 2024
1 parent d802de2 commit 77000ed
Show file tree
Hide file tree
Showing 7 changed files with 126 additions and 64 deletions.
8 changes: 4 additions & 4 deletions registrations/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -1252,9 +1252,9 @@ def _get_refund(order_id: str, refund_id: str) -> Optional[SignUpPaymentRefund]:
return refund

@staticmethod
def _get_refund_status_from_web_store_api(order_id: str) -> Optional[str]:
def _get_refund_status_from_web_store_api(refund_id: str) -> Optional[str]:
try:
return get_web_store_refund_payment_status(order_id=order_id)
return get_web_store_refund_payment_status(refund_id=refund_id)
except WebStoreAPIError:
raise ConflictException(_("Could not check refund status from Talpa API."))

Expand Down Expand Up @@ -1291,7 +1291,7 @@ def refund(self, request, pk=None, version=None):
serializer.validated_data["event_type"]
== WebStoreRefundWebhookEventType.REFUND_PAID.value
):
refund_status = self._get_refund_status_from_web_store_api(order_id)
refund_status = self._get_refund_status_from_web_store_api(refund_id)
if refund_status != WebStoreOrderRefundStatus.PAID_ONLINE.value:
return Response(
_(
Expand All @@ -1306,7 +1306,7 @@ def refund(self, request, pk=None, version=None):
serializer.validated_data["event_type"]
== WebStoreRefundWebhookEventType.REFUND_FAILED.value
):
refund_status = self._get_refund_status_from_web_store_api(order_id)
refund_status = self._get_refund_status_from_web_store_api(refund_id)
if refund_status != WebStoreOrderRefundStatus.CANCELLED.value:
return Response(
_(
Expand Down
77 changes: 66 additions & 11 deletions registrations/tests/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
get_web_store_payment,
get_web_store_payment_status,
get_web_store_refund_payment_status,
get_web_store_refund_payments,
)
from web_store.order.enums import WebStoreOrderRefundStatus, WebStoreOrderStatus
from web_store.payment.enums import WebStorePaymentStatus
Expand All @@ -51,10 +52,11 @@
DEFAULT_CREATE_INSTANT_REFUNDS_RESPONSE,
DEFAULT_GET_ORDER_DATA,
DEFAULT_ORDER_ID,
DEFAULT_REFUND_ID,
)
from web_store.tests.payment.test_web_store_payment_api_client import (
DEFAULT_GET_PAYMENT_DATA,
DEFAULT_GET_REFUND_PAYMENT_DATA,
DEFAULT_GET_REFUND_PAYMENTS_DATA,
)
from web_store.tests.product.test_web_store_product_api_client import (
DEFAULT_GET_PRODUCT_ACCOUNTING_DATA,
Expand Down Expand Up @@ -577,26 +579,79 @@ def test_get_web_store_payment_status_request_exception(status_code):
assert exc_info.value.args[1] == status_code


@pytest.mark.parametrize("order_id", [DEFAULT_ORDER_ID, "1234"])
@pytest.mark.parametrize("refund_id", [DEFAULT_REFUND_ID, "1234"])
def test_get_web_store_refund_payments(refund_id):
with requests_mock.Mocker() as req_mock:
req_mock.get(
f"{django_settings.WEB_STORE_API_BASE_URL}payment/admin/refunds/{refund_id}/payment",
json=DEFAULT_GET_REFUND_PAYMENTS_DATA,
)

payments = get_web_store_refund_payments(refund_id)

assert req_mock.call_count == 1

assert len(payments) == 1
assert payments[0] == DEFAULT_GET_REFUND_PAYMENTS_DATA[0]


@pytest.mark.parametrize(
"status_code",
_COMMON_WEB_STORE_EXCEPTION_STATUS_CODES,
)
def test_get_web_store_refund_payments_request_exception(status_code):
with (
requests_mock.Mocker() as req_mock,
pytest.raises(WebStoreAPIError) as exc_info,
):
req_mock.get(
f"{django_settings.WEB_STORE_API_BASE_URL}payment/admin/refunds/"
f"{DEFAULT_REFUND_ID}/payment",
status_code=status_code,
)

get_web_store_refund_payments(DEFAULT_REFUND_ID)

assert req_mock.call_count == 1

assert exc_info.value.args[1] == status_code


@pytest.mark.parametrize("refund_id", [DEFAULT_REFUND_ID, "1234"])
@pytest.mark.parametrize(
"payment_status",
[payment_status.value for payment_status in WebStoreOrderRefundStatus],
)
def test_get_web_store_refund_payment_status(order_id, payment_status):
payment_response_json = DEFAULT_GET_REFUND_PAYMENT_DATA.copy()
payment_response_json["status"] = payment_status
def test_get_web_store_refund_payment_status(refund_id, payment_status):
payment_response_json = [DEFAULT_GET_REFUND_PAYMENTS_DATA[0].copy()]
payment_response_json[0]["status"] = payment_status

with requests_mock.Mocker() as req_mock:
req_mock.get(
f"{django_settings.WEB_STORE_API_BASE_URL}payment/admin/refund-payment/{order_id}",
f"{django_settings.WEB_STORE_API_BASE_URL}payment/admin/refunds/{refund_id}/payment",
json=payment_response_json,
)

payment_status = get_web_store_refund_payment_status(order_id)
payment_status = get_web_store_refund_payment_status(refund_id)

assert req_mock.call_count == 1

assert payment_response_json["status"] == payment_status
assert payment_response_json[0]["status"] == payment_status


def test_get_web_store_refund_payment_status_none():
with requests_mock.Mocker() as req_mock:
req_mock.get(
f"{django_settings.WEB_STORE_API_BASE_URL}payment/admin/refunds/"
f"{DEFAULT_REFUND_ID}/payment",
json=[],
)

payment_status = get_web_store_refund_payment_status(DEFAULT_REFUND_ID)

assert req_mock.call_count == 1

assert payment_status is None


@pytest.mark.parametrize(
Expand All @@ -609,12 +664,12 @@ def test_get_web_store_refund_payment_status_request_exception(status_code):
pytest.raises(WebStoreAPIError) as exc_info,
):
req_mock.get(
f"{django_settings.WEB_STORE_API_BASE_URL}payment/admin/refund-payment/"
f"{DEFAULT_ORDER_ID}",
f"{django_settings.WEB_STORE_API_BASE_URL}payment/admin/refunds/"
f"{DEFAULT_REFUND_ID}/payment",
status_code=status_code,
)

get_web_store_refund_payment_status(DEFAULT_ORDER_ID)
get_web_store_refund_payment_status(DEFAULT_REFUND_ID)

assert req_mock.call_count == 1

Expand Down
32 changes: 15 additions & 17 deletions registrations/tests/test_web_store_webhook_post.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@
)
from web_store.tests.payment.test_web_store_payment_api_client import (
DEFAULT_GET_PAYMENT_DATA,
DEFAULT_GET_REFUND_PAYMENT_DATA,
DEFAULT_GET_REFUND_PAYMENTS_DATA,
DEFAULT_PAYMENT_ID,
)

Expand All @@ -58,9 +58,7 @@
_DEFAULT_GET_PAYMENT_URL = (
f"{settings.WEB_STORE_API_BASE_URL}payment/admin/{DEFAULT_ORDER_ID}"
)
_DEFAULT_GET_REFUND_URL = (
f"{settings.WEB_STORE_API_BASE_URL}payment/admin/refund-payment/{DEFAULT_ORDER_ID}"
)
_DEFAULT_GET_REFUND_URL = f"{settings.WEB_STORE_API_BASE_URL}payment/admin/refunds/{DEFAULT_REFUND_ID}/payment"


# === util methods ===
Expand Down Expand Up @@ -469,7 +467,7 @@ def test_refund_paid_webhook_for_signup_payment(
with requests_mock.Mocker() as req_mock:
req_mock.get(
_DEFAULT_GET_REFUND_URL,
json=DEFAULT_GET_REFUND_PAYMENT_DATA,
json=DEFAULT_GET_REFUND_PAYMENTS_DATA,
)

assert_payment_refunded(api_client, data, payment)
Expand Down Expand Up @@ -534,7 +532,7 @@ def test_refund_paid_webhook_for_signup_group_payment(
with requests_mock.Mocker() as req_mock:
req_mock.get(
_DEFAULT_GET_REFUND_URL,
json=DEFAULT_GET_REFUND_PAYMENT_DATA,
json=DEFAULT_GET_REFUND_PAYMENTS_DATA,
)

assert_payment_refunded(api_client, data, payment)
Expand Down Expand Up @@ -605,7 +603,7 @@ def test_refund_paid_webhook_for_recurring_event_signup_payment(
with requests_mock.Mocker() as req_mock:
req_mock.get(
_DEFAULT_GET_REFUND_URL,
json=DEFAULT_GET_REFUND_PAYMENT_DATA,
json=DEFAULT_GET_REFUND_PAYMENTS_DATA,
)

assert_payment_refunded(api_client, data, payment)
Expand Down Expand Up @@ -676,7 +674,7 @@ def test_refund_paid_webhook_for_recurring_event_signup_group_payment(
with requests_mock.Mocker() as req_mock:
req_mock.get(
_DEFAULT_GET_REFUND_URL,
json=DEFAULT_GET_REFUND_PAYMENT_DATA,
json=DEFAULT_GET_REFUND_PAYMENTS_DATA,
)

assert_payment_refunded(api_client, data, payment)
Expand Down Expand Up @@ -747,7 +745,7 @@ def test_partial_refund_paid_webhook_for_signup_group_payment(
with requests_mock.Mocker() as req_mock:
req_mock.get(
_DEFAULT_GET_REFUND_URL,
json=DEFAULT_GET_REFUND_PAYMENT_DATA,
json=DEFAULT_GET_REFUND_PAYMENTS_DATA,
)

assert_payment_refunded(api_client, data, payment, partial_refund=True)
Expand Down Expand Up @@ -781,8 +779,8 @@ def test_refund_failed_webhook_for_signup_payment(api_client):
{"refundId": DEFAULT_REFUND_ID},
)

refund_payment_data = DEFAULT_GET_REFUND_PAYMENT_DATA.copy()
refund_payment_data["status"] = WebStoreOrderRefundStatus.CANCELLED.value
refund_payment_data = [DEFAULT_GET_REFUND_PAYMENTS_DATA[0].copy()]
refund_payment_data[0]["status"] = WebStoreOrderRefundStatus.CANCELLED.value

assert AuditLogEntry.objects.count() == 0

Expand Down Expand Up @@ -818,8 +816,8 @@ def test_refund_failed_webhook_for_signup_group_payment(api_client):
{"refundId": DEFAULT_REFUND_ID},
)

refund_payment_data = DEFAULT_GET_REFUND_PAYMENT_DATA.copy()
refund_payment_data["status"] = WebStoreOrderRefundStatus.CANCELLED.value
refund_payment_data = [DEFAULT_GET_REFUND_PAYMENTS_DATA[0].copy()]
refund_payment_data[0]["status"] = WebStoreOrderRefundStatus.CANCELLED.value

assert AuditLogEntry.objects.count() == 0

Expand Down Expand Up @@ -857,8 +855,8 @@ def test_partial_refund_failed_webhook_for_signup_group_payment(api_client):
{"refundId": DEFAULT_REFUND_ID},
)

refund_payment_data = DEFAULT_GET_REFUND_PAYMENT_DATA.copy()
refund_payment_data["status"] = WebStoreOrderRefundStatus.CANCELLED.value
refund_payment_data = [DEFAULT_GET_REFUND_PAYMENTS_DATA[0].copy()]
refund_payment_data[0]["status"] = WebStoreOrderRefundStatus.CANCELLED.value

assert AuditLogEntry.objects.count() == 0

Expand Down Expand Up @@ -1463,8 +1461,8 @@ def test_webhook_and_web_store_refund_status_mismatch(
{"refundId": DEFAULT_REFUND_ID},
)

refund_payment_data = DEFAULT_GET_REFUND_PAYMENT_DATA.copy()
refund_payment_data["status"] = refund_payment_status
refund_payment_data = [DEFAULT_GET_REFUND_PAYMENTS_DATA[0].copy()]
refund_payment_data[0]["status"] = refund_payment_status

with requests_mock.Mocker() as req_mock:
req_mock.get(
Expand Down
15 changes: 10 additions & 5 deletions registrations/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -336,11 +336,11 @@ def get_web_store_payment(order_id: str) -> dict:
_raise_web_store_chained_api_exception(request_exc)


def get_web_store_refund_payment(order_id: str) -> dict:
def get_web_store_refund_payments(refund_id: str) -> list[dict]:
client = WebStorePaymentAPIClient()

try:
return client.get_refund_payment(order_id=order_id)
return client.get_refund_payments(refund_id=refund_id)
except RequestException as request_exc:
_raise_web_store_chained_api_exception(request_exc)

Expand All @@ -355,6 +355,11 @@ def get_web_store_payment_status(order_id: str) -> Optional[str]:
return payment_json.get("status")


def get_web_store_refund_payment_status(order_id: str) -> Optional[str]:
payment_json = get_web_store_refund_payment(order_id)
return payment_json.get("status")
def get_web_store_refund_payment_status(refund_id: str) -> Optional[str]:
payments_list = get_web_store_refund_payments(refund_id)
if payments_list:
# Even though the API returns a list, it will contain only one payment in our case since
# we create a new refund each time and it will have a single payment created in Talpa.
return payments_list[0].get("status")

return None
2 changes: 1 addition & 1 deletion web_store/clients.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ def _make_request(
method: str,
params: Optional[Union[dict, list]] = None,
headers: Optional[dict] = None,
) -> dict[str, Any]:
) -> Union[dict[str, Any], list[dict[str, Any]]]:
request_kwargs = self._get_request_kwargs(method, params, headers)
response = getattr(requests, method)(url, **request_kwargs)

Expand Down
4 changes: 2 additions & 2 deletions web_store/payment/clients.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ def get_payment(self, order_id: str) -> dict:
headers=self.headers,
)

def get_refund_payment(self, order_id: str) -> dict:
def get_refund_payments(self, refund_id: str) -> list[dict]:
return self._make_request(
f"{self.payment_api_base_url}admin/refund-payment/{order_id}",
f"{self.payment_api_base_url}admin/refunds/{refund_id}/payment",
"get",
headers=self.headers,
)
Loading

0 comments on commit 77000ed

Please sign in to comment.