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()