Use aiopyarr for sonarr (#65349)
This commit is contained in:
parent
c14912471d
commit
f30681dae7
20 changed files with 464 additions and 345 deletions
|
@ -1,13 +1,9 @@
|
|||
"""Tests for the Sonarr component."""
|
||||
from homeassistant.components.sonarr.const import CONF_BASE_PATH
|
||||
from homeassistant.const import CONF_API_KEY, CONF_HOST, CONF_PORT, CONF_SSL
|
||||
from homeassistant.const import CONF_API_KEY, CONF_URL
|
||||
|
||||
MOCK_REAUTH_INPUT = {CONF_API_KEY: "test-api-key-reauth"}
|
||||
|
||||
MOCK_USER_INPUT = {
|
||||
CONF_HOST: "192.168.1.189",
|
||||
CONF_PORT: 8989,
|
||||
CONF_BASE_PATH: "/api",
|
||||
CONF_SSL: False,
|
||||
CONF_URL: "http://192.168.1.189:8989",
|
||||
CONF_API_KEY: "MOCK_API_KEY",
|
||||
}
|
||||
|
|
|
@ -3,15 +3,16 @@ 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 aiopyarr import (
|
||||
Command,
|
||||
Diskspace,
|
||||
SonarrCalendar,
|
||||
SonarrQueue,
|
||||
SonarrSeries,
|
||||
SonarrWantedMissing,
|
||||
SystemStatus,
|
||||
)
|
||||
import pytest
|
||||
|
||||
from homeassistant.components.sonarr.const import (
|
||||
CONF_BASE_PATH,
|
||||
|
@ -33,34 +34,46 @@ from homeassistant.core import HomeAssistant
|
|||
from tests.common import MockConfigEntry, load_fixture
|
||||
|
||||
|
||||
def sonarr_calendar():
|
||||
def sonarr_calendar() -> list[SonarrCalendar]:
|
||||
"""Generate a response for the calendar method."""
|
||||
results = json.loads(load_fixture("sonarr/calendar.json"))
|
||||
return [Episode.from_dict(result) for result in results]
|
||||
return [SonarrCalendar(result) for result in results]
|
||||
|
||||
|
||||
def sonarr_commands():
|
||||
def sonarr_commands() -> list[Command]:
|
||||
"""Generate a response for the commands method."""
|
||||
results = json.loads(load_fixture("sonarr/command.json"))
|
||||
return [CommandItem.from_dict(result) for result in results]
|
||||
return [Command(result) for result in results]
|
||||
|
||||
|
||||
def sonarr_queue():
|
||||
def sonarr_diskspace() -> list[Diskspace]:
|
||||
"""Generate a response for the diskspace method."""
|
||||
results = json.loads(load_fixture("sonarr/diskspace.json"))
|
||||
return [Diskspace(result) for result in results]
|
||||
|
||||
|
||||
def sonarr_queue() -> SonarrQueue:
|
||||
"""Generate a response for the queue method."""
|
||||
results = json.loads(load_fixture("sonarr/queue.json"))
|
||||
return [QueueItem.from_dict(result) for result in results]
|
||||
return SonarrQueue(results)
|
||||
|
||||
|
||||
def sonarr_series():
|
||||
def sonarr_series() -> list[SonarrSeries]:
|
||||
"""Generate a response for the series method."""
|
||||
results = json.loads(load_fixture("sonarr/series.json"))
|
||||
return [SeriesItem.from_dict(result) for result in results]
|
||||
return [SonarrSeries(result) for result in results]
|
||||
|
||||
|
||||
def sonarr_wanted():
|
||||
def sonarr_system_status() -> SystemStatus:
|
||||
"""Generate a response for the system status method."""
|
||||
result = json.loads(load_fixture("sonarr/system-status.json"))
|
||||
return SystemStatus(result)
|
||||
|
||||
|
||||
def sonarr_wanted() -> SonarrWantedMissing:
|
||||
"""Generate a response for the wanted method."""
|
||||
results = json.loads(load_fixture("sonarr/wanted-missing.json"))
|
||||
return WantedResults.from_dict(results)
|
||||
return SonarrWantedMissing(results)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
|
@ -95,54 +108,38 @@ def mock_setup_entry() -> Generator[None, None, None]:
|
|||
|
||||
|
||||
@pytest.fixture
|
||||
def mock_sonarr_config_flow(
|
||||
request: pytest.FixtureRequest,
|
||||
) -> Generator[None, MagicMock, None]:
|
||||
def mock_sonarr_config_flow() -> 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
|
||||
"homeassistant.components.sonarr.config_flow.SonarrClient", 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()
|
||||
client.async_get_calendar.return_value = sonarr_calendar()
|
||||
client.async_get_commands.return_value = sonarr_commands()
|
||||
client.async_get_diskspace.return_value = sonarr_diskspace()
|
||||
client.async_get_queue.return_value = sonarr_queue()
|
||||
client.async_get_series.return_value = sonarr_series()
|
||||
client.async_get_system_status.return_value = sonarr_system_status()
|
||||
client.async_get_wanted.return_value = sonarr_wanted()
|
||||
|
||||
yield client
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def mock_sonarr(request: pytest.FixtureRequest) -> Generator[None, MagicMock, None]:
|
||||
def mock_sonarr() -> 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:
|
||||
with patch(
|
||||
"homeassistant.components.sonarr.SonarrClient", 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()
|
||||
client.async_get_calendar.return_value = sonarr_calendar()
|
||||
client.async_get_commands.return_value = sonarr_commands()
|
||||
client.async_get_diskspace.return_value = sonarr_diskspace()
|
||||
client.async_get_queue.return_value = sonarr_queue()
|
||||
client.async_get_series.return_value = sonarr_series()
|
||||
client.async_get_system_status.return_value = sonarr_system_status()
|
||||
client.async_get_wanted.return_value = sonarr_wanted()
|
||||
|
||||
yield client
|
||||
|
||||
|
||||
|
|
|
@ -1,28 +0,0 @@
|
|||
{
|
||||
"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
|
||||
}
|
||||
]
|
||||
}
|
|
@ -17,7 +17,6 @@
|
|||
"queued": "2020-04-06T16:54:06.41945Z",
|
||||
"started": "2020-04-06T16:54:06.421322Z",
|
||||
"trigger": "manual",
|
||||
"state": "started",
|
||||
"manual": true,
|
||||
"startedOn": "2020-04-06T16:54:06.41945Z",
|
||||
"stateChangeTime": "2020-04-06T16:54:06.421322Z",
|
||||
|
@ -27,7 +26,7 @@
|
|||
},
|
||||
{
|
||||
"name": "RefreshSeries",
|
||||
"state": "started",
|
||||
"status": "started",
|
||||
"startedOn": "2020-04-06T16:57:51.406504Z",
|
||||
"stateChangeTime": "2020-04-06T16:57:51.417931Z",
|
||||
"sendUpdatesToClient": true,
|
||||
|
|
|
@ -1,129 +1,140 @@
|
|||
[
|
||||
{
|
||||
"series": {
|
||||
"title": "The Andy Griffith Show",
|
||||
"sortTitle": "andy griffith show",
|
||||
"seasonCount": 8,
|
||||
"status": "ended",
|
||||
"overview": "Down-home humor and an endearing cast of characters helped make The Andy Griffith Show one of the most beloved comedies in the history of TV. The show centered around widower Andy Taylor, who divided his time between raising his young son Opie, and his job as sheriff of the sleepy North Carolina town, Mayberry. Andy and Opie live with Andy's Aunt Bee, who serves as a surrogate mother to both father and son. Andy's nervous cousin, Barney Fife, is his deputy sheriff whose incompetence is tolerated because Mayberry is virtually crime-free.",
|
||||
"network": "CBS",
|
||||
"airTime": "21:30",
|
||||
"images": [
|
||||
{
|
||||
"coverType": "fanart",
|
||||
"url": "https://artworks.thetvdb.com/banners/fanart/original/77754-5.jpg"
|
||||
{
|
||||
"page":1,
|
||||
"pageSize":10,
|
||||
"sortKey":"timeleft",
|
||||
"sortDirection":"ascending",
|
||||
"totalRecords":1,
|
||||
"records":[
|
||||
{
|
||||
"series":{
|
||||
"title":"The Andy Griffith Show",
|
||||
"sortTitle":"andy griffith show",
|
||||
"seasonCount":8,
|
||||
"status":"ended",
|
||||
"overview":"Down-home humor and an endearing cast of characters helped make The Andy Griffith Show one of the most beloved comedies in the history of TV. The show centered around widower Andy Taylor, who divided his time between raising his young son Opie, and his job as sheriff of the sleepy North Carolina town, Mayberry. Andy and Opie live with Andy's Aunt Bee, who serves as a surrogate mother to both father and son. Andy's nervous cousin, Barney Fife, is his deputy sheriff whose incompetence is tolerated because Mayberry is virtually crime-free.",
|
||||
"network":"CBS",
|
||||
"airTime":"21:30",
|
||||
"images":[
|
||||
{
|
||||
"coverType":"fanart",
|
||||
"url":"https://artworks.thetvdb.com/banners/fanart/original/77754-5.jpg"
|
||||
},
|
||||
{
|
||||
"coverType":"banner",
|
||||
"url":"https://artworks.thetvdb.com/banners/graphical/77754-g.jpg"
|
||||
},
|
||||
{
|
||||
"coverType":"poster",
|
||||
"url":"https://artworks.thetvdb.com/banners/posters/77754-4.jpg"
|
||||
}
|
||||
],
|
||||
"seasons":[
|
||||
{
|
||||
"seasonNumber":0,
|
||||
"monitored":false
|
||||
},
|
||||
{
|
||||
"seasonNumber":1,
|
||||
"monitored":false
|
||||
},
|
||||
{
|
||||
"seasonNumber":2,
|
||||
"monitored":true
|
||||
},
|
||||
{
|
||||
"seasonNumber":3,
|
||||
"monitored":false
|
||||
},
|
||||
{
|
||||
"seasonNumber":4,
|
||||
"monitored":false
|
||||
},
|
||||
{
|
||||
"seasonNumber":5,
|
||||
"monitored":true
|
||||
},
|
||||
{
|
||||
"seasonNumber":6,
|
||||
"monitored":true
|
||||
},
|
||||
{
|
||||
"seasonNumber":7,
|
||||
"monitored":true
|
||||
},
|
||||
{
|
||||
"seasonNumber":8,
|
||||
"monitored":true
|
||||
}
|
||||
],
|
||||
"year":1960,
|
||||
"path":"F:\\The Andy Griffith Show",
|
||||
"profileId":5,
|
||||
"seasonFolder":true,
|
||||
"monitored":true,
|
||||
"useSceneNumbering":false,
|
||||
"runtime":25,
|
||||
"tvdbId":77754,
|
||||
"tvRageId":5574,
|
||||
"tvMazeId":3853,
|
||||
"firstAired":"1960-02-15T06:00:00Z",
|
||||
"lastInfoSync":"2016-02-05T16:40:11.614176Z",
|
||||
"seriesType":"standard",
|
||||
"cleanTitle":"theandygriffithshow",
|
||||
"imdbId":"",
|
||||
"titleSlug":"the-andy-griffith-show",
|
||||
"certification":"TV-G",
|
||||
"genres":[
|
||||
"Comedy"
|
||||
],
|
||||
"tags":[
|
||||
|
||||
],
|
||||
"added":"2008-02-04T13:44:24.204583Z",
|
||||
"ratings":{
|
||||
"votes":547,
|
||||
"value":8.6
|
||||
},
|
||||
{
|
||||
"coverType": "banner",
|
||||
"url": "https://artworks.thetvdb.com/banners/graphical/77754-g.jpg"
|
||||
},
|
||||
{
|
||||
"coverType": "poster",
|
||||
"url": "https://artworks.thetvdb.com/banners/posters/77754-4.jpg"
|
||||
}
|
||||
],
|
||||
"seasons": [
|
||||
{
|
||||
"seasonNumber": 0,
|
||||
"monitored": false
|
||||
},
|
||||
{
|
||||
"seasonNumber": 1,
|
||||
"monitored": false
|
||||
},
|
||||
{
|
||||
"seasonNumber": 2,
|
||||
"monitored": true
|
||||
},
|
||||
{
|
||||
"seasonNumber": 3,
|
||||
"monitored": false
|
||||
},
|
||||
{
|
||||
"seasonNumber": 4,
|
||||
"monitored": false
|
||||
},
|
||||
{
|
||||
"seasonNumber": 5,
|
||||
"monitored": true
|
||||
},
|
||||
{
|
||||
"seasonNumber": 6,
|
||||
"monitored": true
|
||||
},
|
||||
{
|
||||
"seasonNumber": 7,
|
||||
"monitored": true
|
||||
},
|
||||
{
|
||||
"seasonNumber": 8,
|
||||
"monitored": true
|
||||
}
|
||||
],
|
||||
"year": 1960,
|
||||
"path": "F:\\The Andy Griffith Show",
|
||||
"profileId": 5,
|
||||
"seasonFolder": true,
|
||||
"monitored": true,
|
||||
"useSceneNumbering": false,
|
||||
"runtime": 25,
|
||||
"tvdbId": 77754,
|
||||
"tvRageId": 5574,
|
||||
"tvMazeId": 3853,
|
||||
"firstAired": "1960-02-15T06:00:00Z",
|
||||
"lastInfoSync": "2016-02-05T16:40:11.614176Z",
|
||||
"seriesType": "standard",
|
||||
"cleanTitle": "theandygriffithshow",
|
||||
"imdbId": "",
|
||||
"titleSlug": "the-andy-griffith-show",
|
||||
"certification": "TV-G",
|
||||
"genres": [
|
||||
"Comedy"
|
||||
],
|
||||
"tags": [],
|
||||
"added": "2008-02-04T13:44:24.204583Z",
|
||||
"ratings": {
|
||||
"votes": 547,
|
||||
"value": 8.6
|
||||
"qualityProfileId":5,
|
||||
"id":17
|
||||
},
|
||||
"qualityProfileId": 5,
|
||||
"id": 17
|
||||
},
|
||||
"episode": {
|
||||
"seriesId": 17,
|
||||
"episodeFileId": 0,
|
||||
"seasonNumber": 1,
|
||||
"episodeNumber": 1,
|
||||
"title": "The New Housekeeper",
|
||||
"airDate": "1960-10-03",
|
||||
"airDateUtc": "1960-10-03T01:00:00Z",
|
||||
"overview": "Sheriff Andy Taylor and his young son Opie are in need of a new housekeeper. Andy's Aunt Bee looks like the perfect candidate and moves in, but her presence causes friction with Opie.",
|
||||
"hasFile": false,
|
||||
"monitored": false,
|
||||
"absoluteEpisodeNumber": 1,
|
||||
"unverifiedSceneNumbering": false,
|
||||
"id": 889
|
||||
},
|
||||
"quality": {
|
||||
"quality": {
|
||||
"id": 7,
|
||||
"name": "SD"
|
||||
"episode":{
|
||||
"seriesId":17,
|
||||
"episodeFileId":0,
|
||||
"seasonNumber":1,
|
||||
"episodeNumber":1,
|
||||
"title":"The New Housekeeper",
|
||||
"airDate":"1960-10-03",
|
||||
"airDateUtc":"1960-10-03T01:00:00Z",
|
||||
"overview":"Sheriff Andy Taylor and his young son Opie are in need of a new housekeeper. Andy's Aunt Bee looks like the perfect candidate and moves in, but her presence causes friction with Opie.",
|
||||
"hasFile":false,
|
||||
"monitored":false,
|
||||
"absoluteEpisodeNumber":1,
|
||||
"unverifiedSceneNumbering":false,
|
||||
"id":889
|
||||
},
|
||||
"revision": {
|
||||
"version": 1,
|
||||
"real": 0
|
||||
}
|
||||
},
|
||||
"size": 4472186820,
|
||||
"title": "The.Andy.Griffith.Show.S01E01.x264-GROUP",
|
||||
"sizeleft": 0,
|
||||
"timeleft": "00:00:00",
|
||||
"estimatedCompletionTime": "2016-02-05T22:46:52.440104Z",
|
||||
"status": "Downloading",
|
||||
"trackedDownloadStatus": "Ok",
|
||||
"statusMessages": [],
|
||||
"downloadId": "SABnzbd_nzo_Mq2f_b",
|
||||
"protocol": "usenet",
|
||||
"id": 1503378561
|
||||
}
|
||||
]
|
||||
"quality":{
|
||||
"quality":{
|
||||
"id":7,
|
||||
"name":"SD"
|
||||
},
|
||||
"revision":{
|
||||
"version":1,
|
||||
"real":0
|
||||
}
|
||||
},
|
||||
"size":4472186820,
|
||||
"title":"The.Andy.Griffith.Show.S01E01.x264-GROUP",
|
||||
"sizeleft":0,
|
||||
"timeleft":"00:00:00",
|
||||
"estimatedCompletionTime":"2016-02-05T22:46:52.440104Z",
|
||||
"status":"Downloading",
|
||||
"trackedDownloadStatus":"Ok",
|
||||
"statusMessages":[
|
||||
|
||||
],
|
||||
"downloadId":"SABnzbd_nzo_Mq2f_b",
|
||||
"protocol":"usenet",
|
||||
"id":1503378561
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
@ -3,11 +3,6 @@
|
|||
"title": "The Andy Griffith Show",
|
||||
"alternateTitles": [],
|
||||
"sortTitle": "andy griffith show",
|
||||
"seasonCount": 8,
|
||||
"totalEpisodeCount": 253,
|
||||
"episodeCount": 0,
|
||||
"episodeFileCount": 0,
|
||||
"sizeOnDisk": 0,
|
||||
"status": "ended",
|
||||
"overview": "Down-home humor and an endearing cast of characters helped make The Andy Griffith Show one of the most beloved comedies in the history of TV. The show centered around widower Andy Taylor, who divided his time between raising his young son Opie, and his job as sheriff of the sleepy North Carolina town, Mayberry. Andy and Opie live with Andy's Aunt Bee, who serves as a surrogate mother to both father and son. Andy's nervous cousin, Barney Fife, is his deputy sheriff whose incompetence is tolerated because Mayberry is virtually crime-free.",
|
||||
"network": "CBS",
|
||||
|
@ -158,6 +153,14 @@
|
|||
"value": 8.6
|
||||
},
|
||||
"qualityProfileId": 2,
|
||||
"statistics": {
|
||||
"seasonCount": 8,
|
||||
"episodeFileCount": 0,
|
||||
"episodeCount": 0,
|
||||
"totalEpisodeCount": 253,
|
||||
"sizeOnDisk": 0,
|
||||
"percentOfEpisodes": 0.0
|
||||
},
|
||||
"id": 105
|
||||
}
|
||||
]
|
||||
|
|
29
tests/components/sonarr/fixtures/system-status.json
Normal file
29
tests/components/sonarr/fixtures/system-status.json
Normal file
|
@ -0,0 +1,29 @@
|
|||
{
|
||||
"appName": "Sonarr",
|
||||
"version": "3.0.6.1451",
|
||||
"buildTime": "2022-01-23T16:51:56Z",
|
||||
"isDebug": false,
|
||||
"isProduction": true,
|
||||
"isAdmin": false,
|
||||
"isUserInteractive": false,
|
||||
"startupPath": "/app/sonarr/bin",
|
||||
"appData": "/config",
|
||||
"osName": "ubuntu",
|
||||
"osVersion": "20.04",
|
||||
"isMonoRuntime": true,
|
||||
"isMono": true,
|
||||
"isLinux": true,
|
||||
"isOsx": false,
|
||||
"isWindows": false,
|
||||
"mode": "console",
|
||||
"branch": "develop",
|
||||
"authentication": "forms",
|
||||
"sqliteVersion": "3.31.1",
|
||||
"urlBase": "",
|
||||
"runtimeVersion": "6.12.0.122",
|
||||
"runtimeName": "mono",
|
||||
"startTime": "2022-02-01T22:10:11.956137Z",
|
||||
"packageVersion": "3.0.6.1451-ls247",
|
||||
"packageAuthor": "[linuxserver.io](https://linuxserver.io)",
|
||||
"packageUpdateMechanism": "docker"
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"page": 1,
|
||||
"pageSize": 10,
|
||||
"pageSize": 50,
|
||||
"sortKey": "airDateUtc",
|
||||
"sortDirection": "descending",
|
||||
"totalRecords": 2,
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
"""Test the Sonarr config flow."""
|
||||
from unittest.mock import MagicMock, patch
|
||||
|
||||
from sonarr import SonarrAccessRestricted, SonarrError
|
||||
from aiopyarr import ArrAuthenticationException, ArrException
|
||||
|
||||
from homeassistant.components.sonarr.const import (
|
||||
CONF_UPCOMING_DAYS,
|
||||
|
@ -11,7 +11,7 @@ from homeassistant.components.sonarr.const import (
|
|||
DOMAIN,
|
||||
)
|
||||
from homeassistant.config_entries import SOURCE_REAUTH, SOURCE_USER
|
||||
from homeassistant.const import CONF_API_KEY, CONF_HOST, CONF_SOURCE, CONF_VERIFY_SSL
|
||||
from homeassistant.const import CONF_API_KEY, CONF_SOURCE, CONF_URL, CONF_VERIFY_SSL
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.data_entry_flow import (
|
||||
RESULT_TYPE_ABORT,
|
||||
|
@ -38,7 +38,7 @@ async def test_cannot_connect(
|
|||
hass: HomeAssistant, mock_sonarr_config_flow: MagicMock
|
||||
) -> None:
|
||||
"""Test we show user form on connection error."""
|
||||
mock_sonarr_config_flow.update.side_effect = SonarrError
|
||||
mock_sonarr_config_flow.async_get_system_status.side_effect = ArrException
|
||||
|
||||
user_input = MOCK_USER_INPUT.copy()
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
|
@ -56,7 +56,9 @@ async def test_invalid_auth(
|
|||
hass: HomeAssistant, mock_sonarr_config_flow: MagicMock
|
||||
) -> None:
|
||||
"""Test we show user form on invalid auth."""
|
||||
mock_sonarr_config_flow.update.side_effect = SonarrAccessRestricted
|
||||
mock_sonarr_config_flow.async_get_system_status.side_effect = (
|
||||
ArrAuthenticationException
|
||||
)
|
||||
|
||||
user_input = MOCK_USER_INPUT.copy()
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
|
@ -74,7 +76,7 @@ async def test_unknown_error(
|
|||
hass: HomeAssistant, mock_sonarr_config_flow: MagicMock
|
||||
) -> None:
|
||||
"""Test we show user form on unknown error."""
|
||||
mock_sonarr_config_flow.update.side_effect = Exception
|
||||
mock_sonarr_config_flow.async_get_system_status.side_effect = Exception
|
||||
|
||||
user_input = MOCK_USER_INPUT.copy()
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
|
@ -153,7 +155,7 @@ async def test_full_user_flow_implementation(
|
|||
assert result["title"] == "192.168.1.189"
|
||||
|
||||
assert result["data"]
|
||||
assert result["data"][CONF_HOST] == "192.168.1.189"
|
||||
assert result["data"][CONF_URL] == "http://192.168.1.189:8989"
|
||||
|
||||
|
||||
async def test_full_user_flow_advanced_options(
|
||||
|
@ -183,7 +185,7 @@ async def test_full_user_flow_advanced_options(
|
|||
assert result["title"] == "192.168.1.189"
|
||||
|
||||
assert result["data"]
|
||||
assert result["data"][CONF_HOST] == "192.168.1.189"
|
||||
assert result["data"][CONF_URL] == "http://192.168.1.189:8989"
|
||||
assert result["data"][CONF_VERIFY_SSL]
|
||||
|
||||
|
||||
|
|
|
@ -1,11 +1,19 @@
|
|||
"""Tests for the Sonsrr integration."""
|
||||
from unittest.mock import MagicMock, patch
|
||||
|
||||
from sonarr import SonarrAccessRestricted, SonarrError
|
||||
from aiopyarr import ArrAuthenticationException, ArrException
|
||||
|
||||
from homeassistant.components.sonarr.const import DOMAIN
|
||||
from homeassistant.components.sonarr.const import CONF_BASE_PATH, DOMAIN
|
||||
from homeassistant.config_entries import SOURCE_REAUTH, ConfigEntryState
|
||||
from homeassistant.const import CONF_SOURCE
|
||||
from homeassistant.const import (
|
||||
CONF_API_KEY,
|
||||
CONF_HOST,
|
||||
CONF_PORT,
|
||||
CONF_SOURCE,
|
||||
CONF_SSL,
|
||||
CONF_URL,
|
||||
CONF_VERIFY_SSL,
|
||||
)
|
||||
from homeassistant.core import HomeAssistant
|
||||
|
||||
from tests.common import MockConfigEntry
|
||||
|
@ -17,7 +25,7 @@ async def test_config_entry_not_ready(
|
|||
mock_sonarr: MagicMock,
|
||||
) -> None:
|
||||
"""Test the configuration entry not ready."""
|
||||
mock_sonarr.update.side_effect = SonarrError
|
||||
mock_sonarr.async_get_system_status.side_effect = ArrException
|
||||
|
||||
mock_config_entry.add_to_hass(hass)
|
||||
await hass.config_entries.async_setup(mock_config_entry.entry_id)
|
||||
|
@ -32,7 +40,7 @@ async def test_config_entry_reauth(
|
|||
mock_sonarr: MagicMock,
|
||||
) -> None:
|
||||
"""Test the configuration entry needing to be re-authenticated."""
|
||||
mock_sonarr.update.side_effect = SonarrAccessRestricted
|
||||
mock_sonarr.async_get_system_status.side_effect = ArrAuthenticationException
|
||||
|
||||
with patch.object(hass.config_entries.flow, "async_init") as mock_flow_init:
|
||||
mock_config_entry.add_to_hass(hass)
|
||||
|
@ -77,3 +85,34 @@ async def test_unload_config_entry(
|
|||
|
||||
assert mock_config_entry.state is ConfigEntryState.NOT_LOADED
|
||||
assert mock_config_entry.entry_id not in hass.data[DOMAIN]
|
||||
|
||||
|
||||
async def test_migrate_config_entry(hass: HomeAssistant):
|
||||
"""Test successful migration of entry data."""
|
||||
legacy_config = {
|
||||
CONF_API_KEY: "MOCK_API_KEY",
|
||||
CONF_HOST: "1.2.3.4",
|
||||
CONF_PORT: 8989,
|
||||
CONF_SSL: False,
|
||||
CONF_VERIFY_SSL: False,
|
||||
CONF_BASE_PATH: "/base/",
|
||||
}
|
||||
entry = MockConfigEntry(domain=DOMAIN, data=legacy_config)
|
||||
|
||||
assert entry.data == legacy_config
|
||||
assert entry.version == 1
|
||||
assert not entry.unique_id
|
||||
|
||||
await entry.async_migrate(hass)
|
||||
|
||||
assert entry.data == {
|
||||
CONF_API_KEY: "MOCK_API_KEY",
|
||||
CONF_HOST: "1.2.3.4",
|
||||
CONF_PORT: 8989,
|
||||
CONF_SSL: False,
|
||||
CONF_VERIFY_SSL: False,
|
||||
CONF_BASE_PATH: "/base/",
|
||||
CONF_URL: "http://1.2.3.4:8989/base",
|
||||
}
|
||||
assert entry.version == 2
|
||||
assert not entry.unique_id
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
from datetime import timedelta
|
||||
from unittest.mock import MagicMock, patch
|
||||
|
||||
from aiopyarr import ArrException
|
||||
import pytest
|
||||
from sonarr import SonarrError
|
||||
|
||||
from homeassistant.components.sensor import DOMAIN as SENSOR_DOMAIN
|
||||
from homeassistant.components.sonarr.const import DOMAIN
|
||||
|
@ -96,8 +96,11 @@ async def test_sensors(
|
|||
assert state
|
||||
assert state.attributes.get(ATTR_ICON) == "mdi:television"
|
||||
assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == "Episodes"
|
||||
assert state.attributes.get("Bob's Burgers S04E11") == "2014-01-26"
|
||||
assert state.attributes.get("The Andy Griffith Show S01E01") == "1960-10-03"
|
||||
assert state.attributes.get("Bob's Burgers S04E11") == "2014-01-27T01:30:00+00:00"
|
||||
assert (
|
||||
state.attributes.get("The Andy Griffith Show S01E01")
|
||||
== "1960-10-03T01:00:00+00:00"
|
||||
)
|
||||
assert state.state == "2"
|
||||
|
||||
|
||||
|
@ -141,44 +144,49 @@ async def test_availability(
|
|||
await hass.config_entries.async_setup(mock_config_entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert hass.states.get(UPCOMING_ENTITY_ID)
|
||||
assert hass.states.get(UPCOMING_ENTITY_ID).state == "1"
|
||||
|
||||
# state to unavailable
|
||||
mock_sonarr.calendar.side_effect = SonarrError
|
||||
mock_sonarr.async_get_calendar.side_effect = ArrException
|
||||
|
||||
future = now + timedelta(minutes=1)
|
||||
with patch("homeassistant.util.dt.utcnow", return_value=future):
|
||||
async_fire_time_changed(hass, future)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert hass.states.get(UPCOMING_ENTITY_ID)
|
||||
assert hass.states.get(UPCOMING_ENTITY_ID).state == STATE_UNAVAILABLE
|
||||
|
||||
# state to available
|
||||
mock_sonarr.calendar.side_effect = None
|
||||
mock_sonarr.async_get_calendar.side_effect = None
|
||||
|
||||
future += timedelta(minutes=1)
|
||||
with patch("homeassistant.util.dt.utcnow", return_value=future):
|
||||
async_fire_time_changed(hass, future)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert hass.states.get(UPCOMING_ENTITY_ID)
|
||||
assert hass.states.get(UPCOMING_ENTITY_ID).state == "1"
|
||||
|
||||
# state to unavailable
|
||||
mock_sonarr.calendar.side_effect = SonarrError
|
||||
mock_sonarr.async_get_calendar.side_effect = ArrException
|
||||
|
||||
future += timedelta(minutes=1)
|
||||
with patch("homeassistant.util.dt.utcnow", return_value=future):
|
||||
async_fire_time_changed(hass, future)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert hass.states.get(UPCOMING_ENTITY_ID)
|
||||
assert hass.states.get(UPCOMING_ENTITY_ID).state == STATE_UNAVAILABLE
|
||||
|
||||
# state to available
|
||||
mock_sonarr.calendar.side_effect = None
|
||||
mock_sonarr.async_get_calendar.side_effect = None
|
||||
|
||||
future += timedelta(minutes=1)
|
||||
with patch("homeassistant.util.dt.utcnow", return_value=future):
|
||||
async_fire_time_changed(hass, future)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert hass.states.get(UPCOMING_ENTITY_ID)
|
||||
assert hass.states.get(UPCOMING_ENTITY_ID).state == "1"
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue