mirror of
https://github.com/home-assistant/core.git
synced 2025-08-04 21:25:13 +02:00
Add name_fn and test_sensor adoptions
This commit is contained in:
@@ -39,6 +39,70 @@ from homeassistant.helpers.update_coordinator import CoordinatorEntity
|
|||||||
from .const import COORDINATOR, DEVICE_ID, DOMAIN, MANUFACTURER, PARAMETERS, STATES
|
from .const import COORDINATOR, DEVICE_ID, DOMAIN, MANUFACTURER, PARAMETERS, STATES
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass(kw_only=True, frozen=True)
|
||||||
|
class WolflinkSensorEntityDescription(SensorEntityDescription):
|
||||||
|
"""Describes Wolflink sensor entity."""
|
||||||
|
|
||||||
|
name_fn: Callable[[Parameter], str]
|
||||||
|
supported_fn: Callable[[Parameter], bool]
|
||||||
|
|
||||||
|
|
||||||
|
SENSOR_DESCRIPTIONS = [
|
||||||
|
WolflinkSensorEntityDescription(
|
||||||
|
key="temperature",
|
||||||
|
device_class=SensorDeviceClass.TEMPERATURE,
|
||||||
|
native_unit_of_measurement=UnitOfTemperature.CELSIUS,
|
||||||
|
supported_fn=lambda param: isinstance(param, Temperature),
|
||||||
|
name_fn=lambda param: param.name,
|
||||||
|
),
|
||||||
|
WolflinkSensorEntityDescription(
|
||||||
|
key="pressure",
|
||||||
|
device_class=SensorDeviceClass.PRESSURE,
|
||||||
|
native_unit_of_measurement=UnitOfPressure.BAR,
|
||||||
|
supported_fn=lambda param: isinstance(param, Pressure),
|
||||||
|
name_fn=lambda param: param.name,
|
||||||
|
),
|
||||||
|
WolflinkSensorEntityDescription(
|
||||||
|
key="energy",
|
||||||
|
device_class=SensorDeviceClass.ENERGY,
|
||||||
|
native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR,
|
||||||
|
supported_fn=lambda param: isinstance(param, EnergyParameter),
|
||||||
|
name_fn=lambda param: param.name,
|
||||||
|
),
|
||||||
|
WolflinkSensorEntityDescription(
|
||||||
|
key="power",
|
||||||
|
device_class=SensorDeviceClass.POWER,
|
||||||
|
native_unit_of_measurement=UnitOfPower.KILO_WATT,
|
||||||
|
supported_fn=lambda param: isinstance(param, PowerParameter),
|
||||||
|
name_fn=lambda param: param.name,
|
||||||
|
),
|
||||||
|
WolflinkSensorEntityDescription(
|
||||||
|
key="percentage",
|
||||||
|
native_unit_of_measurement=PERCENTAGE,
|
||||||
|
supported_fn=lambda param: isinstance(param, PercentageParameter),
|
||||||
|
name_fn=lambda param: param.name,
|
||||||
|
),
|
||||||
|
WolflinkSensorEntityDescription(
|
||||||
|
key="list_item",
|
||||||
|
translation_key="state",
|
||||||
|
supported_fn=lambda param: isinstance(param, ListItemParameter),
|
||||||
|
name_fn=lambda param: param.name,
|
||||||
|
),
|
||||||
|
WolflinkSensorEntityDescription(
|
||||||
|
key="hours",
|
||||||
|
icon="mdi:clock",
|
||||||
|
native_unit_of_measurement=UnitOfTime.HOURS,
|
||||||
|
supported_fn=lambda param: isinstance(param, HoursParameter),
|
||||||
|
name_fn=lambda param: param.name,
|
||||||
|
),
|
||||||
|
WolflinkSensorEntityDescription(
|
||||||
|
key="default",
|
||||||
|
supported_fn=lambda param: isinstance(param, SimpleParameter),
|
||||||
|
name_fn=lambda param: param.name,
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
async def async_setup_entry(
|
async def async_setup_entry(
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
config_entry: ConfigEntry,
|
config_entry: ConfigEntry,
|
||||||
@@ -50,93 +114,15 @@ async def async_setup_entry(
|
|||||||
device_id = hass.data[DOMAIN][config_entry.entry_id][DEVICE_ID]
|
device_id = hass.data[DOMAIN][config_entry.entry_id][DEVICE_ID]
|
||||||
|
|
||||||
entities: list[WolfLinkSensor] = [
|
entities: list[WolfLinkSensor] = [
|
||||||
WolfLinkSensor(
|
WolfLinkSensor(coordinator, parameter, device_id, description)
|
||||||
coordinator, parameter, device_id, get_entity_description(parameter)
|
|
||||||
)
|
|
||||||
for parameter in parameters
|
for parameter in parameters
|
||||||
|
for description in SENSOR_DESCRIPTIONS
|
||||||
|
if description.supported_fn(parameter)
|
||||||
]
|
]
|
||||||
|
|
||||||
async_add_entities(entities, True)
|
async_add_entities(entities, True)
|
||||||
|
|
||||||
|
|
||||||
@dataclass(kw_only=True, frozen=True)
|
|
||||||
class WolflinkSensorEntityDescription(SensorEntityDescription):
|
|
||||||
"""Describes Wolflink sensor entity."""
|
|
||||||
|
|
||||||
supported_fn: Callable[[Parameter], bool]
|
|
||||||
|
|
||||||
|
|
||||||
SENSOR_DESCRIPTIONS = [
|
|
||||||
WolflinkSensorEntityDescription(
|
|
||||||
key="temperature",
|
|
||||||
device_class=SensorDeviceClass.TEMPERATURE,
|
|
||||||
native_unit_of_measurement=UnitOfTemperature.CELSIUS,
|
|
||||||
supported_fn=lambda param: isinstance(param, Temperature),
|
|
||||||
),
|
|
||||||
WolflinkSensorEntityDescription(
|
|
||||||
key="pressure",
|
|
||||||
device_class=SensorDeviceClass.PRESSURE,
|
|
||||||
native_unit_of_measurement=UnitOfPressure.BAR,
|
|
||||||
supported_fn=lambda param: isinstance(param, Pressure),
|
|
||||||
),
|
|
||||||
WolflinkSensorEntityDescription(
|
|
||||||
key="energy",
|
|
||||||
device_class=SensorDeviceClass.ENERGY,
|
|
||||||
native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR,
|
|
||||||
supported_fn=lambda param: isinstance(param, EnergyParameter),
|
|
||||||
),
|
|
||||||
WolflinkSensorEntityDescription(
|
|
||||||
key="power",
|
|
||||||
device_class=SensorDeviceClass.POWER,
|
|
||||||
native_unit_of_measurement=UnitOfPower.KILO_WATT,
|
|
||||||
supported_fn=lambda param: isinstance(param, PowerParameter),
|
|
||||||
),
|
|
||||||
WolflinkSensorEntityDescription(
|
|
||||||
key="percentage",
|
|
||||||
native_unit_of_measurement=PERCENTAGE,
|
|
||||||
supported_fn=lambda param: isinstance(param, PercentageParameter),
|
|
||||||
),
|
|
||||||
WolflinkSensorEntityDescription(
|
|
||||||
key="list_item",
|
|
||||||
translation_key="state",
|
|
||||||
supported_fn=lambda param: isinstance(param, ListItemParameter),
|
|
||||||
),
|
|
||||||
WolflinkSensorEntityDescription(
|
|
||||||
key="hours",
|
|
||||||
icon="mdi:clock",
|
|
||||||
native_unit_of_measurement=UnitOfTime.HOURS,
|
|
||||||
supported_fn=lambda param: isinstance(param, HoursParameter),
|
|
||||||
),
|
|
||||||
WolflinkSensorEntityDescription(
|
|
||||||
key="default",
|
|
||||||
supported_fn=lambda param: isinstance(param, SimpleParameter),
|
|
||||||
),
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
def get_entity_description(parameter: Parameter) -> WolflinkSensorEntityDescription:
|
|
||||||
"""Return the entity description for a given parameter."""
|
|
||||||
for description in SENSOR_DESCRIPTIONS:
|
|
||||||
if description.supported_fn(parameter):
|
|
||||||
return WolflinkSensorEntityDescription(
|
|
||||||
key=parameter.parameter_id,
|
|
||||||
name=parameter.name,
|
|
||||||
device_class=description.device_class,
|
|
||||||
native_unit_of_measurement=description.native_unit_of_measurement,
|
|
||||||
icon=description.icon,
|
|
||||||
entity_registry_enabled_default=description.entity_registry_enabled_default,
|
|
||||||
entity_category=description.entity_category,
|
|
||||||
has_entity_name=description.has_entity_name,
|
|
||||||
translation_key=description.translation_key,
|
|
||||||
supported_fn=description.supported_fn,
|
|
||||||
)
|
|
||||||
return WolflinkSensorEntityDescription(
|
|
||||||
key=parameter.parameter_id,
|
|
||||||
name=parameter.name,
|
|
||||||
supported_fn=lambda param: True,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class WolfLinkSensor(CoordinatorEntity, SensorEntity):
|
class WolfLinkSensor(CoordinatorEntity, SensorEntity):
|
||||||
"""Base class for all Wolf entities."""
|
"""Base class for all Wolf entities."""
|
||||||
|
|
||||||
@@ -153,7 +139,7 @@ class WolfLinkSensor(CoordinatorEntity, SensorEntity):
|
|||||||
super().__init__(coordinator)
|
super().__init__(coordinator)
|
||||||
self.entity_description = description
|
self.entity_description = description
|
||||||
self.wolf_object = wolf_object
|
self.wolf_object = wolf_object
|
||||||
self._attr_name = str(description.name)
|
self._attr_name = description.name_fn(wolf_object)
|
||||||
self._attr_unique_id = f"{device_id}:{wolf_object.parameter_id}"
|
self._attr_unique_id = f"{device_id}:{wolf_object.parameter_id}"
|
||||||
self._state = None
|
self._state = None
|
||||||
self._attr_device_info = DeviceInfo(
|
self._attr_device_info = DeviceInfo(
|
||||||
|
25
tests/components/wolflink/snapshots/test_sensor.ambr
Normal file
25
tests/components/wolflink/snapshots/test_sensor.ambr
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
# serializer version: 1
|
||||||
|
# name: test_sensor[wolf_parameter0]
|
||||||
|
None
|
||||||
|
# ---
|
||||||
|
# name: test_sensor[wolf_parameter1]
|
||||||
|
None
|
||||||
|
# ---
|
||||||
|
# name: test_sensor[wolf_parameter2]
|
||||||
|
None
|
||||||
|
# ---
|
||||||
|
# name: test_sensor[wolf_parameter3]
|
||||||
|
None
|
||||||
|
# ---
|
||||||
|
# name: test_sensor[wolf_parameter4]
|
||||||
|
None
|
||||||
|
# ---
|
||||||
|
# name: test_sensor[wolf_parameter5]
|
||||||
|
None
|
||||||
|
# ---
|
||||||
|
# name: test_sensor[wolf_parameter6]
|
||||||
|
None
|
||||||
|
# ---
|
||||||
|
# name: test_sensor[wolf_parameter7]
|
||||||
|
None
|
||||||
|
# ---
|
@@ -3,8 +3,8 @@
|
|||||||
from unittest.mock import MagicMock, Mock
|
from unittest.mock import MagicMock, Mock
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
from syrupy import SnapshotAssertion
|
||||||
from wolf_comm import (
|
from wolf_comm import (
|
||||||
PERCENTAGE,
|
|
||||||
EnergyParameter,
|
EnergyParameter,
|
||||||
HoursParameter,
|
HoursParameter,
|
||||||
ListItemParameter,
|
ListItemParameter,
|
||||||
@@ -20,15 +20,11 @@ from homeassistant.components.wolflink.const import (
|
|||||||
COORDINATOR,
|
COORDINATOR,
|
||||||
DEVICE_ID,
|
DEVICE_ID,
|
||||||
DOMAIN,
|
DOMAIN,
|
||||||
MANUFACTURER,
|
|
||||||
PARAMETERS,
|
PARAMETERS,
|
||||||
)
|
)
|
||||||
from homeassistant.components.wolflink.sensor import (
|
from homeassistant.components.wolflink.sensor import WolfLinkSensor, async_setup_entry
|
||||||
WolfLinkSensor,
|
|
||||||
async_setup_entry,
|
|
||||||
get_entity_description,
|
|
||||||
)
|
|
||||||
from homeassistant.const import (
|
from homeassistant.const import (
|
||||||
|
PERCENTAGE,
|
||||||
UnitOfEnergy,
|
UnitOfEnergy,
|
||||||
UnitOfPower,
|
UnitOfPower,
|
||||||
UnitOfPressure,
|
UnitOfPressure,
|
||||||
@@ -44,22 +40,13 @@ from tests.common import MockConfigEntry
|
|||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def mock_coordinator(hass: HomeAssistant) -> MagicMock:
|
def mock_device_id() -> str:
|
||||||
"""Mock the Wolf SmartSet Service Coordinator."""
|
|
||||||
coordinator = MagicMock()
|
|
||||||
coordinator.data = {}
|
|
||||||
hass.data[DOMAIN] = {CONFIG[DEVICE_ID]: {COORDINATOR: coordinator}}
|
|
||||||
return coordinator
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
|
||||||
def mock_device_id():
|
|
||||||
"""Fixture for a mock device ID."""
|
"""Fixture for a mock device ID."""
|
||||||
return "1234"
|
return "1234"
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def mock_parameter():
|
def mock_parameter() -> Parameter:
|
||||||
"""Fixture for a mock parameter."""
|
"""Fixture for a mock parameter."""
|
||||||
return Mock(spec=Parameter)
|
return Mock(spec=Parameter)
|
||||||
|
|
||||||
@@ -78,22 +65,24 @@ async def mock_config_entry(
|
|||||||
assert device.identifiers == {(DOMAIN, CONFIG[DEVICE_ID])}
|
assert device.identifiers == {(DOMAIN, CONFIG[DEVICE_ID])}
|
||||||
|
|
||||||
|
|
||||||
def test_wolflink_sensor_native_value(mock_coordinator: MagicMock) -> None:
|
def test_wolflink_sensor_native_value() -> None:
|
||||||
"""Test WolflinkSensor native value."""
|
"""Test WolflinkSensor native value."""
|
||||||
|
coordinator = MagicMock()
|
||||||
parameter = MagicMock()
|
parameter = MagicMock()
|
||||||
parameter.parameter_id = "outside_temp"
|
parameter.parameter_id = "outside_temp"
|
||||||
sensor = WolfLinkSensor(mock_coordinator, parameter, "mock_device_id", MagicMock())
|
sensor = WolfLinkSensor(coordinator, parameter, "mock_device_id", MagicMock())
|
||||||
mock_coordinator.data = {"outside_temp": [None, 20]}
|
coordinator.data = {"outside_temp": [None, 20]}
|
||||||
assert sensor.native_value == 20
|
assert sensor.native_value == 20
|
||||||
|
|
||||||
|
|
||||||
def test_wolflink_sensor_extra_state_attributes(mock_coordinator: MagicMock) -> None:
|
def test_wolflink_sensor_extra_state_attributes() -> None:
|
||||||
"""Test WolflinkSensor extra state attributes."""
|
"""Test WolflinkSensor extra state attributes."""
|
||||||
|
coordinator = MagicMock()
|
||||||
parameter = MagicMock()
|
parameter = MagicMock()
|
||||||
parameter.parameter_id = "outside_temp"
|
parameter.parameter_id = "outside_temp"
|
||||||
parameter.value_id = "value_id"
|
parameter.value_id = "value_id"
|
||||||
parameter.parent = "parent"
|
parameter.parent = "parent"
|
||||||
sensor = WolfLinkSensor(mock_coordinator, parameter, "mock_device_id", MagicMock())
|
sensor = WolfLinkSensor(coordinator, parameter, "mock_device_id", MagicMock())
|
||||||
attributes = sensor.extra_state_attributes
|
attributes = sensor.extra_state_attributes
|
||||||
assert attributes["parameter_id"] == "outside_temp"
|
assert attributes["parameter_id"] == "outside_temp"
|
||||||
assert attributes["value_id"] == "value_id"
|
assert attributes["value_id"] == "value_id"
|
||||||
@@ -113,12 +102,13 @@ def test_wolflink_sensor_extra_state_attributes(mock_coordinator: MagicMock) ->
|
|||||||
)
|
)
|
||||||
async def test_async_setup_entry(
|
async def test_async_setup_entry(
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
mock_coordinator: MagicMock,
|
|
||||||
parameter: Parameter,
|
parameter: Parameter,
|
||||||
|
wolf_parameter: Parameter,
|
||||||
expected_class: type,
|
expected_class: type,
|
||||||
expected_unit: str,
|
expected_unit: str,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Test async_setup_entry for various parameter types."""
|
"""Test async_setup_entry for various parameter types."""
|
||||||
|
|
||||||
config_entry = MockConfigEntry(
|
config_entry = MockConfigEntry(
|
||||||
domain=DOMAIN, unique_id=str(CONFIG[DEVICE_ID]), data=CONFIG
|
domain=DOMAIN, unique_id=str(CONFIG[DEVICE_ID]), data=CONFIG
|
||||||
)
|
)
|
||||||
@@ -130,8 +120,8 @@ async def test_async_setup_entry(
|
|||||||
parameter.unit = PERCENTAGE
|
parameter.unit = PERCENTAGE
|
||||||
hass.data.setdefault(DOMAIN, {})[config_entry.entry_id] = {
|
hass.data.setdefault(DOMAIN, {})[config_entry.entry_id] = {
|
||||||
PARAMETERS: [parameter],
|
PARAMETERS: [parameter],
|
||||||
COORDINATOR: mock_coordinator,
|
|
||||||
DEVICE_ID: "1234",
|
DEVICE_ID: "1234",
|
||||||
|
COORDINATOR: MagicMock(), # Ensure COORDINATOR is set up
|
||||||
}
|
}
|
||||||
async_add_entities = MagicMock()
|
async_add_entities = MagicMock()
|
||||||
|
|
||||||
@@ -145,70 +135,48 @@ async def test_async_setup_entry(
|
|||||||
assert entity.native_unit_of_measurement == expected_unit
|
assert entity.native_unit_of_measurement == expected_unit
|
||||||
|
|
||||||
|
|
||||||
def test_get_entity_description() -> None:
|
@pytest.fixture(
|
||||||
"""Test the get_entity_description function."""
|
params=[
|
||||||
parameter = Mock(spec=Temperature)
|
EnergyParameter(6002800000, "Energy Parameter", "Heating", 6005200000),
|
||||||
description = get_entity_description(parameter)
|
ListItemParameter(
|
||||||
assert description.device_class == "temperature"
|
8002800000,
|
||||||
assert description.native_unit_of_measurement == "°C"
|
"List Item Parameter",
|
||||||
|
"Heating",
|
||||||
parameter = Mock(spec=Pressure)
|
(["Pump", "on"], ["Heating", "on"]),
|
||||||
description = get_entity_description(parameter)
|
8005200000,
|
||||||
assert description.device_class == "pressure"
|
),
|
||||||
assert description.native_unit_of_measurement == "bar"
|
PowerParameter(5002800000, "Power Parameter", "Heating", 5005200000),
|
||||||
|
Pressure(4002800000, "Pressure Parameter", "Heating", 4005200000),
|
||||||
parameter = Mock(spec=EnergyParameter)
|
Temperature(3002800000, "Temperature Parameter", "Solar", 3005200000),
|
||||||
description = get_entity_description(parameter)
|
PercentageParameter(2002800000, "Percentage Parameter", "Solar", 2005200000),
|
||||||
assert description.device_class == "energy"
|
HoursParameter(7002800000, "Hours Parameter", "Heating", 7005200000),
|
||||||
assert description.native_unit_of_measurement == "kWh"
|
SimpleParameter(1002800000, "Simple Parameter", "DHW", 1005200000),
|
||||||
|
]
|
||||||
parameter = Mock(spec=PowerParameter)
|
)
|
||||||
description = get_entity_description(parameter)
|
def wolf_parameter(request: pytest.FixtureRequest) -> Parameter:
|
||||||
assert description.device_class == "power"
|
"""Fixture for different WolfLink parameter types."""
|
||||||
assert description.native_unit_of_measurement == "kW"
|
return request.param
|
||||||
|
|
||||||
parameter = Mock(spec=PercentageParameter)
|
|
||||||
description = get_entity_description(parameter)
|
|
||||||
assert description.native_unit_of_measurement == PERCENTAGE
|
|
||||||
|
|
||||||
parameter = Mock(spec=ListItemParameter)
|
|
||||||
description = get_entity_description(parameter)
|
|
||||||
assert description.translation_key == "state"
|
|
||||||
|
|
||||||
parameter = Mock(spec=HoursParameter)
|
|
||||||
description = get_entity_description(parameter)
|
|
||||||
assert description.native_unit_of_measurement == UnitOfTime.HOURS
|
|
||||||
assert description.icon == "mdi:clock"
|
|
||||||
|
|
||||||
parameter = Mock(spec=SimpleParameter)
|
|
||||||
description = get_entity_description(parameter)
|
|
||||||
|
|
||||||
|
|
||||||
def test_wolflink_sensor(mock_coordinator, mock_device_id, mock_parameter) -> None:
|
async def test_sensor(
|
||||||
"""Test the WolfLinkSensor class."""
|
hass: HomeAssistant,
|
||||||
description = get_entity_description(mock_parameter)
|
snapshot: SnapshotAssertion,
|
||||||
sensor = WolfLinkSensor(
|
wolf_parameter: Parameter,
|
||||||
mock_coordinator, mock_parameter, mock_device_id, description
|
) -> None:
|
||||||
|
"""Test the sensor state for various parameter types."""
|
||||||
|
config_entry = MockConfigEntry(
|
||||||
|
domain=DOMAIN, unique_id=str(CONFIG[DEVICE_ID]), data=CONFIG
|
||||||
)
|
)
|
||||||
|
config_entry.add_to_hass(hass)
|
||||||
|
|
||||||
assert sensor.entity_description == description
|
hass.data.setdefault(DOMAIN, {})[config_entry.entry_id] = {
|
||||||
assert sensor.wolf_object == mock_parameter
|
PARAMETERS: [wolf_parameter],
|
||||||
assert sensor._attr_name == str(description.name)
|
DEVICE_ID: "1234",
|
||||||
assert sensor._attr_unique_id == f"{mock_device_id}:{mock_parameter.parameter_id}"
|
COORDINATOR: MagicMock(), # Ensure COORDINATOR is set up
|
||||||
assert sensor._attr_device_info["identifiers"] == {(DOMAIN, str(mock_device_id))}
|
|
||||||
assert (
|
|
||||||
sensor._attr_device_info["configuration_url"]
|
|
||||||
== "https://www.wolf-smartset.com/"
|
|
||||||
)
|
|
||||||
assert sensor._attr_device_info["manufacturer"] == MANUFACTURER
|
|
||||||
|
|
||||||
# Test native_value property
|
|
||||||
mock_coordinator.data = {mock_parameter.parameter_id: ("value_id", "state")}
|
|
||||||
assert sensor.native_value == "state"
|
|
||||||
|
|
||||||
# Test extra_state_attributes property
|
|
||||||
assert sensor.extra_state_attributes == {
|
|
||||||
"parameter_id": mock_parameter.parameter_id,
|
|
||||||
"value_id": mock_parameter.value_id,
|
|
||||||
"parent": mock_parameter.parent,
|
|
||||||
}
|
}
|
||||||
|
async_add_entities = MagicMock()
|
||||||
|
|
||||||
|
await async_setup_entry(hass, config_entry, async_add_entities)
|
||||||
|
|
||||||
|
state = hass.states.get(f"{wolf_parameter.parameter_id}")
|
||||||
|
assert state == snapshot
|
||||||
|
Reference in New Issue
Block a user