mirror of
https://github.com/home-assistant/core.git
synced 2025-07-27 15:17:35 +00:00
commit
cd00d556d4
@ -37,12 +37,14 @@ stages:
|
||||
vmImage: 'ubuntu-latest'
|
||||
container: $[ variables['PythonMain'] ]
|
||||
steps:
|
||||
- script: |
|
||||
python -m venv venv
|
||||
- template: templates/azp-step-cache.yaml@azure
|
||||
parameters:
|
||||
keyfile: 'requirements_test.txt | homeassistant/package_constraints.txt'
|
||||
build: |
|
||||
python -m venv venv
|
||||
|
||||
. venv/bin/activate
|
||||
pip install -r requirements_test.txt -c homeassistant/package_constraints.txt
|
||||
displayName: 'Setup Env'
|
||||
. venv/bin/activate
|
||||
pip install -r requirements_test.txt -c homeassistant/package_constraints.txt
|
||||
- script: |
|
||||
. venv/bin/activate
|
||||
flake8 homeassistant tests script
|
||||
@ -52,12 +54,14 @@ stages:
|
||||
vmImage: 'ubuntu-latest'
|
||||
container: $[ variables['PythonMain'] ]
|
||||
steps:
|
||||
- script: |
|
||||
python -m venv venv
|
||||
- template: templates/azp-step-cache.yaml@azure
|
||||
parameters:
|
||||
keyfile: 'homeassistant/package_constraints.txt'
|
||||
build: |
|
||||
python -m venv venv
|
||||
|
||||
. venv/bin/activate
|
||||
pip install -e .
|
||||
displayName: 'Setup Env'
|
||||
. venv/bin/activate
|
||||
pip install -e .
|
||||
- script: |
|
||||
. venv/bin/activate
|
||||
python -m script.hassfest validate
|
||||
@ -71,12 +75,14 @@ stages:
|
||||
vmImage: 'ubuntu-latest'
|
||||
container: $[ variables['PythonMain'] ]
|
||||
steps:
|
||||
- script: |
|
||||
python -m venv venv
|
||||
- template: templates/azp-step-cache.yaml@azure
|
||||
parameters:
|
||||
keyfile: 'requirements_test.txt | homeassistant/package_constraints.txt'
|
||||
build: |
|
||||
python -m venv venv
|
||||
|
||||
. venv/bin/activate
|
||||
pip install -r requirements_test.txt -c homeassistant/package_constraints.txt
|
||||
displayName: 'Setup Env'
|
||||
. venv/bin/activate
|
||||
pip install -r requirements_test.txt -c homeassistant/package_constraints.txt
|
||||
- script: |
|
||||
. venv/bin/activate
|
||||
./script/check_format
|
||||
@ -100,7 +106,7 @@ stages:
|
||||
steps:
|
||||
- template: templates/azp-step-cache.yaml@azure
|
||||
parameters:
|
||||
keyfile: 'requirements_test_all.txt, .cache, homeassistant/package_constraints.txt'
|
||||
keyfile: 'requirements_test_all.txt | homeassistant/package_constraints.txt'
|
||||
build: |
|
||||
set -e
|
||||
python -m venv venv
|
||||
@ -111,6 +117,10 @@ stages:
|
||||
# This is a TEMP. Eventually we should make sure our 4 dependencies drop typing.
|
||||
# Find offending deps with `pipdeptree -r -p typing`
|
||||
pip uninstall -y typing
|
||||
- script: |
|
||||
. venv/bin/activate
|
||||
pip install -e .
|
||||
displayName: 'Install Home Assistant'
|
||||
- script: |
|
||||
set -e
|
||||
|
||||
@ -140,7 +150,7 @@ stages:
|
||||
steps:
|
||||
- template: templates/azp-step-cache.yaml@azure
|
||||
parameters:
|
||||
keyfile: 'requirements_all.txt, requirements_test.txt, .cache, homeassistant/package_constraints.txt'
|
||||
keyfile: 'requirements_all.txt | requirements_test.txt | homeassistant/package_constraints.txt'
|
||||
build: |
|
||||
set -e
|
||||
python -m venv venv
|
||||
@ -149,6 +159,10 @@ stages:
|
||||
pip install -U pip setuptools
|
||||
pip install -r requirements_all.txt -c homeassistant/package_constraints.txt
|
||||
pip install -r requirements_test.txt -c homeassistant/package_constraints.txt
|
||||
- script: |
|
||||
. venv/bin/activate
|
||||
pip install -e .
|
||||
displayName: 'Install Home Assistant'
|
||||
- script: |
|
||||
. venv/bin/activate
|
||||
pylint homeassistant
|
||||
|
@ -1,5 +1,8 @@
|
||||
"""Support for MyQ-Enabled Garage Doors."""
|
||||
import logging
|
||||
|
||||
from pymyq import login
|
||||
from pymyq.errors import MyQError
|
||||
import voluptuous as vol
|
||||
|
||||
from homeassistant.components.cover import (
|
||||
@ -30,35 +33,29 @@ MYQ_TO_HASS = {
|
||||
|
||||
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
|
||||
{
|
||||
vol.Required(CONF_TYPE): cv.string,
|
||||
vol.Required(CONF_USERNAME): cv.string,
|
||||
vol.Required(CONF_PASSWORD): cv.string,
|
||||
# This parameter is no longer used; keeping it to avoid a breaking change in
|
||||
# a hotfix, but in a future main release, this should be removed:
|
||||
vol.Optional(CONF_TYPE): cv.string,
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
async def async_setup_platform(hass, config, async_add_entities, discovery_info=None):
|
||||
"""Set up the platform."""
|
||||
from pymyq import login
|
||||
from pymyq.errors import MyQError, UnsupportedBrandError
|
||||
|
||||
websession = aiohttp_client.async_get_clientsession(hass)
|
||||
|
||||
username = config[CONF_USERNAME]
|
||||
password = config[CONF_PASSWORD]
|
||||
brand = config[CONF_TYPE]
|
||||
|
||||
try:
|
||||
myq = await login(username, password, brand, websession)
|
||||
except UnsupportedBrandError:
|
||||
_LOGGER.error("Unsupported brand: %s", brand)
|
||||
return
|
||||
myq = await login(username, password, websession)
|
||||
except MyQError as err:
|
||||
_LOGGER.error("There was an error while logging in: %s", err)
|
||||
return
|
||||
|
||||
devices = await myq.get_devices()
|
||||
async_add_entities([MyQDevice(device) for device in devices], True)
|
||||
async_add_entities([MyQDevice(device) for device in myq.covers.values()], True)
|
||||
|
||||
|
||||
class MyQDevice(CoverDevice):
|
||||
|
@ -3,7 +3,7 @@
|
||||
"name": "Myq",
|
||||
"documentation": "https://www.home-assistant.io/integrations/myq",
|
||||
"requirements": [
|
||||
"pymyq==1.2.1"
|
||||
"pymyq==2.0.0"
|
||||
],
|
||||
"dependencies": [],
|
||||
"codeowners": []
|
||||
|
@ -89,9 +89,10 @@ class PlexFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
|
||||
_LOGGER.error("Invalid credentials provided, config not created")
|
||||
errors["base"] = "faulty_credentials"
|
||||
except (plexapi.exceptions.NotFound, requests.exceptions.ConnectionError):
|
||||
_LOGGER.error(
|
||||
"Plex server could not be reached: %s", server_config[CONF_URL]
|
||||
server_identifier = (
|
||||
server_config.get(CONF_URL) or plex_server.server_choice or "Unknown"
|
||||
)
|
||||
_LOGGER.error("Plex server could not be reached: %s", server_identifier)
|
||||
errors["base"] = "not_found"
|
||||
|
||||
except ServerNotSpecified as available_servers:
|
||||
|
@ -39,11 +39,12 @@ class PlexServer:
|
||||
self._server_name = server_config.get(CONF_SERVER)
|
||||
self._verify_ssl = server_config.get(CONF_VERIFY_SSL, DEFAULT_VERIFY_SSL)
|
||||
self.options = options
|
||||
self.server_choice = None
|
||||
|
||||
def connect(self):
|
||||
"""Connect to a Plex server directly, obtaining direct URL if necessary."""
|
||||
|
||||
def _set_missing_url():
|
||||
def _connect_with_token():
|
||||
account = plexapi.myplex.MyPlexAccount(token=self._token)
|
||||
available_servers = [
|
||||
(x.name, x.clientIdentifier)
|
||||
@ -56,13 +57,10 @@ class PlexServer:
|
||||
if not self._server_name and len(available_servers) > 1:
|
||||
raise ServerNotSpecified(available_servers)
|
||||
|
||||
server_choice = (
|
||||
self.server_choice = (
|
||||
self._server_name if self._server_name else available_servers[0][0]
|
||||
)
|
||||
connections = account.resource(server_choice).connections
|
||||
local_url = [x.httpuri for x in connections if x.local]
|
||||
remote_url = [x.uri for x in connections if not x.local]
|
||||
self._url = local_url[0] if local_url else remote_url[0]
|
||||
self._plex_server = account.resource(self.server_choice).connect()
|
||||
|
||||
def _connect_with_url():
|
||||
session = None
|
||||
@ -73,10 +71,10 @@ class PlexServer:
|
||||
self._url, self._token, session
|
||||
)
|
||||
|
||||
if self._token and not self._url:
|
||||
_set_missing_url()
|
||||
|
||||
_connect_with_url()
|
||||
if self._url:
|
||||
_connect_with_url()
|
||||
else:
|
||||
_connect_with_token()
|
||||
|
||||
def clients(self):
|
||||
"""Pass through clients call to plexapi."""
|
||||
|
@ -1,7 +1,7 @@
|
||||
"""Constants used by Home Assistant components."""
|
||||
MAJOR_VERSION = 0
|
||||
MINOR_VERSION = 100
|
||||
PATCH_VERSION = "2"
|
||||
PATCH_VERSION = "3"
|
||||
__short_version__ = "{}.{}".format(MAJOR_VERSION, MINOR_VERSION)
|
||||
__version__ = "{}.{}".format(__short_version__, PATCH_VERSION)
|
||||
REQUIRED_PYTHON_VER = (3, 6, 0)
|
||||
|
@ -1316,7 +1316,7 @@ pymonoprice==0.3
|
||||
pymusiccast==0.1.6
|
||||
|
||||
# homeassistant.components.myq
|
||||
pymyq==1.2.1
|
||||
pymyq==2.0.0
|
||||
|
||||
# homeassistant.components.mysensors
|
||||
pymysensors==0.18.0
|
||||
|
@ -1,35 +1,75 @@
|
||||
"""Mock classes used in tests."""
|
||||
from homeassistant.const import CONF_HOST, CONF_PORT
|
||||
from homeassistant.components.plex.const import CONF_SERVER, CONF_SERVER_IDENTIFIER
|
||||
|
||||
MOCK_HOST_1 = "1.2.3.4"
|
||||
MOCK_PORT_1 = 32400
|
||||
MOCK_HOST_2 = "4.3.2.1"
|
||||
MOCK_PORT_2 = 32400
|
||||
MOCK_SERVERS = [
|
||||
{
|
||||
CONF_HOST: "1.2.3.4",
|
||||
CONF_PORT: 32400,
|
||||
CONF_SERVER: "Plex Server 1",
|
||||
CONF_SERVER_IDENTIFIER: "unique_id_123",
|
||||
},
|
||||
{
|
||||
CONF_HOST: "4.3.2.1",
|
||||
CONF_PORT: 32400,
|
||||
CONF_SERVER: "Plex Server 2",
|
||||
CONF_SERVER_IDENTIFIER: "unique_id_456",
|
||||
},
|
||||
]
|
||||
|
||||
|
||||
class MockAvailableServer: # pylint: disable=too-few-public-methods
|
||||
"""Mock avilable server objects."""
|
||||
class MockResource:
|
||||
"""Mock a PlexAccount resource."""
|
||||
|
||||
def __init__(self, name, client_id):
|
||||
def __init__(self, index):
|
||||
"""Initialize the object."""
|
||||
self.name = name
|
||||
self.clientIdentifier = client_id # pylint: disable=invalid-name
|
||||
self.name = MOCK_SERVERS[index][CONF_SERVER]
|
||||
self.clientIdentifier = MOCK_SERVERS[index][ # pylint: disable=invalid-name
|
||||
CONF_SERVER_IDENTIFIER
|
||||
]
|
||||
self.provides = ["server"]
|
||||
self._mock_plex_server = MockPlexServer(index)
|
||||
|
||||
def connect(self):
|
||||
"""Mock the resource connect method."""
|
||||
return self._mock_plex_server
|
||||
|
||||
|
||||
class MockConnection: # pylint: disable=too-few-public-methods
|
||||
"""Mock a single account resource connection object."""
|
||||
class MockPlexAccount:
|
||||
"""Mock a PlexAccount instance."""
|
||||
|
||||
def __init__(self, ssl):
|
||||
def __init__(self, servers=1):
|
||||
"""Initialize the object."""
|
||||
self._resources = []
|
||||
for index in range(servers):
|
||||
self._resources.append(MockResource(index))
|
||||
|
||||
def resource(self, name):
|
||||
"""Mock the PlexAccount resource lookup method."""
|
||||
return [x for x in self._resources if x.name == name][0]
|
||||
|
||||
def resources(self):
|
||||
"""Mock the PlexAccount resources listing method."""
|
||||
return self._resources
|
||||
|
||||
|
||||
class MockPlexServer:
|
||||
"""Mock a PlexServer instance."""
|
||||
|
||||
def __init__(self, index=0, ssl=True):
|
||||
"""Initialize the object."""
|
||||
host = MOCK_SERVERS[index][CONF_HOST]
|
||||
port = MOCK_SERVERS[index][CONF_PORT]
|
||||
self.friendlyName = MOCK_SERVERS[index][ # pylint: disable=invalid-name
|
||||
CONF_SERVER
|
||||
]
|
||||
self.machineIdentifier = MOCK_SERVERS[index][ # pylint: disable=invalid-name
|
||||
CONF_SERVER_IDENTIFIER
|
||||
]
|
||||
prefix = "https" if ssl else "http"
|
||||
self.httpuri = f"{prefix}://{MOCK_HOST_1}:{MOCK_PORT_1}"
|
||||
self.uri = "{prefix}://{MOCK_HOST_2}:{MOCK_PORT_2}"
|
||||
self.local = True
|
||||
self._baseurl = f"{prefix}://{host}:{port}"
|
||||
|
||||
|
||||
class MockConnections: # pylint: disable=too-few-public-methods
|
||||
"""Mock a list of resource connections."""
|
||||
|
||||
def __init__(self, ssl=False):
|
||||
"""Initialize the object."""
|
||||
self.connections = [MockConnection(ssl)]
|
||||
@property
|
||||
def url_in_use(self):
|
||||
"""Return URL used by PlexServer."""
|
||||
return self._baseurl
|
||||
|
@ -1,28 +1,26 @@
|
||||
"""Tests for Plex config flow."""
|
||||
from unittest.mock import MagicMock, Mock, patch, PropertyMock
|
||||
from unittest.mock import patch
|
||||
|
||||
import asynctest
|
||||
import plexapi.exceptions
|
||||
import requests.exceptions
|
||||
|
||||
from homeassistant.components.plex import config_flow
|
||||
from homeassistant.const import CONF_HOST, CONF_PORT, CONF_TOKEN, CONF_URL
|
||||
from homeassistant.const import CONF_HOST, CONF_PORT, CONF_SSL, CONF_TOKEN, CONF_URL
|
||||
from homeassistant.setup import async_setup_component
|
||||
|
||||
from tests.common import MockConfigEntry
|
||||
|
||||
from .mock_classes import MOCK_HOST_1, MOCK_PORT_1, MockAvailableServer, MockConnections
|
||||
from .mock_classes import MOCK_SERVERS, MockPlexAccount, MockPlexServer
|
||||
|
||||
MOCK_NAME_1 = "Plex Server 1"
|
||||
MOCK_ID_1 = "unique_id_123"
|
||||
MOCK_NAME_2 = "Plex Server 2"
|
||||
MOCK_ID_2 = "unique_id_456"
|
||||
MOCK_TOKEN = "secret_token"
|
||||
MOCK_FILE_CONTENTS = {
|
||||
f"{MOCK_HOST_1}:{MOCK_PORT_1}": {"ssl": False, "token": MOCK_TOKEN, "verify": True}
|
||||
f"{MOCK_SERVERS[0][CONF_HOST]}:{MOCK_SERVERS[0][CONF_PORT]}": {
|
||||
"ssl": False,
|
||||
"token": MOCK_TOKEN,
|
||||
"verify": True,
|
||||
}
|
||||
}
|
||||
MOCK_SERVER_1 = MockAvailableServer(MOCK_NAME_1, MOCK_ID_1)
|
||||
MOCK_SERVER_2 = MockAvailableServer(MOCK_NAME_2, MOCK_ID_2)
|
||||
|
||||
DEFAULT_OPTIONS = {
|
||||
config_flow.MP_DOMAIN: {
|
||||
@ -41,25 +39,21 @@ def init_config_flow(hass):
|
||||
|
||||
async def test_bad_credentials(hass):
|
||||
"""Test when provided credentials are rejected."""
|
||||
mock_connections = MockConnections()
|
||||
mm_plex_account = MagicMock()
|
||||
mm_plex_account.resources = Mock(return_value=[MOCK_SERVER_1])
|
||||
mm_plex_account.resource = Mock(return_value=mock_connections)
|
||||
|
||||
with patch("plexapi.myplex.MyPlexAccount", return_value=mm_plex_account), patch(
|
||||
"plexapi.server.PlexServer", side_effect=plexapi.exceptions.Unauthorized
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
config_flow.DOMAIN, context={"source": "user"}
|
||||
)
|
||||
assert result["type"] == "form"
|
||||
assert result["step_id"] == "start_website_auth"
|
||||
|
||||
result = await hass.config_entries.flow.async_configure(result["flow_id"])
|
||||
assert result["type"] == "external"
|
||||
|
||||
with patch(
|
||||
"plexapi.myplex.MyPlexAccount", side_effect=plexapi.exceptions.Unauthorized
|
||||
), asynctest.patch("plexauth.PlexAuth.initiate_auth"), asynctest.patch(
|
||||
"plexauth.PlexAuth.token", return_value="BAD TOKEN"
|
||||
):
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
config_flow.DOMAIN, context={"source": "user"}
|
||||
)
|
||||
assert result["type"] == "form"
|
||||
assert result["step_id"] == "start_website_auth"
|
||||
|
||||
result = await hass.config_entries.flow.async_configure(result["flow_id"])
|
||||
assert result["type"] == "external"
|
||||
|
||||
result = await hass.config_entries.flow.async_configure(result["flow_id"])
|
||||
assert result["type"] == "external_done"
|
||||
|
||||
@ -74,31 +68,32 @@ async def test_import_file_from_discovery(hass):
|
||||
"""Test importing a legacy file during discovery."""
|
||||
|
||||
file_host_and_port, file_config = list(MOCK_FILE_CONTENTS.items())[0]
|
||||
used_url = f"http://{file_host_and_port}"
|
||||
file_use_ssl = file_config[CONF_SSL]
|
||||
file_prefix = "https" if file_use_ssl else "http"
|
||||
used_url = f"{file_prefix}://{file_host_and_port}"
|
||||
|
||||
with patch("plexapi.server.PlexServer") as mock_plex_server, patch(
|
||||
mock_plex_server = MockPlexServer(ssl=file_use_ssl)
|
||||
|
||||
with patch("plexapi.server.PlexServer", return_value=mock_plex_server), patch(
|
||||
"homeassistant.components.plex.config_flow.load_json",
|
||||
return_value=MOCK_FILE_CONTENTS,
|
||||
):
|
||||
type(mock_plex_server.return_value).machineIdentifier = PropertyMock(
|
||||
return_value=MOCK_ID_1
|
||||
)
|
||||
type(mock_plex_server.return_value).friendlyName = PropertyMock(
|
||||
return_value=MOCK_NAME_1
|
||||
)
|
||||
type( # pylint: disable=protected-access
|
||||
mock_plex_server.return_value
|
||||
)._baseurl = PropertyMock(return_value=used_url)
|
||||
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
config_flow.DOMAIN,
|
||||
context={"source": "discovery"},
|
||||
data={CONF_HOST: MOCK_HOST_1, CONF_PORT: MOCK_PORT_1},
|
||||
data={
|
||||
CONF_HOST: MOCK_SERVERS[0][CONF_HOST],
|
||||
CONF_PORT: MOCK_SERVERS[0][CONF_PORT],
|
||||
},
|
||||
)
|
||||
assert result["type"] == "create_entry"
|
||||
assert result["title"] == MOCK_NAME_1
|
||||
assert result["data"][config_flow.CONF_SERVER] == MOCK_NAME_1
|
||||
assert result["data"][config_flow.CONF_SERVER_IDENTIFIER] == MOCK_ID_1
|
||||
assert result["title"] == mock_plex_server.friendlyName
|
||||
assert result["data"][config_flow.CONF_SERVER] == mock_plex_server.friendlyName
|
||||
assert (
|
||||
result["data"][config_flow.CONF_SERVER_IDENTIFIER]
|
||||
== mock_plex_server.machineIdentifier
|
||||
)
|
||||
assert result["data"][config_flow.PLEX_SERVER_CONFIG][CONF_URL] == used_url
|
||||
assert (
|
||||
result["data"][config_flow.PLEX_SERVER_CONFIG][CONF_TOKEN]
|
||||
@ -112,7 +107,10 @@ async def test_discovery(hass):
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
config_flow.DOMAIN,
|
||||
context={"source": "discovery"},
|
||||
data={CONF_HOST: MOCK_HOST_1, CONF_PORT: MOCK_PORT_1},
|
||||
data={
|
||||
CONF_HOST: MOCK_SERVERS[0][CONF_HOST],
|
||||
CONF_PORT: MOCK_SERVERS[0][CONF_PORT],
|
||||
},
|
||||
)
|
||||
assert result["type"] == "abort"
|
||||
assert result["reason"] == "discovery_no_file"
|
||||
@ -128,7 +126,10 @@ async def test_discovery_while_in_progress(hass):
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
config_flow.DOMAIN,
|
||||
context={"source": "discovery"},
|
||||
data={CONF_HOST: MOCK_HOST_1, CONF_PORT: MOCK_PORT_1},
|
||||
data={
|
||||
CONF_HOST: MOCK_SERVERS[0][CONF_HOST],
|
||||
CONF_PORT: MOCK_SERVERS[0][CONF_PORT],
|
||||
},
|
||||
)
|
||||
assert result["type"] == "abort"
|
||||
assert result["reason"] == "already_configured"
|
||||
@ -137,42 +138,28 @@ async def test_discovery_while_in_progress(hass):
|
||||
async def test_import_success(hass):
|
||||
"""Test a successful configuration import."""
|
||||
|
||||
mock_connections = MockConnections(ssl=True)
|
||||
|
||||
mm_plex_account = MagicMock()
|
||||
mm_plex_account.resources = Mock(return_value=[MOCK_SERVER_1])
|
||||
mm_plex_account.resource = Mock(return_value=mock_connections)
|
||||
|
||||
with patch("plexapi.server.PlexServer") as mock_plex_server:
|
||||
type(mock_plex_server.return_value).machineIdentifier = PropertyMock(
|
||||
return_value=MOCK_SERVER_1.clientIdentifier
|
||||
)
|
||||
type(mock_plex_server.return_value).friendlyName = PropertyMock(
|
||||
return_value=MOCK_SERVER_1.name
|
||||
)
|
||||
type( # pylint: disable=protected-access
|
||||
mock_plex_server.return_value
|
||||
)._baseurl = PropertyMock(return_value=mock_connections.connections[0].httpuri)
|
||||
mock_plex_server = MockPlexServer()
|
||||
|
||||
with patch("plexapi.server.PlexServer", return_value=mock_plex_server):
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
config_flow.DOMAIN,
|
||||
context={"source": "import"},
|
||||
data={
|
||||
CONF_TOKEN: MOCK_TOKEN,
|
||||
CONF_URL: f"https://{MOCK_HOST_1}:{MOCK_PORT_1}",
|
||||
CONF_URL: f"https://{MOCK_SERVERS[0][CONF_HOST]}:{MOCK_SERVERS[0][CONF_PORT]}",
|
||||
},
|
||||
)
|
||||
|
||||
assert result["type"] == "create_entry"
|
||||
assert result["title"] == MOCK_SERVER_1.name
|
||||
assert result["data"][config_flow.CONF_SERVER] == MOCK_SERVER_1.name
|
||||
assert result["title"] == mock_plex_server.friendlyName
|
||||
assert result["data"][config_flow.CONF_SERVER] == mock_plex_server.friendlyName
|
||||
assert (
|
||||
result["data"][config_flow.CONF_SERVER_IDENTIFIER]
|
||||
== MOCK_SERVER_1.clientIdentifier
|
||||
== mock_plex_server.machineIdentifier
|
||||
)
|
||||
assert (
|
||||
result["data"][config_flow.PLEX_SERVER_CONFIG][CONF_URL]
|
||||
== mock_connections.connections[0].httpuri
|
||||
== mock_plex_server.url_in_use
|
||||
)
|
||||
assert result["data"][config_flow.PLEX_SERVER_CONFIG][CONF_TOKEN] == MOCK_TOKEN
|
||||
|
||||
@ -188,7 +175,7 @@ async def test_import_bad_hostname(hass):
|
||||
context={"source": "import"},
|
||||
data={
|
||||
CONF_TOKEN: MOCK_TOKEN,
|
||||
CONF_URL: f"http://{MOCK_HOST_1}:{MOCK_PORT_1}",
|
||||
CONF_URL: f"http://{MOCK_SERVERS[0][CONF_HOST]}:{MOCK_SERVERS[0][CONF_PORT]}",
|
||||
},
|
||||
)
|
||||
assert result["type"] == "form"
|
||||
@ -205,19 +192,12 @@ async def test_unknown_exception(hass):
|
||||
assert result["type"] == "form"
|
||||
assert result["step_id"] == "start_website_auth"
|
||||
|
||||
mock_connections = MockConnections()
|
||||
mm_plex_account = MagicMock()
|
||||
mm_plex_account.resources = Mock(return_value=[MOCK_SERVER_1])
|
||||
mm_plex_account.resource = Mock(return_value=mock_connections)
|
||||
|
||||
with patch("plexapi.myplex.MyPlexAccount", return_value=mm_plex_account), patch(
|
||||
"plexapi.server.PlexServer", side_effect=Exception
|
||||
), asynctest.patch("plexauth.PlexAuth.initiate_auth"), asynctest.patch(
|
||||
"plexauth.PlexAuth.token", return_value="MOCK_TOKEN"
|
||||
):
|
||||
result = await hass.config_entries.flow.async_configure(result["flow_id"])
|
||||
assert result["type"] == "external"
|
||||
result = await hass.config_entries.flow.async_configure(result["flow_id"])
|
||||
assert result["type"] == "external"
|
||||
|
||||
with patch("plexapi.myplex.MyPlexAccount", side_effect=Exception), asynctest.patch(
|
||||
"plexauth.PlexAuth.initiate_auth"
|
||||
), asynctest.patch("plexauth.PlexAuth.token", return_value="MOCK_TOKEN"):
|
||||
result = await hass.config_entries.flow.async_configure(result["flow_id"])
|
||||
assert result["type"] == "external_done"
|
||||
|
||||
@ -237,18 +217,15 @@ async def test_no_servers_found(hass):
|
||||
assert result["type"] == "form"
|
||||
assert result["step_id"] == "start_website_auth"
|
||||
|
||||
mm_plex_account = MagicMock()
|
||||
mm_plex_account.resources = Mock(return_value=[])
|
||||
result = await hass.config_entries.flow.async_configure(result["flow_id"])
|
||||
assert result["type"] == "external"
|
||||
|
||||
with patch(
|
||||
"plexapi.myplex.MyPlexAccount", return_value=mm_plex_account
|
||||
"plexapi.myplex.MyPlexAccount", return_value=MockPlexAccount(servers=0)
|
||||
), asynctest.patch("plexauth.PlexAuth.initiate_auth"), asynctest.patch(
|
||||
"plexauth.PlexAuth.token", return_value=MOCK_TOKEN
|
||||
):
|
||||
|
||||
result = await hass.config_entries.flow.async_configure(result["flow_id"])
|
||||
assert result["type"] == "external"
|
||||
|
||||
result = await hass.config_entries.flow.async_configure(result["flow_id"])
|
||||
assert result["type"] == "external_done"
|
||||
|
||||
@ -261,6 +238,8 @@ async def test_no_servers_found(hass):
|
||||
async def test_single_available_server(hass):
|
||||
"""Test creating an entry with one server available."""
|
||||
|
||||
mock_plex_server = MockPlexServer()
|
||||
|
||||
await async_setup_component(hass, "http", {"http": {}})
|
||||
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
@ -269,46 +248,28 @@ async def test_single_available_server(hass):
|
||||
assert result["type"] == "form"
|
||||
assert result["step_id"] == "start_website_auth"
|
||||
|
||||
mock_connections = MockConnections()
|
||||
result = await hass.config_entries.flow.async_configure(result["flow_id"])
|
||||
assert result["type"] == "external"
|
||||
|
||||
mm_plex_account = MagicMock()
|
||||
mm_plex_account.resources = Mock(return_value=[MOCK_SERVER_1])
|
||||
mm_plex_account.resource = Mock(return_value=mock_connections)
|
||||
|
||||
with patch("plexapi.myplex.MyPlexAccount", return_value=mm_plex_account), patch(
|
||||
"plexapi.server.PlexServer"
|
||||
) as mock_plex_server, asynctest.patch(
|
||||
"plexauth.PlexAuth.initiate_auth"
|
||||
), asynctest.patch(
|
||||
with patch("plexapi.myplex.MyPlexAccount", return_value=MockPlexAccount()), patch(
|
||||
"plexapi.server.PlexServer", return_value=mock_plex_server
|
||||
), asynctest.patch("plexauth.PlexAuth.initiate_auth"), asynctest.patch(
|
||||
"plexauth.PlexAuth.token", return_value=MOCK_TOKEN
|
||||
):
|
||||
type(mock_plex_server.return_value).machineIdentifier = PropertyMock(
|
||||
return_value=MOCK_SERVER_1.clientIdentifier
|
||||
)
|
||||
type(mock_plex_server.return_value).friendlyName = PropertyMock(
|
||||
return_value=MOCK_SERVER_1.name
|
||||
)
|
||||
type( # pylint: disable=protected-access
|
||||
mock_plex_server.return_value
|
||||
)._baseurl = PropertyMock(return_value=mock_connections.connections[0].httpuri)
|
||||
|
||||
result = await hass.config_entries.flow.async_configure(result["flow_id"])
|
||||
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"] == "create_entry"
|
||||
assert result["title"] == MOCK_SERVER_1.name
|
||||
assert result["data"][config_flow.CONF_SERVER] == MOCK_SERVER_1.name
|
||||
assert result["title"] == mock_plex_server.friendlyName
|
||||
assert result["data"][config_flow.CONF_SERVER] == mock_plex_server.friendlyName
|
||||
assert (
|
||||
result["data"][config_flow.CONF_SERVER_IDENTIFIER]
|
||||
== MOCK_SERVER_1.clientIdentifier
|
||||
== mock_plex_server.machineIdentifier
|
||||
)
|
||||
assert (
|
||||
result["data"][config_flow.PLEX_SERVER_CONFIG][CONF_URL]
|
||||
== mock_connections.connections[0].httpuri
|
||||
== mock_plex_server.url_in_use
|
||||
)
|
||||
assert result["data"][config_flow.PLEX_SERVER_CONFIG][CONF_TOKEN] == MOCK_TOKEN
|
||||
|
||||
@ -316,6 +277,8 @@ async def test_single_available_server(hass):
|
||||
async def test_multiple_servers_with_selection(hass):
|
||||
"""Test creating an entry with multiple servers available."""
|
||||
|
||||
mock_plex_server = MockPlexServer()
|
||||
|
||||
await async_setup_component(hass, "http", {"http": {}})
|
||||
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
@ -324,31 +287,18 @@ async def test_multiple_servers_with_selection(hass):
|
||||
assert result["type"] == "form"
|
||||
assert result["step_id"] == "start_website_auth"
|
||||
|
||||
mock_connections = MockConnections()
|
||||
mm_plex_account = MagicMock()
|
||||
mm_plex_account.resources = Mock(return_value=[MOCK_SERVER_1, MOCK_SERVER_2])
|
||||
mm_plex_account.resource = Mock(return_value=mock_connections)
|
||||
result = await hass.config_entries.flow.async_configure(result["flow_id"])
|
||||
assert result["type"] == "external"
|
||||
|
||||
with patch("plexapi.myplex.MyPlexAccount", return_value=mm_plex_account), patch(
|
||||
"plexapi.server.PlexServer"
|
||||
) as mock_plex_server, asynctest.patch(
|
||||
with patch(
|
||||
"plexapi.myplex.MyPlexAccount", return_value=MockPlexAccount(servers=2)
|
||||
), patch(
|
||||
"plexapi.server.PlexServer", return_value=mock_plex_server
|
||||
), asynctest.patch(
|
||||
"plexauth.PlexAuth.initiate_auth"
|
||||
), asynctest.patch(
|
||||
"plexauth.PlexAuth.token", return_value=MOCK_TOKEN
|
||||
):
|
||||
type(mock_plex_server.return_value).machineIdentifier = PropertyMock(
|
||||
return_value=MOCK_SERVER_1.clientIdentifier
|
||||
)
|
||||
type(mock_plex_server.return_value).friendlyName = PropertyMock(
|
||||
return_value=MOCK_SERVER_1.name
|
||||
)
|
||||
type( # pylint: disable=protected-access
|
||||
mock_plex_server.return_value
|
||||
)._baseurl = PropertyMock(return_value=mock_connections.connections[0].httpuri)
|
||||
|
||||
result = await hass.config_entries.flow.async_configure(result["flow_id"])
|
||||
assert result["type"] == "external"
|
||||
|
||||
result = await hass.config_entries.flow.async_configure(result["flow_id"])
|
||||
assert result["type"] == "external_done"
|
||||
|
||||
@ -357,18 +307,21 @@ async def test_multiple_servers_with_selection(hass):
|
||||
assert result["step_id"] == "select_server"
|
||||
|
||||
result = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"], user_input={config_flow.CONF_SERVER: MOCK_SERVER_1.name}
|
||||
result["flow_id"],
|
||||
user_input={
|
||||
config_flow.CONF_SERVER: MOCK_SERVERS[0][config_flow.CONF_SERVER]
|
||||
},
|
||||
)
|
||||
assert result["type"] == "create_entry"
|
||||
assert result["title"] == MOCK_SERVER_1.name
|
||||
assert result["data"][config_flow.CONF_SERVER] == MOCK_SERVER_1.name
|
||||
assert result["title"] == mock_plex_server.friendlyName
|
||||
assert result["data"][config_flow.CONF_SERVER] == mock_plex_server.friendlyName
|
||||
assert (
|
||||
result["data"][config_flow.CONF_SERVER_IDENTIFIER]
|
||||
== MOCK_SERVER_1.clientIdentifier
|
||||
== mock_plex_server.machineIdentifier
|
||||
)
|
||||
assert (
|
||||
result["data"][config_flow.PLEX_SERVER_CONFIG][CONF_URL]
|
||||
== mock_connections.connections[0].httpuri
|
||||
== mock_plex_server.url_in_use
|
||||
)
|
||||
assert result["data"][config_flow.PLEX_SERVER_CONFIG][CONF_TOKEN] == MOCK_TOKEN
|
||||
|
||||
@ -376,13 +329,17 @@ async def test_multiple_servers_with_selection(hass):
|
||||
async def test_adding_last_unconfigured_server(hass):
|
||||
"""Test automatically adding last unconfigured server when multiple servers on account."""
|
||||
|
||||
mock_plex_server = MockPlexServer()
|
||||
|
||||
await async_setup_component(hass, "http", {"http": {}})
|
||||
|
||||
MockConfigEntry(
|
||||
domain=config_flow.DOMAIN,
|
||||
data={
|
||||
config_flow.CONF_SERVER_IDENTIFIER: MOCK_ID_2,
|
||||
config_flow.CONF_SERVER: MOCK_NAME_2,
|
||||
config_flow.CONF_SERVER_IDENTIFIER: MOCK_SERVERS[1][
|
||||
config_flow.CONF_SERVER_IDENTIFIER
|
||||
],
|
||||
config_flow.CONF_SERVER: MOCK_SERVERS[1][config_flow.CONF_SERVER],
|
||||
},
|
||||
).add_to_hass(hass)
|
||||
|
||||
@ -392,45 +349,32 @@ async def test_adding_last_unconfigured_server(hass):
|
||||
assert result["type"] == "form"
|
||||
assert result["step_id"] == "start_website_auth"
|
||||
|
||||
mock_connections = MockConnections()
|
||||
mm_plex_account = MagicMock()
|
||||
mm_plex_account.resources = Mock(return_value=[MOCK_SERVER_1, MOCK_SERVER_2])
|
||||
mm_plex_account.resource = Mock(return_value=mock_connections)
|
||||
result = await hass.config_entries.flow.async_configure(result["flow_id"])
|
||||
assert result["type"] == "external"
|
||||
|
||||
with patch("plexapi.myplex.MyPlexAccount", return_value=mm_plex_account), patch(
|
||||
"plexapi.server.PlexServer"
|
||||
) as mock_plex_server, asynctest.patch(
|
||||
with patch(
|
||||
"plexapi.myplex.MyPlexAccount", return_value=MockPlexAccount(servers=2)
|
||||
), patch(
|
||||
"plexapi.server.PlexServer", return_value=mock_plex_server
|
||||
), asynctest.patch(
|
||||
"plexauth.PlexAuth.initiate_auth"
|
||||
), asynctest.patch(
|
||||
"plexauth.PlexAuth.token", return_value=MOCK_TOKEN
|
||||
):
|
||||
type(mock_plex_server.return_value).machineIdentifier = PropertyMock(
|
||||
return_value=MOCK_SERVER_1.clientIdentifier
|
||||
)
|
||||
type(mock_plex_server.return_value).friendlyName = PropertyMock(
|
||||
return_value=MOCK_SERVER_1.name
|
||||
)
|
||||
type( # pylint: disable=protected-access
|
||||
mock_plex_server.return_value
|
||||
)._baseurl = PropertyMock(return_value=mock_connections.connections[0].httpuri)
|
||||
|
||||
result = await hass.config_entries.flow.async_configure(result["flow_id"])
|
||||
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"] == "create_entry"
|
||||
assert result["title"] == MOCK_SERVER_1.name
|
||||
assert result["data"][config_flow.CONF_SERVER] == MOCK_SERVER_1.name
|
||||
assert result["title"] == mock_plex_server.friendlyName
|
||||
assert result["data"][config_flow.CONF_SERVER] == mock_plex_server.friendlyName
|
||||
assert (
|
||||
result["data"][config_flow.CONF_SERVER_IDENTIFIER]
|
||||
== MOCK_SERVER_1.clientIdentifier
|
||||
== mock_plex_server.machineIdentifier
|
||||
)
|
||||
assert (
|
||||
result["data"][config_flow.PLEX_SERVER_CONFIG][CONF_URL]
|
||||
== mock_connections.connections[0].httpuri
|
||||
== mock_plex_server.url_in_use
|
||||
)
|
||||
assert result["data"][config_flow.PLEX_SERVER_CONFIG][CONF_TOKEN] == MOCK_TOKEN
|
||||
|
||||
@ -438,32 +382,28 @@ async def test_adding_last_unconfigured_server(hass):
|
||||
async def test_already_configured(hass):
|
||||
"""Test a duplicated successful flow."""
|
||||
|
||||
mock_plex_server = MockPlexServer()
|
||||
|
||||
flow = init_config_flow(hass)
|
||||
MockConfigEntry(
|
||||
domain=config_flow.DOMAIN, data={config_flow.CONF_SERVER_IDENTIFIER: MOCK_ID_1}
|
||||
domain=config_flow.DOMAIN,
|
||||
data={
|
||||
config_flow.CONF_SERVER_IDENTIFIER: MOCK_SERVERS[0][
|
||||
config_flow.CONF_SERVER_IDENTIFIER
|
||||
]
|
||||
},
|
||||
).add_to_hass(hass)
|
||||
|
||||
mock_connections = MockConnections()
|
||||
|
||||
mm_plex_account = MagicMock()
|
||||
mm_plex_account.resources = Mock(return_value=[MOCK_SERVER_1])
|
||||
mm_plex_account.resource = Mock(return_value=mock_connections)
|
||||
|
||||
with patch("plexapi.server.PlexServer") as mock_plex_server, asynctest.patch(
|
||||
"plexauth.PlexAuth.initiate_auth"
|
||||
), asynctest.patch("plexauth.PlexAuth.token", return_value=MOCK_TOKEN):
|
||||
type(mock_plex_server.return_value).machineIdentifier = PropertyMock(
|
||||
return_value=MOCK_SERVER_1.clientIdentifier
|
||||
)
|
||||
type(mock_plex_server.return_value).friendlyName = PropertyMock(
|
||||
return_value=MOCK_SERVER_1.name
|
||||
)
|
||||
type( # pylint: disable=protected-access
|
||||
mock_plex_server.return_value
|
||||
)._baseurl = PropertyMock(return_value=mock_connections.connections[0].httpuri)
|
||||
|
||||
with patch(
|
||||
"plexapi.server.PlexServer", return_value=mock_plex_server
|
||||
), asynctest.patch("plexauth.PlexAuth.initiate_auth"), asynctest.patch(
|
||||
"plexauth.PlexAuth.token", return_value=MOCK_TOKEN
|
||||
):
|
||||
result = await flow.async_step_import(
|
||||
{CONF_TOKEN: MOCK_TOKEN, CONF_URL: f"http://{MOCK_HOST_1}:{MOCK_PORT_1}"}
|
||||
{
|
||||
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"
|
||||
@ -477,16 +417,20 @@ async def test_all_available_servers_configured(hass):
|
||||
MockConfigEntry(
|
||||
domain=config_flow.DOMAIN,
|
||||
data={
|
||||
config_flow.CONF_SERVER_IDENTIFIER: MOCK_ID_1,
|
||||
config_flow.CONF_SERVER: MOCK_NAME_1,
|
||||
config_flow.CONF_SERVER_IDENTIFIER: MOCK_SERVERS[0][
|
||||
config_flow.CONF_SERVER_IDENTIFIER
|
||||
],
|
||||
config_flow.CONF_SERVER: MOCK_SERVERS[0][config_flow.CONF_SERVER],
|
||||
},
|
||||
).add_to_hass(hass)
|
||||
|
||||
MockConfigEntry(
|
||||
domain=config_flow.DOMAIN,
|
||||
data={
|
||||
config_flow.CONF_SERVER_IDENTIFIER: MOCK_ID_2,
|
||||
config_flow.CONF_SERVER: MOCK_NAME_2,
|
||||
config_flow.CONF_SERVER_IDENTIFIER: MOCK_SERVERS[1][
|
||||
config_flow.CONF_SERVER_IDENTIFIER
|
||||
],
|
||||
config_flow.CONF_SERVER: MOCK_SERVERS[1][config_flow.CONF_SERVER],
|
||||
},
|
||||
).add_to_hass(hass)
|
||||
|
||||
@ -496,20 +440,14 @@ async def test_all_available_servers_configured(hass):
|
||||
assert result["type"] == "form"
|
||||
assert result["step_id"] == "start_website_auth"
|
||||
|
||||
mock_connections = MockConnections()
|
||||
mm_plex_account = MagicMock()
|
||||
mm_plex_account.resources = Mock(return_value=[MOCK_SERVER_1, MOCK_SERVER_2])
|
||||
mm_plex_account.resource = Mock(return_value=mock_connections)
|
||||
result = await hass.config_entries.flow.async_configure(result["flow_id"])
|
||||
assert result["type"] == "external"
|
||||
|
||||
with patch(
|
||||
"plexapi.myplex.MyPlexAccount", return_value=mm_plex_account
|
||||
"plexapi.myplex.MyPlexAccount", return_value=MockPlexAccount(servers=2)
|
||||
), asynctest.patch("plexauth.PlexAuth.initiate_auth"), asynctest.patch(
|
||||
"plexauth.PlexAuth.token", return_value=MOCK_TOKEN
|
||||
):
|
||||
|
||||
result = await hass.config_entries.flow.async_configure(result["flow_id"])
|
||||
assert result["type"] == "external"
|
||||
|
||||
result = await hass.config_entries.flow.async_configure(result["flow_id"])
|
||||
assert result["type"] == "external_done"
|
||||
|
||||
@ -557,13 +495,12 @@ async def test_external_timed_out(hass):
|
||||
assert result["type"] == "form"
|
||||
assert result["step_id"] == "start_website_auth"
|
||||
|
||||
result = await hass.config_entries.flow.async_configure(result["flow_id"])
|
||||
assert result["type"] == "external"
|
||||
|
||||
with asynctest.patch("plexauth.PlexAuth.initiate_auth"), asynctest.patch(
|
||||
"plexauth.PlexAuth.token", return_value=None
|
||||
):
|
||||
|
||||
result = await hass.config_entries.flow.async_configure(result["flow_id"])
|
||||
assert result["type"] == "external"
|
||||
|
||||
result = await hass.config_entries.flow.async_configure(result["flow_id"])
|
||||
assert result["type"] == "external_done"
|
||||
|
||||
@ -583,12 +520,12 @@ async def test_callback_view(hass, aiohttp_client):
|
||||
assert result["type"] == "form"
|
||||
assert result["step_id"] == "start_website_auth"
|
||||
|
||||
result = await hass.config_entries.flow.async_configure(result["flow_id"])
|
||||
assert result["type"] == "external"
|
||||
|
||||
with asynctest.patch("plexauth.PlexAuth.initiate_auth"), asynctest.patch(
|
||||
"plexauth.PlexAuth.token", return_value=MOCK_TOKEN
|
||||
):
|
||||
result = await hass.config_entries.flow.async_configure(result["flow_id"])
|
||||
assert result["type"] == "external"
|
||||
|
||||
client = await aiohttp_client(hass.http.app)
|
||||
forward_url = f'{config_flow.AUTH_CALLBACK_PATH}?flow_id={result["flow_id"]}'
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user