Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

0.74.1 #15651

Merged
merged 5 commits into from
Jul 24, 2018
Merged

0.74.1 #15651

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion homeassistant/components/cast/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Component to embed Google Cast."""
from homeassistant import data_entry_flow
from homeassistant.helpers import config_entry_flow


Expand All @@ -8,7 +9,14 @@

async def async_setup(hass, config):
"""Set up the Cast component."""
hass.data[DOMAIN] = config.get(DOMAIN, {})
conf = config.get(DOMAIN)

hass.data[DOMAIN] = conf or {}

if conf is not None:
hass.async_create_task(hass.config_entries.flow.async_init(
DOMAIN, source=data_entry_flow.SOURCE_IMPORT))

return True


Expand Down
3 changes: 2 additions & 1 deletion homeassistant/components/frontend/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@
REQUIREMENTS = ['home-assistant-frontend==20180720.0']

DOMAIN = 'frontend'
DEPENDENCIES = ['api', 'websocket_api', 'http', 'system_log', 'onboarding']
DEPENDENCIES = ['api', 'websocket_api', 'http', 'system_log',
'auth', 'onboarding']

CONF_THEMES = 'themes'
CONF_EXTRA_HTML_URL = 'extra_html_url'
Expand Down
19 changes: 13 additions & 6 deletions homeassistant/components/homekit/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,10 @@
from homeassistant.util import get_local_ip
from homeassistant.util.decorator import Registry
from .const import (
CONF_AUTO_START, CONF_ENTITY_CONFIG, CONF_FEATURE_LIST, CONF_FILTER,
DEFAULT_AUTO_START, DEFAULT_PORT, DEVICE_CLASS_CO2, DEVICE_CLASS_PM25,
DOMAIN, HOMEKIT_FILE, SERVICE_HOMEKIT_START, TYPE_OUTLET, TYPE_SWITCH)
BRIDGE_NAME, CONF_AUTO_START, CONF_ENTITY_CONFIG, CONF_FEATURE_LIST,
CONF_FILTER, DEFAULT_AUTO_START, DEFAULT_PORT, DEVICE_CLASS_CO2,
DEVICE_CLASS_PM25, DOMAIN, HOMEKIT_FILE, SERVICE_HOMEKIT_START,
TYPE_OUTLET, TYPE_SWITCH)
from .util import (
show_setup_message, validate_entity_config, validate_media_player_features)

Expand All @@ -43,6 +44,8 @@

CONFIG_SCHEMA = vol.Schema({
DOMAIN: vol.All({
vol.Optional(CONF_NAME, default=BRIDGE_NAME):
vol.All(cv.string, vol.Length(min=3, max=25)),
vol.Optional(CONF_PORT, default=DEFAULT_PORT): cv.port,
vol.Optional(CONF_IP_ADDRESS):
vol.All(ipaddress.ip_address, cv.string),
Expand All @@ -58,13 +61,15 @@ async def async_setup(hass, config):
_LOGGER.debug('Begin setup HomeKit')

conf = config[DOMAIN]
name = conf[CONF_NAME]
port = conf[CONF_PORT]
ip_address = conf.get(CONF_IP_ADDRESS)
auto_start = conf[CONF_AUTO_START]
entity_filter = conf[CONF_FILTER]
entity_config = conf[CONF_ENTITY_CONFIG]

homekit = HomeKit(hass, port, ip_address, entity_filter, entity_config)
homekit = HomeKit(hass, name, port, ip_address, entity_filter,
entity_config)
await hass.async_add_job(homekit.setup)

if auto_start:
Expand Down Expand Up @@ -176,9 +181,11 @@ def generate_aid(entity_id):
class HomeKit():
"""Class to handle all actions between HomeKit and Home Assistant."""

def __init__(self, hass, port, ip_address, entity_filter, entity_config):
def __init__(self, hass, name, port, ip_address, entity_filter,
entity_config):
"""Initialize a HomeKit object."""
self.hass = hass
self._name = name
self._port = port
self._ip_address = ip_address
self._filter = entity_filter
Expand All @@ -199,7 +206,7 @@ def setup(self):
path = self.hass.config.path(HOMEKIT_FILE)
self.driver = HomeDriver(self.hass, address=ip_addr,
port=self._port, persist_file=path)
self.bridge = HomeBridge(self.hass, self.driver)
self.bridge = HomeBridge(self.hass, self.driver, self._name)

def add_bridge_accessory(self, state):
"""Try adding accessory to bridge if configured beforehand."""
Expand Down
4 changes: 2 additions & 2 deletions homeassistant/components/homekit/accessories.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
from homeassistant.util import dt as dt_util

from .const import (
BRIDGE_MODEL, BRIDGE_NAME, BRIDGE_SERIAL_NUMBER, CHAR_BATTERY_LEVEL,
BRIDGE_MODEL, BRIDGE_SERIAL_NUMBER, CHAR_BATTERY_LEVEL,
CHAR_CHARGING_STATE, CHAR_STATUS_LOW_BATTERY, DEBOUNCE_TIMEOUT,
MANUFACTURER, SERV_BATTERY_SERVICE)
from .util import (
Expand Down Expand Up @@ -141,7 +141,7 @@ def update_state(self, new_state):
class HomeBridge(Bridge):
"""Adapter class for Bridge."""

def __init__(self, hass, driver, name=BRIDGE_NAME):
def __init__(self, hass, driver, name):
"""Initialize a Bridge object."""
super().__init__(driver, name)
self.set_info_service(
Expand Down
5 changes: 3 additions & 2 deletions homeassistant/components/media_player/sonos.py
Original file line number Diff line number Diff line change
Expand Up @@ -865,9 +865,10 @@ def source_list(self):
"""List of available input sources."""
sources = [fav.title for fav in self._favorites]

if 'PLAY:5' in self._model or 'CONNECT' in self._model:
model = self._model.upper()
if 'PLAY:5' in model or 'CONNECT' in model:
sources += [SOURCE_LINEIN]
elif 'PLAYBAR' in self._model:
elif 'PLAYBAR' in model:
sources += [SOURCE_LINEIN, SOURCE_TV]

return sources
Expand Down
10 changes: 9 additions & 1 deletion homeassistant/components/sonos/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Component to embed Sonos."""
from homeassistant import data_entry_flow
from homeassistant.helpers import config_entry_flow


