Improve Whirlpool component code quality (#57357)

* Improve Whirlpool component code

This implements a few suggestions given in
https://github.com/home-assistant/core/pull/48346#pullrequestreview-773552670

* Add return typing

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>

* Add reason assertion to config_flow test

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
This commit is contained in:
Abílio Costa 2021-10-10 07:49:02 +01:00 committed by GitHub
parent 80ee583418
commit 49d97e13de
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 81 additions and 31 deletions

View File

@ -48,6 +48,18 @@ AIRCON_FANSPEED_MAP = {
FAN_MODE_TO_AIRCON_FANSPEED = {v: k for k, v in AIRCON_FANSPEED_MAP.items()}
SUPPORTED_FAN_MODES = [FAN_AUTO, FAN_HIGH, FAN_MEDIUM, FAN_LOW, FAN_OFF]
SUPPORTED_HVAC_MODES = [
HVAC_MODE_COOL,
HVAC_MODE_HEAT,
HVAC_MODE_FAN_ONLY,
HVAC_MODE_OFF,
]
SUPPORTED_MAX_TEMP = 30
SUPPORTED_MIN_TEMP = 16
SUPPORTED_SWING_MODES = [SWING_HORIZONTAL, SWING_OFF]
SUPPORTED_TARGET_TEMPERATURE_STEP = 1
async def async_setup_entry(hass, config_entry, async_add_entities):
"""Set up entry."""
@ -66,20 +78,15 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
class AirConEntity(ClimateEntity):
"""Representation of an air conditioner."""
_attr_fan_modes = [FAN_AUTO, FAN_HIGH, FAN_MEDIUM, FAN_LOW, FAN_OFF]
_attr_hvac_modes = [
HVAC_MODE_COOL,
HVAC_MODE_HEAT,
HVAC_MODE_FAN_ONLY,
HVAC_MODE_OFF,
]
_attr_max_temp = 30
_attr_min_temp = 16
_attr_fan_modes = SUPPORTED_FAN_MODES
_attr_hvac_modes = SUPPORTED_HVAC_MODES
_attr_max_temp = SUPPORTED_MAX_TEMP
_attr_min_temp = SUPPORTED_MIN_TEMP
_attr_supported_features = (
SUPPORT_TARGET_TEMPERATURE | SUPPORT_FAN_MODE | SUPPORT_SWING_MODE
)
_attr_swing_modes = [SWING_HORIZONTAL, SWING_OFF]
_attr_target_temperature_step = 1
_attr_swing_modes = SUPPORTED_SWING_MODES
_attr_target_temperature_step = SUPPORTED_TARGET_TEMPERATURE_STEP
_attr_temperature_unit = TEMP_CELSIUS
_attr_should_poll = False
@ -141,7 +148,7 @@ class AirConEntity(ClimateEntity):
return HVAC_MODE_OFF
mode: AirconMode = self._aircon.get_mode()
return AIRCON_MODE_MAP.get(mode, None)
return AIRCON_MODE_MAP.get(mode)
async def async_set_hvac_mode(self, hvac_mode):
"""Set HVAC mode."""
@ -151,8 +158,7 @@ class AirConEntity(ClimateEntity):
mode = HVAC_MODE_TO_AIRCON_MODE.get(hvac_mode)
if not mode:
_LOGGER.warning("Unexpected hvac mode: %s", hvac_mode)
return
raise ValueError(f"Invalid hvac mode {hvac_mode}")
await self._aircon.set_mode(mode)
if not self._aircon.get_power_on():
@ -168,7 +174,7 @@ class AirConEntity(ClimateEntity):
"""Set fan mode."""
fanspeed = FAN_MODE_TO_AIRCON_FANSPEED.get(fan_mode)
if not fanspeed:
return
raise ValueError(f"Invalid fan mode {fan_mode}")
await self._aircon.set_fanspeed(fanspeed)
@property

View File

@ -1,4 +1,6 @@
"""Config flow for Whirlpool Sixth Sense integration."""
from __future__ import annotations
import asyncio
import logging
@ -13,10 +15,14 @@ from .const import DOMAIN
_LOGGER = logging.getLogger(__name__)
STEP_USER_DATA_SCHEMA = vol.Schema({CONF_USERNAME: str, CONF_PASSWORD: str})
STEP_USER_DATA_SCHEMA = vol.Schema(
{vol.Required(CONF_USERNAME): str, vol.Required(CONF_PASSWORD): str}
)
async def validate_input(hass: core.HomeAssistant, data):
async def validate_input(
hass: core.HomeAssistant, data: dict[str, str]
) -> dict[str, str]:
"""Validate the user input allows us to connect.
Data has the keys from STEP_USER_DATA_SCHEMA with values provided by the user.

View File

@ -2,6 +2,7 @@
from unittest.mock import AsyncMock, MagicMock
import aiohttp
import pytest
import whirlpool
from homeassistant.components.climate.const import (
@ -271,13 +272,14 @@ async def test_service_calls(hass: HomeAssistant, mock_aircon_api: MagicMock):
)
mock_aircon_api.return_value.set_mode.reset_mock()
# HVAC_MODE_DRY should be ignored
await hass.services.async_call(
CLIMATE_DOMAIN,
SERVICE_SET_HVAC_MODE,
{ATTR_ENTITY_ID: "climate.said1", ATTR_HVAC_MODE: HVAC_MODE_DRY},
blocking=True,
)
# HVAC_MODE_DRY is not supported
with pytest.raises(ValueError):
await hass.services.async_call(
CLIMATE_DOMAIN,
SERVICE_SET_HVAC_MODE,
{ATTR_ENTITY_ID: "climate.said1", ATTR_HVAC_MODE: HVAC_MODE_DRY},
blocking=True,
)
mock_aircon_api.return_value.set_mode.assert_not_called()
mock_aircon_api.return_value.set_mode.reset_mock()
@ -325,13 +327,14 @@ async def test_service_calls(hass: HomeAssistant, mock_aircon_api: MagicMock):
)
mock_aircon_api.return_value.set_fanspeed.reset_mock()
# FAN_MIDDLE should be ignored
await hass.services.async_call(
CLIMATE_DOMAIN,
SERVICE_SET_FAN_MODE,
{ATTR_ENTITY_ID: "climate.said1", ATTR_FAN_MODE: FAN_MIDDLE},
blocking=True,
)
# FAN_MIDDLE is not supported
with pytest.raises(ValueError):
await hass.services.async_call(
CLIMATE_DOMAIN,
SERVICE_SET_FAN_MODE,
{ATTR_ENTITY_ID: "climate.said1", ATTR_FAN_MODE: FAN_MIDDLE},
blocking=True,
)
mock_aircon_api.return_value.set_fanspeed.assert_not_called()
mock_aircon_api.return_value.set_fanspeed.reset_mock()

View File

@ -7,6 +7,8 @@ import aiohttp
from homeassistant import config_entries
from homeassistant.components.whirlpool.const import DOMAIN
from tests.common import MockConfigEntry
async def test_form(hass):
"""Test we get the form."""
@ -120,3 +122,36 @@ async def test_form_generic_auth_exception(hass):
)
assert result2["type"] == "form"
assert result2["errors"] == {"base": "unknown"}
async def test_form_already_configured(hass):
"""Test we handle cannot connect error."""
mock_entry = MockConfigEntry(
domain=DOMAIN,
data={"username": "test-username", "password": "test-password"},
unique_id="test-username",
)
mock_entry.add_to_hass(hass)
result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": config_entries.SOURCE_USER}
)
assert result["type"] == "form"
assert result["step_id"] == config_entries.SOURCE_USER
with patch("homeassistant.components.whirlpool.config_flow.Auth.do_auth"), patch(
"homeassistant.components.whirlpool.config_flow.Auth.is_access_token_valid",
return_value=True,
):
result2 = await hass.config_entries.flow.async_configure(
result["flow_id"],
{
"username": "test-username",
"password": "test-password",
},
)
await hass.async_block_till_done()
assert result2["type"] == "abort"
assert result2["reason"] == "already_configured"