diff --git a/bec_widgets/validation/monitor_config_validator.py b/bec_widgets/validation/monitor_config_validator.py index 84008928..27cdc212 100644 --- a/bec_widgets/validation/monitor_config_validator.py +++ b/bec_widgets/validation/monitor_config_validator.py @@ -60,7 +60,7 @@ class Signal(BaseModel): if entry not in device.signals: raise PydanticCustomError( "no_entry_for_device", - "Entry '{wrong_value}' not found in device '{device_name}' signals", + 'Entry "{wrong_value}" not found in device "{device_name}" signals', {"wrong_value": entry, "device_name": name}, ) @@ -100,8 +100,8 @@ class PlotConfig(BaseModel): def validate_x_signals(cls, v): if len(v.signals) != 1: raise PydanticCustomError( - "x_device_one_signal", - "There must be exactly one signal for x axis. Number of x signals: '{wrong_value}'", + "x_axis_multiple_signals", + 'There must be exactly one signal for x axis. Number of x signals: "{wrong_value}"', {"wrong_value": v}, ) diff --git a/tests/test_bec_monitor.py b/tests/test_bec_monitor.py index 6e9f9b00..54577690 100644 --- a/tests/test_bec_monitor.py +++ b/tests/test_bec_monitor.py @@ -54,6 +54,11 @@ def mocked_client(): device_names = ["samx", "gauss_bpm", "gauss_adc1", "gauss_adc2", "gauss_adc3", "bpm4i"] mocked_devices = {name: get_mocked_device(name) for name in device_names} + # Adding a device with empty signals for validation tests + no_signal_device = FakeDevice(name="no_signal_device") + del no_signal_device.signals # Simulate a device with no signals + mocked_devices["no_signal_device"] = no_signal_device + # Create a MagicMock object client = MagicMock() diff --git a/tests/test_validator_errors.py b/tests/test_validator_errors.py new file mode 100644 index 00000000..7657b9cf --- /dev/null +++ b/tests/test_validator_errors.py @@ -0,0 +1,80 @@ +# pylint: disable=missing-function-docstring +import pytest +from pydantic import ValidationError +from bec_widgets.validation.monitor_config_validator import ( + MonitorConfigValidator, + Signal, + PlotAxis, + PlotConfig, +) + +from test_bec_monitor import mocked_client + + +@pytest.fixture(scope="function") +def setup_devices(mocked_client): + MonitorConfigValidator.devices = mocked_client.device_manager.devices + + +def test_signal_validation_name_missing(setup_devices): + with pytest.raises(ValidationError) as excinfo: + Signal(name=None) + errors = excinfo.value.errors() + assert len(errors) == 1 + assert errors[0]["type"] == "no_device_name" + assert "Device name must be provided" in str(excinfo.value) + + +def test_signal_validation_name_not_in_bec(setup_devices): + with pytest.raises(ValidationError) as excinfo: + Signal(name="non_existent_device") + errors = excinfo.value.errors() + assert len(errors) == 1 + assert errors[0]["type"] == "no_device_bec" + assert 'Device "non_existent_device" not found in current BEC session' in str(excinfo.value) + + +def test_signal_validation_device_has_no_signals(setup_devices): + with pytest.raises(ValidationError) as excinfo: + Signal(name="no_signal_device") + + errors = excinfo.value.errors() + assert len(errors) == 1 + assert errors[0]["type"] == "no_device_signals" + assert 'Device "no_signal_device" does not have "signals" defined' in errors[0]["msg"] + + +def test_signal_validation_entry_not_in_device(setup_devices): + with pytest.raises(ValidationError) as excinfo: + Signal(name="samx", entry="non_existent_entry") + + errors = excinfo.value.errors() + assert len(errors) == 1 + assert errors[0]["type"] == "no_entry_for_device" + assert 'Entry "non_existent_entry" not found in device "samx" signals' in errors[0]["msg"] + + +def test_signal_validation_success(setup_devices): + signal = Signal(name="samx") + assert signal.name == "samx" + + +def test_plot_config_x_axis_signal_validation(setup_devices): + # Setup a valid signal + valid_signal = Signal(name="samx") + + # Case with more than one signal for x-axis + plot_axis_multiple_signals = PlotAxis( + signals=[valid_signal, valid_signal], label="X Axis Label" + ) + with pytest.raises(ValidationError) as excinfo: + PlotConfig( + plot_name="Test Plot", + x=plot_axis_multiple_signals, + y=PlotAxis(signals=[valid_signal], label="Y Axis Label"), + ) + + errors = excinfo.value.errors() + assert len(errors) == 1 + assert errors[0]["type"] == "x_axis_multiple_signals" + assert "There must be exactly one signal for x axis" in errors[0]["msg"]