|
1 | 1 | import json
|
| 2 | +from unittest import skipIf |
2 | 3 |
|
3 | 4 | from unittest.mock import patch
|
4 | 5 | from django.test import override_settings
|
|
9 | 10 |
|
10 | 11 | from oscarapi.basket.operations import get_basket, get_user_basket
|
11 | 12 | from oscarapi.tests.utils import APITest
|
| 13 | +from oscarapi import settings |
12 | 14 |
|
13 | 15 |
|
14 | 16 | Basket = get_model("basket", "Basket")
|
@@ -1149,6 +1151,160 @@ def test_get_user_basket_with_multiple_baskets(self):
|
1149 | 1151 | self.assertEqual(user_basket, Basket.open.first())
|
1150 | 1152 |
|
1151 | 1153 |
|
| 1154 | +@skipIf(settings.BLOCK_ADMIN_API_ACCESS, "Admin API is enabled") |
| 1155 | +class BasketAdminTest(APITest): |
| 1156 | + """ |
| 1157 | + Test suite for admin basket list operations. |
| 1158 | + Covers access permissions, pagination, and ordering. |
| 1159 | + """ |
| 1160 | + |
| 1161 | + fixtures = [ |
| 1162 | + "product", |
| 1163 | + "productcategory", |
| 1164 | + "productattribute", |
| 1165 | + "productclass", |
| 1166 | + "productattributevalue", |
| 1167 | + "category", |
| 1168 | + "attributeoptiongroup", |
| 1169 | + "attributeoption", |
| 1170 | + "stockrecord", |
| 1171 | + "partner", |
| 1172 | + "option", |
| 1173 | + ] |
| 1174 | + |
| 1175 | + def test_basket_admin_list_access(self): |
| 1176 | + """ |
| 1177 | + Test access permissions for basket list view. |
| 1178 | +
|
| 1179 | + Verifies that: |
| 1180 | + - Unauthenticated users are forbidden |
| 1181 | + - Standard users are forbidden |
| 1182 | + - Admin users can access the list |
| 1183 | + """ |
| 1184 | + url = reverse("admin-basket-list") |
| 1185 | + |
| 1186 | + # Test unauthenticated access |
| 1187 | + response = self.client.get(url) |
| 1188 | + self.assertEqual(response.status_code, 403) |
| 1189 | + |
| 1190 | + # Test standard user access |
| 1191 | + self.login("nobody", "nobody") |
| 1192 | + response = self.client.get(url) |
| 1193 | + self.assertEqual(response.status_code, 403) |
| 1194 | + |
| 1195 | + # Test admin access |
| 1196 | + self.login("admin", "admin") |
| 1197 | + response = self.client.get(url) |
| 1198 | + self.assertEqual(response.status_code, 200) |
| 1199 | + |
| 1200 | + def test_basket_admin_list_pagination(self): |
| 1201 | + """ |
| 1202 | + Test pagination functionality for basket list view. |
| 1203 | +
|
| 1204 | + Checks: |
| 1205 | + - Default page size is 100 |
| 1206 | + - Custom page size works correctly |
| 1207 | + - Next page link is present |
| 1208 | + """ |
| 1209 | + |
| 1210 | + # Create baskets for testing |
| 1211 | + admin_user = User.objects.get(username="admin") |
| 1212 | + for _ in range(300): |
| 1213 | + Basket.objects.create(owner=admin_user) |
| 1214 | + |
| 1215 | + self.login("admin", "admin") |
| 1216 | + url = reverse("admin-basket-list") |
| 1217 | + |
| 1218 | + # Test first page pagination |
| 1219 | + response = self.client.get(url) |
| 1220 | + self.assertEqual(response.status_code, 200) |
| 1221 | + self.assertEqual(len(response.data["results"]), 100) |
| 1222 | + |
| 1223 | + # Check next link exists on first page |
| 1224 | + self.assertIsNotNone( |
| 1225 | + response.data["next"], "Next page link should be present on first page" |
| 1226 | + ) |
| 1227 | + |
| 1228 | + # Verify no previous link on first page |
| 1229 | + self.assertIsNone( |
| 1230 | + response.data["previous"], "First page should not have a previous link" |
| 1231 | + ) |
| 1232 | + |
| 1233 | + # Get the next page |
| 1234 | + next_page_url = response.data["next"] |
| 1235 | + next_page_response = self.client.get(next_page_url) |
| 1236 | + |
| 1237 | + self.assertEqual(next_page_response.status_code, 200) |
| 1238 | + self.assertEqual(len(next_page_response.data["results"]), 100) |
| 1239 | + |
| 1240 | + # Check links on second page |
| 1241 | + self.assertIsNotNone( |
| 1242 | + next_page_response.data["next"], |
| 1243 | + "Next page link should be present on second page", |
| 1244 | + ) |
| 1245 | + self.assertIsNotNone( |
| 1246 | + next_page_response.data["previous"], |
| 1247 | + "Second page should have a previous link", |
| 1248 | + ) |
| 1249 | + |
| 1250 | + # Test custom page size |
| 1251 | + response = self.client.get(f"{url}?page_size=5") |
| 1252 | + self.assertEqual(response.status_code, 200) |
| 1253 | + self.assertEqual(len(response.data["results"]), 5) |
| 1254 | + |
| 1255 | + def test_basket_admin_list_ordering(self): |
| 1256 | + """ |
| 1257 | + Test ordering of basket list view. |
| 1258 | +
|
| 1259 | + Verifies that baskets are ordered by ID in descending order. |
| 1260 | + """ |
| 1261 | + # Create baskets for testing |
| 1262 | + admin_user = User.objects.get(username="admin") |
| 1263 | + for _ in range(200): |
| 1264 | + Basket.objects.create(owner=admin_user) |
| 1265 | + |
| 1266 | + self.login("admin", "admin") |
| 1267 | + url = reverse("admin-basket-list") |
| 1268 | + |
| 1269 | + # Fetch and verify ordering |
| 1270 | + response = self.client.get(url) |
| 1271 | + self.assertEqual(response.status_code, 200) |
| 1272 | + |
| 1273 | + basket_ids = [basket["id"] for basket in response.data["results"]] |
| 1274 | + self.assertEqual(basket_ids, sorted(basket_ids, reverse=True)) |
| 1275 | + |
| 1276 | + def test_assign_basket_strategy_call_frequency(self): |
| 1277 | + admin_user, _ = User.objects.get_or_create( |
| 1278 | + username="admin", defaults={"is_staff": True, "password": "admin"} |
| 1279 | + ) |
| 1280 | + total_baskets = 350 |
| 1281 | + |
| 1282 | + # Populate baskets for the test |
| 1283 | + Basket.objects.bulk_create( |
| 1284 | + [Basket(owner=admin_user) for _ in range(total_baskets)] |
| 1285 | + ) |
| 1286 | + |
| 1287 | + # Log in as admin |
| 1288 | + self.client.login(username="admin", password="admin") |
| 1289 | + |
| 1290 | + url = reverse("admin-basket-list") |
| 1291 | + |
| 1292 | + # Mock assign_basket_strategy and bypass serialization |
| 1293 | + with patch("oscarapi.views.admin.basket.assign_basket_strategy") as mock_assign: |
| 1294 | + with patch( |
| 1295 | + "oscarapi.serializers.basket.BasketSerializer.to_representation", |
| 1296 | + return_value={}, |
| 1297 | + ): |
| 1298 | + self.client.get(url) |
| 1299 | + |
| 1300 | + # Assert that the mock was called exactly 100 times instead of 350 |
| 1301 | + self.assertEqual( |
| 1302 | + mock_assign.call_count, |
| 1303 | + 100, |
| 1304 | + f"First page should have 100 assign_basket_strategy calls, got {mock_assign.call_count}", |
| 1305 | + ) |
| 1306 | + |
| 1307 | + |
1152 | 1308 | @override_settings(
|
1153 | 1309 | MIDDLEWARE=(
|
1154 | 1310 | "django.middleware.common.CommonMiddleware",
|
|
0 commit comments