| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586 |
- """The shared drying preflight's blocked-reason rules (#2638).
- An AMS can report several ``dry_sf_reason`` codes at once, and the two callers
- render that differently: the immediate endpoint raises the message, the
- scheduler stores a token the frontend translates. Both pick the code through
- ``primary_reason_code`` so one blocked AMS is not described two ways.
- """
- import pytest
- from backend.app.services import drying_preflight as preflight
- pytestmark = pytest.mark.unit
- class TestPrimaryReasonCode:
- def test_a_single_code_is_returned_as_is(self):
- assert preflight.primary_reason_code([2]) == 2
- @pytest.mark.parametrize("power_code", sorted(preflight.POWER_REASON_CODES))
- def test_power_outranks_a_transient_code(self, power_code):
- """ "AMS is busy" clears by itself; "plug the PSU in" does not, and the
- user can only act on one of them."""
- assert preflight.primary_reason_code([2, power_code]) == power_code
- assert preflight.primary_reason_code([power_code, 2]) == power_code
- def test_power_outranks_retract(self):
- assert preflight.primary_reason_code([preflight.RETRACT_REASON_CODE, 1]) == 1
- def test_retract_outranks_a_transient_code(self):
- assert preflight.primary_reason_code([0, preflight.RETRACT_REASON_CODE]) == preflight.RETRACT_REASON_CODE
- def test_transient_codes_keep_the_reported_order(self):
- assert preflight.primary_reason_code([6, 2, 4]) == 6
- def test_no_codes_is_no_answer(self):
- assert preflight.primary_reason_code([]) is None
- class TestWaitingReason:
- def test_power(self):
- assert preflight.waiting_reason_for_codes([2, 8]) == preflight.WAITING_REASON_POWER
- def test_retract(self):
- assert preflight.waiting_reason_for_codes([2, 3]) == preflight.WAITING_REASON_RETRACT
- def test_transient_falls_through_to_the_generic_token(self):
- assert preflight.waiting_reason_for_codes([2]) == preflight.WAITING_REASON_BLOCKED
- def test_no_codes_is_not_a_specific_reason(self):
- """Callers only ask when something is blocking, but answering with a
- power alert for an empty list would be worse than saying nothing
- specific."""
- assert preflight.waiting_reason_for_codes([]) == preflight.WAITING_REASON_BLOCKED
- class TestBothPathsAgree:
- """The endpoint quotes a message and the scheduler stores a token. Whatever
- they pick, it has to be the same code underneath."""
- @pytest.mark.parametrize(
- "codes,expected_token",
- [
- ([2, 1], preflight.WAITING_REASON_POWER),
- ([2, 8], preflight.WAITING_REASON_POWER),
- ([0, 3], preflight.WAITING_REASON_RETRACT),
- ([6, 2], preflight.WAITING_REASON_BLOCKED),
- ],
- )
- def test_the_message_and_the_token_describe_one_code(self, codes, expected_token):
- code = preflight.primary_reason_code(codes)
- # What the immediate endpoint raises.
- assert code in preflight.DRY_SF_REASON_MESSAGES
- # What the scheduled row records, for the same code.
- assert preflight.waiting_reason_for_codes(codes) == expected_token
- class TestBlockingReasonCodes:
- def test_unknown_and_malformed_codes_are_dropped(self):
- """A firmware that grows a code we have no message for must not block a
- run with an unexplainable reason."""
- assert preflight.blocking_reason_codes({"dry_sf_reason": [2, 99, "x", None]}) == [2]
- def test_a_missing_unit_is_not_blocking(self):
- assert preflight.blocking_reason_codes(None) == []
|