Renault test optimisation (#53705)

* Cleanup tests

* Use a MockConfigEntry

* Don't set up the integration for duplicate config entry testing
This commit is contained in:
epenet 2021-08-16 12:52:58 +02:00 committed by GitHub
parent 045b1ca6ae
commit 75275254f9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 314 additions and 293 deletions

View File

@ -1,52 +1,32 @@
"""Tests for the Renault integration.""" """Tests for the Renault integration."""
from __future__ import annotations from __future__ import annotations
from datetime import timedelta
from typing import Any from typing import Any
from unittest.mock import patch from unittest.mock import patch
from renault_api.kamereon import models, schemas from renault_api.kamereon import schemas
from renault_api.renault_vehicle import RenaultVehicle from renault_api.renault_account import RenaultAccount
from homeassistant.components.renault.const import ( from homeassistant.components.renault.const import DOMAIN
CONF_KAMEREON_ACCOUNT_ID, from homeassistant.config_entries import SOURCE_USER
CONF_LOCALE,
DOMAIN,
)
from homeassistant.components.renault.renault_vehicle import RenaultVehicleProxy
from homeassistant.const import CONF_PASSWORD, CONF_USERNAME
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
from homeassistant.helpers import aiohttp_client from homeassistant.helpers import aiohttp_client
from .const import MOCK_VEHICLES from .const import MOCK_CONFIG, MOCK_VEHICLES
from tests.common import MockConfigEntry, load_fixture from tests.common import MockConfigEntry, load_fixture
async def setup_renault_integration(hass: HomeAssistant): def get_mock_config_entry():
"""Create the Renault integration.""" """Create the Renault integration."""
config_entry = MockConfigEntry( return MockConfigEntry(
domain=DOMAIN, domain=DOMAIN,
source="user", source=SOURCE_USER,
data={ data=MOCK_CONFIG,
CONF_LOCALE: "fr_FR", unique_id="account_id_1",
CONF_USERNAME: "email@test.com",
CONF_PASSWORD: "test",
CONF_KAMEREON_ACCOUNT_ID: "account_id_2",
},
unique_id="account_id_2",
options={}, options={},
entry_id="1", entry_id="123456",
) )
config_entry.add_to_hass(hass)
with patch(
"homeassistant.components.renault.RenaultHub.attempt_login", return_value=True
), patch("homeassistant.components.renault.RenaultHub.async_initialise"):
await hass.config_entries.async_setup(config_entry.entry_id)
await hass.async_block_till_done()
return config_entry
def get_fixtures(vehicle_type: str) -> dict[str, Any]: def get_fixtures(vehicle_type: str) -> dict[str, Any]:
@ -76,84 +56,116 @@ def get_fixtures(vehicle_type: str) -> dict[str, Any]:
} }
async def create_vehicle_proxy( async def setup_renault_integration_simple(hass: HomeAssistant):
hass: HomeAssistant, vehicle_type: str """Create the Renault integration."""
) -> RenaultVehicleProxy: config_entry = get_mock_config_entry()
"""Create a vehicle proxy for testing.""" config_entry.add_to_hass(hass)
renault_account = RenaultAccount(
config_entry.unique_id,
websession=aiohttp_client.async_get_clientsession(hass),
)
with patch("renault_api.renault_session.RenaultSession.login"), patch(
"renault_api.renault_client.RenaultClient.get_api_account",
return_value=renault_account,
), patch("renault_api.renault_account.RenaultAccount.get_vehicles"):
await hass.config_entries.async_setup(config_entry.entry_id)
await hass.async_block_till_done()
return config_entry
async def setup_renault_integration_vehicle(hass: HomeAssistant, vehicle_type: str):
"""Create the Renault integration."""
config_entry = get_mock_config_entry()
config_entry.add_to_hass(hass)
renault_account = RenaultAccount(
config_entry.unique_id,
websession=aiohttp_client.async_get_clientsession(hass),
)
mock_vehicle = MOCK_VEHICLES[vehicle_type] mock_vehicle = MOCK_VEHICLES[vehicle_type]
mock_fixtures = get_fixtures(vehicle_type) mock_fixtures = get_fixtures(vehicle_type)
vehicles_response: models.KamereonVehiclesResponse = ( with patch("renault_api.renault_session.RenaultSession.login"), patch(
schemas.KamereonVehiclesResponseSchema.loads( "renault_api.renault_client.RenaultClient.get_api_account",
load_fixture(f"renault/vehicle_{vehicle_type}.json") return_value=renault_account,
) ), patch(
) "renault_api.renault_account.RenaultAccount.get_vehicles",
vehicle_details = vehicles_response.vehicleLinks[0].vehicleDetails return_value=(
vehicle = RenaultVehicle( schemas.KamereonVehiclesResponseSchema.loads(
vehicles_response.accountId, load_fixture(f"renault/vehicle_{vehicle_type}.json")
vehicle_details.vin, )
websession=aiohttp_client.async_get_clientsession(hass), ),
) ), patch(
"renault_api.renault_vehicle.RenaultVehicle.supports_endpoint",
vehicle_proxy = RenaultVehicleProxy(
hass, vehicle, vehicle_details, timedelta(seconds=300)
)
with patch(
"homeassistant.components.renault.renault_vehicle.RenaultVehicleProxy.endpoint_available",
side_effect=mock_vehicle["endpoints_available"], side_effect=mock_vehicle["endpoints_available"],
), patch( ), patch(
"homeassistant.components.renault.renault_vehicle.RenaultVehicleProxy.get_battery_status", "renault_api.renault_vehicle.RenaultVehicle.has_contract_for_endpoint",
return_value=True,
), patch(
"renault_api.renault_vehicle.RenaultVehicle.get_battery_status",
return_value=mock_fixtures["battery_status"], return_value=mock_fixtures["battery_status"],
), patch( ), patch(
"homeassistant.components.renault.renault_vehicle.RenaultVehicleProxy.get_charge_mode", "renault_api.renault_vehicle.RenaultVehicle.get_charge_mode",
return_value=mock_fixtures["charge_mode"], return_value=mock_fixtures["charge_mode"],
), patch( ), patch(
"homeassistant.components.renault.renault_vehicle.RenaultVehicleProxy.get_cockpit", "renault_api.renault_vehicle.RenaultVehicle.get_cockpit",
return_value=mock_fixtures["cockpit"], return_value=mock_fixtures["cockpit"],
), patch( ), patch(
"homeassistant.components.renault.renault_vehicle.RenaultVehicleProxy.get_hvac_status", "renault_api.renault_vehicle.RenaultVehicle.get_hvac_status",
return_value=mock_fixtures["hvac_status"], return_value=mock_fixtures["hvac_status"],
): ):
await vehicle_proxy.async_initialise() await hass.config_entries.async_setup(config_entry.entry_id)
return vehicle_proxy await hass.async_block_till_done()
return config_entry
async def create_vehicle_proxy_with_side_effect( async def setup_renault_integration_vehicle_with_side_effect(
hass: HomeAssistant, vehicle_type: str, side_effect: Any hass: HomeAssistant, vehicle_type: str, side_effect: Any
) -> RenaultVehicleProxy: ):
"""Create a vehicle proxy for testing unavailable entities.""" """Create the Renault integration."""
mock_vehicle = MOCK_VEHICLES[vehicle_type] config_entry = get_mock_config_entry()
config_entry.add_to_hass(hass)
vehicles_response: models.KamereonVehiclesResponse = ( renault_account = RenaultAccount(
schemas.KamereonVehiclesResponseSchema.loads( config_entry.unique_id,
load_fixture(f"renault/vehicle_{vehicle_type}.json")
)
)
vehicle_details = vehicles_response.vehicleLinks[0].vehicleDetails
vehicle = RenaultVehicle(
vehicles_response.accountId,
vehicle_details.vin,
websession=aiohttp_client.async_get_clientsession(hass), websession=aiohttp_client.async_get_clientsession(hass),
) )
mock_vehicle = MOCK_VEHICLES[vehicle_type]
vehicle_proxy = RenaultVehicleProxy( with patch("renault_api.renault_session.RenaultSession.login"), patch(
hass, vehicle, vehicle_details, timedelta(seconds=300) "renault_api.renault_client.RenaultClient.get_api_account",
) return_value=renault_account,
with patch( ), patch(
"homeassistant.components.renault.renault_vehicle.RenaultVehicleProxy.endpoint_available", "renault_api.renault_account.RenaultAccount.get_vehicles",
return_value=(
schemas.KamereonVehiclesResponseSchema.loads(
load_fixture(f"renault/vehicle_{vehicle_type}.json")
)
),
), patch(
"renault_api.renault_vehicle.RenaultVehicle.supports_endpoint",
side_effect=mock_vehicle["endpoints_available"], side_effect=mock_vehicle["endpoints_available"],
), patch( ), patch(
"homeassistant.components.renault.renault_vehicle.RenaultVehicleProxy.get_battery_status", "renault_api.renault_vehicle.RenaultVehicle.has_contract_for_endpoint",
return_value=True,
), patch(
"renault_api.renault_vehicle.RenaultVehicle.get_battery_status",
side_effect=side_effect, side_effect=side_effect,
), patch( ), patch(
"homeassistant.components.renault.renault_vehicle.RenaultVehicleProxy.get_charge_mode", "renault_api.renault_vehicle.RenaultVehicle.get_charge_mode",
side_effect=side_effect, side_effect=side_effect,
), patch( ), patch(
"homeassistant.components.renault.renault_vehicle.RenaultVehicleProxy.get_cockpit", "renault_api.renault_vehicle.RenaultVehicle.get_cockpit",
side_effect=side_effect, side_effect=side_effect,
), patch( ), patch(
"homeassistant.components.renault.renault_vehicle.RenaultVehicleProxy.get_hvac_status", "renault_api.renault_vehicle.RenaultVehicle.get_hvac_status",
side_effect=side_effect, side_effect=side_effect,
): ):
await vehicle_proxy.async_initialise() await hass.config_entries.async_setup(config_entry.entry_id)
return vehicle_proxy await hass.async_block_till_done()
return config_entry

