Fix RootFolder not iterable in Radarr (#97537)

Co-authored-by: epenet <6771947+epenet@users.noreply.github.com>
This commit is contained in:
Joost Lekkerkerker 2023-07-31 18:44:03 +02:00 committed by GitHub
parent 085e274f44
commit c2e9fd85c2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 189 additions and 28 deletions

View file

@ -3,7 +3,7 @@ from __future__ import annotations
from abc import ABC, abstractmethod from abc import ABC, abstractmethod
from datetime import timedelta from datetime import timedelta
from typing import Generic, TypeVar, cast from typing import Generic, TypeVar
from aiopyarr import Health, RadarrMovie, RootFolder, SystemStatus, exceptions from aiopyarr import Health, RadarrMovie, RootFolder, SystemStatus, exceptions
from aiopyarr.models.host_configuration import PyArrHostConfiguration from aiopyarr.models.host_configuration import PyArrHostConfiguration
@ -71,7 +71,10 @@ class DiskSpaceDataUpdateCoordinator(RadarrDataUpdateCoordinator[list[RootFolder
async def _fetch_data(self) -> list[RootFolder]: async def _fetch_data(self) -> list[RootFolder]:
"""Fetch the data.""" """Fetch the data."""
return cast(list[RootFolder], await self.api_client.async_get_root_folders()) root_folders = await self.api_client.async_get_root_folders()
if isinstance(root_folders, RootFolder):
root_folders = [root_folders]
return root_folders
class HealthDataUpdateCoordinator(RadarrDataUpdateCoordinator[list[Health]]): class HealthDataUpdateCoordinator(RadarrDataUpdateCoordinator[list[Health]]):
@ -87,4 +90,7 @@ class MoviesDataUpdateCoordinator(RadarrDataUpdateCoordinator[int]):
async def _fetch_data(self) -> int: async def _fetch_data(self) -> int:
"""Fetch the movies data.""" """Fetch the movies data."""
return len(cast(list[RadarrMovie], await self.api_client.async_get_movies())) movies = await self.api_client.async_get_movies()
if isinstance(movies, RadarrMovie):
return 1
return len(movies)

View file

@ -41,6 +41,7 @@ def mock_connection(
error: bool = False, error: bool = False,
invalid_auth: bool = False, invalid_auth: bool = False,
windows: bool = False, windows: bool = False,
single_return: bool = False,
) -> None: ) -> None:
"""Mock radarr connection.""" """Mock radarr connection."""
if error: if error:
@ -75,22 +76,27 @@ def mock_connection(
headers={"Content-Type": CONTENT_TYPE_JSON}, headers={"Content-Type": CONTENT_TYPE_JSON},
) )
root_folder_fixture = "rootfolder-linux"
if windows: if windows:
root_folder_fixture = "rootfolder-windows"
if single_return:
root_folder_fixture = f"single-{root_folder_fixture}"
aioclient_mock.get( aioclient_mock.get(
f"{url}/api/v3/rootfolder", f"{url}/api/v3/rootfolder",
text=load_fixture("radarr/rootfolder-windows.json"), text=load_fixture(f"radarr/{root_folder_fixture}.json"),
headers={"Content-Type": CONTENT_TYPE_JSON},
)
else:
aioclient_mock.get(
f"{url}/api/v3/rootfolder",
text=load_fixture("radarr/rootfolder-linux.json"),
headers={"Content-Type": CONTENT_TYPE_JSON}, headers={"Content-Type": CONTENT_TYPE_JSON},
) )
movie_fixture = "movie"
if single_return:
movie_fixture = f"single-{movie_fixture}"
aioclient_mock.get( aioclient_mock.get(
f"{url}/api/v3/movie", f"{url}/api/v3/movie",
text=load_fixture("radarr/movie.json"), text=load_fixture(f"radarr/{movie_fixture}.json"),
headers={"Content-Type": CONTENT_TYPE_JSON}, headers={"Content-Type": CONTENT_TYPE_JSON},
) )
@ -139,6 +145,7 @@ async def setup_integration(
connection_error: bool = False, connection_error: bool = False,
invalid_auth: bool = False, invalid_auth: bool = False,
windows: bool = False, windows: bool = False,
single_return: bool = False,
) -> MockConfigEntry: ) -> MockConfigEntry:
"""Set up the radarr integration in Home Assistant.""" """Set up the radarr integration in Home Assistant."""
entry = MockConfigEntry( entry = MockConfigEntry(
@ -159,6 +166,7 @@ async def setup_integration(
error=connection_error, error=connection_error,
invalid_auth=invalid_auth, invalid_auth=invalid_auth,
windows=windows, windows=windows,
single_return=single_return,
) )
if not skip_entry_setup: if not skip_entry_setup:
@ -183,7 +191,7 @@ def patch_radarr():
def create_entry(hass: HomeAssistant) -> MockConfigEntry: def create_entry(hass: HomeAssistant) -> MockConfigEntry:
"""Create Efergy entry in Home Assistant.""" """Create Radarr entry in Home Assistant."""
entry = MockConfigEntry( entry = MockConfigEntry(
domain=DOMAIN, domain=DOMAIN,
data={ data={

View file

@ -0,0 +1,116 @@
{
"id": 0,
"title": "string",
"originalTitle": "string",
"alternateTitles": [
{
"sourceType": "tmdb",
"movieId": 1,
"title": "string",
"sourceId": 0,
"votes": 0,
"voteCount": 0,
"language": {
"id": 1,
"name": "English"
},
"id": 1
}
],
"sortTitle": "string",
"sizeOnDisk": 0,
"overview": "string",
"inCinemas": "2020-11-06T00:00:00Z",
"physicalRelease": "2019-03-19T00:00:00Z",
"images": [
{
"coverType": "poster",
"url": "string",
"remoteUrl": "string"
}
],
"website": "string",
"year": 0,
"hasFile": true,
"youTubeTrailerId": "string",
"studio": "string",
"path": "string",
"rootFolderPath": "string",
"qualityProfileId": 0,
"monitored": true,
"minimumAvailability": "announced",
"isAvailable": true,
"folderName": "string",
"runtime": 0,
"cleanTitle": "string",
"imdbId": "string",
"tmdbId": 0,
"titleSlug": "string",
"certification": "string",
"genres": ["string"],
"tags": [0],
"added": "2018-12-28T05:56:49Z",
"ratings": {
"votes": 0,
"value": 0
},
"movieFile": {
"movieId": 0,
"relativePath": "string",
"path": "string",
"size": 916662234,
"dateAdded": "2020-11-26T02:00:35Z",
"indexerFlags": 1,
"quality": {
"quality": {
"id": 14,
"name": "WEBRip-720p",
"source": "webrip",
"resolution": 720,
"modifier": "none"
},
"revision": {
"version": 1,
"real": 0,
"isRepack": false
}
},
"mediaInfo": {
"audioBitrate": 0,
"audioChannels": 2,
"audioCodec": "AAC",
"audioLanguages": "",
"audioStreamCount": 1,
"videoBitDepth": 8,
"videoBitrate": 1000000,
"videoCodec": "x264",
"videoFps": 25.0,
"resolution": "1280x534",
"runTime": "1:49:06",
"scanType": "Progressive",
"subtitles": ""
},
"originalFilePath": "string",
"qualityCutoffNotMet": true,
"languages": [
{
"id": 26,
"name": "Hindi"
}
],
"edition": "",
"id": 35361
},
"collection": {
"name": "string",
"tmdbId": 0,
"images": [
{
"coverType": "poster",
"url": "string",
"remoteUrl": "string"
}
]
},
"status": "deleted"
}

View file

@ -0,0 +1,6 @@
{
"path": "/downloads",
"freeSpace": 282500064232,
"unmappedFolders": [],
"id": 1
}

View file

@ -0,0 +1,6 @@
{
"path": "D:\\Downloads\\TV",
"freeSpace": 282500064232,
"unmappedFolders": [],
"id": 1
}

View file

@ -1,4 +1,5 @@
"""The tests for Radarr sensor platform.""" """The tests for Radarr sensor platform."""
import pytest
from homeassistant.components.sensor import SensorDeviceClass from homeassistant.components.sensor import SensorDeviceClass
from homeassistant.const import ATTR_DEVICE_CLASS, ATTR_UNIT_OF_MEASUREMENT from homeassistant.const import ATTR_DEVICE_CLASS, ATTR_UNIT_OF_MEASUREMENT
@ -9,15 +10,43 @@ from . import setup_integration
from tests.test_util.aiohttp import AiohttpClientMocker from tests.test_util.aiohttp import AiohttpClientMocker
@pytest.mark.parametrize(
("windows", "single", "root_folder"),
[
(
False,
False,
"downloads",
),
(
False,
True,
"downloads",
),
(
True,
False,
"tv",
),
(
True,
True,
"tv",
),
],
)
async def test_sensors( async def test_sensors(
hass: HomeAssistant, hass: HomeAssistant,
aioclient_mock: AiohttpClientMocker, aioclient_mock: AiohttpClientMocker,
entity_registry_enabled_by_default: None, entity_registry_enabled_by_default: None,
windows: bool,
single: bool,
root_folder: str,
) -> None: ) -> None:
"""Test for successfully setting up the Radarr platform.""" """Test for successfully setting up the Radarr platform."""
await setup_integration(hass, aioclient_mock) await setup_integration(hass, aioclient_mock, windows=windows, single_return=single)
state = hass.states.get("sensor.mock_title_disk_space_downloads") state = hass.states.get(f"sensor.mock_title_disk_space_{root_folder}")
assert state.state == "263.10" assert state.state == "263.10"
assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == "GB" assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == "GB"
state = hass.states.get("sensor.mock_title_movies") state = hass.states.get("sensor.mock_title_movies")
@ -26,13 +55,3 @@ async def test_sensors(
state = hass.states.get("sensor.mock_title_start_time") state = hass.states.get("sensor.mock_title_start_time")
assert state.state == "2020-09-01T23:50:20+00:00" assert state.state == "2020-09-01T23:50:20+00:00"
assert state.attributes.get(ATTR_DEVICE_CLASS) == SensorDeviceClass.TIMESTAMP assert state.attributes.get(ATTR_DEVICE_CLASS) == SensorDeviceClass.TIMESTAMP
async def test_windows(
hass: HomeAssistant, aioclient_mock: AiohttpClientMocker
) -> None:
"""Test for successfully setting up the Radarr platform on Windows."""
await setup_integration(hass, aioclient_mock, windows=True)
state = hass.states.get("sensor.mock_title_disk_space_tv")
assert state.state == "263.10"