Remove deprecated Plex YAML config (#36388)
parent
3b606504a8
commit
9aac8482d5
|
@ -9,18 +9,12 @@ from plexwebsocket import PlexWebsocket
|
|||
import requests.exceptions
|
||||
import voluptuous as vol
|
||||
|
||||
from homeassistant import config_entries
|
||||
from homeassistant.components.media_player import DOMAIN as MP_DOMAIN
|
||||
from homeassistant.components.media_player.const import (
|
||||
ATTR_MEDIA_CONTENT_ID,
|
||||
ATTR_MEDIA_CONTENT_TYPE,
|
||||
)
|
||||
from homeassistant.const import (
|
||||
ATTR_ENTITY_ID,
|
||||
CONF_HOST,
|
||||
CONF_PORT,
|
||||
CONF_SSL,
|
||||
CONF_TOKEN,
|
||||
CONF_URL,
|
||||
CONF_VERIFY_SSL,
|
||||
EVENT_HOMEASSISTANT_STOP,
|
||||
|
@ -34,19 +28,12 @@ from homeassistant.helpers.dispatcher import (
|
|||
)
|
||||
|
||||
from .const import (
|
||||
CONF_IGNORE_NEW_SHARED_USERS,
|
||||
CONF_SERVER,
|
||||
CONF_SERVER_IDENTIFIER,
|
||||
CONF_SHOW_ALL_CONTROLS,
|
||||
CONF_USE_EPISODE_ART,
|
||||
DEFAULT_PORT,
|
||||
DEFAULT_SSL,
|
||||
DEFAULT_VERIFY_SSL,
|
||||
DISPATCHERS,
|
||||
DOMAIN as PLEX_DOMAIN,
|
||||
PLATFORMS,
|
||||
PLATFORMS_COMPLETED,
|
||||
PLEX_MEDIA_PLAYER_OPTIONS,
|
||||
PLEX_SERVER_CONFIG,
|
||||
PLEX_UPDATE_PLATFORMS_SIGNAL,
|
||||
SERVERS,
|
||||
|
@ -56,40 +43,6 @@ from .const import (
|
|||
from .errors import ShouldUpdateConfigEntry
|
||||
from .server import PlexServer
|
||||
|
||||
MEDIA_PLAYER_SCHEMA = vol.All(
|
||||
cv.deprecated(CONF_SHOW_ALL_CONTROLS, invalidation_version="0.110"),
|
||||
vol.Schema(
|
||||
{
|
||||
vol.Optional(CONF_USE_EPISODE_ART, default=False): cv.boolean,
|
||||
vol.Optional(CONF_SHOW_ALL_CONTROLS): cv.boolean,
|
||||
vol.Optional(CONF_IGNORE_NEW_SHARED_USERS, default=False): cv.boolean,
|
||||
}
|
||||
),
|
||||
)
|
||||
|
||||
SERVER_CONFIG_SCHEMA = vol.Schema(
|
||||
vol.All(
|
||||
{
|
||||
vol.Optional(CONF_HOST): cv.string,
|
||||
vol.Optional(CONF_PORT, default=DEFAULT_PORT): cv.port,
|
||||
vol.Optional(CONF_TOKEN): cv.string,
|
||||
vol.Optional(CONF_SERVER): cv.string,
|
||||
vol.Optional(CONF_SSL, default=DEFAULT_SSL): cv.boolean,
|
||||
vol.Optional(CONF_VERIFY_SSL, default=DEFAULT_VERIFY_SSL): cv.boolean,
|
||||
vol.Optional(MP_DOMAIN, default={}): MEDIA_PLAYER_SCHEMA,
|
||||
},
|
||||
cv.has_at_least_one_key(CONF_HOST, CONF_TOKEN),
|
||||
)
|
||||
)
|
||||
|
||||
CONFIG_SCHEMA = vol.Schema(
|
||||
vol.All(
|
||||
cv.deprecated(PLEX_DOMAIN, invalidation_version="0.111"),
|
||||
{PLEX_DOMAIN: SERVER_CONFIG_SCHEMA},
|
||||
),
|
||||
extra=vol.ALLOW_EXTRA,
|
||||
)
|
||||
|
||||
_LOGGER = logging.getLogger(__package__)
|
||||
|
||||
|
||||
|
@ -100,32 +53,9 @@ async def async_setup(hass, config):
|
|||
{SERVERS: {}, DISPATCHERS: {}, WEBSOCKETS: {}, PLATFORMS_COMPLETED: {}},
|
||||
)
|
||||
|
||||
plex_config = config.get(PLEX_DOMAIN, {})
|
||||
if plex_config:
|
||||
_async_setup_plex(hass, plex_config)
|
||||
|
||||
return True
|
||||
|
||||
|
||||
def _async_setup_plex(hass, config):
|
||||
"""Pass configuration to a config flow."""
|
||||
server_config = dict(config)
|
||||
if MP_DOMAIN in server_config:
|
||||
hass.data.setdefault(PLEX_MEDIA_PLAYER_OPTIONS, server_config.pop(MP_DOMAIN))
|
||||
if CONF_HOST in server_config:
|
||||
protocol = "https" if server_config.pop(CONF_SSL) else "http"
|
||||
server_config[
|
||||
CONF_URL
|
||||
] = f"{protocol}://{server_config.pop(CONF_HOST)}:{server_config.pop(CONF_PORT)}"
|
||||
hass.async_create_task(
|
||||
hass.config_entries.flow.async_init(
|
||||
PLEX_DOMAIN,
|
||||
context={"source": config_entries.SOURCE_IMPORT},
|
||||
data=server_config,
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
async def async_setup_entry(hass, entry):
|
||||
"""Set up Plex from a config entry."""
|
||||
server_config = entry.data[PLEX_SERVER_CONFIG]
|
||||
|
@ -135,14 +65,6 @@ async def async_setup_entry(hass, entry):
|
|||
entry, unique_id=entry.data[CONF_SERVER_IDENTIFIER]
|
||||
)
|
||||
|
||||
if MP_DOMAIN not in entry.options:
|
||||
options = dict(entry.options)
|
||||
options.setdefault(
|
||||
MP_DOMAIN,
|
||||
hass.data.get(PLEX_MEDIA_PLAYER_OPTIONS) or MEDIA_PLAYER_SCHEMA({}),
|
||||
)
|
||||
hass.config_entries.async_update_entry(entry, options=options)
|
||||
|
||||
plex_server = PlexServer(
|
||||
hass, server_config, entry.data[CONF_SERVER_IDENTIFIER], entry.options
|
||||
)
|
||||
|
|
|
@ -170,10 +170,6 @@ class PlexFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
|
|||
"""Validate a provided configuration."""
|
||||
errors = {}
|
||||
self.current_login = server_config
|
||||
is_importing = (
|
||||
self.context["source"] # pylint: disable=no-member
|
||||
== config_entries.SOURCE_IMPORT
|
||||
)
|
||||
|
||||
plex_server = PlexServer(self.hass, server_config)
|
||||
try:
|
||||
|
@ -196,11 +192,6 @@ class PlexFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
|
|||
errors[CONF_HOST] = "not_found"
|
||||
|
||||
except ServerNotSpecified as available_servers:
|
||||
if is_importing:
|
||||
_LOGGER.warning(
|
||||
"Imported configuration has multiple available Plex servers. Specify server in configuration or add a new Integration."
|
||||
)
|
||||
return self.async_abort(reason="non-interactive")
|
||||
self.available_servers = available_servers.args[0]
|
||||
return await self.async_step_select_server()
|
||||
|
||||
|
@ -209,8 +200,6 @@ class PlexFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
|
|||
return self.async_abort(reason="unknown")
|
||||
|
||||
if errors:
|
||||
if is_importing:
|
||||
return self.async_abort(reason="non-interactive")
|
||||
if self._manual:
|
||||
return await self.async_step_manual_setup(
|
||||
user_input=server_config, errors=errors
|
||||
|
@ -274,11 +263,6 @@ class PlexFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
|
|||
errors={},
|
||||
)
|
||||
|
||||
async def async_step_import(self, import_config):
|
||||
"""Import from Plex configuration."""
|
||||
_LOGGER.debug("Imported Plex configuration")
|
||||
return await self.async_step_server_validate(import_config)
|
||||
|
||||
async def async_step_integration_discovery(self, discovery_info):
|
||||
"""Handle GDM discovery."""
|
||||
machine_identifier = discovery_info["data"]["Resource-Identifier"]
|
||||
|
|
|
@ -16,7 +16,6 @@ PLATFORMS_COMPLETED = "platforms_completed"
|
|||
SERVERS = "servers"
|
||||
WEBSOCKETS = "websockets"
|
||||
|
||||
PLEX_MEDIA_PLAYER_OPTIONS = "plex_mp_options"
|
||||
PLEX_SERVER_CONFIG = "server_config"
|
||||
|
||||
PLEX_NEW_MP_SIGNAL = "plex_new_mp_signal.{}"
|
||||
|
@ -27,7 +26,6 @@ PLEX_UPDATE_SENSOR_SIGNAL = "plex_update_sensor_signal.{}"
|
|||
CONF_SERVER = "server"
|
||||
CONF_SERVER_IDENTIFIER = "server_id"
|
||||
CONF_USE_EPISODE_ART = "use_episode_art"
|
||||
CONF_SHOW_ALL_CONTROLS = "show_all_controls"
|
||||
CONF_IGNORE_NEW_SHARED_USERS = "ignore_new_shared_users"
|
||||
CONF_IGNORE_PLEX_WEB_CLIENTS = "ignore_plex_web_clients"
|
||||
CONF_MONITORED_USERS = "monitored_users"
|
||||
|
|
|
@ -353,7 +353,7 @@ class PlexServer:
|
|||
@property
|
||||
def option_use_episode_art(self):
|
||||
"""Return use_episode_art option."""
|
||||
return self.options[MP_DOMAIN][CONF_USE_EPISODE_ART]
|
||||
return self.options[MP_DOMAIN].get(CONF_USE_EPISODE_ART, False)
|
||||
|
||||
@property
|
||||
def option_monitored_users(self):
|
||||
|
|
|
@ -41,8 +41,6 @@
|
|||
"all_configured": "All linked servers already configured",
|
||||
"already_configured": "This Plex server is already configured",
|
||||
"already_in_progress": "Plex is being configured",
|
||||
"invalid_import": "Imported configuration is invalid",
|
||||
"non-interactive": "Non-interactive import",
|
||||
"token_request_timeout": "Timed out obtaining token",
|
||||
"unknown": "Failed for unknown reason"
|
||||
}
|
||||
|
@ -60,4 +58,4 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,7 +37,7 @@ from homeassistant.const import (
|
|||
from homeassistant.helpers.dispatcher import async_dispatcher_send
|
||||
|
||||
from .const import DEFAULT_DATA, DEFAULT_OPTIONS, MOCK_SERVERS, MOCK_TOKEN
|
||||
from .mock_classes import MockGDM, MockPlexAccount, MockPlexServer
|
||||
from .mock_classes import MockGDM, MockPlexAccount, MockPlexServer, MockResource
|
||||
|
||||
from tests.async_mock import patch
|
||||
from tests.common import MockConfigEntry
|
||||
|
@ -75,45 +75,42 @@ async def test_bad_credentials(hass):
|
|||
assert result["errors"][CONF_TOKEN] == "faulty_credentials"
|
||||
|
||||
|
||||
async def test_import_success(hass):
|
||||
"""Test a successful configuration import."""
|
||||
|
||||
mock_plex_server = MockPlexServer()
|
||||
|
||||
with patch("plexapi.server.PlexServer", return_value=mock_plex_server):
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
DOMAIN,
|
||||
context={"source": "import"},
|
||||
data={
|
||||
CONF_TOKEN: MOCK_TOKEN,
|
||||
CONF_URL: f"https://{MOCK_SERVERS[0][CONF_HOST]}:{MOCK_SERVERS[0][CONF_PORT]}",
|
||||
},
|
||||
)
|
||||
|
||||
assert result["type"] == "create_entry"
|
||||
assert result["title"] == mock_plex_server.friendlyName
|
||||
assert result["data"][CONF_SERVER] == mock_plex_server.friendlyName
|
||||
assert result["data"][CONF_SERVER_IDENTIFIER] == mock_plex_server.machineIdentifier
|
||||
assert result["data"][PLEX_SERVER_CONFIG][CONF_URL] == mock_plex_server._baseurl
|
||||
assert result["data"][PLEX_SERVER_CONFIG][CONF_TOKEN] == MOCK_TOKEN
|
||||
|
||||
|
||||
async def test_import_bad_hostname(hass):
|
||||
async def test_bad_hostname(hass):
|
||||
"""Test when an invalid address is provided."""
|
||||
mock_plex_account = MockPlexAccount()
|
||||
|
||||
await async_process_ha_core_config(
|
||||
hass, {"internal_url": "http://example.local:8123"},
|
||||
)
|
||||
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
DOMAIN, context={"source": "user"}
|
||||
)
|
||||
assert result["type"] == "form"
|
||||
assert result["step_id"] == "user"
|
||||
|
||||
with patch(
|
||||
"plexapi.server.PlexServer", side_effect=requests.exceptions.ConnectionError
|
||||
"plexapi.myplex.MyPlexAccount", return_value=mock_plex_account
|
||||
), patch.object(
|
||||
MockResource, "connect", side_effect=requests.exceptions.ConnectionError
|
||||
), patch(
|
||||
"plexauth.PlexAuth.initiate_auth"
|
||||
), patch(
|
||||
"plexauth.PlexAuth.token", return_value=MOCK_TOKEN
|
||||
):
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
DOMAIN,
|
||||
context={"source": "import"},
|
||||
data={
|
||||
CONF_TOKEN: MOCK_TOKEN,
|
||||
CONF_URL: f"http://{MOCK_SERVERS[0][CONF_HOST]}:{MOCK_SERVERS[0][CONF_PORT]}",
|
||||
},
|
||||
result = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"], user_input={}
|
||||
)
|
||||
assert result["type"] == "abort"
|
||||
assert result["reason"] == "non-interactive"
|
||||
assert result["type"] == "external"
|
||||
|
||||
result = await hass.config_entries.flow.async_configure(result["flow_id"])
|
||||
assert result["type"] == "external_done"
|
||||
|
||||
result = await hass.config_entries.flow.async_configure(result["flow_id"])
|
||||
|
||||
assert result["type"] == "form"
|
||||
assert result["step_id"] == "user"
|
||||
assert result["errors"][CONF_HOST] == "not_found"
|
||||
|
||||
|
||||
async def test_unknown_exception(hass):
|
||||
|
@ -311,35 +308,6 @@ async def test_adding_last_unconfigured_server(hass):
|
|||
assert result["data"][PLEX_SERVER_CONFIG][CONF_TOKEN] == MOCK_TOKEN
|
||||
|
||||
|
||||
async def test_already_configured(hass):
|
||||
"""Test a duplicated successful flow."""
|
||||
|
||||
mock_plex_server = MockPlexServer()
|
||||
|
||||
MockConfigEntry(
|
||||
domain=DOMAIN,
|
||||
data={
|
||||
CONF_SERVER: MOCK_SERVERS[0][CONF_SERVER],
|
||||
CONF_SERVER_IDENTIFIER: MOCK_SERVERS[0][CONF_SERVER_IDENTIFIER],
|
||||
},
|
||||
unique_id=MOCK_SERVERS[0][CONF_SERVER_IDENTIFIER],
|
||||
).add_to_hass(hass)
|
||||
|
||||
with patch("plexapi.server.PlexServer", return_value=mock_plex_server), patch(
|
||||
"plexauth.PlexAuth.initiate_auth"
|
||||
), patch("plexauth.PlexAuth.token", return_value=MOCK_TOKEN):
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
DOMAIN,
|
||||
context={"source": "import"},
|
||||
data={
|
||||
CONF_TOKEN: MOCK_TOKEN,
|
||||
CONF_URL: f"http://{MOCK_SERVERS[0][CONF_HOST]}:{MOCK_SERVERS[0][CONF_PORT]}",
|
||||
},
|
||||
)
|
||||
assert result["type"] == "abort"
|
||||
assert result["reason"] == "already_configured"
|
||||
|
||||
|
||||
async def test_all_available_servers_configured(hass):
|
||||
"""Test when all available servers are already configured."""
|
||||
|
||||
|
@ -542,21 +510,6 @@ async def test_callback_view(hass, aiohttp_client):
|
|||
assert resp.status == 200
|
||||
|
||||
|
||||
async def test_multiple_servers_with_import(hass):
|
||||
"""Test importing a config with multiple servers available."""
|
||||
|
||||
with patch(
|
||||
"plexapi.myplex.MyPlexAccount", return_value=MockPlexAccount(servers=2)
|
||||
), patch("plexauth.PlexAuth.initiate_auth"), patch(
|
||||
"plexauth.PlexAuth.token", return_value=MOCK_TOKEN
|
||||
):
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
DOMAIN, context={"source": "import"}, data={CONF_TOKEN: MOCK_TOKEN},
|
||||
)
|
||||
assert result["type"] == "abort"
|
||||
assert result["reason"] == "non-interactive"
|
||||
|
||||
|
||||
async def test_manual_config(hass):
|
||||
"""Test creating via manual configuration."""
|
||||
await async_process_ha_core_config(
|
||||
|
|
|
@ -6,7 +6,6 @@ import ssl
|
|||
import plexapi
|
||||
import requests
|
||||
|
||||
from homeassistant.components.media_player import DOMAIN as MP_DOMAIN
|
||||
import homeassistant.components.plex.const as const
|
||||
from homeassistant.config_entries import (
|
||||
ENTRY_STATE_LOADED,
|
||||
|
@ -14,60 +13,16 @@ from homeassistant.config_entries import (
|
|||
ENTRY_STATE_SETUP_ERROR,
|
||||
ENTRY_STATE_SETUP_RETRY,
|
||||
)
|
||||
from homeassistant.const import (
|
||||
CONF_HOST,
|
||||
CONF_PORT,
|
||||
CONF_SSL,
|
||||
CONF_TOKEN,
|
||||
CONF_URL,
|
||||
CONF_VERIFY_SSL,
|
||||
)
|
||||
from homeassistant.const import CONF_URL, CONF_VERIFY_SSL
|
||||
from homeassistant.helpers.dispatcher import async_dispatcher_send
|
||||
from homeassistant.setup import async_setup_component
|
||||
import homeassistant.util.dt as dt_util
|
||||
|
||||
from .const import DEFAULT_DATA, DEFAULT_OPTIONS, MOCK_SERVERS, MOCK_TOKEN
|
||||
from .const import DEFAULT_DATA, DEFAULT_OPTIONS
|
||||
from .mock_classes import MockPlexAccount, MockPlexServer
|
||||
|
||||
from tests.async_mock import patch
|
||||
from tests.common import MockConfigEntry, async_fire_time_changed
|
||||
|
||||
|
||||
async def test_setup_with_config(hass):
|
||||
"""Test setup component with config."""
|
||||
config = {
|
||||
const.DOMAIN: {
|
||||
CONF_HOST: MOCK_SERVERS[0][CONF_HOST],
|
||||
CONF_PORT: MOCK_SERVERS[0][CONF_PORT],
|
||||
CONF_TOKEN: MOCK_TOKEN,
|
||||
CONF_SSL: True,
|
||||
CONF_VERIFY_SSL: True,
|
||||
MP_DOMAIN: {
|
||||
const.CONF_IGNORE_NEW_SHARED_USERS: False,
|
||||
const.CONF_USE_EPISODE_ART: False,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
mock_plex_server = MockPlexServer()
|
||||
|
||||
with patch("plexapi.server.PlexServer", return_value=mock_plex_server), patch(
|
||||
"homeassistant.components.plex.PlexWebsocket.listen"
|
||||
) as mock_listen:
|
||||
assert await async_setup_component(hass, const.DOMAIN, config) is True
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert mock_listen.called
|
||||
assert len(hass.config_entries.async_entries(const.DOMAIN)) == 1
|
||||
entry = hass.config_entries.async_entries(const.DOMAIN)[0]
|
||||
assert entry.state == ENTRY_STATE_LOADED
|
||||
|
||||
server_id = mock_plex_server.machineIdentifier
|
||||
loaded_server = hass.data[const.DOMAIN][const.SERVERS][server_id]
|
||||
|
||||
assert loaded_server.plex_server == mock_plex_server
|
||||
|
||||
|
||||
# class TestClockedPlex(ClockedTestCase):
|
||||
# """Create clock-controlled tests.async_mock class."""
|
||||
|
||||
|
|
Loading…
Reference in New Issue