Renault test optimisation (#53705)
* Cleanup tests * Use a MockConfigEntry * Don't set up the integration for duplicate config entry testingpull/54698/head
parent
045b1ca6ae
commit
75275254f9
|
@ -1,52 +1,32 @@
|
|||
"""Tests for the Renault integration."""
|
||||
from __future__ import annotations
|
||||
|
||||
from datetime import timedelta
|
||||
from typing import Any
|
||||
from unittest.mock import patch
|
||||
|
||||
from renault_api.kamereon import models, schemas
|
||||
from renault_api.renault_vehicle import RenaultVehicle
|
||||
from renault_api.kamereon import schemas
|
||||
from renault_api.renault_account import RenaultAccount
|
||||
|
||||
from homeassistant.components.renault.const import (
|
||||
CONF_KAMEREON_ACCOUNT_ID,
|
||||
CONF_LOCALE,
|
||||
DOMAIN,
|
||||
)
|
||||
from homeassistant.components.renault.renault_vehicle import RenaultVehicleProxy
|
||||
from homeassistant.const import CONF_PASSWORD, CONF_USERNAME
|
||||
from homeassistant.components.renault.const import DOMAIN
|
||||
from homeassistant.config_entries import SOURCE_USER
|
||||
from homeassistant.core import HomeAssistant
|
||||
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
|
||||
|
||||
|
||||
async def setup_renault_integration(hass: HomeAssistant):
|
||||
def get_mock_config_entry():
|
||||
"""Create the Renault integration."""
|
||||
config_entry = MockConfigEntry(
|
||||
return MockConfigEntry(
|
||||
domain=DOMAIN,
|
||||
source="user",
|
||||
data={
|
||||
CONF_LOCALE: "fr_FR",
|
||||
CONF_USERNAME: "email@test.com",
|
||||
CONF_PASSWORD: "test",
|
||||
CONF_KAMEREON_ACCOUNT_ID: "account_id_2",
|
||||
},
|
||||
unique_id="account_id_2",
|
||||
source=SOURCE_USER,
|
||||
data=MOCK_CONFIG,
|
||||
unique_id="account_id_1",
|
||||
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]:
|
||||
|
@ -76,84 +56,116 @@ def get_fixtures(vehicle_type: str) -> dict[str, Any]:
|
|||
}
|
||||
|
||||
|
||||
async def create_vehicle_proxy(
|
||||
hass: HomeAssistant, vehicle_type: str
|
||||
) -> RenaultVehicleProxy:
|
||||
"""Create a vehicle proxy for testing."""
|
||||
async def setup_renault_integration_simple(hass: HomeAssistant):
|
||||
"""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),
|
||||
)
|
||||
|
||||
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_fixtures = get_fixtures(vehicle_type)
|
||||
|
||||
vehicles_response: models.KamereonVehiclesResponse = (
|
||||
schemas.KamereonVehiclesResponseSchema.loads(
|
||||
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),
|
||||
)
|
||||
|
||||
vehicle_proxy = RenaultVehicleProxy(
|
||||
hass, vehicle, vehicle_details, timedelta(seconds=300)
|
||||
)
|
||||
with patch(
|
||||
"homeassistant.components.renault.renault_vehicle.RenaultVehicleProxy.endpoint_available",
|
||||
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",
|
||||
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"],
|
||||
), 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"],
|
||||
), patch(
|
||||
"homeassistant.components.renault.renault_vehicle.RenaultVehicleProxy.get_charge_mode",
|
||||
"renault_api.renault_vehicle.RenaultVehicle.get_charge_mode",
|
||||
return_value=mock_fixtures["charge_mode"],
|
||||
), patch(
|
||||
"homeassistant.components.renault.renault_vehicle.RenaultVehicleProxy.get_cockpit",
|
||||
"renault_api.renault_vehicle.RenaultVehicle.get_cockpit",
|
||||
return_value=mock_fixtures["cockpit"],
|
||||
), patch(
|
||||
"homeassistant.components.renault.renault_vehicle.RenaultVehicleProxy.get_hvac_status",
|
||||
"renault_api.renault_vehicle.RenaultVehicle.get_hvac_status",
|
||||
return_value=mock_fixtures["hvac_status"],
|
||||
):
|
||||
await vehicle_proxy.async_initialise()
|
||||
return vehicle_proxy
|
||||
await hass.config_entries.async_setup(config_entry.entry_id)
|
||||
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
|
||||
) -> RenaultVehicleProxy:
|
||||
"""Create a vehicle proxy for testing unavailable entities."""
|
||||
mock_vehicle = MOCK_VEHICLES[vehicle_type]
|
||||
):
|
||||
"""Create the Renault integration."""
|
||||
config_entry = get_mock_config_entry()
|
||||
config_entry.add_to_hass(hass)
|
||||
|
||||
vehicles_response: models.KamereonVehiclesResponse = (
|
||||
schemas.KamereonVehiclesResponseSchema.loads(
|
||||
load_fixture(f"renault/vehicle_{vehicle_type}.json")
|
||||
)
|
||||
)
|
||||
vehicle_details = vehicles_response.vehicleLinks[0].vehicleDetails
|
||||
vehicle = RenaultVehicle(
|
||||
vehicles_response.accountId,
|
||||
vehicle_details.vin,
|
||||
renault_account = RenaultAccount(
|
||||
config_entry.unique_id,
|
||||
websession=aiohttp_client.async_get_clientsession(hass),
|
||||
)
|
||||
mock_vehicle = MOCK_VEHICLES[vehicle_type]
|
||||
|
||||
vehicle_proxy = RenaultVehicleProxy(
|
||||
hass, vehicle, vehicle_details, timedelta(seconds=300)
|
||||
)
|
||||
with patch(
|
||||
"homeassistant.components.renault.renault_vehicle.RenaultVehicleProxy.endpoint_available",
|
||||
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",
|
||||
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"],
|
||||
), 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,
|
||||
), patch(
|
||||
"homeassistant.components.renault.renault_vehicle.RenaultVehicleProxy.get_charge_mode",
|
||||
"renault_api.renault_vehicle.RenaultVehicle.get_charge_mode",
|
||||
side_effect=side_effect,
|
||||
), patch(
|
||||
"homeassistant.components.renault.renault_vehicle.RenaultVehicleProxy.get_cockpit",
|
||||
"renault_api.renault_vehicle.RenaultVehicle.get_cockpit",
|
||||
side_effect=side_effect,
|
||||
), patch(
|
||||
"homeassistant.components.renault.renault_vehicle.RenaultVehicleProxy.get_hvac_status",
|
||||
"renault_api.renault_vehicle.RenaultVehicle.get_hvac_status",
|
||||
side_effect=side_effect,
|
||||
):
|
||||
await vehicle_proxy.async_initialise()
|
||||
return vehicle_proxy
|
||||
await hass.config_entries.async_setup(config_entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
return config_entry
|
||||
|
|
|
@ -3,6 +3,7 @@ from unittest.mock import AsyncMock, PropertyMock, patch
|
|||
|
||||
from renault_api.gigya.exceptions import InvalidCredentialsException
|
||||
from renault_api.kamereon import schemas
|
||||
from renault_api.renault_account import RenaultAccount
|
||||
|
||||
from homeassistant import config_entries, data_entry_flow
|
||||
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.core import HomeAssistant
|
||||
from homeassistant.helpers import aiohttp_client
|
||||
|
||||
from . import get_mock_config_entry
|
||||
|
||||
from tests.common import load_fixture
|
||||
|
||||
|
||||
async def test_config_flow_single_account(hass: HomeAssistant):
|
||||
"""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(
|
||||
"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",
|
||||
},
|
||||
"homeassistant.components.renault.async_setup_entry",
|
||||
return_value=True,
|
||||
) as mock_setup_entry:
|
||||
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(
|
||||
"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
|
||||
assert result["errors"] == {"base": "invalid_credentials"}
|
||||
# Account list single
|
||||
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()
|
||||
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_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"
|
||||
|
||||
# Account list single
|
||||
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"
|
||||
assert len(mock_setup_entry.mock_calls) == 1
|
||||
|
||||
|
||||
async def test_config_flow_no_account(hass: HomeAssistant):
|
||||
"""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"] == {}
|
||||
|
||||
# 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",
|
||||
},
|
||||
with patch(
|
||||
"homeassistant.components.renault.async_setup_entry",
|
||||
return_value=True,
|
||||
) as mock_setup_entry:
|
||||
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"] == {}
|
||||
|
||||
assert result["type"] == data_entry_flow.RESULT_TYPE_ABORT
|
||||
assert result["reason"] == "kamereon_no_account"
|
||||
# Account list empty
|
||||
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):
|
||||
"""Test what happens if multiple Kamereon accounts are available."""
|
||||
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"] == {}
|
||||
with patch(
|
||||
"homeassistant.components.renault.async_setup_entry",
|
||||
return_value=True,
|
||||
) as mock_setup_entry:
|
||||
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
|
||||
with patch("renault_api.renault_session.RenaultSession.login"), patch(
|
||||
"homeassistant.components.renault.config_flow.RenaultHub.get_account_ids",
|
||||
return_value=["account_id_1", "account_id_2"],
|
||||
):
|
||||
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_1 = RenaultAccount(
|
||||
"account_id_1",
|
||||
websession=aiohttp_client.async_get_clientsession(hass),
|
||||
)
|
||||
renault_account_2 = RenaultAccount(
|
||||
"account_id_2",
|
||||
websession=aiohttp_client.async_get_clientsession(hass),
|
||||
)
|
||||
|
||||
assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
|
||||
assert result["step_id"] == "kamereon"
|
||||
# Multiple accounts
|
||||
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
|
||||
result = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"],
|
||||
user_input={CONF_KAMEREON_ACCOUNT_ID: "account_id_2"},
|
||||
)
|
||||
assert result["type"] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY
|
||||
assert result["title"] == "account_id_2"
|
||||
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 result["type"] == data_entry_flow.RESULT_TYPE_FORM
|
||||
assert result["step_id"] == "kamereon"
|
||||
|
||||
# Account selected
|
||||
result = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"],
|
||||
user_input={CONF_KAMEREON_ACCOUNT_ID: "account_id_2"},
|
||||
)
|
||||
assert result["type"] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY
|
||||
assert result["title"] == "account_id_2"
|
||||
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
|
||||
|
|
|
@ -1,85 +1,63 @@
|
|||
"""Tests for Renault setup process."""
|
||||
from unittest.mock import AsyncMock, patch
|
||||
from unittest.mock import patch
|
||||
|
||||
import aiohttp
|
||||
import pytest
|
||||
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.renault_vehicle import RenaultVehicleProxy
|
||||
from homeassistant.exceptions import ConfigEntryNotReady
|
||||
from homeassistant.config_entries import ConfigEntryState
|
||||
|
||||
from .const import MOCK_CONFIG
|
||||
|
||||
from tests.common import MockConfigEntry, load_fixture
|
||||
from . import get_mock_config_entry, setup_renault_integration_simple
|
||||
|
||||
|
||||
async def test_setup_unload_and_reload_entry(hass):
|
||||
async def test_setup_unload_entry(hass):
|
||||
"""Test entry setup and unload."""
|
||||
# Create a mock entry so we don't have to go through config flow
|
||||
config_entry = MockConfigEntry(
|
||||
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("homeassistant.components.renault.PLATFORMS", []):
|
||||
config_entry = await setup_renault_integration_simple(hass)
|
||||
|
||||
with patch("renault_api.renault_session.RenaultSession.login"), patch(
|
||||
"renault_api.renault_client.RenaultClient.get_api_account",
|
||||
return_value=renault_account,
|
||||
):
|
||||
# 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)
|
||||
assert len(hass.config_entries.async_entries(DOMAIN)) == 1
|
||||
assert config_entry.state is ConfigEntryState.LOADED
|
||||
assert config_entry.unique_id in hass.data[DOMAIN]
|
||||
|
||||
renault_hub: RenaultHub = hass.data[DOMAIN][config_entry.unique_id]
|
||||
assert len(renault_hub.vehicles) == 1
|
||||
assert isinstance(
|
||||
renault_hub.vehicles["VF1AAAAA555777999"], RenaultVehicleProxy
|
||||
)
|
||||
|
||||
# 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]
|
||||
# Unload the entry and verify that the data has been removed
|
||||
await hass.config_entries.async_unload(config_entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
assert config_entry.state is ConfigEntryState.NOT_LOADED
|
||||
assert config_entry.unique_id not in hass.data[DOMAIN]
|
||||
|
||||
|
||||
async def test_setup_entry_bad_password(hass):
|
||||
"""Test entry setup and unload."""
|
||||
# Create a mock entry so we don't have to go through config flow
|
||||
config_entry = MockConfigEntry(
|
||||
domain=DOMAIN, data=MOCK_CONFIG, entry_id="test", unique_id=123456
|
||||
)
|
||||
config_entry = get_mock_config_entry()
|
||||
config_entry.add_to_hass(hass)
|
||||
|
||||
with patch(
|
||||
"renault_api.renault_session.RenaultSession.login",
|
||||
side_effect=InvalidCredentialsException(403042, "invalid loginID or password"),
|
||||
):
|
||||
# Set up the entry and assert that the values set during setup are where we expect
|
||||
# them to be.
|
||||
assert not 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_ERROR
|
||||
assert not hass.data.get(DOMAIN)
|
||||
|
||||
|
||||
async def test_setup_entry_exception(hass):
|
||||
"""Test ConfigEntryNotReady when API raises an exception during entry setup."""
|
||||
config_entry = MockConfigEntry(
|
||||
domain=DOMAIN, data=MOCK_CONFIG, entry_id="test", unique_id=123456
|
||||
)
|
||||
config_entry = get_mock_config_entry()
|
||||
config_entry.add_to_hass(hass)
|
||||
|
||||
# In this case we are testing the condition where async_setup_entry raises
|
||||
# ConfigEntryNotReady.
|
||||
with patch(
|
||||
"renault_api.renault_session.RenaultSession.login",
|
||||
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)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
"""Tests for Renault sensors."""
|
||||
from unittest.mock import PropertyMock, patch
|
||||
from unittest.mock import patch
|
||||
|
||||
import pytest
|
||||
from renault_api.kamereon import exceptions
|
||||
|
@ -9,9 +9,8 @@ from homeassistant.const import STATE_UNAVAILABLE
|
|||
from homeassistant.setup import async_setup_component
|
||||
|
||||
from . import (
|
||||
create_vehicle_proxy,
|
||||
create_vehicle_proxy_with_side_effect,
|
||||
setup_renault_integration,
|
||||
setup_renault_integration_vehicle,
|
||||
setup_renault_integration_vehicle_with_side_effect,
|
||||
)
|
||||
from .const import MOCK_VEHICLES
|
||||
|
||||
|
@ -25,16 +24,8 @@ async def test_sensors(hass, vehicle_type):
|
|||
entity_registry = mock_registry(hass)
|
||||
device_registry = mock_device_registry(hass)
|
||||
|
||||
vehicle_proxy = await create_vehicle_proxy(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)
|
||||
with patch("homeassistant.components.renault.PLATFORMS", [SENSOR_DOMAIN]):
|
||||
await setup_renault_integration_vehicle(hass, vehicle_type)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
mock_vehicle = MOCK_VEHICLES[vehicle_type]
|
||||
|
@ -68,16 +59,8 @@ async def test_sensor_empty(hass, vehicle_type):
|
|||
entity_registry = mock_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.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)
|
||||
with patch("homeassistant.components.renault.PLATFORMS", [SENSOR_DOMAIN]):
|
||||
await setup_renault_integration_vehicle_with_side_effect(hass, vehicle_type, {})
|
||||
await hass.async_block_till_done()
|
||||
|
||||
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",
|
||||
)
|
||||
|
||||
vehicle_proxy = await create_vehicle_proxy_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)
|
||||
with patch("homeassistant.components.renault.PLATFORMS", [SENSOR_DOMAIN]):
|
||||
await setup_renault_integration_vehicle_with_side_effect(
|
||||
hass, vehicle_type, invalid_upstream_exception
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
mock_vehicle = MOCK_VEHICLES[vehicle_type]
|
||||
|
@ -165,18 +140,10 @@ async def test_sensor_access_denied(hass):
|
|||
"Access is denied for this resource",
|
||||
)
|
||||
|
||||
vehicle_proxy = await create_vehicle_proxy_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)
|
||||
with patch("homeassistant.components.renault.PLATFORMS", [SENSOR_DOMAIN]):
|
||||
await setup_renault_integration_vehicle_with_side_effect(
|
||||
hass, "zoe_40", access_denied_exception
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
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",
|
||||
)
|
||||
|
||||
vehicle_proxy = await create_vehicle_proxy_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)
|
||||
with patch("homeassistant.components.renault.PLATFORMS", [SENSOR_DOMAIN]):
|
||||
await setup_renault_integration_vehicle_with_side_effect(
|
||||
hass, "zoe_40", not_supported_exception
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert len(device_registry.devices) == 0
|
||||
|
|
Loading…
Reference in New Issue