Expand All @@ -8,7 +9,14 @@

async def async_setup(hass, config):
"""Set up the Sonos component."""
hass.data[DOMAIN] = config.get(DOMAIN, {})
conf = config.get(DOMAIN)

hass.data[DOMAIN] = conf or {}

if conf is not None:
hass.async_create_task(hass.config_entries.flow.async_init(
DOMAIN, source=data_entry_flow.SOURCE_IMPORT))

return True


Expand Down
2 changes: 1 addition & 1 deletion homeassistant/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"""Constants used by Home Assistant components."""
MAJOR_VERSION = 0
MINOR_VERSION = 74
PATCH_VERSION = '0'
PATCH_VERSION = '1'
__short_version__ = '{}.{}'.format(MAJOR_VERSION, MINOR_VERSION)
__version__ = '{}.{}'.format(__short_version__, PATCH_VERSION)
REQUIRED_PYTHON_VER = (3, 5, 3)
Expand Down
12 changes: 12 additions & 0 deletions homeassistant/helpers/config_entry_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,18 @@ async def async_step_discovery(self, discovery_info):

return await self.async_step_confirm()

async def async_step_import(self, _):
"""Handle a flow initialized by import."""
if self._async_in_progress() or self._async_current_entries():
return self.async_abort(
reason='single_instance_allowed'
)

return self.async_create_entry(
title=self._title,
data={},
)

@callback
def _async_current_entries(self):
"""Return current entries."""
Expand Down
31 changes: 31 additions & 0 deletions tests/components/cast/test_init.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
from unittest.mock import patch

from homeassistant import data_entry_flow
from homeassistant.setup import async_setup_component
from homeassistant.components import cast

from tests.common import MockDependency, mock_coro
Expand All @@ -20,3 +21,33 @@ async def test_creating_entry_sets_up_media_player(hass):
await hass.async_block_till_done()

assert len(mock_setup.mock_calls) == 1


async def test_configuring_cast_creates_entry(hass):
"""Test that specifying config will create an entry."""
with patch('homeassistant.components.cast.async_setup_entry',
return_value=mock_coro(True)) as mock_setup, \
MockDependency('pychromecast', 'discovery'), \
patch('pychromecast.discovery.discover_chromecasts',
return_value=True):
await async_setup_component(hass, cast.DOMAIN, {
'cast': {
'some_config': 'to_trigger_import'
}
})
await hass.async_block_till_done()

