mirror of
https://github.com/inventree/InvenTree.git
synced 2026-09-27 22:26:00 +00:00
PO status fix (#12885)
* Fix for PurchaseOrder status code view - Order dependent, due to new viewset * Add regression tests for status code API endpoints
This commit is contained in:
@@ -1426,6 +1426,21 @@ class BuildListTest(BuildAPITest):
|
||||
assert_fnc=lambda x: x.data['results'][0],
|
||||
)
|
||||
|
||||
def test_status_codes_endpoint(self):
|
||||
"""The 'build/status/' endpoint must resolve to the status-codes view.
|
||||
|
||||
Regression test: ensures the literal 'status/' path is not shadowed by the
|
||||
'build/<pk>/' detail route it sits alongside in the same urlconf.
|
||||
"""
|
||||
response = self.get(reverse('api-build-status-codes'), expected_code=200)
|
||||
|
||||
self.assertIn('status_class', response.data)
|
||||
self.assertIn('values', response.data)
|
||||
self.assertIn('PENDING', response.data['values'])
|
||||
self.assertEqual(
|
||||
response.data['values']['PENDING']['key'], BuildStatus.PENDING.value
|
||||
)
|
||||
|
||||
|
||||
class BuildOutputCreateTest(BuildAPITest):
|
||||
"""Unit test for creating build output via API."""
|
||||
|
||||
@@ -2695,8 +2695,6 @@ class OrderCalendarExport(ICalFeed):
|
||||
|
||||
|
||||
order_api_urls = [
|
||||
# Purchase Order, Line Item, and Extra Line API endpoints via ViewSet router
|
||||
path('', include(order_router.urls)),
|
||||
# Purchase order status code information (requires custom kwargs)
|
||||
path(
|
||||
'po/status/',
|
||||
@@ -2704,6 +2702,8 @@ order_api_urls = [
|
||||
{StatusView.MODEL_REF: PurchaseOrderStatus},
|
||||
name='api-po-status-codes',
|
||||
),
|
||||
# Purchase Order, Line Item, and Extra Line API endpoints via ViewSet router
|
||||
path('', include(order_router.urls)),
|
||||
# API endpoints for sales orders
|
||||
path(
|
||||
'so/',
|
||||
|
||||
@@ -999,6 +999,27 @@ class PurchaseOrderTest(OrderTest):
|
||||
self.assertIn('status_text', result)
|
||||
self.assertIsNotNone(result['status_text'])
|
||||
|
||||
def test_status_codes_endpoint(self):
|
||||
"""The 'po/status/' endpoint must resolve to the status-codes view.
|
||||
|
||||
Regression test: PurchaseOrder is served by a ViewSet router, whose
|
||||
generated detail route ('po/<pk>/') uses DRF's default, permissive pk
|
||||
lookup regex. That regex is happy to match the literal segment 'status'
|
||||
as a pk, so if the router is registered ahead of the 'po/status/' path in
|
||||
the urlconf, this endpoint gets swallowed by
|
||||
PurchaseOrderViewSet.retrieve(pk='status') instead of reaching StatusView -
|
||||
returning a 404 (no such PurchaseOrder) rather than the status code data.
|
||||
"""
|
||||
response = self.get(reverse('api-po-status-codes'), expected_code=200)
|
||||
|
||||
# A genuine StatusView response - not a PurchaseOrder-detail-shaped 404
|
||||
self.assertIn('status_class', response.data)
|
||||
self.assertIn('values', response.data)
|
||||
self.assertIn('PENDING', response.data['values'])
|
||||
self.assertEqual(
|
||||
response.data['values']['PENDING']['key'], PurchaseOrderStatus.PENDING.value
|
||||
)
|
||||
|
||||
|
||||
class PurchaseOrderLineItemTest(OrderTest):
|
||||
"""Unit tests for PurchaseOrderLineItems."""
|
||||
@@ -2489,6 +2510,25 @@ class SalesOrderTest(OrderTest):
|
||||
self.assertIn('status_text', result)
|
||||
self.assertIsNotNone(result['status_text'])
|
||||
|
||||
def test_status_codes_endpoint(self):
|
||||
"""The 'so/status/' endpoint must resolve to the status-codes view.
|
||||
|
||||
SalesOrder is not (yet) served by a ViewSet router - its detail route uses
|
||||
Django's '<int:pk>' path converter, which is not vulnerable to the
|
||||
router-based bug affecting PurchaseOrder (see PurchaseOrderTest for
|
||||
details). This is a coverage test guarding against a future regression,
|
||||
e.g. if SalesOrder is migrated to a router-based viewset without also
|
||||
restricting the pk lookup pattern.
|
||||
"""
|
||||
response = self.get(reverse('api-so-status-codes'), expected_code=200)
|
||||
|
||||
self.assertIn('status_class', response.data)
|
||||
self.assertIn('values', response.data)
|
||||
self.assertIn('PENDING', response.data['values'])
|
||||
self.assertEqual(
|
||||
response.data['values']['PENDING']['key'], SalesOrderStatus.PENDING.value
|
||||
)
|
||||
|
||||
|
||||
class SalesOrderLineItemTest(OrderTest):
|
||||
"""Tests for the SalesOrderLineItem API."""
|
||||
@@ -3888,6 +3928,23 @@ class ReturnOrderTests(InvenTreeAPITestCase):
|
||||
reverse('api-return-order-detail', kwargs={'pk': 1}), ['customer_detail']
|
||||
)
|
||||
|
||||
def test_status_codes_endpoint(self):
|
||||
"""The 'ro/status/' endpoint must resolve to the status-codes view.
|
||||
|
||||
ReturnOrder is not (yet) served by a ViewSet router - its detail route uses
|
||||
Django's '<int:pk>' path converter, which is not vulnerable to the
|
||||
router-based bug affecting PurchaseOrder (see PurchaseOrderTest for
|
||||
details). This is a coverage test guarding against a future regression.
|
||||
"""
|
||||
response = self.get(reverse('api-return-order-status-codes'), expected_code=200)
|
||||
|
||||
self.assertIn('status_class', response.data)
|
||||
self.assertIn('values', response.data)
|
||||
self.assertIn('PENDING', response.data['values'])
|
||||
self.assertEqual(
|
||||
response.data['values']['PENDING']['key'], ReturnOrderStatus.PENDING.value
|
||||
)
|
||||
|
||||
|
||||
class ReturnOrderLineItemTests(InvenTreeAPITestCase):
|
||||
"""Unit tests for ReturnOrderLineItem API endpoints."""
|
||||
@@ -4051,6 +4108,26 @@ class ReturnOrderLineItemTests(InvenTreeAPITestCase):
|
||||
|
||||
self.assertEqual(models.ReturnOrderExtraLine.objects.count(), n - 2)
|
||||
|
||||
def test_status_codes_endpoint(self):
|
||||
"""The 'ro-line/status/' endpoint must resolve to the status-codes view.
|
||||
|
||||
ReturnOrderLineItem is not (yet) served by a ViewSet router - its detail
|
||||
route uses Django's '<int:pk>' path converter, which is not vulnerable to
|
||||
the router-based bug affecting PurchaseOrder (see PurchaseOrderTest for
|
||||
details). This is a coverage test guarding against a future regression.
|
||||
"""
|
||||
response = self.get(
|
||||
reverse('api-return-order-line-status-codes'), expected_code=200
|
||||
)
|
||||
|
||||
self.assertIn('status_class', response.data)
|
||||
self.assertIn('values', response.data)
|
||||
self.assertIn('PENDING', response.data['values'])
|
||||
self.assertEqual(
|
||||
response.data['values']['PENDING']['key'],
|
||||
ReturnOrderLineStatus.PENDING.value,
|
||||
)
|
||||
|
||||
|
||||
class ExtraLineTotalPriceTest(InvenTreeAPITestCase):
|
||||
"""Unit tests for the 'total_price' field on ExtraLine API endpoints.
|
||||
|
||||
@@ -2417,6 +2417,19 @@ class StockItemTest(StockAPITestCase):
|
||||
item.refresh_from_db()
|
||||
self.assertEqual(item.batch, 'NEW-BATCH-CODE')
|
||||
|
||||
def test_status_codes_endpoint(self):
|
||||
"""The 'stock/status/' endpoint must resolve to the status-codes view.
|
||||
|
||||
Regression test: ensures the literal 'status/' path is not shadowed by the
|
||||
'stock/<pk>/' detail route it sits alongside in the same urlconf.
|
||||
"""
|
||||
response = self.get(reverse('api-stock-status-codes'), expected_code=200)
|
||||
|
||||
self.assertIn('status_class', response.data)
|
||||
self.assertIn('values', response.data)
|
||||
self.assertIn('OK', response.data['values'])
|
||||
self.assertEqual(response.data['values']['OK']['key'], StockStatus.OK.value)
|
||||
|
||||
|
||||
class StockItemDisassembleTest(StockAPITestCase):
|
||||
"""Series of API tests for the StockItem disassembly endpoint."""
|
||||
@@ -4051,6 +4064,23 @@ class StockTrackingTest(StockAPITestCase):
|
||||
assert_fnc=lambda x: x.data['results'][0],
|
||||
)
|
||||
|
||||
def test_status_codes_endpoint(self):
|
||||
"""The 'track/status/' endpoint must resolve to the status-codes view.
|
||||
|
||||
Regression test: ensures the literal 'status/' path is not shadowed by the
|
||||
'track/<pk>/' detail route it sits alongside in the same urlconf.
|
||||
"""
|
||||
response = self.get(
|
||||
reverse('api-stock-tracking-status-codes'), expected_code=200
|
||||
)
|
||||
|
||||
self.assertIn('status_class', response.data)
|
||||
self.assertIn('values', response.data)
|
||||
self.assertIn('CREATED', response.data['values'])
|
||||
self.assertEqual(
|
||||
response.data['values']['CREATED']['key'], StockHistoryCode.CREATED.value
|
||||
)
|
||||
|
||||
|
||||
class StockAssignTest(StockAPITestCase):
|
||||
"""Unit tests for the stock assignment API endpoint, where stock items are manually assigned to a customer."""
|
||||
|
||||
Reference in New Issue
Block a user