Skip to content

Commit eb300d8

Browse files
Add unit tests for AdminRefundOrder view (#3313)
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
1 parent 2671e7b commit eb300d8

1 file changed

Lines changed: 196 additions & 0 deletions

File tree

ecommerce/admin_test.py

Lines changed: 196 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,196 @@
1+
"""Tests for ecommerce admin views"""
2+
3+
import pytest
4+
from django.contrib.messages import get_messages
5+
from django.urls import reverse
6+
7+
from ecommerce.factories import OrderFactory
8+
from ecommerce.models import OrderStatus
9+
10+
pytestmark = [pytest.mark.django_db]
11+
12+
13+
def _login_admin(client, admin_user):
14+
"""Log in the admin user into the Django test client."""
15+
16+
client.force_login(admin_user)
17+
return client
18+
19+
20+
def test_admin_refund_order_get_success(client, admin_user):
21+
"""GET should render the refund confirmation page for a fulfilled order."""
22+
23+
_login_admin(client, admin_user)
24+
order = OrderFactory.create(state=OrderStatus.FULFILLED)
25+
26+
response = client.get(f"{reverse('refund-order')}?order={order.id}")
27+
28+
assert response.status_code == 200
29+
assert response.context["order"].id == order.id
30+
31+
refund_form = response.context["refund_form"]
32+
assert refund_form.initial["_selected_action"] == order.id
33+
assert float(refund_form.initial["refund_amount"]) == float(order.total_price_paid)
34+
assert response.context["form_valid"] is True
35+
assert response.context["errors"] == {}
36+
37+
38+
def test_admin_refund_order_get_not_found(client, admin_user):
39+
"""GET with a non-existing order should redirect with an error message."""
40+
41+
_login_admin(client, admin_user)
42+
missing_order_id = 999999
43+
44+
response = client.get(f"{reverse('refund-order')}?order={missing_order_id}")
45+
46+
assert response.status_code == 302
47+
assert response.url == reverse("admin:ecommerce_fulfilledorder_changelist")
48+
49+
messages = list(get_messages(response.wsgi_request))
50+
assert len(messages) == 1
51+
assert f"Order {missing_order_id} could not be found - is it Fulfilled?" == str(
52+
messages[0].message
53+
)
54+
55+
56+
def test_admin_refund_order_get_not_fulfilled(client, admin_user):
57+
"""GET with a non-fulfilled order should behave like missing fulfilled order."""
58+
59+
_login_admin(client, admin_user)
60+
order = OrderFactory.create(state=OrderStatus.PENDING)
61+
62+
response = client.get(f"{reverse('refund-order')}?order={order.id}")
63+
64+
assert response.status_code == 302
65+
assert response.url == reverse("admin:ecommerce_fulfilledorder_changelist")
66+
67+
messages = list(get_messages(response.wsgi_request))
68+
assert len(messages) == 1
69+
assert f"Order {order.id} could not be found - is it Fulfilled?" == str(
70+
messages[0].message
71+
)
72+
73+
74+
@pytest.mark.parametrize(
75+
("perform_unenrolls", "expected_message_suffix"),
76+
[
77+
(False, "refunded."),
78+
(True, "refunded and unenrollment is in progress."),
79+
],
80+
)
81+
def test_admin_refund_order_post_success(
82+
client, admin_user, mocker, perform_unenrolls, expected_message_suffix
83+
):
84+
"""POST with valid data should call refund_order and redirect to refunded order admin."""
85+
86+
_login_admin(client, admin_user)
87+
order = OrderFactory.create(state=OrderStatus.FULFILLED)
88+
89+
mock_refund_order = mocker.patch(
90+
"ecommerce.admin.refund_order", return_value=(True, None)
91+
)
92+
93+
post_data = {
94+
"order": str(order.id),
95+
"_selected_action": str(order.id),
96+
"refund_reason": "Test refund",
97+
"refund_amount": "10.00",
98+
}
99+
if perform_unenrolls:
100+
post_data["perform_unenrolls"] = "on"
101+
102+
response = client.post(reverse("refund-order"), data=post_data)
103+
104+
assert response.status_code == 302
105+
assert response.url == reverse(
106+
"admin:ecommerce_refundedorder_change", args=(order.id,)
107+
)
108+
109+
mock_refund_order.assert_called_once()
110+
kwargs = mock_refund_order.call_args.kwargs
111+
assert kwargs["order_id"] == order.id
112+
assert kwargs["refund_reason"] == "Test refund"
113+
assert kwargs["unenroll"] is perform_unenrolls
114+
115+
messages = list(get_messages(response.wsgi_request))
116+
assert len(messages) == 1
117+
assert (
118+
str(messages[0].message)
119+
== f"Order {order.reference_number} {expected_message_suffix}"
120+
)
121+
122+
123+
def test_admin_refund_order_post_refund_failed(client, admin_user, mocker):
124+
"""If refund_order returns False, an error message is shown and redirect occurs."""
125+
126+
_login_admin(client, admin_user)
127+
order = OrderFactory.create(state=OrderStatus.FULFILLED)
128+
129+
mocker.patch("ecommerce.admin.refund_order", return_value=(False, "error"))
130+
131+
post_data = {
132+
"order": str(order.id),
133+
"_selected_action": str(order.id),
134+
"refund_reason": "Test refund",
135+
"refund_amount": "10.00",
136+
}
137+
138+
response = client.post(reverse("refund-order"), data=post_data)
139+
140+
assert response.status_code == 302
141+
assert response.url == reverse(
142+
"admin:ecommerce_refundedorder_change", args=(order.id,)
143+
)
144+
145+
messages = list(get_messages(response.wsgi_request))
146+
assert len(messages) == 1
147+
assert str(messages[0].message) == f"Order {order.reference_number} refund failed."
148+
149+
150+
def test_admin_refund_order_post_invalid_form(client, admin_user, mocker):
151+
"""Invalid form data should re-render the page with errors and not call refund_order."""
152+
153+
_login_admin(client, admin_user)
154+
order = OrderFactory.create(state=OrderStatus.FULFILLED)
155+
156+
mock_refund_order = mocker.patch("ecommerce.admin.refund_order")
157+
158+
post_data = {
159+
"order": str(order.id),
160+
"_selected_action": str(order.id),
161+
}
162+
163+
response = client.post(reverse("refund-order"), data=post_data)
164+
165+
assert response.status_code == 200
166+
mock_refund_order.assert_not_called()
167+
168+
assert response.context["form_valid"] is False
169+
assert "refund_reason" in response.context["errors"]
170+
assert "refund_amount" in response.context["errors"]
171+
172+
173+
def test_admin_refund_order_post_order_not_found(client, admin_user):
174+
"""Missing order on POST should redirect to fulfilled orders changelist with an error."""
175+
176+
_login_admin(client, admin_user)
177+
missing_order_id = 999999
178+
179+
post_data = {
180+
"order": str(missing_order_id),
181+
"_selected_action": str(missing_order_id),
182+
"refund_reason": "Test refund",
183+
"refund_amount": "10.00",
184+
}
185+
186+
response = client.post(reverse("refund-order"), data=post_data)
187+
188+
assert response.status_code == 302
189+
assert response.url == reverse("admin:ecommerce_fulfilledorder_changelist")
190+
191+
messages = list(get_messages(response.wsgi_request))
192+
assert len(messages) == 1
193+
assert (
194+
str(messages[0].message)
195+
== f"Order {missing_order_id} could not be found - is it Fulfilled?"
196+
)

0 commit comments

Comments
 (0)