Refactor wallbox tests (#51094)

* Changed Testing, removed custom exception
Removed custom exceptions, reverted to builtin. Changed testing approach in all tests, now using the core interface to setup device and mock_requests to create test responses for all calls.

* Reintroduce InvalidAuth exception in __init__
Remove reference to internal HA exception, Reintroduce custom exception

* Removed duplicate entry in test_config_flow

* removed tests from test_init that calling methods directly

* Update tests/components/wallbox/__init__.py

Removed duplicate add_to_hass call

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

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
This commit is contained in:
hesselonline 2021-06-27 21:06:25 +02:00 committed by GitHub
parent 2d1744c573
commit e56069558a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 137 additions and 270 deletions

View file

@ -121,19 +121,5 @@ async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry):
return unload_ok return unload_ok
class CannotConnect(exceptions.HomeAssistantError):
"""Error to indicate we cannot connect."""
def __init__(self, msg=""):
"""Create a log record."""
super().__init__()
_LOGGER.error("Cannot connect to Wallbox API. %s", msg)
class InvalidAuth(exceptions.HomeAssistantError): class InvalidAuth(exceptions.HomeAssistantError):
"""Error to indicate there is invalid auth.""" """Error to indicate there is invalid auth."""
def __init__(self, msg=""):
"""Create a log record."""
super().__init__()
_LOGGER.error("Cannot authenticate with Wallbox API. %s", msg)

View file

@ -4,7 +4,7 @@ import voluptuous as vol
from homeassistant import config_entries, core from homeassistant import config_entries, core
from homeassistant.const import CONF_PASSWORD, CONF_USERNAME from homeassistant.const import CONF_PASSWORD, CONF_USERNAME
from . import CannotConnect, InvalidAuth, WallboxHub from . import InvalidAuth, WallboxHub
from .const import CONF_STATION, DOMAIN from .const import CONF_STATION, DOMAIN
COMPONENT_DOMAIN = DOMAIN COMPONENT_DOMAIN = DOMAIN
@ -46,7 +46,7 @@ class ConfigFlow(config_entries.ConfigFlow, domain=COMPONENT_DOMAIN):
try: try:
info = await validate_input(self.hass, user_input) info = await validate_input(self.hass, user_input)
except CannotConnect: except ConnectionError:
errors["base"] = "cannot_connect" errors["base"] = "cannot_connect"
except InvalidAuth: except InvalidAuth:
errors["base"] = "invalid_auth" errors["base"] = "invalid_auth"

View file

@ -1 +1,44 @@
"""Tests for the Wallbox integration.""" """Tests for the Wallbox integration."""
import json
import requests_mock
from homeassistant.components.wallbox.const import CONF_STATION, DOMAIN
from homeassistant.const import CONF_PASSWORD, CONF_USERNAME
from tests.common import MockConfigEntry
test_response = json.loads(
'{"charging_power": 0,"max_available_power": "xx","charging_speed": 0,"added_range": "xx","added_energy": "44.697"}'
)
async def setup_integration(hass):
"""Test wallbox sensor class setup."""
entry = MockConfigEntry(
domain=DOMAIN,
data={
CONF_USERNAME: "test_username",
CONF_PASSWORD: "test_password",
CONF_STATION: "12345",
},
entry_id="testEntry",
)
entry.add_to_hass(hass)
with requests_mock.Mocker() as mock_request:
mock_request.get(
"https://api.wall-box.com/auth/token/user",
text='{"jwt":"fakekeyhere","user_id":12345,"ttl":145656758,"error":false,"status":200}',
status_code=200,
)
mock_request.get(
"https://api.wall-box.com/chargers/status/12345",
json=test_response,
status_code=200,
)
await hass.config_entries.async_setup(entry.entry_id)
await hass.async_block_till_done()

View file

