async def test_config_flow_step_device_manual_model_succes(hass): """Test config flow, device connection error, manual model.""" result = await hass.config_entries.flow.async_init( const.DOMAIN, context={"source": config_entries.SOURCE_USER}) assert result["type"] == "form" assert result["step_id"] == "cloud" assert result["errors"] == {} result = await hass.config_entries.flow.async_configure( result["flow_id"], {const.CONF_MANUAL: True}, ) assert result["type"] == "form" assert result["step_id"] == "manual" assert result["errors"] == {} error = DeviceException({}) error.__cause__ = ChecksumError({}) with patch( "homeassistant.components.xiaomi_miio.device.Device.info", side_effect=error, ): result = await hass.config_entries.flow.async_configure( result["flow_id"], { CONF_HOST: TEST_HOST, CONF_TOKEN: TEST_TOKEN }, ) assert result["type"] == "form" assert result["step_id"] == "connect" assert result["errors"] == {"base": "wrong_token"} overwrite_model = const.MODELS_VACUUM[0] with patch( "homeassistant.components.xiaomi_miio.device.Device.info", side_effect=DeviceException({}), ): result = await hass.config_entries.flow.async_configure( result["flow_id"], {const.CONF_MODEL: overwrite_model}, ) assert result["type"] == "create_entry" assert result["title"] == overwrite_model assert result["data"] == { const.CONF_FLOW_TYPE: const.CONF_DEVICE, const.CONF_CLOUD_USERNAME: None, const.CONF_CLOUD_PASSWORD: None, const.CONF_CLOUD_COUNTRY: None, CONF_HOST: TEST_HOST, CONF_TOKEN: TEST_TOKEN, const.CONF_MODEL: overwrite_model, const.CONF_MAC: None, }
async def test_config_flow_step_device_manual_model_succes(hass): """Test config flow, device connection error, manual model.""" result = await hass.config_entries.flow.async_init( const.DOMAIN, context={"source": config_entries.SOURCE_USER}) assert result["type"] == "form" assert result["step_id"] == "device" assert result["errors"] == {} with patch( "homeassistant.components.xiaomi_miio.device.Device.info", side_effect=DeviceException({}), ): result = await hass.config_entries.flow.async_configure( result["flow_id"], { CONF_HOST: TEST_HOST, CONF_TOKEN: TEST_TOKEN }, ) assert result["type"] == "form" assert result["step_id"] == "device" assert result["errors"] == {"base": "cannot_connect"} overwrite_model = const.MODELS_VACUUM[0] with patch( "homeassistant.components.xiaomi_miio.device.Device.info", side_effect=DeviceException({}), ), patch("homeassistant.components.xiaomi_miio.async_setup_entry", return_value=True): result = await hass.config_entries.flow.async_configure( result["flow_id"], { CONF_TOKEN: TEST_TOKEN, const.CONF_MODEL: overwrite_model }, ) assert result["type"] == "create_entry" assert result["title"] == overwrite_model assert result["data"] == { const.CONF_FLOW_TYPE: const.CONF_DEVICE, CONF_HOST: TEST_HOST, CONF_TOKEN: TEST_TOKEN, const.CONF_MODEL: overwrite_model, const.CONF_MAC: None, }
async def test_xiaomi_exceptions(hass, caplog, mock_mirobo_is_on): """Test error logging on exceptions.""" entity_name = "test_vacuum_cleaner_error" entity_id = await setup_component(hass, entity_name) def is_available(): state = hass.states.get(entity_id) return state.state != STATE_UNAVAILABLE # The initial setup has to be done successfully assert "Initializing with host 192.168.1.100 (token 12345...)" in caplog.text assert "WARNING" not in caplog.text assert is_available() # Second update causes an exception, which should be logged mock_mirobo_is_on.status.side_effect = DeviceException("dummy exception") await hass.helpers.entity_component.async_update_entity(entity_id) assert "WARNING" in caplog.text assert "Got exception while fetching the state" in caplog.text assert not is_available() # Third update does not get logged as the device is already unavailable, # so we clear the log and reset the status to test that caplog.clear() mock_mirobo_is_on.status.reset_mock() await hass.helpers.entity_component.async_update_entity(entity_id) assert "Got exception while fetching the state" not in caplog.text assert not is_available() assert mock_mirobo_is_on.status.call_count == 1
async def test_config_flow_step_device_connect_error(hass): """Test config flow, device connection error.""" result = await hass.config_entries.flow.async_init( const.DOMAIN, context={"source": config_entries.SOURCE_USER}) assert result["type"] == "form" assert result["step_id"] == "cloud" assert result["errors"] == {} result = await hass.config_entries.flow.async_configure( result["flow_id"], {const.CONF_MANUAL: True}, ) assert result["type"] == "form" assert result["step_id"] == "manual" assert result["errors"] == {} with patch( "homeassistant.components.xiaomi_miio.device.Device.info", side_effect=DeviceException({}), ): result = await hass.config_entries.flow.async_configure( result["flow_id"], { CONF_HOST: TEST_HOST, CONF_TOKEN: TEST_TOKEN }, ) assert result["type"] == "form" assert result["step_id"] == "connect" assert result["errors"] == {"base": "cannot_connect"}
async def test_xiaomi_exceptions(hass, mock_mirobo_is_on): """Test error logging on exceptions.""" entity_name = "test_vacuum_cleaner_error" entity_id = await setup_component(hass, entity_name) def is_available(): state = hass.states.get(entity_id) return state.state != STATE_UNAVAILABLE # The initial setup has to be done successfully assert is_available() # Second update causes an exception, which should be logged mock_mirobo_is_on.status.side_effect = DeviceException("dummy exception") future = dt_util.utcnow() + timedelta(seconds=60) async_fire_time_changed(hass, future) await hass.async_block_till_done() assert not is_available() # Third update does not get logged as the device is already unavailable, # so we clear the log and reset the status to test that mock_mirobo_is_on.status.reset_mock() future += timedelta(seconds=60) async_fire_time_changed(hass, future) await hass.async_block_till_done() assert not is_available() assert mock_mirobo_is_on.status.call_count == 1
async def test_config_flow_step_gateway_connect_error(hass): """Test config flow, gateway connection error.""" result = await hass.config_entries.flow.async_init( const.DOMAIN, context={"source": config_entries.SOURCE_USER}) assert result["type"] == "form" assert result["step_id"] == "user" assert result["errors"] == {} result = await hass.config_entries.flow.async_configure( result["flow_id"], {config_flow.CONF_GATEWAY: True}, ) assert result["type"] == "form" assert result["step_id"] == "gateway" assert result["errors"] == {} with patch( "homeassistant.components.xiaomi_miio.gateway.gateway.Gateway.info", side_effect=DeviceException({}), ): result = await hass.config_entries.flow.async_configure( result["flow_id"], { CONF_HOST: TEST_HOST, CONF_NAME: TEST_NAME, CONF_TOKEN: TEST_TOKEN }, ) assert result["type"] == "form" assert result["step_id"] == "gateway" assert result["errors"] == {"base": "cannot_connect"}
async def test_config_flow_step_gateway_connect_error(opp): """Test config flow, gateway connection error.""" result = await opp.config_entries.flow.async_init( const.DOMAIN, context={"source": config_entries.SOURCE_USER} ) assert result["type"] == "form" assert result["step_id"] == "device" assert result["errors"] == {} with patch( "openpeerpower.components.xiaomi_miio.device.Device.info", side_effect=DeviceException({}), ): result = await opp.config_entries.flow.async_configure( result["flow_id"], {CONF_HOST: TEST_HOST, CONF_TOKEN: TEST_TOKEN}, ) assert result["type"] == "form" assert result["step_id"] == "device" assert result["errors"] == {"base": "cannot_connect"}
await hass.services.async_call( DOMAIN, SERVICE_SEND_COMMAND, {"entity_id": entity_id, "command": "raw", "params": {"k1": 2}}, blocking=True, ) mock_mirobo_is_got_error.assert_has_calls( [mock.call.raw_command("raw", {"k1": 2})], any_order=True ) mock_mirobo_is_got_error.assert_has_calls(STATUS_CALLS, any_order=True) mock_mirobo_is_got_error.reset_mock() @pytest.mark.parametrize( "error, status_calls", [(None, STATUS_CALLS), (DeviceException("dummy exception"), [])], ) @pytest.mark.parametrize( "service, service_data, device_method, device_method_call", [ ( SERVICE_START_REMOTE_CONTROL, {ATTR_ENTITY_ID: "vacuum.test_vacuum_cleaner_2"}, "manual_start", mock.call(), ), ( SERVICE_MOVE_REMOTE_CONTROL, { ATTR_ENTITY_ID: "vacuum.test_vacuum_cleaner_2", "duration": 1000,
def raise_error(): raise DeviceException("v1 does not support set_dry")