assert len(mock_setup.mock_calls) == 1


async def test_not_configuring_cast_not_creates_entry(hass):
"""Test that no config will not create an entry."""
with patch('homeassistant.components.cast.async_setup_entry',
return_value=mock_coro(True)) as mock_setup, \
MockDependency('pychromecast', 'discovery'), \
patch('pychromecast.discovery.discover_chromecasts',
return_value=True):
await async_setup_component(hass, cast.DOMAIN, {})
await hass.async_block_till_done()

assert len(mock_setup.mock_calls) == 0
12 changes: 12 additions & 0 deletions tests/components/frontend/test_init.py
Original file line number Diff line number Diff line change
Expand Up @@ -336,3 +336,15 @@ async def test_lovelace_ui_load_err(hass, hass_ws_client):
assert msg['type'] == wapi.TYPE_RESULT
assert msg['success'] is False
assert msg['error']['code'] == 'load_error'


async def test_auth_load(mock_http_client):
"""Test auth component loaded by default."""
resp = await mock_http_client.get('/auth/providers')
assert resp.status == 200


async def test_onboarding_load(mock_http_client):
"""Test onboarding component loaded by default."""
resp = await mock_http_client.get('/api/onboarding')
assert resp.status == 200
2 changes: 1 addition & 1 deletion tests/components/homekit/test_accessories.py
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ async def test_battery_service(hass, hk_driver):

def test_home_bridge(hk_driver):
"""Test HomeBridge class."""
bridge = HomeBridge('hass', hk_driver)
bridge = HomeBridge('hass', hk_driver, BRIDGE_NAME)
assert bridge.hass == 'hass'
assert bridge.display_name == BRIDGE_NAME
assert bridge.category == 2 # Category.BRIDGE
Expand Down
27 changes: 15 additions & 12 deletions tests/components/homekit/test_homekit.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,10 @@
STATUS_STOPPED, STATUS_WAIT)
from homeassistant.components.homekit.accessories import HomeBridge
from homeassistant.components.homekit.const import (
CONF_AUTO_START, DEFAULT_PORT, DOMAIN, HOMEKIT_FILE, SERVICE_HOMEKIT_START)
CONF_AUTO_START, BRIDGE_NAME, DEFAULT_PORT, DOMAIN, HOMEKIT_FILE,
SERVICE_HOMEKIT_START)
from homeassistant.const import (
CONF_IP_ADDRESS, CONF_PORT,
CONF_NAME, CONF_IP_ADDRESS, CONF_PORT,
EVENT_HOMEASSISTANT_START, EVENT_HOMEASSISTANT_STOP)
from homeassistant.core import State
from homeassistant.helpers.entityfilter import generate_filter
Expand Down Expand Up @@ -47,7 +48,8 @@ async def test_setup_min(hass):
assert await setup.async_setup_component(
hass, DOMAIN, {DOMAIN: {}})

mock_homekit.assert_any_call(hass, DEFAULT_PORT, None, ANY, {})
mock_homekit.assert_any_call(hass, BRIDGE_NAME, DEFAULT_PORT, None, ANY,
{})
assert mock_homekit().setup.called is True

# Test auto start enabled
Expand All @@ -60,15 +62,16 @@ async def test_setup_min(hass):

async def test_setup_auto_start_disabled(hass):
"""Test async_setup with auto start disabled and test service calls."""
config = {DOMAIN: {CONF_AUTO_START: False, CONF_PORT: 11111,
CONF_IP_ADDRESS: '172.0.0.0'}}
config = {DOMAIN: {CONF_AUTO_START: False, CONF_NAME: 'Test Name',
CONF_PORT: 11111, CONF_IP_ADDRESS: '172.0.0.0'}}

with patch(PATH_HOMEKIT + '.HomeKit') as mock_homekit:
mock_homekit.return_value = homekit = Mock()
assert await setup.async_setup_component(
hass, DOMAIN, config)

mock_homekit.assert_any_call(hass, 11111, '172.0.0.0', ANY, {})
mock_homekit.assert_any_call(hass, 'Test Name', 11111, '172.0.0.0', ANY,
{})
assert mock_homekit().setup.called is True