@ -1,13 +1,18 @@
"""Test the Wallbox config flow.""" """Test the Wallbox config flow."""
import json
from unittest.mock import patch from unittest.mock import patch
from voluptuous.schema_builder import raises import requests_mock
from homeassistant import config_entries, data_entry_flow from homeassistant import config_entries, data_entry_flow
from homeassistant.components.wallbox import CannotConnect, InvalidAuth, config_flow from homeassistant.components.wallbox import InvalidAuth, config_flow
from homeassistant.components.wallbox.const import DOMAIN from homeassistant.components.wallbox.const import DOMAIN
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
test_response = json.loads(
'{"charging_power": 0,"max_available_power": 25,"charging_speed": 0,"added_range": 372,"added_energy": 44.697}'
)
async def test_show_set_form(hass: HomeAssistant) -> None: async def test_show_set_form(hass: HomeAssistant) -> None:
"""Test that the setup form is served.""" """Test that the setup form is served."""
@ -42,16 +47,31 @@ async def test_form_invalid_auth(hass):
assert result2["errors"] == {"base": "invalid_auth"} assert result2["errors"] == {"base": "invalid_auth"}
async def test_form_cannot_connect(hass): async def test_form_cannot_authenticate(hass):
"""Test we handle cannot connect error.""" """Test we handle cannot connect error."""
result = await hass.config_entries.flow.async_init( result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": config_entries.SOURCE_USER} DOMAIN, context={"source": config_entries.SOURCE_USER}
) )
with patch( with requests_mock.Mocker() as mock_request:
"homeassistant.components.wallbox.config_flow.WallboxHub.async_authenticate", mock_request.get(
side_effect=CannotConnect, "https://api.wall-box.com/auth/token/user",
): text='{"jwt":"fakekeyhere","user_id":12345,"ttl":145656758,"error":false,"status":200}',
status_code=403,
)
mock_request.get(
"https://api.wall-box.com/chargers/status/12345",
text='{"Temperature": 100, "Location": "Toronto", "Datetime": "2020-07-23", "Units": "Celsius"}',
status_code=403,
)
result2 = await hass.config_entries.flow.async_configure(
result["flow_id"],
{
"station": "12345",
"username": "test-username",
"password": "test-password",
},
)
result2 = await hass.config_entries.flow.async_configure( result2 = await hass.config_entries.flow.async_configure(
result["flow_id"], result["flow_id"],
{ {
@ -65,64 +85,61 @@ async def test_form_cannot_connect(hass):
assert result2["errors"] == {"base": "invalid_auth"} assert result2["errors"] == {"base": "invalid_auth"}
async def test_validate_input(hass): async def test_form_cannot_connect(hass):
"""Test we can validate input.""" """Test we handle cannot connect error."""
data = { result = await hass.config_entries.flow.async_init(
"station": "12345", DOMAIN, context={"source": config_entries.SOURCE_USER}
"username": "test-username", )
"password": "test-password",
}
def alternate_authenticate_method(): with requests_mock.Mocker() as mock_request:
return None mock_request.get(
"https://api.wall-box.com/auth/token/user",
text='{"jwt":"fakekeyhere","user_id":12345,"ttl":145656758,"error":false,"status":200}',
status_code=200,
)
mock_request.get(
"https://api.wall-box.com/chargers/status/12345",
text='{"Temperature": 100, "Location": "Toronto", "Datetime": "2020-07-23", "Units": "Celsius"}',
status_code=404,
)
result2 = await hass.config_entries.flow.async_configure(
result["flow_id"],
{
"station": "12345",
"username": "test-username",
"password": "test-password",
},
)
def alternate_get_charger_status_method(station): assert result2["type"] == "form"
data = '{"Temperature": 100, "Location": "Toronto", "Datetime": "2020-07-23", "Units": "Celsius"}' assert result2["errors"] == {"base": "cannot_connect"}
return data
with patch(
"wallbox.Wallbox.authenticate",
side_effect=alternate_authenticate_method,
), patch(
"wallbox.Wallbox.getChargerStatus",
side_effect=alternate_get_charger_status_method,
):
result = await config_flow.validate_input(hass, data)
assert result == {"title": "Wallbox Portal"}
async def test_configflow_class(): async def test_form_validate_input(hass):
"""Test configFlow class.""" """Test we handle cannot connect error."""
configflow = config_flow.ConfigFlow() result = await hass.config_entries.flow.async_init(
assert configflow DOMAIN, context={"source": config_entries.SOURCE_USER}
)
with patch( with requests_mock.Mocker() as mock_request:
"homeassistant.components.wallbox.config_flow.validate_input", mock_request.get(
side_effect=TypeError, "https://api.wall-box.com/auth/token/user",
), raises(Exception): text='{"jwt":"fakekeyhere","user_id":12345,"ttl":145656758,"error":false,"status":200}',
assert await configflow.async_step_user(True) status_code=200,
)
mock_request.get(
"https://api.wall-box.com/chargers/status/12345",
text='{"Temperature": 100, "Location": "Toronto", "Datetime": "2020-07-23", "Units": "Celsius"}',
status_code=200,
)
result2 = await hass.config_entries.flow.async_configure(
result["flow_id"],
{
"station": "12345",
"username": "test-username",
"password": "test-password",
},
)
with patch( assert result2["title"] == "Wallbox Portal"
"homeassistant.components.wallbox.config_flow.validate_input", assert result2["data"]["station"] == "12345"
side_effect=CannotConnect,
), raises(Exception):
assert await configflow.async_step_user(True)
with patch(
"homeassistant.components.wallbox.config_flow.validate_input",
), raises(Exception):
assert await configflow.async_step_user(True)
def test_cannot_connect_class():
"""Test cannot Connect class."""
cannot_connect = CannotConnect
assert cannot_connect
def test_invalid_auth_class():
"""Test invalid auth class."""
invalid_auth = InvalidAuth
assert invalid_auth

View file

@ -1,16 +1,12 @@
"""Test Wallbox Init Component.""" """Test Wallbox Init Component."""
import json import json
import pytest
import requests_mock
from voluptuous.schema_builder import raises
from homeassistant.components import wallbox
from homeassistant.components.wallbox.const import CONF_STATION, DOMAIN from homeassistant.components.wallbox.const import CONF_STATION, DOMAIN
from homeassistant.const import CONF_PASSWORD, CONF_USERNAME from homeassistant.const import CONF_PASSWORD, CONF_USERNAME
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
from tests.common import MockConfigEntry from tests.common import MockConfigEntry
from tests.components.wallbox import setup_integration
entry = MockConfigEntry( entry = MockConfigEntry(
domain=DOMAIN, domain=DOMAIN,
@ -31,135 +27,9 @@ test_response_rounding_error = json.loads(
) )
async def test_wallbox_setup_entry(hass: HomeAssistant):
"""Test Wallbox Setup."""
with requests_mock.Mocker() as m:
m.get(
"https://api.wall-box.com/auth/token/user",
text='{"jwt":"fakekeyhere","user_id":12345,"ttl":145656758,"error":false,"status":200}',
status_code=200,
)
m.get(
"https://api.wall-box.com/chargers/status/12345",
text='{"Temperature": 100, "Location": "Toronto", "Datetime": "2020-07-23", "Units": "Celsius"}',
status_code=200,
)
assert await wallbox.async_setup_entry(hass, entry)
with requests_mock.Mocker() as m, raises(ConnectionError):
m.get(
"https://api.wall-box.com/auth/token/user",
text='{"jwt":"fakekeyhere","user_id":12345,"ttl":145656758,"error":false,"status":404}',
status_code=404,
)
assert await wallbox.async_setup_entry(hass, entry) is False
async def test_wallbox_unload_entry(hass: HomeAssistant): async def test_wallbox_unload_entry(hass: HomeAssistant):
"""Test Wallbox Unload.""" """Test Wallbox Unload."""
hass.data[DOMAIN] = {"connections": {entry.entry_id: entry}}
assert await wallbox.async_unload_entry(hass, entry) await setup_integration(hass)
hass.data[DOMAIN] = {"fail_entry": entry} assert await hass.config_entries.async_unload(entry.entry_id)
with pytest.raises(KeyError):
await wallbox.async_unload_entry(hass, entry)
async def test_get_data(hass: HomeAssistant):
"""Test hub class, get_data."""
station = ("12345",)
username = ("test-username",)
password = "test-password"
hub = wallbox.WallboxHub(station, username, password, hass)
with requests_mock.Mocker() as m:
m.get(
"https://api.wall-box.com/auth/token/user",
text='{"jwt":"fakekeyhere","user_id":12345,"ttl":145656758,"error":false,"status":200}',
status_code=200,
)
m.get(
"https://api.wall-box.com/chargers/status/('12345',)",
json=test_response,
status_code=200,
)
assert await hub.async_get_data()
async def test_get_data_rounding_error(hass: HomeAssistant):
"""Test hub class, get_data with rounding error."""
station = ("12345",)
username = ("test-username",)
password = "test-password"
hub = wallbox.WallboxHub(station, username, password, hass)
with requests_mock.Mocker() as m:
m.get(
"https://api.wall-box.com/auth/token/user",
text='{"jwt":"fakekeyhere","user_id":12345,"ttl":145656758,"error":false,"status":200}',
status_code=200,
)
m.get(
"https://api.wall-box.com/chargers/status/('12345',)",
json=test_response_rounding_error,
status_code=200,
)
assert await hub.async_get_data()
async def test_authentication_exception(hass: HomeAssistant):
"""Test hub class, authentication raises exception."""
station = ("12345",)
username = ("test-username",)
password = "test-password"
hub = wallbox.WallboxHub(station, username, password, hass)
with requests_mock.Mocker() as m, raises(wallbox.InvalidAuth):
m.get("https://api.wall-box.com/auth/token/user", text="data", status_code=403)
assert await hub.async_authenticate()
with requests_mock.Mocker() as m, raises(ConnectionError):
m.get("https://api.wall-box.com/auth/token/user", text="data", status_code=404)
assert await hub.async_authenticate()
with requests_mock.Mocker() as m, raises(wallbox.InvalidAuth):
m.get("https://api.wall-box.com/auth/token/user", text="data", status_code=403)
m.get(
"https://api.wall-box.com/chargers/status/test",
json=test_response,
status_code=403,
)
assert await hub.async_get_data()
async def test_get_data_exception(hass: HomeAssistant):
"""Test hub class, authentication raises exception."""
station = ("12345",)
username = ("test-username",)
password = "test-password"
hub = wallbox.WallboxHub(station, username, password, hass)
with requests_mock.Mocker() as m, raises(ConnectionError):
m.get(
"https://api.wall-box.com/auth/token/user",
text='{"jwt":"fakekeyhere","user_id":12345,"ttl":145656758,"error":false,"status":200}',
status_code=200,
)
m.get(
"https://api.wall-box.com/chargers/status/('12345',)",
text="data",
status_code=404,
)
assert await hub.async_get_data()

View file

@ -1,13 +1,10 @@
"""Test Wallbox Switch component.""" """Test Wallbox Switch component."""
import json
from unittest.mock import MagicMock
from homeassistant.components.wallbox import sensor
from homeassistant.components.wallbox.const import CONF_STATION, DOMAIN from homeassistant.components.wallbox.const import CONF_STATION, DOMAIN
from homeassistant.const import CONF_PASSWORD, CONF_USERNAME from homeassistant.const import CONF_PASSWORD, CONF_USERNAME
from tests.common import MockConfigEntry from tests.common import MockConfigEntry
from tests.components.wallbox import setup_integration
entry = MockConfigEntry( entry = MockConfigEntry(
domain=DOMAIN, domain=DOMAIN,
@ -19,63 +16,17 @@ entry = MockConfigEntry(
entry_id="testEntry", entry_id="testEntry",
) )
test_response = json.loads(
'{"charging_power": 0,"max_available_power": 25,"charging_speed": 0,"added_range": 372,"added_energy": 44.697}'
)
test_response_rounding_error = json.loads( async def test_wallbox_sensor_class(hass):
'{"charging_power": "XX","max_available_power": "xx","charging_speed": 0,"added_range": "xx","added_energy": "XX"}'
)
CONF_STATION = ("12345",)
CONF_USERNAME = ("test-username",)
CONF_PASSWORD = "test-password"
# wallbox = WallboxHub(CONF_STATION, CONF_USERNAME, CONF_PASSWORD, hass)
async def test_wallbox_sensor_class():
"""Test wallbox sensor class.""" """Test wallbox sensor class."""
coordinator = MagicMock(return_value="connected") await setup_integration(hass)
idx = 1
ent = "charging_power"
wallboxSensor = sensor.WallboxSensor(coordinator, idx, ent, entry) state = hass.states.get("sensor.mock_title_charging_power")
assert state.attributes["unit_of_measurement"] == "kW"
assert state.attributes["icon"] == "mdi:ev-station"
assert state.name == "Mock Title Charging Power"
assert wallboxSensor.icon == "mdi:ev-station" state = hass.states.get("sensor.mock_title_charging_speed")
assert wallboxSensor.unit_of_measurement == "kW" assert state.attributes["icon"] == "mdi:speedometer"
assert wallboxSensor.name == "Mock Title Charging Power" assert state.name == "Mock Title Charging Speed"
assert wallboxSensor.state
# async def test_wallbox_updater(hass: HomeAssistantType):
# """Test wallbox updater."""
# with requests_mock.Mocker() as m:
# m.get(
# "https://api.wall-box.com/auth/token/user",
# text='{"jwt":"fakekeyhere","user_id":12345,"ttl":145656758,"error":false,"status":200}',
# status_code=200,
# )
# m.get(
# "https://api.wall-box.com/chargers/status/('12345',)",
# json=test_response,
# status_code=200,
# )
# await sensor.wallbox_updater(wallbox, hass)
# async def test_wallbox_updater_rounding_error(hass: HomeAssistantType):
# """Test wallbox updater rounding error."""
# with requests_mock.Mocker() as m:
# m.get(
# "https://api.wall-box.com/auth/token/user",
# text='{"jwt":"fakekeyhere","user_id":12345,"ttl":145656758,"error":false,"status":200}',
# status_code=200,
# )
# m.get(
# "https://api.wall-box.com/chargers/status/('12345',)",
# json=test_response_rounding_error,
# status_code=200,
# )
# await sensor.wallbox_updater(wallbox, hass)