View File

@ -3,6 +3,7 @@ from unittest.mock import AsyncMock, PropertyMock, patch
from renault_api.gigya.exceptions import InvalidCredentialsException from renault_api.gigya.exceptions import InvalidCredentialsException
from renault_api.kamereon import schemas from renault_api.kamereon import schemas
from renault_api.renault_account import RenaultAccount
from homeassistant import config_entries, data_entry_flow from homeassistant import config_entries, data_entry_flow
from homeassistant.components.renault.const import ( from homeassistant.components.renault.const import (
@ -12,126 +13,197 @@ from homeassistant.components.renault.const import (
) )
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 homeassistant.helpers import aiohttp_client
from . import get_mock_config_entry
from tests.common import load_fixture from tests.common import load_fixture
async def test_config_flow_single_account(hass: HomeAssistant): async def test_config_flow_single_account(hass: HomeAssistant):
"""Test we get the form.""" """Test we get the form."""
result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": config_entries.SOURCE_USER}
)
assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
assert result["errors"] == {}
# Failed credentials
with patch( with patch(
"renault_api.renault_session.RenaultSession.login", "homeassistant.components.renault.async_setup_entry",
side_effect=InvalidCredentialsException(403042, "invalid loginID or password"), return_value=True,
): ) as mock_setup_entry:
result = await hass.config_entries.flow.async_configure( result = await hass.config_entries.flow.async_init(
result["flow_id"], DOMAIN, context={"source": config_entries.SOURCE_USER}
user_input={ )
CONF_LOCALE: "fr_FR", assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
CONF_USERNAME: "email@test.com", assert result["errors"] == {}
CONF_PASSWORD: "test",
}, # Failed credentials
with patch(
"renault_api.renault_session.RenaultSession.login",
side_effect=InvalidCredentialsException(
403042, "invalid loginID or password"
),
):
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
user_input={
CONF_LOCALE: "fr_FR",
CONF_USERNAME: "email@test.com",
CONF_PASSWORD: "test",
},
)
assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
assert result["errors"] == {"base": "invalid_credentials"}
renault_account = AsyncMock()
type(renault_account).account_id = PropertyMock(return_value="account_id_1")
renault_account.get_vehicles.return_value = (
schemas.KamereonVehiclesResponseSchema.loads(
load_fixture("renault/vehicle_zoe_40.json")
)
) )
assert result["type"] == data_entry_flow.RESULT_TYPE_FORM # Account list single
assert result["errors"] == {"base": "invalid_credentials"} with patch("renault_api.renault_session.RenaultSession.login"), patch(
"renault_api.renault_account.RenaultAccount.account_id", return_value="123"
), patch(
"renault_api.renault_client.RenaultClient.get_api_accounts",
return_value=[renault_account],
):
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
user_input={
CONF_LOCALE: "fr_FR",
CONF_USERNAME: "email@test.com",
CONF_PASSWORD: "test",
},
)
renault_account = AsyncMock() assert result["type"] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY
type(renault_account).account_id = PropertyMock(return_value="account_id_1") assert result["title"] == "account_id_1"
renault_account.get_vehicles.return_value = ( assert result["data"][CONF_USERNAME] == "email@test.com"
schemas.KamereonVehiclesResponseSchema.loads( assert result["data"][CONF_PASSWORD] == "test"
load_fixture("renault/vehicle_zoe_40.json") assert result["data"][CONF_KAMEREON_ACCOUNT_ID] == "account_id_1"
) assert result["data"][CONF_LOCALE] == "fr_FR"
)
# Account list single assert len(mock_setup_entry.mock_calls) == 1
with patch("renault_api.renault_session.RenaultSession.login"), patch(
"renault_api.renault_account.RenaultAccount.account_id", return_value="123"
), patch(
"renault_api.renault_client.RenaultClient.get_api_accounts",
return_value=[renault_account],
):
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
user_input={
CONF_LOCALE: "fr_FR",
CONF_USERNAME: "email@test.com",
CONF_PASSWORD: "test",
},
)
assert result["type"] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY
assert result["title"] == "account_id_1"
assert result["data"][CONF_USERNAME] == "email@test.com"
assert result["data"][CONF_PASSWORD] == "test"
assert result["data"][CONF_KAMEREON_ACCOUNT_ID] == "account_id_1"
assert result["data"][CONF_LOCALE] == "fr_FR"
async def test_config_flow_no_account(hass: HomeAssistant): async def test_config_flow_no_account(hass: HomeAssistant):
"""Test we get the form.""" """Test we get the form."""
result = await hass.config_entries.flow.async_init( with patch(
DOMAIN, context={"source": config_entries.SOURCE_USER} "homeassistant.components.renault.async_setup_entry",
) return_value=True,
assert result["type"] == data_entry_flow.RESULT_TYPE_FORM ) as mock_setup_entry:
assert result["errors"] == {} result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": config_entries.SOURCE_USER}
# Account list empty
with patch("renault_api.renault_session.RenaultSession.login"), patch(
"homeassistant.components.renault.config_flow.RenaultHub.get_account_ids",
return_value=[],
):
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
user_input={
CONF_LOCALE: "fr_FR",
CONF_USERNAME: "email@test.com",
CONF_PASSWORD: "test",
},
) )
assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
assert result["errors"] == {}
assert result["type"] == data_entry_flow.RESULT_TYPE_ABORT # Account list empty
assert result["reason"] == "kamereon_no_account" with patch("renault_api.renault_session.RenaultSession.login"), patch(
"renault_api.renault_client.RenaultClient.get_api_accounts",
return_value=[],
):
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
user_input={
CONF_LOCALE: "fr_FR",
CONF_USERNAME: "email@test.com",
CONF_PASSWORD: "test",
},
)
assert result["type"] == data_entry_flow.RESULT_TYPE_ABORT
assert result["reason"] == "kamereon_no_account"
assert len(mock_setup_entry.mock_calls) == 0
async def test_config_flow_multiple_accounts(hass: HomeAssistant): async def test_config_flow_multiple_accounts(hass: HomeAssistant):
"""Test what happens if multiple Kamereon accounts are available.""" """Test what happens if multiple Kamereon accounts are available."""
result = await hass.config_entries.flow.async_init( with patch(
DOMAIN, context={"source": config_entries.SOURCE_USER} "homeassistant.components.renault.async_setup_entry",
) return_value=True,
assert result["type"] == data_entry_flow.RESULT_TYPE_FORM ) as mock_setup_entry:
assert result["errors"] == {} result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": config_entries.SOURCE_USER}
)
assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
assert result["errors"] == {}
# Multiple accounts renault_account_1 = RenaultAccount(
with patch("renault_api.renault_session.RenaultSession.login"), patch( "account_id_1",
"homeassistant.components.renault.config_flow.RenaultHub.get_account_ids", websession=aiohttp_client.async_get_clientsession(hass),
return_value=["account_id_1", "account_id_2"], )
): renault_account_2 = RenaultAccount(
result = await hass.config_entries.flow.async_configure( "account_id_2",
result["flow_id"], websession=aiohttp_client.async_get_clientsession(hass),
user_input={
CONF_LOCALE: "fr_FR",
CONF_USERNAME: "email@test.com",
CONF_PASSWORD: "test",
},
) )
assert result["type"] == data_entry_flow.RESULT_TYPE_FORM # Multiple accounts
assert result["step_id"] == "kamereon" with patch("renault_api.renault_session.RenaultSession.login"), patch(
"renault_api.renault_client.RenaultClient.get_api_accounts",
return_value=[renault_account_1, renault_account_2],
), patch("renault_api.renault_account.RenaultAccount.get_vehicles"):
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
user_input={
CONF_LOCALE: "fr_FR",
CONF_USERNAME: "email@test.com",
CONF_PASSWORD: "test",
},
)
# Account selected assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
result = await hass.config_entries.flow.async_configure( assert result["step_id"] == "kamereon"
result["flow_id"],
user_input={CONF_KAMEREON_ACCOUNT_ID: "account_id_2"}, # Account selected
) result = await hass.config_entries.flow.async_configure(
assert result["type"] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY result["flow_id"],
assert result["title"] == "account_id_2" user_input={CONF_KAMEREON_ACCOUNT_ID: "account_id_2"},
assert result["data"][CONF_USERNAME] == "email@test.com" )
assert result["data"][CONF_PASSWORD] == "test" assert result["type"] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY
assert result["data"][CONF_KAMEREON_ACCOUNT_ID] == "account_id_2" assert result["title"] == "account_id_2"
assert result["data"][CONF_LOCALE] == "fr_FR" assert result["data"][CONF_USERNAME] == "email@test.com"
assert result["data"][CONF_PASSWORD] == "test"
assert result["data"][CONF_KAMEREON_ACCOUNT_ID] == "account_id_2"
assert result["data"][CONF_LOCALE] == "fr_FR"
assert len(mock_setup_entry.mock_calls) == 1
async def test_config_flow_duplicate(hass: HomeAssistant):
"""Test abort if unique_id configured."""
with patch(
"homeassistant.components.renault.async_setup_entry",
return_value=True,
) as mock_setup_entry:
get_mock_config_entry().add_to_hass(hass)
assert len(hass.config_entries.async_entries(DOMAIN)) == 1
result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": config_entries.SOURCE_USER}
)
assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
assert result["errors"] == {}
renault_account = RenaultAccount(
"account_id_1",
websession=aiohttp_client.async_get_clientsession(hass),
)
with patch("renault_api.renault_session.RenaultSession.login"), patch(
"renault_api.renault_client.RenaultClient.get_api_accounts",
return_value=[renault_account],
), patch("renault_api.renault_account.RenaultAccount.get_vehicles"):
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
user_input={
CONF_LOCALE: "fr_FR",
CONF_USERNAME: "email@test.com",
CONF_PASSWORD: "test",
},
)
assert result["type"] == data_entry_flow.RESULT_TYPE_ABORT
assert result["reason"] == "already_configured"
await hass.async_block_till_done()
assert len(mock_setup_entry.mock_calls) == 0