# Test auto_start disabled
Expand Down Expand Up @@ -96,7 +99,7 @@ async def test_setup_auto_start_disabled(hass):

async def test_homekit_setup(hass, hk_driver):
"""Test setup of bridge and driver."""
homekit = HomeKit(hass, DEFAULT_PORT, None, {}, {})
homekit = HomeKit(hass, BRIDGE_NAME, DEFAULT_PORT, None, {}, {})

with patch(PATH_HOMEKIT + '.accessories.HomeDriver',
return_value=hk_driver) as mock_driver, \
Expand All @@ -115,7 +118,7 @@ async def test_homekit_setup(hass, hk_driver):

async def test_homekit_setup_ip_address(hass, hk_driver):
"""Test setup with given IP address."""
homekit = HomeKit(hass, DEFAULT_PORT, '172.0.0.0', {}, {})
homekit = HomeKit(hass, BRIDGE_NAME, DEFAULT_PORT, '172.0.0.0', {}, {})

with patch(PATH_HOMEKIT + '.accessories.HomeDriver',
return_value=hk_driver) as mock_driver:
Expand All @@ -126,7 +129,7 @@ async def test_homekit_setup_ip_address(hass, hk_driver):

async def test_homekit_add_accessory():
"""Add accessory if config exists and get_acc returns an accessory."""
homekit = HomeKit('hass', None, None, lambda entity_id: True, {})
homekit = HomeKit('hass', None, None, None, lambda entity_id: True, {})
homekit.driver = 'driver'
homekit.bridge = mock_bridge = Mock()

Expand All @@ -149,7 +152,7 @@ async def test_homekit_add_accessory():
async def test_homekit_entity_filter(hass):
"""Test the entity filter."""
entity_filter = generate_filter(['cover'], ['demo.test'], [], [])
homekit = HomeKit(hass, None, None, entity_filter, {})
homekit = HomeKit(hass, None, None, None, entity_filter, {})

with patch(PATH_HOMEKIT + '.get_accessory') as mock_get_acc:
mock_get_acc.return_value = None
Expand All @@ -169,7 +172,7 @@ async def test_homekit_entity_filter(hass):
async def test_homekit_start(hass, hk_driver, debounce_patcher):
"""Test HomeKit start method."""
pin = b'123-45-678'
homekit = HomeKit(hass, None, None, {}, {'cover.demo': {}})
homekit = HomeKit(hass, None, None, None, {}, {'cover.demo': {}})
homekit.bridge = 'bridge'
homekit.driver = hk_driver

Expand Down Expand Up @@ -199,7 +202,7 @@ async def test_homekit_start(hass, hk_driver, debounce_patcher):

async def test_homekit_stop(hass):
"""Test HomeKit stop method."""
homekit = HomeKit(hass, None, None, None, None)
homekit = HomeKit(hass, None, None, None, None, None)
homekit.driver = Mock()

assert homekit.status == STATUS_READY
Expand Down
27 changes: 27 additions & 0 deletions tests/components/sonos/test_init.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
from unittest.mock import patch

from homeassistant import data_entry_flow
from homeassistant.setup import async_setup_component
from homeassistant.components import sonos

from tests.common import mock_coro
Expand All @@ -18,3 +19,29 @@ async def test_creating_entry_sets_up_media_player(hass):
await hass.async_block_till_done()

assert len(mock_setup.mock_calls) == 1


async def test_configuring_sonos_creates_entry(hass):
"""Test that specifying config will create an entry."""
with patch('homeassistant.components.sonos.async_setup_entry',
return_value=mock_coro(True)) as mock_setup, \
patch('soco.discover', return_value=True):
await async_setup_component(hass, sonos.DOMAIN, {
'sonos': {
'some_config': 'to_trigger_import'
}
})
await hass.async_block_till_done()

assert len(mock_setup.mock_calls) == 1


async def test_not_configuring_sonos_not_creates_entry(hass):
"""Test that no config will not create an entry."""
with patch('homeassistant.components.sonos.async_setup_entry',
return_value=mock_coro(True)) as mock_setup, \
patch('soco.discover', return_value=True):
await async_setup_component(hass, sonos.DOMAIN, {})
await hass.async_block_till_done()

assert len(mock_setup.mock_calls) == 0
Loading