116 lines
4.3 KiB
Python
116 lines
4.3 KiB
Python
import unittest
|
|
|
|
from module_business.domain.enums import (
|
|
DocumentStatus,
|
|
PalletEventType,
|
|
PalletFlowState,
|
|
ReturnStatus,
|
|
)
|
|
from module_business.domain.pallet_state_machine import (
|
|
InvalidPalletTransition,
|
|
PalletStateMachine,
|
|
)
|
|
|
|
|
|
class PalletStateMachineTest(unittest.TestCase):
|
|
def test_dispatch_cannot_skip_receiving_confirmation(self) -> None:
|
|
with self.assertRaises(InvalidPalletTransition):
|
|
PalletStateMachine.ensure_transition(
|
|
PalletFlowState.FILLED_IN_WAREHOUSE,
|
|
PalletFlowState.AT_SITE_UNUSED,
|
|
)
|
|
|
|
ALLOWED_TRANSITIONS = (
|
|
(PalletFlowState.UNSTOCKED, PalletFlowState.EMPTY_IN_WAREHOUSE),
|
|
(PalletFlowState.EMPTY_IN_WAREHOUSE, PalletFlowState.FILLED_IN_WAREHOUSE),
|
|
(PalletFlowState.FILLED_IN_WAREHOUSE, PalletFlowState.IN_TRANSIT),
|
|
(PalletFlowState.IN_TRANSIT, PalletFlowState.AT_SITE_UNUSED),
|
|
(PalletFlowState.AT_SITE_UNUSED, PalletFlowState.AT_SITE_PARTIAL),
|
|
(PalletFlowState.AT_SITE_UNUSED, PalletFlowState.AT_SITE_EMPTY),
|
|
(PalletFlowState.AT_SITE_UNUSED, PalletFlowState.RETURNING),
|
|
(PalletFlowState.AT_SITE_PARTIAL, PalletFlowState.AT_SITE_PARTIAL),
|
|
(PalletFlowState.AT_SITE_PARTIAL, PalletFlowState.AT_SITE_EMPTY),
|
|
(PalletFlowState.AT_SITE_PARTIAL, PalletFlowState.RETURNING),
|
|
(PalletFlowState.AT_SITE_EMPTY, PalletFlowState.RETURNING),
|
|
(PalletFlowState.RETURNING, PalletFlowState.FILLED_IN_WAREHOUSE),
|
|
(PalletFlowState.RETURNING, PalletFlowState.EMPTY_IN_WAREHOUSE),
|
|
)
|
|
|
|
def test_confirmed_flow_is_allowed(self) -> None:
|
|
for current, target in self.ALLOWED_TRANSITIONS:
|
|
PalletStateMachine.ensure_transition(current, target)
|
|
|
|
def test_refill_at_customer_site_is_rejected(self) -> None:
|
|
with self.assertRaises(InvalidPalletTransition):
|
|
PalletStateMachine.ensure_transition(
|
|
PalletFlowState.AT_SITE_EMPTY,
|
|
PalletFlowState.FILLED_IN_WAREHOUSE,
|
|
)
|
|
|
|
def test_raw_string_states_are_rejected(self) -> None:
|
|
with self.assertRaisesRegex(TypeError, 'PalletFlowState'):
|
|
PalletStateMachine.ensure_transition(
|
|
'UNSTOCKED',
|
|
'EMPTY_IN_WAREHOUSE',
|
|
)
|
|
|
|
def test_mixed_state_types_are_rejected(self) -> None:
|
|
mixed_states = (
|
|
('UNSTOCKED', PalletFlowState.EMPTY_IN_WAREHOUSE),
|
|
(PalletFlowState.UNSTOCKED, 'EMPTY_IN_WAREHOUSE'),
|
|
)
|
|
for current, target in mixed_states:
|
|
with self.subTest(current=current, target=target), self.assertRaisesRegex(TypeError, 'PalletFlowState'):
|
|
PalletStateMachine.ensure_transition(current, target)
|
|
|
|
def test_confirmed_flow_is_the_only_allowed_transition_set(self) -> None:
|
|
actual_allowed = set()
|
|
for current in PalletFlowState:
|
|
for target in PalletFlowState:
|
|
try:
|
|
PalletStateMachine.ensure_transition(current, target)
|
|
except InvalidPalletTransition:
|
|
continue
|
|
actual_allowed.add((current, target))
|
|
|
|
self.assertEqual(set(self.ALLOWED_TRANSITIONS), actual_allowed)
|
|
|
|
|
|
class PalletEnumTest(unittest.TestCase):
|
|
def test_supporting_enum_values_match_domain_contract(self) -> None:
|
|
self.assertEqual(
|
|
[
|
|
'UNSTOCKED',
|
|
'EMPTY_IN_WAREHOUSE',
|
|
'FILLED_IN_WAREHOUSE',
|
|
'IN_TRANSIT',
|
|
'AT_SITE_UNUSED',
|
|
'AT_SITE_PARTIAL',
|
|
'AT_SITE_EMPTY',
|
|
'RETURNING',
|
|
],
|
|
[item.value for item in PalletFlowState],
|
|
)
|
|
self.assertEqual(['DRAFT', 'CONFIRMED'], [item.value for item in DocumentStatus])
|
|
self.assertEqual(
|
|
['REQUESTED', 'CONFIRMED'],
|
|
[item.value for item in ReturnStatus],
|
|
)
|
|
self.assertEqual(
|
|
[
|
|
'INBOUND_CONFIRMED',
|
|
'FILLING_CONFIRMED',
|
|
'SHIPMENT_CONFIRMED',
|
|
'SHIPMENT_RECEIVED',
|
|
'TUNNEL_ENTERED',
|
|
'USAGE_RECORDED',
|
|
'RETURN_REQUESTED',
|
|
'RETURN_CONFIRMED',
|
|
],
|
|
[item.value for item in PalletEventType],
|
|
)
|
|
|
|
|
|
if __name__ == '__main__':
|
|
unittest.main()
|