View File

@ -1,85 +1,63 @@
"""Tests for Renault setup process.""" """Tests for Renault setup process."""
from unittest.mock import AsyncMock, patch from unittest.mock import patch
import aiohttp import aiohttp
import pytest
from renault_api.gigya.exceptions import InvalidCredentialsException from renault_api.gigya.exceptions import InvalidCredentialsException
from renault_api.kamereon import schemas
from homeassistant.components.renault import (
RenaultHub,
async_setup_entry,
async_unload_entry,
)
from homeassistant.components.renault.const import DOMAIN from homeassistant.components.renault.const import DOMAIN
from homeassistant.components.renault.renault_vehicle import RenaultVehicleProxy from homeassistant.config_entries import ConfigEntryState
from homeassistant.exceptions import ConfigEntryNotReady
from .const import MOCK_CONFIG from . import get_mock_config_entry, setup_renault_integration_simple
from tests.common import MockConfigEntry, load_fixture
async def test_setup_unload_and_reload_entry(hass): async def test_setup_unload_entry(hass):
"""Test entry setup and unload.""" """Test entry setup and unload."""
# Create a mock entry so we don't have to go through config flow with patch("homeassistant.components.renault.PLATFORMS", []):
config_entry = MockConfigEntry( config_entry = await setup_renault_integration_simple(hass)
domain=DOMAIN, data=MOCK_CONFIG, entry_id="test", unique_id=123456
)
renault_account = AsyncMock()
renault_account.get_vehicles.return_value = (
schemas.KamereonVehiclesResponseSchema.loads(
load_fixture("renault/vehicle_zoe_40.json")
)
)
with patch("renault_api.renault_session.RenaultSession.login"), patch( assert len(hass.config_entries.async_entries(DOMAIN)) == 1
"renault_api.renault_client.RenaultClient.get_api_account", assert config_entry.state is ConfigEntryState.LOADED
return_value=renault_account, assert config_entry.unique_id in hass.data[DOMAIN]
):
# Set up the entry and assert that the values set during setup are where we expect
# them to be.
assert await async_setup_entry(hass, config_entry)
assert DOMAIN in hass.data and config_entry.unique_id in hass.data[DOMAIN]
assert isinstance(hass.data[DOMAIN][config_entry.unique_id], RenaultHub)
renault_hub: RenaultHub = hass.data[DOMAIN][config_entry.unique_id] # Unload the entry and verify that the data has been removed
assert len(renault_hub.vehicles) == 1 await hass.config_entries.async_unload(config_entry.entry_id)
assert isinstance( await hass.async_block_till_done()
renault_hub.vehicles["VF1AAAAA555777999"], RenaultVehicleProxy assert config_entry.state is ConfigEntryState.NOT_LOADED
) assert config_entry.unique_id not in hass.data[DOMAIN]
# Unload the entry and verify that the data has been removed
assert await async_unload_entry(hass, config_entry)
assert config_entry.unique_id not in hass.data[DOMAIN]
async def test_setup_entry_bad_password(hass): async def test_setup_entry_bad_password(hass):
"""Test entry setup and unload.""" """Test entry setup and unload."""
# Create a mock entry so we don't have to go through config flow # Create a mock entry so we don't have to go through config flow
config_entry = MockConfigEntry( config_entry = get_mock_config_entry()
domain=DOMAIN, data=MOCK_CONFIG, entry_id="test", unique_id=123456 config_entry.add_to_hass(hass)
)
with patch( with patch(
"renault_api.renault_session.RenaultSession.login", "renault_api.renault_session.RenaultSession.login",
side_effect=InvalidCredentialsException(403042, "invalid loginID or password"), side_effect=InvalidCredentialsException(403042, "invalid loginID or password"),
): ):
# Set up the entry and assert that the values set during setup are where we expect await hass.config_entries.async_setup(config_entry.entry_id)
# them to be. await hass.async_block_till_done()
assert not await async_setup_entry(hass, config_entry)
assert len(hass.config_entries.async_entries(DOMAIN)) == 1
assert config_entry.state is ConfigEntryState.SETUP_ERROR
assert not hass.data.get(DOMAIN)
async def test_setup_entry_exception(hass): async def test_setup_entry_exception(hass):
"""Test ConfigEntryNotReady when API raises an exception during entry setup.""" """Test ConfigEntryNotReady when API raises an exception during entry setup."""
config_entry = MockConfigEntry( config_entry = get_mock_config_entry()
domain=DOMAIN, data=MOCK_CONFIG, entry_id="test", unique_id=123456 config_entry.add_to_hass(hass)
)
# In this case we are testing the condition where async_setup_entry raises # In this case we are testing the condition where async_setup_entry raises
# ConfigEntryNotReady. # ConfigEntryNotReady.
with patch( with patch(
"renault_api.renault_session.RenaultSession.login", "renault_api.renault_session.RenaultSession.login",
side_effect=aiohttp.ClientConnectionError, side_effect=aiohttp.ClientConnectionError,
), pytest.raises(ConfigEntryNotReady): ):
assert await async_setup_entry(hass, config_entry) await hass.config_entries.async_setup(config_entry.entry_id)
await hass.async_block_till_done()
assert len(hass.config_entries.async_entries(DOMAIN)) == 1
assert config_entry.state is ConfigEntryState.SETUP_RETRY
assert not hass.data.get(DOMAIN)

