From beddfb14b2c93e09c0fb79d307f5d59d507b8a23 Mon Sep 17 00:00:00 2001 From: wyzula-jan Date: Fri, 12 Jun 2026 17:54:10 +0200 Subject: [PATCH] feat(beamline_states): exempt scan-interlock states from display filters --- .../beamline_states/beamline_state_manager.py | 3 +- tests/unit_tests/test_beamline_state_pill.py | 43 ++++++++++++++++--- 2 files changed, 38 insertions(+), 8 deletions(-) diff --git a/bec_widgets/widgets/services/beamline_states/beamline_state_manager.py b/bec_widgets/widgets/services/beamline_states/beamline_state_manager.py index e73ae86e..da865281 100644 --- a/bec_widgets/widgets/services/beamline_states/beamline_state_manager.py +++ b/bec_widgets/widgets/services/beamline_states/beamline_state_manager.py @@ -655,7 +655,8 @@ class BeamlineStateManager(BECWidget, QWidget): visible_names = [] hidden_names = [] for name in self._state_order: - if self._is_state_visible(name): + # States watched by the scan interlock are exempt from filtering. + if name in self._interlock_states or self._is_state_visible(name): visible_names.append(name) else: hidden_names.append(name) diff --git a/tests/unit_tests/test_beamline_state_pill.py b/tests/unit_tests/test_beamline_state_pill.py index bbbef714..5c6debb2 100644 --- a/tests/unit_tests/test_beamline_state_pill.py +++ b/tests/unit_tests/test_beamline_state_pill.py @@ -654,7 +654,36 @@ def test_beamline_state_manager_header_visibility_follows_filters(qtbot, mocked_ ) beamline_state_manager._state_pills["limits"].update_state( - {"name": "limits", "status": "valid", "label": "Within limits."}, {} + {"name": "limits", "status": "invalid", "label": "Out of limits."}, {} + ) + beamline_state_manager._state_pills["shutter_open"].update_state( + {"name": "shutter_open", "status": "valid", "label": "Open."}, {} + ) + beamline_state_manager._selected_statuses = {"valid"} + beamline_state_manager._apply_filters() + + model = beamline_state_manager._model + assert not beamline_state_manager._view.isRowHidden(0) + assert not beamline_state_manager._view.isRowHidden(model.index_for_name("shutter_open").row()) + assert beamline_state_manager._view.isRowHidden(2) + assert beamline_state_manager._view.isRowHidden(model.index_for_name("limits").row()) + + beamline_state_manager.clear_filters() + + assert not beamline_state_manager._view.isRowHidden(2) + + +def test_beamline_state_manager_interlock_states_bypass_filters(qtbot, mocked_client): + beamline_state_manager = create_widget(qtbot, BeamlineStateManager, client=mocked_client) + beamline_state_manager.update_available_states( + {"states": [_limits_state(), _shutter_state()]}, {} + ) + _install_fake_scan_interlock( + beamline_state_manager, _FakeScanInterlock(states_watched={"shutter_open": "valid"}) + ) + + beamline_state_manager._state_pills["limits"].update_state( + {"name": "limits", "status": "invalid", "label": "Out of limits."}, {} ) beamline_state_manager._state_pills["shutter_open"].update_state( {"name": "shutter_open", "status": "invalid", "label": "Closed."}, {} @@ -663,14 +692,14 @@ def test_beamline_state_manager_header_visibility_follows_filters(qtbot, mocked_ beamline_state_manager._apply_filters() model = beamline_state_manager._model - assert beamline_state_manager._view.isRowHidden(0) - assert beamline_state_manager._view.isRowHidden(model.index_for_name("shutter_open").row()) - assert not beamline_state_manager._view.isRowHidden(2) - assert not beamline_state_manager._view.isRowHidden(model.index_for_name("limits").row()) + assert not beamline_state_manager._view.isRowHidden(model.index_for_name("shutter_open").row()) + assert beamline_state_manager._view.isRowHidden(model.index_for_name("limits").row()) + assert "1 state is hidden" in beamline_state_manager._hidden_summary.text() - beamline_state_manager.clear_filters() + beamline_state_manager._device_filter_text = "nonexistent_device" + beamline_state_manager._apply_filters() - assert not beamline_state_manager._view.isRowHidden(0) + assert not beamline_state_manager._view.isRowHidden(model.index_for_name("shutter_open").row()) def test_beamline_state_manager_paints_section_headers(qtbot, mocked_client):