Refactor sonarr tests (#64886)

This commit is contained in:
Chris Talkington 2022-01-31 16:59:18 -06:00 committed by GitHub
parent 0f88790303
commit 70da08499a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 310 additions and 359 deletions

View File

@ -1,244 +1,13 @@
"""Tests for the Sonarr component."""
from http import HTTPStatus
from socket import gaierror as SocketGIAError
from unittest.mock import patch
from homeassistant.components.sonarr.const import (
CONF_BASE_PATH,
CONF_UPCOMING_DAYS,
CONF_WANTED_MAX_ITEMS,
DEFAULT_UPCOMING_DAYS,
DEFAULT_WANTED_MAX_ITEMS,
DOMAIN,
)
from homeassistant.const import (
CONF_API_KEY,
CONF_HOST,
CONF_PORT,
CONF_SSL,
CONF_VERIFY_SSL,
CONTENT_TYPE_JSON,
)
from homeassistant.core import HomeAssistant
from tests.common import MockConfigEntry, load_fixture
from tests.test_util.aiohttp import AiohttpClientMocker
HOST = "192.168.1.189"
PORT = 8989
BASE_PATH = "/api"
API_KEY = "MOCK_API_KEY"
from homeassistant.components.sonarr.const import CONF_BASE_PATH
from homeassistant.const import CONF_API_KEY, CONF_HOST, CONF_PORT, CONF_SSL
MOCK_REAUTH_INPUT = {CONF_API_KEY: "test-api-key-reauth"}
MOCK_USER_INPUT = {
CONF_HOST: HOST,
CONF_PORT: PORT,
CONF_BASE_PATH: BASE_PATH,
CONF_HOST: "192.168.1.189",
CONF_PORT: 8989,
CONF_BASE_PATH: "/api",
CONF_SSL: False,
CONF_API_KEY: API_KEY,
CONF_API_KEY: "MOCK_API_KEY",
}
def mock_connection(
aioclient_mock: AiohttpClientMocker,
host: str = HOST,
port: str = PORT,
base_path: str = BASE_PATH,
error: bool = False,
invalid_auth: bool = False,
server_error: bool = False,
) -> None:
"""Mock Sonarr connection."""
if error:
mock_connection_error(
aioclient_mock,
host=host,
port=port,
base_path=base_path,
)
return
if invalid_auth:
mock_connection_invalid_auth(
aioclient_mock,
host=host,
port=port,
base_path=base_path,
)
return
if server_error:
mock_connection_server_error(
aioclient_mock,
host=host,
port=port,
base_path=base_path,
)
return
sonarr_url = f"http://{host}:{port}{base_path}"
aioclient_mock.get(
f"{sonarr_url}/system/status",
text=load_fixture("sonarr/system-status.json"),
headers={"Content-Type": CONTENT_TYPE_JSON},
)
aioclient_mock.get(
f"{sonarr_url}/diskspace",
text=load_fixture("sonarr/diskspace.json"),
headers={"Content-Type": CONTENT_TYPE_JSON},
)
aioclient_mock.get(
f"{sonarr_url}/calendar",
text=load_fixture("sonarr/calendar.json"),
headers={"Content-Type": CONTENT_TYPE_JSON},
)
aioclient_mock.get(
f"{sonarr_url}/command",
text=load_fixture("sonarr/command.json"),
headers={"Content-Type": CONTENT_TYPE_JSON},
)
aioclient_mock.get(
f"{sonarr_url}/queue",
text=load_fixture("sonarr/queue.json"),
headers={"Content-Type": CONTENT_TYPE_JSON},
)
aioclient_mock.get(
f"{sonarr_url}/series",
text=load_fixture("sonarr/series.json"),
headers={"Content-Type": CONTENT_TYPE_JSON},
)
aioclient_mock.get(
f"{sonarr_url}/wanted/missing",
text=load_fixture("sonarr/wanted-missing.json"),
headers={"Content-Type": CONTENT_TYPE_JSON},
)
def mock_connection_error(
aioclient_mock: AiohttpClientMocker,
host: str = HOST,
port: str = PORT,
base_path: str = BASE_PATH,
) -> None:
"""Mock Sonarr connection errors."""
sonarr_url = f"http://{host}:{port}{base_path}"
aioclient_mock.get(f"{sonarr_url}/system/status", exc=SocketGIAError)
aioclient_mock.get(f"{sonarr_url}/diskspace", exc=SocketGIAError)
aioclient_mock.get(f"{sonarr_url}/calendar", exc=SocketGIAError)
aioclient_mock.get(f"{sonarr_url}/command", exc=SocketGIAError)
aioclient_mock.get(f"{sonarr_url}/queue", exc=SocketGIAError)
aioclient_mock.get(f"{sonarr_url}/series", exc=SocketGIAError)
aioclient_mock.get(f"{sonarr_url}/missing/wanted", exc=SocketGIAError)
def mock_connection_invalid_auth(
aioclient_mock: AiohttpClientMocker,
host: str = HOST,
port: str = PORT,
base_path: str = BASE_PATH,
) -> None:
"""Mock Sonarr invalid auth errors."""
sonarr_url = f"http://{host}:{port}{base_path}"
aioclient_mock.get(f"{sonarr_url}/system/status", status=HTTPStatus.FORBIDDEN)
aioclient_mock.get(f"{sonarr_url}/diskspace", status=HTTPStatus.FORBIDDEN)
aioclient_mock.get(f"{sonarr_url}/calendar", status=HTTPStatus.FORBIDDEN)
aioclient_mock.get(f"{sonarr_url}/command", status=HTTPStatus.FORBIDDEN)
aioclient_mock.get(f"{sonarr_url}/queue", status=HTTPStatus.FORBIDDEN)
aioclient_mock.get(f"{sonarr_url}/series", status=HTTPStatus.FORBIDDEN)
aioclient_mock.get(f"{sonarr_url}/missing/wanted", status=HTTPStatus.FORBIDDEN)
def mock_connection_server_error(
aioclient_mock: AiohttpClientMocker,
host: str = HOST,
port: str = PORT,
base_path: str = BASE_PATH,
) -> None:
"""Mock Sonarr server errors."""
sonarr_url = f"http://{host}:{port}{base_path}"
aioclient_mock.get(
f"{sonarr_url}/system/status", status=HTTPStatus.INTERNAL_SERVER_ERROR
)
aioclient_mock.get(
f"{sonarr_url}/diskspace", status=HTTPStatus.INTERNAL_SERVER_ERROR
)
aioclient_mock.get(
f"{sonarr_url}/calendar", status=HTTPStatus.INTERNAL_SERVER_ERROR
)
aioclient_mock.get(f"{sonarr_url}/command", status=HTTPStatus.INTERNAL_SERVER_ERROR)
aioclient_mock.get(f"{sonarr_url}/queue", status=HTTPStatus.INTERNAL_SERVER_ERROR)
aioclient_mock.get(f"{sonarr_url}/series", status=HTTPStatus.INTERNAL_SERVER_ERROR)
aioclient_mock.get(
f"{sonarr_url}/missing/wanted", status=HTTPStatus.INTERNAL_SERVER_ERROR
)
async def setup_integration(
hass: HomeAssistant,
aioclient_mock: AiohttpClientMocker,
host: str = HOST,
port: str = PORT,
base_path: str = BASE_PATH,
api_key: str = API_KEY,
unique_id: str = None,
skip_entry_setup: bool = False,
connection_error: bool = False,
invalid_auth: bool = False,
server_error: bool = False,
) -> MockConfigEntry:
"""Set up the Sonarr integration in Home Assistant."""
entry = MockConfigEntry(
domain=DOMAIN,
unique_id=unique_id,
data={
CONF_HOST: host,
CONF_PORT: port,
CONF_BASE_PATH: base_path,
CONF_SSL: False,
CONF_VERIFY_SSL: False,
CONF_API_KEY: api_key,
CONF_UPCOMING_DAYS: DEFAULT_UPCOMING_DAYS,
CONF_WANTED_MAX_ITEMS: DEFAULT_WANTED_MAX_ITEMS,
},
options={
CONF_UPCOMING_DAYS: DEFAULT_UPCOMING_DAYS,
CONF_WANTED_MAX_ITEMS: DEFAULT_WANTED_MAX_ITEMS,
},
)
entry.add_to_hass(hass)
mock_connection(
aioclient_mock,
host=host,
port=port,
base_path=base_path,
error=connection_error,
invalid_auth=invalid_auth,
server_error=server_error,
)
if not skip_entry_setup:
await hass.config_entries.async_setup(entry.entry_id)
await hass.async_block_till_done()
return entry
def _patch_async_setup_entry(return_value=True):
"""Patch the async entry setup of sonarr."""
return patch(
"homeassistant.components.sonarr.async_setup_entry",
return_value=return_value,
)

View File

@ -0,0 +1,159 @@
"""Fixtures for Sonarr integration tests."""
from collections.abc import Generator
import json
from unittest.mock import MagicMock, patch
import pytest
from sonarr.models import (
Application,
CommandItem,
Episode,
QueueItem,
SeriesItem,
WantedResults,
)
from homeassistant.components.sonarr.const import (
CONF_BASE_PATH,
CONF_UPCOMING_DAYS,
CONF_WANTED_MAX_ITEMS,
DEFAULT_UPCOMING_DAYS,
DEFAULT_WANTED_MAX_ITEMS,
DOMAIN,
)
from homeassistant.const import (
CONF_API_KEY,
CONF_HOST,
CONF_PORT,
CONF_SSL,
CONF_VERIFY_SSL,
)
from homeassistant.core import HomeAssistant
from tests.common import MockConfigEntry, load_fixture
def sonarr_calendar():
"""Generate a response for the calendar method."""
results = json.loads(load_fixture("sonarr/calendar.json"))
return [Episode.from_dict(result) for result in results]
def sonarr_commands():
"""Generate a response for the commands method."""
results = json.loads(load_fixture("sonarr/command.json"))
return [CommandItem.from_dict(result) for result in results]
def sonarr_queue():
"""Generate a response for the queue method."""
results = json.loads(load_fixture("sonarr/queue.json"))
return [QueueItem.from_dict(result) for result in results]
def sonarr_series():
"""Generate a response for the series method."""
results = json.loads(load_fixture("sonarr/series.json"))
return [SeriesItem.from_dict(result) for result in results]
def sonarr_wanted():
"""Generate a response for the wanted method."""
results = json.loads(load_fixture("sonarr/wanted-missing.json"))
return WantedResults.from_dict(results)
@pytest.fixture
def mock_config_entry() -> MockConfigEntry:
"""Return the default mocked config entry."""
return MockConfigEntry(
title="Sonarr",
domain=DOMAIN,
data={
CONF_HOST: "192.168.1.189",
CONF_PORT: 8989,
CONF_BASE_PATH: "/api",
CONF_SSL: False,
CONF_VERIFY_SSL: False,
CONF_API_KEY: "MOCK_API_KEY",
CONF_UPCOMING_DAYS: DEFAULT_UPCOMING_DAYS,
CONF_WANTED_MAX_ITEMS: DEFAULT_WANTED_MAX_ITEMS,
},
options={
CONF_UPCOMING_DAYS: DEFAULT_UPCOMING_DAYS,
CONF_WANTED_MAX_ITEMS: DEFAULT_WANTED_MAX_ITEMS,
},
unique_id=None,
)
@pytest.fixture
def mock_setup_entry() -> Generator[None, None, None]:
"""Mock setting up a config entry."""
with patch("homeassistant.components.sonarr.async_setup_entry", return_value=True):
yield
@pytest.fixture
def mock_sonarr_config_flow(
request: pytest.FixtureRequest,
) -> Generator[None, MagicMock, None]:
"""Return a mocked Sonarr client."""
fixture: str = "sonarr/app.json"
if hasattr(request, "param") and request.param:
fixture = request.param
app = Application(json.loads(load_fixture(fixture)))
with patch(
"homeassistant.components.sonarr.config_flow.Sonarr", autospec=True
) as sonarr_mock:
client = sonarr_mock.return_value
client.host = "192.168.1.189"
client.port = 8989
client.base_path = "/api"
client.tls = False
client.app = app
client.update.return_value = app
client.calendar.return_value = sonarr_calendar()
client.commands.return_value = sonarr_commands()
client.queue.return_value = sonarr_queue()
client.series.return_value = sonarr_series()
client.wanted.return_value = sonarr_wanted()
yield client
@pytest.fixture
def mock_sonarr(request: pytest.FixtureRequest) -> Generator[None, MagicMock, None]:
"""Return a mocked Sonarr client."""
fixture: str = "sonarr/app.json"
if hasattr(request, "param") and request.param:
fixture = request.param
app = Application(json.loads(load_fixture(fixture)))
with patch("homeassistant.components.sonarr.Sonarr", autospec=True) as sonarr_mock:
client = sonarr_mock.return_value
client.host = "192.168.1.189"
client.port = 8989
client.base_path = "/api"
client.tls = False
client.app = app
client.update.return_value = app
client.calendar.return_value = sonarr_calendar()
client.commands.return_value = sonarr_commands()
client.queue.return_value = sonarr_queue()
client.series.return_value = sonarr_series()
client.wanted.return_value = sonarr_wanted()
yield client
@pytest.fixture
async def init_integration(
hass: HomeAssistant, mock_config_entry: MockConfigEntry, mock_sonarr: MagicMock
) -> MockConfigEntry:
"""Set up the Sonarr integration for testing."""
mock_config_entry.add_to_hass(hass)
await hass.config_entries.async_setup(mock_config_entry.entry_id)
await hass.async_block_till_done()
return mock_config_entry

View File

@ -0,0 +1,28 @@
{
"info": {
"version": "2.0.0.1121",
"buildTime": "2014-02-08T20:49:36.5560392Z",
"isDebug": false,
"isProduction": true,
"isAdmin": true,
"isUserInteractive": false,
"startupPath": "C:\\ProgramData\\NzbDrone\\bin",
"appData": "C:\\ProgramData\\NzbDrone",
"osVersion": "6.2.9200.0",
"isMono": false,
"isLinux": false,
"isWindows": true,
"branch": "develop",
"authentication": false,
"startOfWeek": 0,
"urlBase": ""
},
"diskspace": [
{
"path": "C:\\",
"label": "",
"freeSpace": 282500067328,
"totalSpace": 499738734592
}
]
}

View File

@ -1,18 +0,0 @@
{
"version": "2.0.0.1121",
"buildTime": "2014-02-08T20:49:36.5560392Z",
"isDebug": false,
"isProduction": true,
"isAdmin": true,
"isUserInteractive": false,
"startupPath": "C:\\ProgramData\\NzbDrone\\bin",
"appData": "C:\\ProgramData\\NzbDrone",
"osVersion": "6.2.9200.0",
"isMono": false,
"isLinux": false,
"isWindows": true,
"branch": "develop",
"authentication": false,
"startOfWeek": 0,
"urlBase": ""
}

View File

@ -1,5 +1,7 @@
"""Test the Sonarr config flow."""
from unittest.mock import patch
from unittest.mock import MagicMock, patch
from sonarr import SonarrAccessRestricted, SonarrError
from homeassistant.components.sonarr.const import (
CONF_UPCOMING_DAYS,
@ -17,17 +19,8 @@ from homeassistant.data_entry_flow import (
RESULT_TYPE_FORM,
)
from tests.components.sonarr import (
HOST,
MOCK_REAUTH_INPUT,
MOCK_USER_INPUT,
_patch_async_setup_entry,
mock_connection,
mock_connection_error,
mock_connection_invalid_auth,
setup_integration,
)
from tests.test_util.aiohttp import AiohttpClientMocker
from tests.common import MockConfigEntry
from tests.components.sonarr import MOCK_REAUTH_INPUT, MOCK_USER_INPUT
async def test_show_user_form(hass: HomeAssistant) -> None:
@ -42,10 +35,10 @@ async def test_show_user_form(hass: HomeAssistant) -> None:
async def test_cannot_connect(
hass: HomeAssistant, aioclient_mock: AiohttpClientMocker
hass: HomeAssistant, mock_sonarr_config_flow: MagicMock
) -> None:
"""Test we show user form on connection error."""
mock_connection_error(aioclient_mock)
mock_sonarr_config_flow.update.side_effect = SonarrError
user_input = MOCK_USER_INPUT.copy()
result = await hass.config_entries.flow.async_init(
@ -60,10 +53,10 @@ async def test_cannot_connect(
async def test_invalid_auth(
hass: HomeAssistant, aioclient_mock: AiohttpClientMocker
hass: HomeAssistant, mock_sonarr_config_flow: MagicMock
) -> None:
"""Test we show user form on invalid auth."""
mock_connection_invalid_auth(aioclient_mock)
mock_sonarr_config_flow.update.side_effect = SonarrAccessRestricted
user_input = MOCK_USER_INPUT.copy()
result = await hass.config_entries.flow.async_init(
@ -78,30 +71,30 @@ async def test_invalid_auth(
async def test_unknown_error(
hass: HomeAssistant, aioclient_mock: AiohttpClientMocker
hass: HomeAssistant, mock_sonarr_config_flow: MagicMock
) -> None:
"""Test we show user form on unknown error."""
mock_sonarr_config_flow.update.side_effect = Exception
user_input = MOCK_USER_INPUT.copy()
with patch(
"homeassistant.components.sonarr.config_flow.Sonarr.update",
side_effect=Exception,
):
result = await hass.config_entries.flow.async_init(
DOMAIN,
context={CONF_SOURCE: SOURCE_USER},
data=user_input,
)
result = await hass.config_entries.flow.async_init(
DOMAIN,
context={CONF_SOURCE: SOURCE_USER},
data=user_input,
)
assert result["type"] == RESULT_TYPE_ABORT
assert result["reason"] == "unknown"
async def test_full_reauth_flow_implementation(
hass: HomeAssistant, aioclient_mock: AiohttpClientMocker
hass: HomeAssistant,
mock_sonarr_config_flow: MagicMock,
mock_setup_entry: None,
init_integration: MockConfigEntry,
) -> None:
"""Test the manual reauth flow from start to finish."""
entry = await setup_integration(hass, aioclient_mock, skip_entry_setup=True)
assert entry
entry = init_integration
result = await hass.config_entries.flow.async_init(
DOMAIN,
@ -124,26 +117,23 @@ async def test_full_reauth_flow_implementation(
assert result["step_id"] == "user"
user_input = MOCK_REAUTH_INPUT.copy()
with _patch_async_setup_entry() as mock_setup_entry:
result = await hass.config_entries.flow.async_configure(
result["flow_id"], user_input=user_input
)
await hass.async_block_till_done()
result = await hass.config_entries.flow.async_configure(
result["flow_id"], user_input=user_input
)
await hass.async_block_till_done()
assert result["type"] == RESULT_TYPE_ABORT
assert result["reason"] == "reauth_successful"
assert entry.data[CONF_API_KEY] == "test-api-key-reauth"
mock_setup_entry.assert_called_once()
async def test_full_user_flow_implementation(
hass: HomeAssistant, aioclient_mock: AiohttpClientMocker
hass: HomeAssistant,
mock_sonarr_config_flow: MagicMock,
mock_setup_entry: None,
) -> None:
"""Test the full manual user flow from start to finish."""
mock_connection(aioclient_mock)
result = await hass.config_entries.flow.async_init(
DOMAIN,
context={CONF_SOURCE: SOURCE_USER},
@ -154,25 +144,24 @@ async def test_full_user_flow_implementation(
user_input = MOCK_USER_INPUT.copy()
with _patch_async_setup_entry():
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
user_input=user_input,
)
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
user_input=user_input,
)
assert result["type"] == RESULT_TYPE_CREATE_ENTRY
assert result["title"] == HOST
assert result["title"] == "192.168.1.189"
assert result["data"]
assert result["data"][CONF_HOST] == HOST
assert result["data"][CONF_HOST] == "192.168.1.189"
async def test_full_user_flow_advanced_options(
hass: HomeAssistant, aioclient_mock: AiohttpClientMocker
hass: HomeAssistant,
mock_sonarr_config_flow: MagicMock,
mock_setup_entry: None,
) -> None:
"""Test the full manual user flow with advanced options."""
mock_connection(aioclient_mock)
result = await hass.config_entries.flow.async_init(
DOMAIN, context={CONF_SOURCE: SOURCE_USER, "show_advanced_options": True}
)
@ -185,24 +174,27 @@ async def test_full_user_flow_advanced_options(
CONF_VERIFY_SSL: True,
}
with _patch_async_setup_entry():
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
user_input=user_input,
)
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
user_input=user_input,
)
assert result["type"] == RESULT_TYPE_CREATE_ENTRY
assert result["title"] == HOST
assert result["title"] == "192.168.1.189"
assert result["data"]
assert result["data"][CONF_HOST] == HOST
assert result["data"][CONF_HOST] == "192.168.1.189"
assert result["data"][CONF_VERIFY_SSL]
async def test_options_flow(hass, aioclient_mock: AiohttpClientMocker):
@patch("homeassistant.components.sonarr.PLATFORMS", [])
async def test_options_flow(
hass: HomeAssistant,
mock_setup_entry: None,
init_integration: MockConfigEntry,
):
"""Test updating options."""
with patch("homeassistant.components.sonarr.PLATFORMS", []):
entry = await setup_integration(hass, aioclient_mock)
entry = init_integration
assert entry.options[CONF_UPCOMING_DAYS] == DEFAULT_UPCOMING_DAYS
assert entry.options[CONF_WANTED_MAX_ITEMS] == DEFAULT_WANTED_MAX_ITEMS
@ -212,12 +204,11 @@ async def test_options_flow(hass, aioclient_mock: AiohttpClientMocker):
assert result["type"] == RESULT_TYPE_FORM
assert result["step_id"] == "init"
with _patch_async_setup_entry():
result = await hass.config_entries.options.async_configure(
result["flow_id"],
user_input={CONF_UPCOMING_DAYS: 2, CONF_WANTED_MAX_ITEMS: 100},
)
await hass.async_block_till_done()
result = await hass.config_entries.options.async_configure(
result["flow_id"],
user_input={CONF_UPCOMING_DAYS: 2, CONF_WANTED_MAX_ITEMS: 100},
)
await hass.async_block_till_done()
assert result["type"] == RESULT_TYPE_CREATE_ENTRY
assert result["data"][CONF_UPCOMING_DAYS] == 2

View File

@ -1,60 +1,79 @@
"""Tests for the Sonsrr integration."""
from unittest.mock import patch
from unittest.mock import MagicMock, patch
from sonarr import SonarrAccessRestricted, SonarrError
from homeassistant.components.sonarr.const import DOMAIN
from homeassistant.config_entries import SOURCE_REAUTH, ConfigEntryState
from homeassistant.const import CONF_SOURCE
from homeassistant.core import HomeAssistant
from tests.components.sonarr import setup_integration
from tests.test_util.aiohttp import AiohttpClientMocker
from tests.common import MockConfigEntry
async def test_config_entry_not_ready(
hass: HomeAssistant, aioclient_mock: AiohttpClientMocker
hass: HomeAssistant,
mock_config_entry: MockConfigEntry,
mock_sonarr: MagicMock,
) -> None:
"""Test the configuration entry not ready."""
entry = await setup_integration(hass, aioclient_mock, connection_error=True)
assert entry.state is ConfigEntryState.SETUP_RETRY
mock_sonarr.update.side_effect = SonarrError
mock_config_entry.add_to_hass(hass)
await hass.config_entries.async_setup(mock_config_entry.entry_id)
await hass.async_block_till_done()
assert mock_config_entry.state is ConfigEntryState.SETUP_RETRY
async def test_config_entry_reauth(
hass: HomeAssistant, aioclient_mock: AiohttpClientMocker
hass: HomeAssistant,
mock_config_entry: MockConfigEntry,
mock_sonarr: MagicMock,
) -> None:
"""Test the configuration entry needing to be re-authenticated."""
with patch.object(hass.config_entries.flow, "async_init") as mock_flow_init:
entry = await setup_integration(hass, aioclient_mock, invalid_auth=True)
mock_sonarr.update.side_effect = SonarrAccessRestricted
assert entry.state is ConfigEntryState.SETUP_ERROR
with patch.object(hass.config_entries.flow, "async_init") as mock_flow_init:
mock_config_entry.add_to_hass(hass)
await hass.config_entries.async_setup(mock_config_entry.entry_id)
await hass.async_block_till_done()
assert mock_config_entry.state is ConfigEntryState.SETUP_ERROR
mock_flow_init.assert_called_once_with(
DOMAIN,
context={
CONF_SOURCE: SOURCE_REAUTH,
"entry_id": entry.entry_id,
"unique_id": entry.unique_id,
"title_placeholders": {"name": entry.title},
"entry_id": mock_config_entry.entry_id,
"unique_id": mock_config_entry.unique_id,
"title_placeholders": {"name": mock_config_entry.title},
},
data=entry.data,
data=mock_config_entry.data,
)
async def test_unload_config_entry(
hass: HomeAssistant, aioclient_mock: AiohttpClientMocker
hass: HomeAssistant,
mock_config_entry: MockConfigEntry,
mock_sonarr: MagicMock,
) -> None:
"""Test the configuration entry unloading."""
mock_config_entry.add_to_hass(hass)
with patch(
"homeassistant.components.sonarr.sensor.async_setup_entry",
return_value=True,
):
entry = await setup_integration(hass, aioclient_mock)
await hass.config_entries.async_setup(mock_config_entry.entry_id)
await hass.async_block_till_done()
assert hass.data[DOMAIN]
assert entry.entry_id in hass.data[DOMAIN]
assert entry.state is ConfigEntryState.LOADED
assert mock_config_entry.state is ConfigEntryState.LOADED
assert mock_config_entry.entry_id in hass.data[DOMAIN]
await hass.config_entries.async_unload(entry.entry_id)
await hass.config_entries.async_unload(mock_config_entry.entry_id)
await hass.async_block_till_done()
assert entry.entry_id not in hass.data[DOMAIN]
assert entry.state is ConfigEntryState.NOT_LOADED
assert mock_config_entry.state is ConfigEntryState.NOT_LOADED
assert mock_config_entry.entry_id not in hass.data[DOMAIN]

View File

@ -1,8 +1,9 @@
"""Tests for the Sonarr sensor platform."""
from datetime import timedelta
from unittest.mock import patch
from unittest.mock import MagicMock, patch
import pytest
from sonarr import SonarrError
from homeassistant.components.sensor import DOMAIN as SENSOR_DOMAIN
from homeassistant.components.sonarr.const import DOMAIN
@ -16,18 +17,18 @@ from homeassistant.core import HomeAssistant
from homeassistant.helpers import entity_registry as er
from homeassistant.util import dt as dt_util
from tests.common import async_fire_time_changed
from tests.components.sonarr import mock_connection, setup_integration
from tests.test_util.aiohttp import AiohttpClientMocker
from tests.common import MockConfigEntry, async_fire_time_changed
UPCOMING_ENTITY_ID = f"{SENSOR_DOMAIN}.sonarr_upcoming"
async def test_sensors(
hass: HomeAssistant, aioclient_mock: AiohttpClientMocker
hass: HomeAssistant,
mock_config_entry: MockConfigEntry,
mock_sonarr: MagicMock,
) -> None:
"""Test the creation and values of the sensors."""
entry = await setup_integration(hass, aioclient_mock, skip_entry_setup=True)
entry = mock_config_entry
registry = er.async_get(hass)
# Pre-create registry entries for disabled by default sensors
@ -48,6 +49,7 @@ async def test_sensors(
disabled_by=None,
)
mock_config_entry.add_to_hass(hass)
await hass.config_entries.async_setup(entry.entry_id)
await hass.async_block_till_done()
@ -104,10 +106,11 @@ async def test_sensors(
),
)
async def test_disabled_by_default_sensors(
hass: HomeAssistant, aioclient_mock: AiohttpClientMocker, entity_id: str
hass: HomeAssistant,
init_integration: MockConfigEntry,
entity_id: str,
) -> None:
"""Test the disabled by default sensors."""
await setup_integration(hass, aioclient_mock)
registry = er.async_get(hass)
state = hass.states.get(entity_id)
@ -120,19 +123,22 @@ async def test_disabled_by_default_sensors(
async def test_availability(
hass: HomeAssistant, aioclient_mock: AiohttpClientMocker
hass: HomeAssistant,
mock_config_entry: MockConfigEntry,
mock_sonarr: MagicMock,
) -> None:
"""Test entity availability."""
now = dt_util.utcnow()
mock_config_entry.add_to_hass(hass)
with patch("homeassistant.util.dt.utcnow", return_value=now):
await setup_integration(hass, aioclient_mock)
await hass.config_entries.async_setup(mock_config_entry.entry_id)
await hass.async_block_till_done()
assert hass.states.get(UPCOMING_ENTITY_ID).state == "1"
# state to unavailable
aioclient_mock.clear_requests()
mock_connection(aioclient_mock, error=True)
mock_sonarr.calendar.side_effect = SonarrError
future = now + timedelta(minutes=1)
with patch("homeassistant.util.dt.utcnow", return_value=future):
@ -142,8 +148,7 @@ async def test_availability(
assert hass.states.get(UPCOMING_ENTITY_ID).state == STATE_UNAVAILABLE
# state to available
aioclient_mock.clear_requests()
mock_connection(aioclient_mock)
mock_sonarr.calendar.side_effect = None
future += timedelta(minutes=1)
with patch("homeassistant.util.dt.utcnow", return_value=future):
@ -153,8 +158,7 @@ async def test_availability(
assert hass.states.get(UPCOMING_ENTITY_ID).state == "1"
# state to unavailable
aioclient_mock.clear_requests()
mock_connection(aioclient_mock, invalid_auth=True)
mock_sonarr.calendar.side_effect = SonarrError
future += timedelta(minutes=1)
with patch("homeassistant.util.dt.utcnow", return_value=future):
@ -164,8 +168,7 @@ async def test_availability(
assert hass.states.get(UPCOMING_ENTITY_ID).state == STATE_UNAVAILABLE
# state to available
aioclient_mock.clear_requests()
mock_connection(aioclient_mock)
mock_sonarr.calendar.side_effect = None
future += timedelta(minutes=1)
with patch("homeassistant.util.dt.utcnow", return_value=future):