View File

@ -1,5 +1,5 @@
"""Tests for Renault sensors.""" """Tests for Renault sensors."""
from unittest.mock import PropertyMock, patch from unittest.mock import patch
import pytest import pytest
from renault_api.kamereon import exceptions from renault_api.kamereon import exceptions
@ -9,9 +9,8 @@ from homeassistant.const import STATE_UNAVAILABLE
from homeassistant.setup import async_setup_component from homeassistant.setup import async_setup_component
from . import ( from . import (
create_vehicle_proxy, setup_renault_integration_vehicle,
create_vehicle_proxy_with_side_effect, setup_renault_integration_vehicle_with_side_effect,
setup_renault_integration,
) )
from .const import MOCK_VEHICLES from .const import MOCK_VEHICLES
@ -25,16 +24,8 @@ async def test_sensors(hass, vehicle_type):
entity_registry = mock_registry(hass) entity_registry = mock_registry(hass)
device_registry = mock_device_registry(hass) device_registry = mock_device_registry(hass)
vehicle_proxy = await create_vehicle_proxy(hass, vehicle_type) with patch("homeassistant.components.renault.PLATFORMS", [SENSOR_DOMAIN]):
await setup_renault_integration_vehicle(hass, vehicle_type)
with patch(
"homeassistant.components.renault.RenaultHub.vehicles",
new_callable=PropertyMock,
return_value={
vehicle_proxy.details.vin: vehicle_proxy,
},
), patch("homeassistant.components.renault.PLATFORMS", [SENSOR_DOMAIN]):
await setup_renault_integration(hass)
await hass.async_block_till_done() await hass.async_block_till_done()
mock_vehicle = MOCK_VEHICLES[vehicle_type] mock_vehicle = MOCK_VEHICLES[vehicle_type]
@ -68,16 +59,8 @@ async def test_sensor_empty(hass, vehicle_type):
entity_registry = mock_registry(hass) entity_registry = mock_registry(hass)
device_registry = mock_device_registry(hass) device_registry = mock_device_registry(hass)
vehicle_proxy = await create_vehicle_proxy_with_side_effect(hass, vehicle_type, {}) with patch("homeassistant.components.renault.PLATFORMS", [SENSOR_DOMAIN]):
await setup_renault_integration_vehicle_with_side_effect(hass, vehicle_type, {})
with patch(
"homeassistant.components.renault.RenaultHub.vehicles",
new_callable=PropertyMock,
return_value={
vehicle_proxy.details.vin: vehicle_proxy,
},
), patch("homeassistant.components.renault.PLATFORMS", [SENSOR_DOMAIN]):
await setup_renault_integration(hass)
await hass.async_block_till_done() await hass.async_block_till_done()
mock_vehicle = MOCK_VEHICLES[vehicle_type] mock_vehicle = MOCK_VEHICLES[vehicle_type]
@ -116,18 +99,10 @@ async def test_sensor_errors(hass, vehicle_type):
"Invalid response from the upstream server (The request sent to the GDC is erroneous) ; 502 Bad Gateway", "Invalid response from the upstream server (The request sent to the GDC is erroneous) ; 502 Bad Gateway",
) )
vehicle_proxy = await create_vehicle_proxy_with_side_effect( with patch("homeassistant.components.renault.PLATFORMS", [SENSOR_DOMAIN]):
hass, vehicle_type, invalid_upstream_exception await setup_renault_integration_vehicle_with_side_effect(
) hass, vehicle_type, invalid_upstream_exception
)
with patch(
"homeassistant.components.renault.RenaultHub.vehicles",
new_callable=PropertyMock,
return_value={
vehicle_proxy.details.vin: vehicle_proxy,
},
), patch("homeassistant.components.renault.PLATFORMS", [SENSOR_DOMAIN]):
await setup_renault_integration(hass)
await hass.async_block_till_done() await hass.async_block_till_done()
mock_vehicle = MOCK_VEHICLES[vehicle_type] mock_vehicle = MOCK_VEHICLES[vehicle_type]
@ -165,18 +140,10 @@ async def test_sensor_access_denied(hass):
"Access is denied for this resource", "Access is denied for this resource",
) )
vehicle_proxy = await create_vehicle_proxy_with_side_effect( with patch("homeassistant.components.renault.PLATFORMS", [SENSOR_DOMAIN]):
hass, "zoe_40", access_denied_exception await setup_renault_integration_vehicle_with_side_effect(
) hass, "zoe_40", access_denied_exception
)
with patch(
"homeassistant.components.renault.RenaultHub.vehicles",
new_callable=PropertyMock,
return_value={
vehicle_proxy.details.vin: vehicle_proxy,
},
), patch("homeassistant.components.renault.PLATFORMS", [SENSOR_DOMAIN]):
await setup_renault_integration(hass)
await hass.async_block_till_done() await hass.async_block_till_done()
assert len(device_registry.devices) == 0 assert len(device_registry.devices) == 0
@ -194,18 +161,10 @@ async def test_sensor_not_supported(hass):
"This feature is not technically supported by this gateway", "This feature is not technically supported by this gateway",
) )
vehicle_proxy = await create_vehicle_proxy_with_side_effect( with patch("homeassistant.components.renault.PLATFORMS", [SENSOR_DOMAIN]):
hass, "zoe_40", not_supported_exception await setup_renault_integration_vehicle_with_side_effect(
) hass, "zoe_40", not_supported_exception
)
with patch(
"homeassistant.components.renault.RenaultHub.vehicles",
new_callable=PropertyMock,
return_value={
vehicle_proxy.details.vin: vehicle_proxy,
},
), patch("homeassistant.components.renault.PLATFORMS", [SENSOR_DOMAIN]):
await setup_renault_integration(hass)
await hass.async_block_till_done() await hass.async_block_till_done()
assert len(device_registry.devices) == 0 assert len(device_registry.devices) == 0