diff --git a/tests/components/tuya/__init__.py b/tests/components/tuya/__init__.py index 5f9c8ef86c6..cc14003bcf5 100644 --- a/tests/components/tuya/__init__.py +++ b/tests/components/tuya/__init__.py @@ -13,6 +13,11 @@ from homeassistant.core import HomeAssistant from tests.common import MockConfigEntry DEVICE_MOCKS = { + "clkg_curtain_switch": [ + # https://github.com/home-assistant/core/issues/136055 + Platform.COVER, + Platform.LIGHT, + ], "cs_arete_two_12l_dehumidifier_air_purifier": [ Platform.FAN, Platform.HUMIDIFIER, diff --git a/tests/components/tuya/fixtures/clkg_curtain_switch.json b/tests/components/tuya/fixtures/clkg_curtain_switch.json new file mode 100644 index 00000000000..28e3248f8b5 --- /dev/null +++ b/tests/components/tuya/fixtures/clkg_curtain_switch.json @@ -0,0 +1,95 @@ +{ + "endpoint": "https://apigw.tuyaeu.com", + "terminal_id": "1729466466688hgsTp2", + "mqtt_connected": true, + "disabled_by": null, + "disabled_polling": false, + "id": "bf1fa053e0ba4e002c6we8", + "name": "Tapparelle studio", + "category": "clkg", + "product_id": "nhyj64w2", + "product_name": "Curtain switch", + "online": true, + "sub": true, + "time_zone": "+02:00", + "active_time": "2025-01-13T23:37:14+00:00", + "create_time": "2025-01-13T23:37:14+00:00", + "update_time": "2025-01-13T23:37:14+00:00", + "function": { + "control": { + "type": "Enum", + "value": { + "range": ["open", "stop", "close"] + } + }, + "percent_control": { + "type": "Integer", + "value": { + "unit": "%", + "min": 0, + "max": 100, + "scale": 0, + "step": 10 + } + }, + "cur_calibration": { + "type": "Enum", + "value": { + "range": ["start", "end"] + } + }, + "switch_backlight": { + "type": "Boolean", + "value": {} + }, + "control_back_mode": { + "type": "Enum", + "value": { + "range": ["forward", "back"] + } + } + }, + "status_range": { + "control": { + "type": "Enum", + "value": { + "range": ["open", "stop", "close"] + } + }, + "percent_control": { + "type": "Integer", + "value": { + "unit": "%", + "min": 0, + "max": 100, + "scale": 0, + "step": 10 + } + }, + "cur_calibration": { + "type": "Enum", + "value": { + "range": ["start", "end"] + } + }, + "switch_backlight": { + "type": "Boolean", + "value": {} + }, + "control_back_mode": { + "type": "Enum", + "value": { + "range": ["forward", "back"] + } + } + }, + "status": { + "control": "stop", + "percent_control": 100, + "cur_calibration": "end", + "switch_backlight": true, + "control_back_mode": "forward" + }, + "set_up": true, + "support_local": true +} diff --git a/tests/components/tuya/snapshots/test_cover.ambr b/tests/components/tuya/snapshots/test_cover.ambr new file mode 100644 index 00000000000..843ee2db6b0 --- /dev/null +++ b/tests/components/tuya/snapshots/test_cover.ambr @@ -0,0 +1,52 @@ +# serializer version: 1 +# name: test_platform_setup_and_discovery[clkg_curtain_switch][cover.tapparelle_studio_curtain-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'config_subentry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'cover', + 'entity_category': None, + 'entity_id': 'cover.tapparelle_studio_curtain', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': , + 'original_icon': None, + 'original_name': 'Curtain', + 'platform': 'tuya', + 'previous_unique_id': None, + 'suggested_object_id': None, + 'supported_features': , + 'translation_key': 'curtain', + 'unique_id': 'tuya.bf1fa053e0ba4e002c6we8control', + 'unit_of_measurement': None, + }) +# --- +# name: test_platform_setup_and_discovery[clkg_curtain_switch][cover.tapparelle_studio_curtain-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'current_position': 0, + 'device_class': 'curtain', + 'friendly_name': 'Tapparelle studio Curtain', + 'supported_features': , + }), + 'context': , + 'entity_id': 'cover.tapparelle_studio_curtain', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'closed', + }) +# --- diff --git a/tests/components/tuya/snapshots/test_light.ambr b/tests/components/tuya/snapshots/test_light.ambr new file mode 100644 index 00000000000..b9395b3d682 --- /dev/null +++ b/tests/components/tuya/snapshots/test_light.ambr @@ -0,0 +1,58 @@ +# serializer version: 1 +# name: test_platform_setup_and_discovery[clkg_curtain_switch][light.tapparelle_studio_backlight-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': dict({ + 'supported_color_modes': list([ + , + ]), + }), + 'config_entry_id': , + 'config_subentry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'light', + 'entity_category': , + 'entity_id': 'light.tapparelle_studio_backlight', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': None, + 'original_icon': None, + 'original_name': 'Backlight', + 'platform': 'tuya', + 'previous_unique_id': None, + 'suggested_object_id': None, + 'supported_features': 0, + 'translation_key': 'backlight', + 'unique_id': 'tuya.bf1fa053e0ba4e002c6we8switch_backlight', + 'unit_of_measurement': None, + }) +# --- +# name: test_platform_setup_and_discovery[clkg_curtain_switch][light.tapparelle_studio_backlight-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'color_mode': , + 'friendly_name': 'Tapparelle studio Backlight', + 'supported_color_modes': list([ + , + ]), + 'supported_features': , + }), + 'context': , + 'entity_id': 'light.tapparelle_studio_backlight', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'on', + }) +# --- diff --git a/tests/components/tuya/test_cover.py b/tests/components/tuya/test_cover.py new file mode 100644 index 00000000000..6f94896c8c7 --- /dev/null +++ b/tests/components/tuya/test_cover.py @@ -0,0 +1,57 @@ +"""Test Tuya cover platform.""" + +from __future__ import annotations + +from unittest.mock import patch + +import pytest +from syrupy.assertion import SnapshotAssertion +from tuya_sharing import CustomerDevice + +from homeassistant.components.tuya import ManagerCompat +from homeassistant.const import Platform +from homeassistant.core import HomeAssistant +from homeassistant.helpers import entity_registry as er + +from . import DEVICE_MOCKS, initialize_entry + +from tests.common import MockConfigEntry, snapshot_platform + + +@pytest.mark.parametrize( + "mock_device_code", + [k for k, v in DEVICE_MOCKS.items() if Platform.COVER in v], +) +@patch("homeassistant.components.tuya.PLATFORMS", [Platform.COVER]) +async def test_platform_setup_and_discovery( + hass: HomeAssistant, + mock_manager: ManagerCompat, + mock_config_entry: MockConfigEntry, + mock_device: CustomerDevice, + entity_registry: er.EntityRegistry, + snapshot: SnapshotAssertion, +) -> None: + """Test platform setup and discovery.""" + await initialize_entry(hass, mock_manager, mock_config_entry, mock_device) + + await snapshot_platform(hass, entity_registry, snapshot, mock_config_entry.entry_id) + + +@pytest.mark.parametrize( + "mock_device_code", + [k for k, v in DEVICE_MOCKS.items() if Platform.COVER not in v], +) +@patch("homeassistant.components.tuya.PLATFORMS", [Platform.COVER]) +async def test_platform_setup_no_discovery( + hass: HomeAssistant, + mock_manager: ManagerCompat, + mock_config_entry: MockConfigEntry, + mock_device: CustomerDevice, + entity_registry: er.EntityRegistry, +) -> None: + """Test platform setup without discovery.""" + await initialize_entry(hass, mock_manager, mock_config_entry, mock_device) + + assert not er.async_entries_for_config_entry( + entity_registry, mock_config_entry.entry_id + ) diff --git a/tests/components/tuya/test_light.py b/tests/components/tuya/test_light.py new file mode 100644 index 00000000000..cb7639fb662 --- /dev/null +++ b/tests/components/tuya/test_light.py @@ -0,0 +1,57 @@ +"""Test Tuya light platform.""" + +from __future__ import annotations + +from unittest.mock import patch + +import pytest +from syrupy.assertion import SnapshotAssertion +from tuya_sharing import CustomerDevice + +from homeassistant.components.tuya import ManagerCompat +from homeassistant.const import Platform +from homeassistant.core import HomeAssistant +from homeassistant.helpers import entity_registry as er + +from . import DEVICE_MOCKS, initialize_entry + +from tests.common import MockConfigEntry, snapshot_platform + + +@pytest.mark.parametrize( + "mock_device_code", + [k for k, v in DEVICE_MOCKS.items() if Platform.LIGHT in v], +) +@patch("homeassistant.components.tuya.PLATFORMS", [Platform.LIGHT]) +async def test_platform_setup_and_discovery( + hass: HomeAssistant, + mock_manager: ManagerCompat, + mock_config_entry: MockConfigEntry, + mock_device: CustomerDevice, + entity_registry: er.EntityRegistry, + snapshot: SnapshotAssertion, +) -> None: + """Test platform setup and discovery.""" + await initialize_entry(hass, mock_manager, mock_config_entry, mock_device) + + await snapshot_platform(hass, entity_registry, snapshot, mock_config_entry.entry_id) + + +@pytest.mark.parametrize( + "mock_device_code", + [k for k, v in DEVICE_MOCKS.items() if Platform.LIGHT not in v], +) +@patch("homeassistant.components.tuya.PLATFORMS", [Platform.LIGHT]) +async def test_platform_setup_no_discovery( + hass: HomeAssistant, + mock_manager: ManagerCompat, + mock_config_entry: MockConfigEntry, + mock_device: CustomerDevice, + entity_registry: er.EntityRegistry, +) -> None: + """Test platform setup and discovery.""" + await initialize_entry(hass, mock_manager, mock_config_entry, mock_device) + + assert not er.async_entries_for_config_entry( + entity_registry, mock_config_entry.entry_id + )