Amberelectric (#56448)
* Add Amber Electric integration * Linting * Fixing some type hinting * Adding docstrings * Removing files that shouldn't have been changed * Splitting out test helpers * Testing the price sensor * Testing Controlled load and feed in channels * Refactoring mocks * switching state for native_value and unit_of_measurement for native_unit_of_measurement * Fixing docstrings * Fixing requiremennts_all.txt * isort fixes * Fixing pylint errors * Omitting __init__.py from test coverage * Add missing config_flow tests * Adding more sensor tests * Applying suggested changes to __init.py__ * Refactor coordinator to return the data object with all of the relevent data already setup * Another coordinator refactor - Better use the dictionary for when we build the sensors * Removing first function * Refactoring sensor files to use entity descriptions, remove factory * Rounding renewable percentage, return icons correctly * Cleaning up translation strings * Fixing relative path, removing TODO * Coordintator tests now accept new (more accurate) fixtures * Using a description placeholder * Putting missing translations strings back in * tighten up the no site error logic - self._site_id should never be None at the point of loading async_step_site * Removing DEVICE_CLASS, replacing the units with AUD/kWh * Settings _attr_unique_id * Removing icon function (it's already the default) * Apply suggestions from code review Co-authored-by: Paulus Schoutsen <paulus@home-assistant.io> * Adding strings.json * Tighter wrapping for try/except * Generating translations * Removing update_method - not needed as it's being overriden * Apply suggestions from code review Co-authored-by: Paulus Schoutsen <paulus@home-assistant.io> * Fixing tests * Add missing description placeholder * Fix warning * changing name from update to update_data to match async_update_data * renaming [async_]update_data => [async_]update_price_data to avoid confusion * Creating too man renewable sensors * Override update method * Coordinator tests use _async_update_data * Using $/kWh as the units * Using isinstance instead of __class__ test. Removing a zero len check * Asserting self._sites in second step * Linting * Remove useless tests Co-authored-by: jan iversen <jancasacondor@gmail.com> Co-authored-by: Paulus Schoutsen <paulus@home-assistant.io>
This commit is contained in:
parent
f93539ef4c
commit
412ecacca3
17 changed files with 1326 additions and 0 deletions
148
tests/components/amberelectric/test_config_flow.py
Normal file
148
tests/components/amberelectric/test_config_flow.py
Normal file
|
@ -0,0 +1,148 @@
|
|||
"""Tests for the Amber config flow."""
|
||||
|
||||
from typing import Generator
|
||||
from unittest.mock import Mock, patch
|
||||
|
||||
from amberelectric import ApiException
|
||||
from amberelectric.model.site import Site
|
||||
import pytest
|
||||
|
||||
from homeassistant import data_entry_flow
|
||||
from homeassistant.components.amberelectric.const import (
|
||||
CONF_SITE_ID,
|
||||
CONF_SITE_NAME,
|
||||
CONF_SITE_NMI,
|
||||
DOMAIN,
|
||||
)
|
||||
from homeassistant.config_entries import SOURCE_USER
|
||||
from homeassistant.const import CONF_API_TOKEN
|
||||
from homeassistant.core import HomeAssistant
|
||||
|
||||
API_KEY = "psk_123456789"
|
||||
|
||||
|
||||
@pytest.fixture(name="invalid_key_api")
|
||||
def mock_invalid_key_api() -> Generator:
|
||||
"""Return an authentication error."""
|
||||
instance = Mock()
|
||||
instance.get_sites.side_effect = ApiException(status=403)
|
||||
|
||||
with patch("amberelectric.api.AmberApi.create", return_value=instance):
|
||||
yield instance
|
||||
|
||||
|
||||
@pytest.fixture(name="api_error")
|
||||
def mock_api_error() -> Generator:
|
||||
"""Return an authentication error."""
|
||||
instance = Mock()
|
||||
instance.get_sites.side_effect = ApiException(status=500)
|
||||
|
||||
with patch("amberelectric.api.AmberApi.create", return_value=instance):
|
||||
yield instance
|
||||
|
||||
|
||||
@pytest.fixture(name="single_site_api")
|
||||
def mock_single_site_api() -> Generator:
|
||||
"""Return a single site."""
|
||||
instance = Mock()
|
||||
site = Site("01FG0AGP818PXK0DWHXJRRT2DH", "11111111111", [])
|
||||
instance.get_sites.return_value = [site]
|
||||
|
||||
with patch("amberelectric.api.AmberApi.create", return_value=instance):
|
||||
yield instance
|
||||
|
||||
|
||||
@pytest.fixture(name="no_site_api")
|
||||
def mock_no_site_api() -> Generator:
|
||||
"""Return no site."""
|
||||
instance = Mock()
|
||||
instance.get_sites.return_value = []
|
||||
|
||||
with patch("amberelectric.api.AmberApi.create", return_value=instance):
|
||||
yield instance
|
||||
|
||||
|
||||
async def test_single_site(hass: HomeAssistant, single_site_api: Mock) -> None:
|
||||
"""Test single site."""
|
||||
initial_result = await hass.config_entries.flow.async_init(
|
||||
DOMAIN, context={"source": SOURCE_USER}
|
||||
)
|
||||
assert initial_result.get("type") == data_entry_flow.RESULT_TYPE_FORM
|
||||
assert initial_result.get("step_id") == "user"
|
||||
|
||||
# Test filling in API key
|
||||
enter_api_key_result = await hass.config_entries.flow.async_init(
|
||||
DOMAIN,
|
||||
context={"source": SOURCE_USER},
|
||||
data={CONF_API_TOKEN: API_KEY},
|
||||
)
|
||||
assert enter_api_key_result.get("type") == data_entry_flow.RESULT_TYPE_FORM
|
||||
assert enter_api_key_result.get("step_id") == "site"
|
||||
|
||||
select_site_result = await hass.config_entries.flow.async_configure(
|
||||
enter_api_key_result["flow_id"],
|
||||
{CONF_SITE_NMI: "11111111111", CONF_SITE_NAME: "Home"},
|
||||
)
|
||||
|
||||
# Show available sites
|
||||
assert select_site_result.get("type") == data_entry_flow.RESULT_TYPE_CREATE_ENTRY
|
||||
assert select_site_result.get("title") == "Home"
|
||||
data = select_site_result.get("data")
|
||||
assert data
|
||||
assert data[CONF_API_TOKEN] == API_KEY
|
||||
assert data[CONF_SITE_ID] == "01FG0AGP818PXK0DWHXJRRT2DH"
|
||||
assert data[CONF_SITE_NMI] == "11111111111"
|
||||
|
||||
|
||||
async def test_no_site(hass: HomeAssistant, no_site_api: Mock) -> None:
|
||||
"""Test no site."""
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
DOMAIN,
|
||||
context={"source": SOURCE_USER},
|
||||
data={CONF_API_TOKEN: "psk_123456789"},
|
||||
)
|
||||
|
||||
assert result.get("type") == data_entry_flow.RESULT_TYPE_FORM
|
||||
# Goes back to the user step
|
||||
assert result.get("step_id") == "user"
|
||||
assert result.get("errors") == {"api_token": "no_site"}
|
||||
|
||||
|
||||
async def test_invalid_key(hass: HomeAssistant, invalid_key_api: Mock) -> None:
|
||||
"""Test invalid api key."""
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
DOMAIN, context={"source": SOURCE_USER}
|
||||
)
|
||||
assert result.get("type") == data_entry_flow.RESULT_TYPE_FORM
|
||||
assert result.get("step_id") == "user"
|
||||
|
||||
# Test filling in API key
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
DOMAIN,
|
||||
context={"source": SOURCE_USER},
|
||||
data={CONF_API_TOKEN: "psk_123456789"},
|
||||
)
|
||||
assert result.get("type") == data_entry_flow.RESULT_TYPE_FORM
|
||||
# Goes back to the user step
|
||||
assert result.get("step_id") == "user"
|
||||
assert result.get("errors") == {"api_token": "invalid_api_token"}
|
||||
|
||||
|
||||
async def test_unknown_error(hass: HomeAssistant, api_error: Mock) -> None:
|
||||
"""Test invalid api key."""
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
DOMAIN, context={"source": SOURCE_USER}
|
||||
)
|
||||
assert result.get("type") == data_entry_flow.RESULT_TYPE_FORM
|
||||
assert result.get("step_id") == "user"
|
||||
|
||||
# Test filling in API key
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
DOMAIN,
|
||||
context={"source": SOURCE_USER},
|
||||
data={CONF_API_TOKEN: "psk_123456789"},
|
||||
)
|
||||
assert result.get("type") == data_entry_flow.RESULT_TYPE_FORM
|
||||
# Goes back to the user step
|
||||
assert result.get("step_id") == "user"
|
||||
assert result.get("errors") == {"api_token": "unknown_error"}
|
Loading…
Add table
Add a link
Reference in a new issue