diff --git a/src/bsblan/bsblan.py b/src/bsblan/bsblan.py index 728c84a4..15384ca9 100644 --- a/src/bsblan/bsblan.py +++ b/src/bsblan/bsblan.py @@ -96,14 +96,11 @@ class BSBLAN: _close_session: bool = False _firmware_version: str | None = None _api_version: str | None = None - _min_temp: float | None = None - _max_temp: float | None = None - _temperature_range_initialized: bool = False _api_data: APIConfig | None = None _initialized: bool = False _api_validator: APIValidator = field(init=False) _temperature_unit: str = "°C" - # Per-circuit temperature ranges: circuit_number -> (min, max, initialized) + # Per-circuit temperature ranges: circuit_number -> {min, max} _circuit_temp_ranges: dict[int, dict[str, float | None]] = field( default_factory=dict, ) @@ -345,7 +342,7 @@ async def _ensure_hot_water_group_validated( return # Request only these specific parameters from the device - params = await self._extract_params_summary(group_params) + params = self._extract_params_summary(group_params) response_data = await self._request( params={"Parameter": params["string_par"]} ) @@ -386,39 +383,6 @@ async def _ensure_hot_water_group_validated( len(params_to_remove), ) - async def _initialize_api_validator(self) -> None: - """Initialize and validate API data against device capabilities. - - DEPRECATED: This method validates all sections upfront. - Use _setup_api_validator() + _ensure_section_validated() for lazy loading. - This method is kept for backwards compatibility. - """ - if self._api_version is None: - raise BSBLANError(ErrorMsg.API_VERSION) - - # Initialize API data if not already done - if self._api_data is None: - self._api_data = self._copy_api_config() - - # Initialize the API validator - self._api_validator = APIValidator(self._api_data) - - # Perform initial validation of each section (eager loading) - sections: list[SectionLiteral] = [ - "heating", - "sensor", - "staticValues", - "device", - "hot_water", - ] - for section in sections: - response_data = await self._validate_api_section(section) - - # Extract temperature unit from heating section validation - # (parameter 710 - target_temperature is always in heating section) - if section == "heating" and response_data: - self._extract_temperature_unit_from_response(response_data) - async def _validate_api_section( self, section: SectionLiteral, include: list[str] | None = None ) -> dict[str, Any] | None: @@ -466,7 +430,7 @@ async def _validate_api_section( try: # Request data from device for validation - params = await self._extract_params_summary(section_data) + params = self._extract_params_summary(section_data) response_data = await self._request( params={"Parameter": params["string_par"]} ) @@ -635,22 +599,12 @@ async def _initialize_temperature_range( from the response (parameter 710), so no extra API call is needed here. """ - if circuit == 1 and self._temperature_range_initialized: - return - if circuit != 1 and circuit in self._circuit_temp_initialized: + if circuit in self._circuit_temp_initialized: return temp_range = await self._fetch_temperature_range(circuit) - - if circuit == 1: - # HC1 uses legacy fields for backwards compatibility - self._min_temp = temp_range["min"] - self._max_temp = temp_range["max"] - self._temperature_range_initialized = True - else: - # HC2 uses per-circuit storage - self._circuit_temp_ranges[circuit] = temp_range - self._circuit_temp_initialized.add(circuit) + self._circuit_temp_ranges[circuit] = temp_range + self._circuit_temp_initialized.add(circuit) def _validate_circuit(self, circuit: int) -> None: """Validate the circuit number. @@ -680,23 +634,6 @@ def get_temperature_unit(self) -> str: """ return self._temperature_unit - async def _initialize_api_data(self) -> APIConfig: - """Initialize and cache the API data. - - Returns: - APIConfig: The API configuration data. - - Raises: - BSBLANError: If the API version or data is not initialized. - - """ - if self._api_data is None: - self._api_data = self._copy_api_config() - logger.debug("API data initialized for version: %s", self._api_version) - if self._api_data is None: - raise BSBLANError(ErrorMsg.API_DATA_NOT_INITIALIZED) - return self._api_data - def _copy_api_config(self) -> APIConfig: """Create a copy of the API configuration for the current version. @@ -900,7 +837,7 @@ def _validate_single_parameter(self, *params: Any, error_msg: str) -> None: if sum(param is not None for param in params) != 1: raise BSBLANError(error_msg) - async def _extract_params_summary(self, params: dict[Any, Any]) -> dict[Any, Any]: + def _extract_params_summary(self, params: dict[Any, Any]) -> dict[Any, Any]: """Get the parameters info from BSBLAN device. Args: @@ -961,7 +898,7 @@ async def _fetch_section_data( if not section_params: raise BSBLANError(ErrorMsg.INVALID_INCLUDE_PARAMS) - params = await self._extract_params_summary(section_params) + params = self._extract_params_summary(section_params) data = await self._request(params={"Parameter": params["string_par"]}) data = dict(zip(params["list"], list(data.values()), strict=True)) return model_class.model_validate(data) @@ -1219,21 +1156,12 @@ async def _validate_target_temperature( raise BSBLANInvalidParameterError(target_temperature) from err # Try to load temperature range for bounds checking - if circuit == 1: - # HC1 uses legacy fields for backwards compatibility - if self._min_temp is None or self._max_temp is None: - await self._initialize_temperature_range(circuit) - - min_temp = self._min_temp - max_temp = self._max_temp - else: - # HC2 uses per-circuit storage - if circuit not in self._circuit_temp_initialized: - await self._initialize_temperature_range(circuit) + if circuit not in self._circuit_temp_initialized: + await self._initialize_temperature_range(circuit) - temp_range = self._circuit_temp_ranges.get(circuit, {}) - min_temp = temp_range.get("min") - max_temp = temp_range.get("max") + temp_range = self._circuit_temp_ranges.get(circuit, {}) + min_temp = temp_range.get("min") + max_temp = temp_range.get("max") # Skip range validation if device doesn't provide min/max if min_temp is None or max_temp is None: @@ -1337,7 +1265,7 @@ async def _fetch_hot_water_data( if not filtered_params: raise BSBLANError(error_msg) - params = await self._extract_params_summary(filtered_params) + params = self._extract_params_summary(filtered_params) data = await self._request(params={"Parameter": params["string_par"]}) data = dict(zip(params["list"], list(data.values()), strict=True)) return model_class.model_validate(data) diff --git a/src/bsblan/exceptions.py b/src/bsblan/exceptions.py index bfaf61cb..5c021b8b 100644 --- a/src/bsblan/exceptions.py +++ b/src/bsblan/exceptions.py @@ -26,15 +26,14 @@ class BSBLANConnectionError(BSBLANError): message_timeout: str = "Timeout occurred while connecting to BSBLAN device." message_error: str = "Error occurred while connecting to BSBLAN device." - def __init__(self, response: str | None = None) -> None: + def __init__(self, message: str | None = None) -> None: """Initialize a new instance of the BSBLANConnectionError class. Args: - response: Optional response message. + message: Optional error message. """ - self.response = response - super().__init__(self.message) + super().__init__(message) class BSBLANVersionError(BSBLANError): diff --git a/tests/conftest.py b/tests/conftest.py index 0c25bbc8..6694b832 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -36,9 +36,6 @@ async def mock_bsblan( monkeypatch.setattr(bsblan, "_firmware_version", "1.0.38-20200730234859") monkeypatch.setattr(bsblan, "_api_version", "v3") monkeypatch.setattr(bsblan, "_api_data", API_V3) - initialize_api_data_mock: AsyncMock = AsyncMock() - # return the constant dictionary - monkeypatch.setattr(bsblan, "_initialize_api_data", initialize_api_data_mock) request_mock: AsyncMock = AsyncMock(return_value={"status": "ok"}) monkeypatch.setattr(bsblan, "_request", request_mock) yield bsblan diff --git a/tests/test_api_initialization.py b/tests/test_api_initialization.py index 1d96cf5a..aa8810a7 100644 --- a/tests/test_api_initialization.py +++ b/tests/test_api_initialization.py @@ -1,9 +1,6 @@ """Tests for API data initialization error handling.""" # pylint: disable=protected-access -from typing import Any -from unittest.mock import AsyncMock - import aiohttp import pytest @@ -11,22 +8,10 @@ from bsblan.bsblan import BSBLANConfig from bsblan.constants import ( API_VERSIONS, - ErrorMsg, ) from bsblan.exceptions import BSBLANError -@pytest.mark.asyncio -async def test_initialize_api_data_no_api_version() -> None: - """Test initializing API data with no API version set.""" - config = BSBLANConfig(host="example.com") - bsblan = BSBLAN(config) - - # API version is None by default - with pytest.raises(BSBLANError, match=ErrorMsg.API_VERSION): - await bsblan._initialize_api_data() - - @pytest.mark.asyncio async def test_request_no_session() -> None: """Test request method with no session initialized.""" @@ -39,8 +24,8 @@ async def test_request_no_session() -> None: @pytest.mark.asyncio -async def test_api_data_initialized_from_versions(monkeypatch: Any) -> None: - """Test that API data is initialized from API_VERSIONS when None (line 141).""" +async def test_api_data_initialized_from_versions() -> None: + """Test that API data is initialized via _setup_api_validator.""" async with aiohttp.ClientSession() as session: config = BSBLANConfig(host="example.com") client = BSBLAN(config, session=session) @@ -49,23 +34,18 @@ async def test_api_data_initialized_from_versions(monkeypatch: Any) -> None: client._api_version = "v1" client._api_data = None # This should be initialized - # Mock request to avoid real network calls - request_mock: AsyncMock = AsyncMock(return_value={}) - monkeypatch.setattr(client, "_request", request_mock) - - # Call _initialize_api_validator which should initialize _api_data - await client._initialize_api_validator() + # Call _setup_api_validator which should initialize _api_data + await client._setup_api_validator() # Verify API data was initialized (should be a copy, not the same object) assert client._api_data is not None # Verify it started with the same keys as API_VERSIONS["v1"] assert set(client._api_data.keys()) == set(API_VERSIONS["v1"].keys()) - # Note: Values will differ after validation since validator modifies the copy @pytest.mark.asyncio -async def test_api_data_property_raises_without_version() -> None: - """Test _initialize_api_data raises error when API version is None (line 368).""" +async def test_copy_api_config_raises_without_version() -> None: + """Test _copy_api_config raises error when API version is None.""" async with aiohttp.ClientSession() as session: config = BSBLANConfig(host="example.com") client = BSBLAN(config, session=session) @@ -76,28 +56,4 @@ async def test_api_data_property_raises_without_version() -> None: # This should raise BSBLANError with pytest.raises(BSBLANError, match="API version not set"): - await client._initialize_api_data() - - -@pytest.mark.asyncio -async def test_initialize_api_data_returns_existing() -> None: - """Test _initialize_api_data returns existing data when already initialized.""" - async with aiohttp.ClientSession() as session: - config = BSBLANConfig(host="example.com") - client = BSBLAN(config, session=session) - - # Set up with pre-initialized data - client._api_version = "v1" - existing_data = { - "heating": {"710": "Test"}, - "staticValues": {"714": "Test"}, - "device": {}, - "sensor": {}, - "hot_water": {}, - } - client._api_data = existing_data # type: ignore[assignment] - - # This should return the existing data without re-initializing - result = await client._initialize_api_data() - assert result is existing_data - assert result == existing_data + client._copy_api_config() diff --git a/tests/test_api_validation.py b/tests/test_api_validation.py index 6ce31b5a..c9bd657d 100644 --- a/tests/test_api_validation.py +++ b/tests/test_api_validation.py @@ -174,7 +174,7 @@ def mock_validate( try: # _api_validator is already set on bsblan - async def mock_extract_params(*_args: Any) -> dict[str, Any]: + def mock_extract_params(*_args: Any) -> dict[str, Any]: # Not using the parameters return {"string_par": "5870", "list": ["Device Parameter"]} diff --git a/tests/test_bsblan_edge_cases.py b/tests/test_bsblan_edge_cases.py index bae914ed..125aa978 100644 --- a/tests/test_bsblan_edge_cases.py +++ b/tests/test_bsblan_edge_cases.py @@ -9,25 +9,9 @@ import pytest from bsblan import BSBLAN, BSBLANConfig -from bsblan.constants import ErrorMsg from bsblan.exceptions import BSBLANConnectionError, BSBLANError -@pytest.mark.asyncio -async def test_initialize_api_data_edge_case() -> None: - """Test _initialize_api_data when API data is None after version setting.""" - config = BSBLANConfig(host="example.com") - bsblan = BSBLAN(config) - - # Force API version to be set but data to be None - bsblan._api_version = "v3" - bsblan._api_data = None - - # This should trigger the defensive check in _initialize_api_data - api_data = await bsblan._initialize_api_data() - assert api_data is not None - - @pytest.mark.asyncio async def test_validate_api_section_key_error(monkeypatch: Any) -> None: """Test validate_api_section when section is not found in API data.""" @@ -107,35 +91,3 @@ def test_bsblan_config_initialization_edge_cases() -> None: assert bsblan.session is None assert bsblan._initialized is False assert len(bsblan._hot_water_param_cache) == 0 - - -@pytest.mark.asyncio -async def test_initialize_api_data_none_after_init(monkeypatch: Any) -> None: - """Test _initialize_api_data raises error when api_data remains None. - - This covers the defensive check at line 391 in bsblan.py. - """ - config = BSBLANConfig(host="example.com") - bsblan = BSBLAN(config) - - # Set API version so we pass the first check - bsblan._api_version = "v3" - - # Monkeypatch dict comprehension to return None (simulating failure) - original_items = dict.items - - def mock_items(self: dict[str, Any]) -> Any: - # Return empty to prevent assignment - return original_items(self) - - # Force _api_data to stay None by patching the assignment - def mock_setattr(obj: Any, name: str, value: Any) -> None: - if name == "_api_data": - object.__setattr__(obj, name, None) - else: - object.__setattr__(obj, name, value) - - monkeypatch.setattr(BSBLAN, "__setattr__", mock_setattr) - - with pytest.raises(BSBLANError, match=ErrorMsg.API_DATA_NOT_INITIALIZED): - await bsblan._initialize_api_data() diff --git a/tests/test_circuit.py b/tests/test_circuit.py index 79e5db0e..7cd48e52 100644 --- a/tests/test_circuit.py +++ b/tests/test_circuit.py @@ -36,9 +36,8 @@ async def mock_bsblan_circuit() -> AsyncGenerator[BSBLAN, None]: bsblan._firmware_version = "1.0.38-20200730234859" bsblan._api_version = "v3" bsblan._api_data = build_api_config("v3") - bsblan._min_temp = 8.0 - bsblan._max_temp = 30.0 - bsblan._temperature_range_initialized = True + bsblan._circuit_temp_ranges[1] = {"min": 8.0, "max": 30.0} + bsblan._circuit_temp_initialized.add(1) api_validator = APIValidator(bsblan._api_data) api_validator.validated_sections.add("heating") @@ -464,11 +463,9 @@ async def test_circuit1_temp_range_unchanged( await bsblan._initialize_temperature_range(circuit=1) - assert bsblan._temperature_range_initialized - assert bsblan._min_temp == 8.0 - assert bsblan._max_temp == 20.0 - # HC1 should NOT be in per-circuit storage - assert 1 not in bsblan._circuit_temp_initialized + assert 1 in bsblan._circuit_temp_initialized + assert bsblan._circuit_temp_ranges[1]["min"] == 8.0 + assert bsblan._circuit_temp_ranges[1]["max"] == 20.0 @pytest.mark.asyncio diff --git a/tests/test_initialization.py b/tests/test_initialization.py index 5dafca23..86d91ef9 100644 --- a/tests/test_initialization.py +++ b/tests/test_initialization.py @@ -20,74 +20,33 @@ @pytest.mark.asyncio -async def test_initialize_api_data_v1(aresponses: ResponsesMockServer) -> None: - """Test initialization of API data with v1 version.""" - # Mock the device config endpoint for v1 - aresponses.add( - "example.com", - "/JQ", - "POST", - aresponses.Response( - status=200, - headers={"Content-Type": "application/json"}, - text=json.dumps( - { - "Brötje": { - "5870": "Some Parameter", - } - } - ), - ), - ) - +async def test_copy_api_config_v1() -> None: + """Test _copy_api_config with v1 version.""" async with aiohttp.ClientSession() as session: bsblan = BSBLAN(BSBLANConfig(host="example.com"), session=session) bsblan._api_version = "v1" - await bsblan._initialize_api_data() + api_data = bsblan._copy_api_config() - # Verify API data was initialized - assert bsblan._api_data is not None + # Verify API data was created + assert api_data is not None @pytest.mark.asyncio -async def test_initialize_api_data_v3(aresponses: ResponsesMockServer) -> None: - """Test initialization of API data with v3 version.""" - # Mock the device info endpoint for v3 - aresponses.add( - "example.com", - "/JQ", - "POST", - aresponses.Response( - status=200, - headers={"Content-Type": "application/json"}, - text=json.dumps( - { - "knownDevices": { - "0": { - "device": "Test Device", - "family": "123", - "type": "456", - "var": "789", - } - } - } - ), - ), - ) - +async def test_copy_api_config_v3() -> None: + """Test _copy_api_config with v3 version.""" async with aiohttp.ClientSession() as session: bsblan = BSBLAN(BSBLANConfig(host="example.com"), session=session) bsblan._api_version = "v3" - await bsblan._initialize_api_data() + api_data = bsblan._copy_api_config() - # Verify API data was initialized - assert bsblan._api_data is not None + # Verify API data was created + assert api_data is not None @pytest.mark.asyncio -async def test_api_version_error() -> None: +async def test_copy_api_config_no_version() -> None: """Test error when API version is not set.""" async with aiohttp.ClientSession() as session: bsblan = BSBLAN(BSBLANConfig(host="example.com"), session=session) @@ -96,7 +55,7 @@ async def test_api_version_error() -> None: bsblan._api_version = None with pytest.raises(BSBLANError, match=ErrorMsg.API_VERSION): - await bsblan._initialize_api_data() + bsblan._copy_api_config() @pytest.mark.asyncio @@ -201,41 +160,16 @@ async def mock_setup_validator() -> None: @pytest.mark.asyncio -async def test_initialize_api_validator() -> None: - """Test initialize_api_validator method.""" +async def test_setup_api_validator() -> None: + """Test _setup_api_validator method.""" async with aiohttp.ClientSession() as session: bsblan = BSBLAN(BSBLANConfig(host="example.com"), session=session) bsblan._api_version = "v3" - bsblan._api_data = { - "heating": {}, - "sensor": {}, - "staticValues": {}, - "device": {}, - "hot_water": {}, - "heating_circuit2": {}, - "staticValues_circuit2": {}, - } - - # Create a coroutine mock for _validate_api_section that returns response data - async def mock_validate_section(section: str) -> dict[str, Any]: - # Return mock response for heating to trigger temperature extraction - if section == "heating": - return { - "710": { - "name": "Target Temperature", - "value": "20.0", - "unit": "°C", - } - } - return {} - - bsblan._validate_api_section = mock_validate_section # type: ignore[method-assign] - - await bsblan._initialize_api_validator() + + await bsblan._setup_api_validator() assert bsblan._api_validator is not None - # Verify temperature unit was extracted from heating section - assert bsblan._temperature_unit == "°C" + assert bsblan._api_data is not None @pytest.mark.asyncio diff --git a/tests/test_temperature_unit.py b/tests/test_temperature_unit.py index c4c7b48c..1e66f0f1 100644 --- a/tests/test_temperature_unit.py +++ b/tests/test_temperature_unit.py @@ -41,9 +41,9 @@ async def test_initialize_temperature_range_celsius() -> None: await bsblan._initialize_temperature_range() # Verify temperature range was set correctly - assert bsblan._min_temp == 10.0 - assert bsblan._max_temp == 30.0 - assert bsblan._temperature_range_initialized is True + assert bsblan._circuit_temp_ranges[1]["min"] == 10.0 + assert bsblan._circuit_temp_ranges[1]["max"] == 30.0 + assert 1 in bsblan._circuit_temp_initialized @pytest.mark.asyncio @@ -63,9 +63,9 @@ async def test_initialize_temperature_range_fahrenheit() -> None: await bsblan._initialize_temperature_range() # Verify temperature range was set correctly - assert bsblan._min_temp == 50.0 - assert bsblan._max_temp == 86.0 - assert bsblan._temperature_range_initialized is True + assert bsblan._circuit_temp_ranges[1]["min"] == 50.0 + assert bsblan._circuit_temp_ranges[1]["max"] == 86.0 + assert 1 in bsblan._circuit_temp_initialized @pytest.mark.asyncio @@ -92,9 +92,9 @@ async def test_initialize_temperature_range_alternate_celsius_format() -> None: await bsblan._initialize_temperature_range() # Verify temperature range was set correctly - assert bsblan._min_temp == 10.0 - assert bsblan._max_temp == 30.0 - assert bsblan._temperature_range_initialized is True + assert bsblan._circuit_temp_ranges[1]["min"] == 10.0 + assert bsblan._circuit_temp_ranges[1]["max"] == 30.0 + assert 1 in bsblan._circuit_temp_initialized @pytest.mark.asyncio diff --git a/tests/test_temperature_validation.py b/tests/test_temperature_validation.py index 8e53cf2a..0d33bff2 100644 --- a/tests/test_temperature_validation.py +++ b/tests/test_temperature_validation.py @@ -37,8 +37,8 @@ async def test_validate_target_temperature_invalid_value() -> None: bsblan = BSBLAN(config) # Initialize temperature range - bsblan._min_temp = 10.0 - bsblan._max_temp = 30.0 + bsblan._circuit_temp_ranges[1] = {"min": 10.0, "max": 30.0} + bsblan._circuit_temp_initialized.add(1) # Test with non-numeric value with pytest.raises(BSBLANInvalidParameterError): @@ -52,8 +52,8 @@ async def test_validate_target_temperature_out_of_range() -> None: bsblan = BSBLAN(config) # Initialize temperature range - bsblan._min_temp = 10.0 - bsblan._max_temp = 30.0 + bsblan._circuit_temp_ranges[1] = {"min": 10.0, "max": 30.0} + bsblan._circuit_temp_initialized.add(1) # Test with value below minimum with pytest.raises(BSBLANInvalidParameterError): @@ -71,8 +71,8 @@ async def test_validate_target_temperature_valid() -> None: bsblan = BSBLAN(config) # Initialize temperature range - bsblan._min_temp = 10.0 - bsblan._max_temp = 30.0 + bsblan._circuit_temp_ranges[1] = {"min": 10.0, "max": 30.0} + bsblan._circuit_temp_initialized.add(1) # Test with valid value (should not raise exception) await bsblan._validate_target_temperature("22.0") @@ -108,7 +108,8 @@ async def test_temperature_range_min_temp_not_available(monkeypatch: Any) -> Non await client._initialize_temperature_range() # min_temp should remain None - assert client._min_temp is None + temp_range = client._circuit_temp_ranges.get(1, {}) + assert temp_range.get("min") is None @pytest.mark.asyncio @@ -141,7 +142,8 @@ async def test_temperature_range_max_temp_not_available(monkeypatch: Any) -> Non await client._initialize_temperature_range() # max_temp should remain None - assert client._max_temp is None + temp_range = client._circuit_temp_ranges.get(1, {}) + assert temp_range.get("max") is None @pytest.mark.asyncio @@ -171,5 +173,6 @@ async def test_temperature_range_static_values_error(monkeypatch: Any) -> None: await client._initialize_temperature_range() # Both should remain None - assert client._min_temp is None - assert client._max_temp is None + temp_range = client._circuit_temp_ranges.get(1, {}) + assert temp_range.get("min") is None + assert temp_range.get("max") is None diff --git a/tests/test_thermostat.py b/tests/test_thermostat.py index de76f2a1..246600f8 100644 --- a/tests/test_thermostat.py +++ b/tests/test_thermostat.py @@ -42,9 +42,8 @@ async def mock_bsblan() -> AsyncGenerator[BSBLAN, None]: bsblan = BSBLAN(config, session=session) bsblan._firmware_version = "1.0.38-20200730234859" bsblan._api_version = "v3" - bsblan._min_temp = 8.0 - bsblan._max_temp = 30.0 - bsblan._temperature_range_initialized = True + bsblan._circuit_temp_ranges[1] = {"min": 8.0, "max": 30.0} + bsblan._circuit_temp_initialized.add(1) yield bsblan diff --git a/tests/test_version_errors.py b/tests/test_version_errors.py index 81853b3c..002ed19a 100644 --- a/tests/test_version_errors.py +++ b/tests/test_version_errors.py @@ -85,14 +85,14 @@ async def test_fetch_firmware_version() -> None: @pytest.mark.asyncio -async def test_initialize_api_validator_no_api_version() -> None: - """Test initialize API validator with no API version set.""" +async def test_setup_api_validator_no_api_version() -> None: + """Test setup API validator with no API version set.""" config = BSBLANConfig(host="example.com") bsblan = BSBLAN(config) # API version is None by default with pytest.raises(BSBLANError, match=ErrorMsg.API_VERSION): - await bsblan._initialize_api_validator() + await bsblan._setup_api_validator() @pytest.mark.asyncio