def test_registering_view_while_running(hass, test_client): """Test that we can register a view while the server is running.""" yield from setup.async_setup_component( hass, http.DOMAIN, { http.DOMAIN: { http.CONF_SERVER_PORT: get_test_instance_port(), } } ) yield from setup.async_setup_component(hass, 'api') yield from hass.async_start() yield from hass.async_block_till_done() hass.http.register_view(TestView) client = yield from test_client(hass.http.app) resp = yield from client.get('/hello') assert resp.status == 200 text = yield from resp.text() assert text == 'hello'
def gpslogger_client(loop, hass, aiohttp_client): """Mock client for GPSLogger (unauthenticated).""" assert loop.run_until_complete(async_setup_component( hass, 'persistent_notification', {})) assert loop.run_until_complete(async_setup_component( hass, DOMAIN, { DOMAIN: {} })) with patch('homeassistant.components.device_tracker.update_config'): yield loop.run_until_complete(aiohttp_client(hass.http.app))
def hass_fixture(loop, hass): """Setup a hass instance for these tests.""" # We need to do this to get access to homeassistant/turn_(on,off) loop.run_until_complete(async_setup(hass, {core.DOMAIN: {}})) loop.run_until_complete( setup.async_setup_component(hass, http.DOMAIN, { http.DOMAIN: { http.CONF_SERVER_PORT: SERVER_PORT } })) loop.run_until_complete( setup.async_setup_component(hass, light.DOMAIN, { 'light': [{ 'platform': 'demo' }] })) loop.run_until_complete( setup.async_setup_component(hass, cover.DOMAIN, { 'cover': [{ 'platform': 'demo' }], })) loop.run_until_complete( setup.async_setup_component(hass, media_player.DOMAIN, { 'media_player': [{ 'platform': 'demo' }] })) loop.run_until_complete( setup.async_setup_component(hass, fan.DOMAIN, { 'fan': [{ 'platform': 'demo' }] })) # Kitchen light is explicitly excluded from being exposed ceiling_lights_entity = hass.states.get('light.ceiling_lights') attrs = dict(ceiling_lights_entity.attributes) attrs[ga.const.ATTR_GOOGLE_ASSISTANT_NAME] = "Roof Lights" attrs[ga.const.CONF_ALIASES] = ['top lights', 'ceiling lights'] hass.states.async_set( ceiling_lights_entity.entity_id, ceiling_lights_entity.state, attributes=attrs) return hass
def test_setup_fails_if_no_connect_broker(hass): """Test for setup failure if connection to broker is missing.""" test_broker_cfg = {mqtt.DOMAIN: {mqtt.CONF_BROKER: 'test-broker'}} with mock.patch('homeassistant.components.mqtt.MQTT', side_effect=socket.error()): result = yield from async_setup_component(hass, mqtt.DOMAIN, test_broker_cfg) assert not result with mock.patch('paho.mqtt.client.Client') as mock_client: mock_client().connect = lambda *args: 1 result = yield from async_setup_component(hass, mqtt.DOMAIN, test_broker_cfg) assert not result
def geofency_client(loop, hass, aiohttp_client): """Geofency mock client (unauthenticated).""" assert loop.run_until_complete(async_setup_component( hass, 'persistent_notification', {})) assert loop.run_until_complete(async_setup_component( hass, DOMAIN, { DOMAIN: { CONF_MOBILE_BEACONS: ['Car 1'] }})) loop.run_until_complete(hass.async_block_till_done()) with patch('homeassistant.components.device_tracker.update_config'): yield loop.run_until_complete(aiohttp_client(hass.http.app))
def test_run_camera_setup(hass, test_client): """Test that it fetches the given dispatcher data.""" yield from async_setup_component(hass, 'camera', { 'camera': { 'platform': 'dispatcher', 'name': 'dispatcher', 'signal': 'test_camera', }}) client = yield from test_client(hass.http.app) async_dispatcher_send(hass, 'test_camera', b'test') yield from hass.async_block_till_done() resp = yield from client.get('/api/camera_proxy/camera.dispatcher') assert resp.status == 200 body = yield from resp.text() assert body == 'test' async_dispatcher_send(hass, 'test_camera', b'test2') yield from hass.async_block_till_done() resp = yield from client.get('/api/camera_proxy/camera.dispatcher') assert resp.status == 200 body = yield from resp.text() assert body == 'test2'
def test_initial_state_overrules_restore_state(hass): """Ensure states are restored on startup.""" mock_restore_cache(hass, ( State('input_select.s1', 'last option'), State('input_select.s2', 'bad option'), )) options = { 'options': [ 'first option', 'middle option', 'last option', ], 'initial': 'middle option', } yield from async_setup_component(hass, DOMAIN, { DOMAIN: { 's1': options, 's2': options, }}) state = hass.states.get('input_select.s1') assert state assert state.state == 'middle option' state = hass.states.get('input_select.s2') assert state assert state.state == 'middle option'
def test_reload(hass): """Test we can re-discover scripts.""" scripts = [ '/some/config/dir/python_scripts/hello.py', '/some/config/dir/python_scripts/world_beer.py' ] with patch('homeassistant.components.python_script.os.path.isdir', return_value=True), \ patch('homeassistant.components.python_script.glob.iglob', return_value=scripts): res = yield from async_setup_component(hass, 'python_script', {}) assert res assert hass.services.has_service('python_script', 'hello') assert hass.services.has_service('python_script', 'world_beer') assert hass.services.has_service('python_script', 'reload') scripts = [ '/some/config/dir/python_scripts/hello2.py', '/some/config/dir/python_scripts/world_beer.py' ] with patch('homeassistant.components.python_script.os.path.isdir', return_value=True), \ patch('homeassistant.components.python_script.glob.iglob', return_value=scripts): yield from hass.services.async_call( 'python_script', 'reload', {}, blocking=True) assert not hass.services.has_service('python_script', 'hello') assert hass.services.has_service('python_script', 'hello2') assert hass.services.has_service('python_script', 'world_beer') assert hass.services.has_service('python_script', 'reload')
def mock_lj(hass): """Initialize components.""" with mock.patch('pylitejet.LiteJet') as mock_pylitejet: mock_lj = mock_pylitejet.return_value mock_lj.switch_pressed_callbacks = {} mock_lj.switch_released_callbacks = {} def on_switch_pressed(number, callback): mock_lj.switch_pressed_callbacks[number] = callback def on_switch_released(number, callback): mock_lj.switch_released_callbacks[number] = callback mock_lj.loads.return_value = range(0) mock_lj.button_switches.return_value = range(1, 3) mock_lj.all_switches.return_value = range(1, 6) mock_lj.scenes.return_value = range(0) mock_lj.get_switch_name.side_effect = get_switch_name mock_lj.on_switch_pressed.side_effect = on_switch_pressed mock_lj.on_switch_released.side_effect = on_switch_released config = { 'litejet': { 'port': '/tmp/this_will_be_mocked' } } assert hass.loop.run_until_complete(setup.async_setup_component( hass, litejet.DOMAIN, config)) mock_lj.start_time = dt_util.utcnow() mock_lj.last_delta = timedelta(0) return mock_lj
def test_initial_state_overrules_restore_state(hass): """Ensure states are restored on startup.""" mock_restore_cache(hass, ( State('counter.test1', '11'), State('counter.test2', '-22'), )) hass.state = CoreState.starting yield from async_setup_component(hass, DOMAIN, { DOMAIN: { 'test1': { CONF_RESTORE: False, }, 'test2': { CONF_INITIAL: 10, CONF_RESTORE: False, }, }}) state = hass.states.get('counter.test1') assert state assert int(state.state) == 0 state = hass.states.get('counter.test2') assert state assert int(state.state) == 10
def test_restore_state(hass): """Ensure states are restored on startup.""" hass.data[DATA_RESTORE_CACHE] = { 'input_slider.b1': State('input_slider.b1', '70'), 'input_slider.b2': State('input_slider.b2', '200'), } hass.state = CoreState.starting mock_component(hass, 'recorder') yield from async_setup_component(hass, DOMAIN, { DOMAIN: { 'b1': { 'initial': 50, 'min': 0, 'max': 100, }, 'b2': { 'initial': 60, 'min': 0, 'max': 100, }, }}) state = hass.states.get('input_slider.b1') assert state assert float(state.state) == 70 state = hass.states.get('input_slider.b2') assert state assert float(state.state) == 60
def test_initial_state_overrules_restore_state(hass): """Ensure states are restored on startup.""" mock_restore_cache(hass, ( State('input_text.b1', 'testing'), State('input_text.b2', 'testing too long'), )) hass.state = CoreState.starting yield from async_setup_component(hass, DOMAIN, { DOMAIN: { 'b1': { 'initial': 'test', 'min': 0, 'max': 10, }, 'b2': { 'initial': 'test', 'min': 0, 'max': 10, }, }}) state = hass.states.get('input_text.b1') assert state assert str(state.state) == 'test' state = hass.states.get('input_text.b2') assert state assert str(state.state) == 'test'
def test_restore_state(hass): """Ensure states are restored on startup.""" hass.data[DATA_RESTORE_CACHE] = { 'sensor.test_template_sensor': State('sensor.test_template_sensor', 'It Test.'), } hass.state = CoreState.starting mock_component(hass, 'recorder') yield from async_setup_component(hass, 'sensor', { 'sensor': { 'platform': 'template', 'sensors': { 'test_template_sensor': { 'value_template': "It {{ states.sensor.test_state.state }}." } } } }) state = hass.states.get('sensor.test_template_sensor') assert state.state == 'It Test.' yield from hass.async_start() yield from hass.async_block_till_done() state = hass.states.get('sensor.test_template_sensor') assert state.state == 'It .'
def test_loading_file(hass, test_client): """Test that it loads image from disk.""" mock_registry(hass) with mock.patch('os.path.isfile', mock.Mock(return_value=True)), \ mock.patch('os.access', mock.Mock(return_value=True)): yield from async_setup_component(hass, 'camera', { 'camera': { 'name': 'config_test', 'platform': 'local_file', 'file_path': 'mock.file', }}) client = yield from test_client(hass.http.app) m_open = MockOpen(read_data=b'hello') with mock.patch( 'homeassistant.components.camera.local_file.open', m_open, create=True ): resp = yield from client.get('/api/camera_proxy/camera.config_test') assert resp.status == 200 body = yield from resp.text() assert body == 'hello'
def test_map_internal_to_remote_ports(hass, mock_miniupnpc): """Test mapping local to remote ports.""" ports = OrderedDict() ports['hass'] = 1000 ports[1883] = 3883 result = yield from async_setup_component(hass, 'upnp', { 'upnp': { 'local_ip': '192.168.0.10', 'ports': ports } }) assert result assert len(mock_miniupnpc.addportmapping.mock_calls) == 2 external, _, host, internal, _, _ = \ mock_miniupnpc.addportmapping.mock_calls[0][1] assert external == 1000 assert internal == 8123 external, _, host, internal, _, _ = \ mock_miniupnpc.addportmapping.mock_calls[1][1] assert external == 3883 assert internal == 1883 hass.bus.async_fire(EVENT_HOMEASSISTANT_STOP) yield from hass.async_block_till_done() assert len(mock_miniupnpc.deleteportmapping.mock_calls) == 2 assert mock_miniupnpc.deleteportmapping.mock_calls[0][1][0] == 1000 assert mock_miniupnpc.deleteportmapping.mock_calls[1][1][0] == 3883
def test_setup_pws(hass, aioclient_mock): """Test that the component is loaded with PWS id.""" aioclient_mock.get(PWS_URL, text=load_fixture('wunderground-valid.json')) with assert_setup_component(1, 'sensor'): yield from async_setup_component(hass, 'sensor', {'sensor': VALID_CONFIG_PWS})
def test_setup_dependencies_platform(hass): """Test we setup the dependencies of a platform. We're explictely testing that we process dependencies even if a component with the same name has already been loaded. """ loader.set_component(hass, 'test_component', MockModule('test_component')) loader.set_component(hass, 'test_component2', MockModule('test_component2')) loader.set_component( hass, 'test_domain.test_component', MockPlatform(dependencies=['test_component', 'test_component2'])) component = EntityComponent(_LOGGER, DOMAIN, hass) yield from async_setup_component(hass, 'test_component', {}) yield from component.async_setup({ DOMAIN: { 'platform': 'test_component', } }) assert 'test_component' in hass.config.components assert 'test_component2' in hass.config.components assert 'test_domain.test_component' in hass.config.components
def test_invalid_credentials( mock_open, mock_isfile, mock_makedirs, mock_json_dump, mock_json_load, mock_create_session, hass): """Test with invalid credentials.""" hass.loop.run_until_complete(async_setup_component(hass, 'http', {})) mock_json_load.return_value = {'refresh_token': 'bad_token'} @asyncio.coroutine def get_session(*args, **kwargs): """Return the test session.""" raise aioautomatic.exceptions.BadRequestError( 'err_invalid_refresh_token') mock_create_session.side_effect = get_session config = { 'platform': 'automatic', 'client_id': 'client_id', 'secret': 'client_secret', 'devices': None, } hass.loop.run_until_complete( async_setup_scanner(hass, config, None)) assert mock_create_session.called assert len(mock_create_session.mock_calls) == 1 assert mock_create_session.mock_calls[0][1][0] == 'bad_token'
def mock_http_client_with_urls(hass, test_client): """Start the Hass HTTP component.""" hass.loop.run_until_complete(async_setup_component(hass, 'frontend', { DOMAIN: { CONF_EXTRA_HTML_URL: ["https://domain.com/my_extra_url.html"] }})) return hass.loop.run_until_complete(test_client(hass.http.app))
def test_automation_not_trigger_on_bootstrap(hass): """Test if automation is not trigger on bootstrap.""" hass.state = CoreState.not_running calls = async_mock_service(hass, 'test', 'automation') res = yield from async_setup_component(hass, automation.DOMAIN, { automation.DOMAIN: { 'alias': 'hello', 'trigger': { 'platform': 'event', 'event_type': 'test_event', }, 'action': { 'service': 'test.automation', 'entity_id': 'hello.world' } } }) assert res assert not automation.is_on(hass, 'automation.hello') hass.bus.async_fire('test_event') yield from hass.async_block_till_done() assert len(calls) == 0 hass.bus.async_fire(EVENT_HOMEASSISTANT_START) yield from hass.async_block_till_done() assert automation.is_on(hass, 'automation.hello') hass.bus.async_fire('test_event') yield from hass.async_block_till_done() assert len(calls) == 1 assert ['hello.world'] == calls[0].data.get(ATTR_ENTITY_ID)
def test_initial_state_overrules_restore_state(hass): """Ensure states are restored on startup.""" mock_restore_cache(hass, ( State('input_number.b1', '70'), State('input_number.b2', '200'), )) hass.state = CoreState.starting yield from async_setup_component(hass, DOMAIN, { DOMAIN: { 'b1': { 'initial': 50, 'min': 0, 'max': 100, }, 'b2': { 'initial': 60, 'min': 0, 'max': 100, }, }}) state = hass.states.get('input_number.b1') assert state assert float(state.state) == 50 state = hass.states.get('input_number.b2') assert state assert float(state.state) == 60
def test_restore_state(hass): """Test state gets restored.""" mock_component(hass, 'recorder') hass.state = CoreState.starting hass.data[DATA_RESTORE_CACHE] = { 'light.bed_light': State('light.bed_light', 'on', { 'brightness': 'value-brightness', 'color_temp': 'value-color_temp', 'rgb_color': 'value-rgb_color', 'xy_color': 'value-xy_color', 'white_value': 'value-white_value', 'effect': 'value-effect', }), } yield from async_setup_component(hass, 'light', { 'light': { 'platform': 'demo', }}) state = hass.states.get('light.bed_light') assert state is not None assert state.entity_id == 'light.bed_light' assert state.state == 'on' assert state.attributes.get('brightness') == 'value-brightness' assert state.attributes.get('color_temp') == 'value-color_temp' assert state.attributes.get('rgb_color') == 'value-rgb_color' assert state.attributes.get('xy_color') == 'value-xy_color' assert state.attributes.get('white_value') == 'value-white_value' assert state.attributes.get('effect') == 'value-effect'
def test_no_initial_value_and_restore_off(hass): """Test initial value off and restored state is turned on.""" calls = async_mock_service(hass, 'test', 'automation') mock_restore_cache(hass, ( State('automation.hello', STATE_OFF), )) res = yield from async_setup_component(hass, automation.DOMAIN, { automation.DOMAIN: { 'alias': 'hello', 'trigger': { 'platform': 'event', 'event_type': 'test_event', }, 'action': { 'service': 'test.automation', 'entity_id': 'hello.world' } } }) assert res assert not automation.is_on(hass, 'automation.hello') hass.bus.async_fire('test_event') yield from hass.async_block_till_done() assert len(calls) == 0
def test_set_invalid(hass): """Test set_datetime method with only time.""" initial = '2017-01-01' yield from async_setup_component(hass, DOMAIN, { DOMAIN: { 'test_date': { 'has_time': False, 'has_date': True, 'initial': initial } }}) entity_id = 'input_datetime.test_date' dt_obj = datetime.datetime(2017, 9, 7, 19, 46) time_portion = dt_obj.time() yield from hass.services.async_call('input_datetime', 'set_datetime', { 'entity_id': 'test_date', 'time': time_portion }) yield from hass.async_block_till_done() state = hass.states.get(entity_id) assert state.state == initial
def test_set_datetime(hass): """Test set_datetime method.""" yield from async_setup_component(hass, DOMAIN, { DOMAIN: { 'test_datetime': { 'has_time': True, 'has_date': True }, }}) entity_id = 'input_datetime.test_datetime' dt_obj = datetime.datetime(2017, 9, 7, 19, 46) yield from async_set_datetime(hass, entity_id, dt_obj) state = hass.states.get(entity_id) assert state.state == str(dt_obj) assert state.attributes['has_time'] assert state.attributes['has_date'] assert state.attributes['year'] == 2017 assert state.attributes['month'] == 9 assert state.attributes['day'] == 7 assert state.attributes['hour'] == 19 assert state.attributes['minute'] == 46 assert state.attributes['timestamp'] == dt_obj.timestamp()
def test_fail_setup_cannot_connect(hass): """Fail setup if cannot connect.""" with patch.dict(os.environ, {'HASSIO': "127.0.0.1"}), \ patch('homeassistant.components.hassio.HassIO.is_connected', Mock(return_value=mock_coro(False))): result = yield from async_setup_component(hass, 'hassio', {}) assert not result
def test_calling_intent(hass): """Test calling an intent from a conversation.""" intents = async_mock_intent(hass, 'OrderBeer') result = yield from component.async_setup(hass, {}) assert result result = yield from async_setup_component(hass, 'conversation', { 'conversation': { 'intents': { 'OrderBeer': [ 'I would like the {type} beer' ] } } }) assert result yield from hass.services.async_call( 'conversation', 'process', { conversation.ATTR_TEXT: 'I would like the Grolsch beer' }) yield from hass.async_block_till_done() assert len(intents) == 1 intent = intents[0] assert intent.platform == 'conversation' assert intent.intent_type == 'OrderBeer' assert intent.slots == {'type': {'value': 'Grolsch'}} assert intent.text_input == 'I would like the Grolsch beer'
def test_service_calls(hassio_env, hass, aioclient_mock): """Call service and check the API calls behind that.""" assert (yield from async_setup_component(hass, 'hassio', {})) aioclient_mock.post( "http://127.0.0.1/addons/test/start", json={'result': 'ok'}) aioclient_mock.post( "http://127.0.0.1/addons/test/stop", json={'result': 'ok'}) aioclient_mock.post( "http://127.0.0.1/addons/test/restart", json={'result': 'ok'}) aioclient_mock.post( "http://127.0.0.1/addons/test/stdin", json={'result': 'ok'}) aioclient_mock.post( "http://127.0.0.1/host/shutdown", json={'result': 'ok'}) aioclient_mock.post( "http://127.0.0.1/host/reboot", json={'result': 'ok'}) yield from hass.services.async_call( 'hassio', 'addon_start', {'addon': 'test'}) yield from hass.services.async_call( 'hassio', 'addon_stop', {'addon': 'test'}) yield from hass.services.async_call( 'hassio', 'addon_restart', {'addon': 'test'}) yield from hass.services.async_call( 'hassio', 'addon_stdin', {'addon': 'test', 'input': 'test'}) yield from hass.async_block_till_done() assert aioclient_mock.call_count == 4 assert aioclient_mock.mock_calls[-1][2] == 'test' yield from hass.services.async_call('hassio', 'host_shutdown', {}) yield from hass.services.async_call('hassio', 'host_reboot', {}) yield from hass.async_block_till_done() assert aioclient_mock.call_count == 6
def test_setup(hass): """Test we can discover scripts.""" scripts = [ '/some/config/dir/python_scripts/hello.py', '/some/config/dir/python_scripts/world_beer.py' ] with patch('homeassistant.components.python_script.os.path.isdir', return_value=True), \ patch('homeassistant.components.python_script.glob.iglob', return_value=scripts): res = yield from async_setup_component(hass, 'python_script', {}) assert res assert hass.services.has_service('python_script', 'hello') assert hass.services.has_service('python_script', 'world_beer') with patch('homeassistant.components.python_script.open', mock_open(read_data='fake source'), create=True), \ patch('homeassistant.components.python_script.execute') as mock_ex: yield from hass.services.async_call( 'python_script', 'hello', {'some': 'data'}, blocking=True) assert len(mock_ex.mock_calls) == 1 hass, script, source, data = mock_ex.mock_calls[0][1] assert hass is hass assert script == 'hello.py' assert source == 'fake source' assert data == {'some': 'data'}
def test_service_calls_core(hassio_env, hass, aioclient_mock): """Call core service and check the API calls behind that.""" assert (yield from async_setup_component(hass, 'hassio', {})) aioclient_mock.post( "http://127.0.0.1/homeassistant/restart", json={'result': 'ok'}) aioclient_mock.post( "http://127.0.0.1/homeassistant/stop", json={'result': 'ok'}) yield from hass.services.async_call('homeassistant', 'stop') yield from hass.async_block_till_done() assert aioclient_mock.call_count == 2 yield from hass.services.async_call('homeassistant', 'check_config') yield from hass.async_block_till_done() assert aioclient_mock.call_count == 2 with patch( 'homeassistant.config.async_check_ha_config_file', return_value=mock_coro() ) as mock_check_config: yield from hass.services.async_call('homeassistant', 'restart') yield from hass.async_block_till_done() assert mock_check_config.called assert aioclient_mock.call_count == 3
def test_request_sync_service(aioclient_mock, hass): """Test that it posts to the request_sync url.""" aioclient_mock.post(ga.const.REQUEST_SYNC_BASE_URL, status=200) yield from async_setup_component( hass, "google_assistant", { "google_assistant": { "project_id": "test_project", "api_key": GA_API_KEY } }, ) assert aioclient_mock.call_count == 0 yield from hass.services.async_call( ga.const.DOMAIN, ga.const.SERVICE_REQUEST_SYNC, blocking=True, context=Context(user_id="123"), ) assert aioclient_mock.call_count == 1
def test_initial_value_on(hass): """Test initial value on.""" calls = async_mock_service(hass, 'test', 'automation') res = yield from async_setup_component(hass, automation.DOMAIN, { automation.DOMAIN: { 'alias': 'hello', 'initial_state': 'on', 'trigger': { 'platform': 'event', 'event_type': 'test_event', }, 'action': { 'service': 'test.automation', 'entity_id': ['hello.world', 'hello.world2'] } } }) assert res assert automation.is_on(hass, 'automation.hello') hass.bus.async_fire('test_event') yield from hass.async_block_till_done() assert len(calls) == 1
def test_restore_state(hass): """Ensure states are restored on startup.""" mock_restore_cache(hass, ( State('input_boolean.b1', 'on'), State('input_boolean.b2', 'off'), State('input_boolean.b3', 'on'), )) hass.state = CoreState.starting mock_component(hass, 'recorder') yield from async_setup_component(hass, DOMAIN, { DOMAIN: { 'b1': None, 'b2': None, }}) state = hass.states.get('input_boolean.b1') assert state assert state.state == 'on' state = hass.states.get('input_boolean.b2') assert state assert state.state == 'off'
def test_setup_platform(mock_get_measures, mock_request, hass): mock_request.return_value = { 'devices': [{'model': 'test', 'deviceid': 'device id'}], } mock_get_measures.return_value.__getitem__.return_value.weight = 86.0 config = { 'sensor': { 'platform': withings.DOMAIN, 'client_id': 'client id', 'consumer_secret': 'consumer secret', } } result = hass.loop.run_until_complete( async_setup_component(hass, sensor.DOMAIN, config) ) assert result state = hass.states.get('sensor.withings_device_id') assert state is not None assert state.state == '86.0' assert state.attributes.get('weight') == 86.0 assert state.attributes.get('unit_of_measurement') == 'kg'
async def test_all_work_done_before_start(hass): """Test all init work done till start.""" call_order = [] async def component1_setup(hass, config): """Set up mock component.""" await discovery.async_discover( hass, "test_component2", {}, "test_component2", {} ) await discovery.async_discover( hass, "test_component3", {}, "test_component3", {} ) return True def component_track_setup(hass, config): """Set up mock component.""" call_order.append(1) return True mock_integration(hass, MockModule("test_component1", async_setup=component1_setup)) mock_integration(hass, MockModule("test_component2", setup=component_track_setup)) mock_integration(hass, MockModule("test_component3", setup=component_track_setup)) @callback def track_start(event): """Track start event.""" call_order.append(2) hass.bus.async_listen_once(EVENT_HOMEASSISTANT_START, track_start) hass.add_job(setup.async_setup_component(hass, "test_component1", {})) await hass.async_block_till_done() await hass.async_start() assert call_order == [1, 1, 2]
def test_automation_is_on_if_no_initial_state_or_restore(hass): """Test initial value is on when no initial state or restored state.""" calls = mock_service(hass, 'test', 'automation') res = yield from async_setup_component( hass, automation.DOMAIN, { automation.DOMAIN: { 'alias': 'hello', 'trigger': { 'platform': 'event', 'event_type': 'test_event', }, 'action': { 'service': 'test.automation', 'entity_id': 'hello.world' } } }) assert res assert automation.is_on(hass, 'automation.hello') hass.bus.async_fire('test_event') yield from hass.async_block_till_done() assert len(calls) == 1
def test_initial_state_overrules_restore_state(hass): """Ensure states are restored on startup.""" mock_restore_cache( hass, (State("input_text.b1", "testing"), State("input_text.b2", "testing too long")), ) hass.state = CoreState.starting yield from async_setup_component( hass, DOMAIN, { DOMAIN: { "b1": { "initial": "test", "min": 0, "max": 10 }, "b2": { "initial": "test", "min": 0, "max": 10 }, } }, ) state = hass.states.get("input_text.b1") assert state assert str(state.state) == "test" state = hass.states.get("input_text.b2") assert state assert str(state.state) == "test"
def test_set_datetime_time(hass): """Test set_datetime method with only time.""" yield from async_setup_component( hass, DOMAIN, {DOMAIN: { 'test_time': { 'has_time': True, 'has_date': False } }}) entity_id = 'input_datetime.test_time' dt_obj = datetime.datetime(2017, 9, 7, 19, 46) time_portion = dt_obj.time() yield from async_set_datetime(hass, entity_id, dt_obj) state = hass.states.get(entity_id) assert state.state == str(time_portion) assert state.attributes['has_time'] assert not state.attributes['has_date'] assert state.attributes['timestamp'] == (19 * 3600) + (46 * 60)
def hass_fixture(loop, hass): """Set up a HOme Assistant instance for these tests.""" # We need to do this to get access to homeassistant/turn_(on,off) loop.run_until_complete(async_setup(hass, {core.DOMAIN: {}})) loop.run_until_complete( setup.async_setup_component(hass, light.DOMAIN, {'light': [{ 'platform': 'demo' }]})) loop.run_until_complete( setup.async_setup_component(hass, switch.DOMAIN, {'switch': [{ 'platform': 'demo' }]})) loop.run_until_complete( setup.async_setup_component(hass, cover.DOMAIN, { 'cover': [{ 'platform': 'demo' }], })) loop.run_until_complete( setup.async_setup_component(hass, media_player.DOMAIN, {'media_player': [{ 'platform': 'demo' }]})) loop.run_until_complete( setup.async_setup_component(hass, fan.DOMAIN, {'fan': [{ 'platform': 'demo' }]})) loop.run_until_complete( setup.async_setup_component(hass, climate.DOMAIN, {'climate': [{ 'platform': 'demo' }]})) return hass
async def async_from_config_dict(config: Dict[str, Any], hass: core.HomeAssistant, config_dir: Optional[str] = None, enable_log: bool = True, verbose: bool = False, skip_pip: bool = False, log_rotate_days: Any = None, log_file: Any = None, log_no_color: bool = False) \ -> Optional[core.HomeAssistant]: """Try to configure Home Assistant from a configuration dictionary. Dynamically loads required components and its dependencies. This method is a coroutine. """ start = time() if enable_log: async_enable_logging(hass, verbose, log_rotate_days, log_file, log_no_color) core_config = config.get(core.DOMAIN, {}) has_api_password = bool((config.get('http') or {}).get('api_password')) has_trusted_networks = bool((config.get('http') or {}) .get('trusted_networks')) try: await conf_util.async_process_ha_core_config( hass, core_config, has_api_password, has_trusted_networks) except vol.Invalid as config_err: conf_util.async_log_exception( config_err, 'homeassistant', core_config, hass) return None except HomeAssistantError: _LOGGER.error("Home Assistant core failed to initialize. " "Further initialization aborted") return None await hass.async_add_executor_job( conf_util.process_ha_config_upgrade, hass) hass.config.skip_pip = skip_pip if skip_pip: _LOGGER.warning("Skipping pip installation of required modules. " "This may cause issues") # Make a copy because we are mutating it. config = OrderedDict(config) # Merge packages conf_util.merge_packages_config( hass, config, core_config.get(conf_util.CONF_PACKAGES, {})) hass.config_entries = config_entries.ConfigEntries(hass, config) await hass.config_entries.async_load() # Filter out the repeating and common config section [homeassistant] components = set(key.split(' ')[0] for key in config.keys() if key != core.DOMAIN) components.update(hass.config_entries.async_domains()) # Resolve all dependencies of all components. for component in list(components): try: components.update(loader.component_dependencies(hass, component)) except loader.LoaderError: # Ignore it, or we'll break startup # It will be properly handled during setup. pass # setup components res = await core_components.async_setup(hass, config) if not res: _LOGGER.error("Home Assistant core failed to initialize. " "Further initialization aborted") return hass await persistent_notification.async_setup(hass, config) _LOGGER.info("Home Assistant core initialized") # stage 1 for component in components: if component not in FIRST_INIT_COMPONENT: continue hass.async_create_task(async_setup_component(hass, component, config)) await hass.async_block_till_done() # stage 2 for component in components: if component in FIRST_INIT_COMPONENT: continue hass.async_create_task(async_setup_component(hass, component, config)) await hass.async_block_till_done() stop = time() _LOGGER.info("Home Assistant initialized in %.2fs", stop-start) # TEMP: warn users for invalid slugs # Remove after 0.94 or 1.0 if cv.INVALID_SLUGS_FOUND or cv.INVALID_ENTITY_IDS_FOUND: msg = [] if cv.INVALID_ENTITY_IDS_FOUND: msg.append( "Your configuration contains invalid entity ID references. " "Please find and update the following. " "This will become a breaking change." ) msg.append('\n'.join('- {} -> {}'.format(*item) for item in cv.INVALID_ENTITY_IDS_FOUND.items())) if cv.INVALID_SLUGS_FOUND: msg.append( "Your configuration contains invalid slugs. " "Please find and update the following. " "This will become a breaking change." ) msg.append('\n'.join('- {} -> {}'.format(*item) for item in cv.INVALID_SLUGS_FOUND.items())) hass.components.persistent_notification.async_create( '\n\n'.join(msg), "Config Warning", "config_warning" ) # TEMP: warn users of invalid extra keys # Remove after 0.92 if cv.INVALID_EXTRA_KEYS_FOUND: msg = [] msg.append( "Your configuration contains extra keys " "that the platform does not support (but were silently " "accepted before 0.88). Please find and remove the following." "This will become a breaking change." ) msg.append('\n'.join('- {}'.format(it) for it in cv.INVALID_EXTRA_KEYS_FOUND)) hass.components.persistent_notification.async_create( '\n\n'.join(msg), "Config Warning", "config_warning" ) return hass
def setup_comp_1(hass): """Initialize components.""" hass.config.units = METRIC_SYSTEM assert hass.loop.run_until_complete( async_setup_component(hass, "homeassistant", {}))
def mock_stream(hass): """Initialize a demo camera platform with streaming.""" assert hass.loop.run_until_complete( async_setup_component(hass, 'stream', {'stream': {}}))
def mock_http_client(hass, aiohttp_client): """Start the Hass HTTP component.""" hass.loop.run_until_complete(async_setup_component(hass, "frontend", {})) return hass.loop.run_until_complete(aiohttp_client(hass.http.app))
def test_xiaomi_specific_services(hass, caplog, mock_mirobo_is_on): """Test vacuum supported features.""" entity_name = 'test_vacuum_cleaner_2' entity_id = '{}.{}'.format(DOMAIN, entity_name) yield from async_setup_component( hass, DOMAIN, { DOMAIN: { CONF_PLATFORM: PLATFORM, CONF_HOST: '192.168.1.100', CONF_NAME: entity_name, CONF_TOKEN: '12345678901234567890123456789012' } }) assert 'Initializing with host 192.168.1.100 (token 12345' in caplog.text # Check state attributes state = hass.states.get(entity_id) assert state.state == STATE_ON assert state.attributes.get(ATTR_SUPPORTED_FEATURES) == 2047 assert state.attributes.get(ATTR_DO_NOT_DISTURB) == STATE_OFF assert state.attributes.get(ATTR_ERROR) is None assert (state.attributes.get(ATTR_BATTERY_ICON) == 'mdi:battery-30') assert state.attributes.get(ATTR_CLEANING_TIME) == '2:55:34' assert state.attributes.get(ATTR_CLEANED_AREA) == 133.43 assert state.attributes.get(ATTR_FAN_SPEED) == 99 assert (state.attributes.get(ATTR_FAN_SPEED_LIST) == [ 'Quiet', 'Balanced', 'Turbo', 'Max' ]) # Check setting pause yield from hass.services.async_call(DOMAIN, SERVICE_START_PAUSE, blocking=True) assert str(mock_mirobo_is_on.mock_calls[-2]) == 'call.Vacuum().pause()' assert str(mock_mirobo_is_on.mock_calls[-1]) == 'call.Vacuum().status()' # Xiaomi vacuum specific services: yield from hass.services.async_call(DOMAIN, SERVICE_START_REMOTE_CONTROL, {ATTR_ENTITY_ID: entity_id}, blocking=True) assert (str( mock_mirobo_is_on.mock_calls[-2]) == "call.Vacuum().manual_start()") assert str(mock_mirobo_is_on.mock_calls[-1]) == 'call.Vacuum().status()' yield from hass.services.async_call(DOMAIN, SERVICE_MOVE_REMOTE_CONTROL, { "duration": 1000, "rotation": -40, "velocity": -0.1 }, blocking=True) assert ('call.Vacuum().manual_control(' in str(mock_mirobo_is_on.mock_calls[-2])) assert 'duration=1000' in str(mock_mirobo_is_on.mock_calls[-2]) assert 'rotation=-40' in str(mock_mirobo_is_on.mock_calls[-2]) assert 'velocity=-0.1' in str(mock_mirobo_is_on.mock_calls[-2]) assert str(mock_mirobo_is_on.mock_calls[-1]) == 'call.Vacuum().status()' yield from hass.services.async_call(DOMAIN, SERVICE_STOP_REMOTE_CONTROL, {}, blocking=True) assert (str( mock_mirobo_is_on.mock_calls[-2]) == "call.Vacuum().manual_stop()") assert str(mock_mirobo_is_on.mock_calls[-1]) == 'call.Vacuum().status()' yield from hass.services.async_call(DOMAIN, SERVICE_MOVE_REMOTE_CONTROL_STEP, { "duration": 2000, "rotation": 120, "velocity": 0.1 }, blocking=True) assert ('call.Vacuum().manual_control_once(' in str(mock_mirobo_is_on.mock_calls[-2])) assert 'duration=2000' in str(mock_mirobo_is_on.mock_calls[-2]) assert 'rotation=120' in str(mock_mirobo_is_on.mock_calls[-2]) assert 'velocity=0.1' in str(mock_mirobo_is_on.mock_calls[-2]) assert str(mock_mirobo_is_on.mock_calls[-1]) == 'call.Vacuum().status()'
def mock_api_client(hass, hass_client): """Start the Home Assistant HTTP component and return admin API client.""" hass.loop.run_until_complete(async_setup_component(hass, "api", {})) return hass.loop.run_until_complete(hass_client())
def init_invalid_provider_settings(hass, config): """Set invalid provider data and initalize component.""" config["notify"][CONF_PROVIDER] = "FantasyMobile" # invalid provider return async_setup_component(hass, "notify", config)
def setup_comp(hass): """Set up demo component.""" hass.loop.run_until_complete( async_setup_component(hass, LIGHT_DOMAIN, {LIGHT_DOMAIN: {"platform": DOMAIN}}) )
def test_fail_setup_without_environ_var(hass): """Fail setup if no environ variable set.""" with patch.dict(os.environ, {}, clear=True): result = yield from async_setup_component(hass, 'hassio', {}) assert not result
def init_valid_settings(hass, config): """Initialize component with valid settings.""" return async_setup_component(hass, "notify", config)
def test_panel_without_path(hass): """Test panel registration without file path.""" yield from hass.components.frontend.async_register_panel( 'test_component', 'nonexistant_file') yield from async_setup_component(hass, 'frontend', {}) assert 'test_component' not in hass.data[DATA_PANELS]
def test_methods_and_events(hass): """Test methods and events.""" hass.state = CoreState.starting yield from async_setup_component( hass, DOMAIN, {DOMAIN: { 'test1': { CONF_DURATION: 10, } }}) state = hass.states.get('timer.test1') assert state assert state.state == STATUS_IDLE results = [] def fake_event_listener(event): """Fake event listener for trigger.""" results.append(event) hass.bus.async_listen(EVENT_TIMER_FINISHED, fake_event_listener) hass.bus.async_listen(EVENT_TIMER_CANCELLED, fake_event_listener) yield from hass.services.async_call(DOMAIN, SERVICE_START, {CONF_ENTITY_ID: 'timer.test1'}) yield from hass.async_block_till_done() state = hass.states.get('timer.test1') assert state assert state.state == STATUS_ACTIVE yield from hass.services.async_call(DOMAIN, SERVICE_PAUSE, {CONF_ENTITY_ID: 'timer.test1'}) yield from hass.async_block_till_done() state = hass.states.get('timer.test1') assert state assert state.state == STATUS_PAUSED yield from hass.services.async_call(DOMAIN, SERVICE_CANCEL, {CONF_ENTITY_ID: 'timer.test1'}) yield from hass.async_block_till_done() state = hass.states.get('timer.test1') assert state assert state.state == STATUS_IDLE assert len(results) == 1 assert results[-1].event_type == EVENT_TIMER_CANCELLED yield from hass.services.async_call(DOMAIN, SERVICE_START, {CONF_ENTITY_ID: 'timer.test1'}) yield from hass.async_block_till_done() state = hass.states.get('timer.test1') assert state assert state.state == STATUS_ACTIVE async_fire_time_changed(hass, utcnow() + timedelta(seconds=10)) yield from hass.async_block_till_done() state = hass.states.get('timer.test1') assert state assert state.state == STATUS_IDLE assert len(results) == 2 assert results[-1].event_type == EVENT_TIMER_FINISHED yield from hass.services.async_call(DOMAIN, SERVICE_START, {CONF_ENTITY_ID: 'timer.test1'}) yield from hass.async_block_till_done() state = hass.states.get('timer.test1') assert state assert state.state == STATUS_ACTIVE yield from hass.services.async_call(DOMAIN, SERVICE_FINISH, {CONF_ENTITY_ID: 'timer.test1'}) yield from hass.async_block_till_done() state = hass.states.get('timer.test1') assert state assert state.state == STATUS_IDLE assert len(results) == 3 assert results[-1].event_type == EVENT_TIMER_FINISHED
def test_xiaomi_vacuum_services(hass, caplog, mock_mirobo_is_off): """Test vacuum supported features.""" entity_name = 'test_vacuum_cleaner_1' entity_id = '{}.{}'.format(DOMAIN, entity_name) yield from async_setup_component( hass, DOMAIN, { DOMAIN: { CONF_PLATFORM: PLATFORM, CONF_HOST: '127.0.0.1', CONF_NAME: entity_name, CONF_TOKEN: '12345678901234567890123456789012' } }) assert 'Initializing with host 127.0.0.1 (token 12345...)' in caplog.text # Check state attributes state = hass.states.get(entity_id) assert state.state == STATE_OFF assert state.attributes.get(ATTR_SUPPORTED_FEATURES) == 2047 assert state.attributes.get(ATTR_DO_NOT_DISTURB) == STATE_ON assert state.attributes.get(ATTR_ERROR) == 'Error message' assert ( state.attributes.get(ATTR_BATTERY_ICON) == 'mdi:battery-charging-80') assert state.attributes.get(ATTR_CLEANING_TIME) == '2:35:34' assert state.attributes.get(ATTR_CLEANED_AREA) == 123.43 assert state.attributes.get(ATTR_FAN_SPEED) == 'Quiet' assert (state.attributes.get(ATTR_FAN_SPEED_LIST) == [ 'Quiet', 'Balanced', 'Turbo', 'Max' ]) # Call services yield from hass.services.async_call(DOMAIN, SERVICE_TURN_ON, blocking=True) assert str(mock_mirobo_is_off.mock_calls[-2]) == 'call.Vacuum().start()' assert str(mock_mirobo_is_off.mock_calls[-1]) == 'call.Vacuum().status()' yield from hass.services.async_call(DOMAIN, SERVICE_TURN_OFF, blocking=True) assert str(mock_mirobo_is_off.mock_calls[-2]) == 'call.Vacuum().home()' assert str(mock_mirobo_is_off.mock_calls[-1]) == 'call.Vacuum().status()' yield from hass.services.async_call(DOMAIN, SERVICE_TOGGLE, blocking=True) assert str(mock_mirobo_is_off.mock_calls[-2]) == 'call.Vacuum().start()' assert str(mock_mirobo_is_off.mock_calls[-1]) == 'call.Vacuum().status()' yield from hass.services.async_call(DOMAIN, SERVICE_STOP, blocking=True) assert str(mock_mirobo_is_off.mock_calls[-2]) == 'call.Vacuum().stop()' assert str(mock_mirobo_is_off.mock_calls[-1]) == 'call.Vacuum().status()' yield from hass.services.async_call(DOMAIN, SERVICE_START_PAUSE, blocking=True) assert str(mock_mirobo_is_off.mock_calls[-2]) == 'call.Vacuum().start()' assert str(mock_mirobo_is_off.mock_calls[-1]) == 'call.Vacuum().status()' yield from hass.services.async_call(DOMAIN, SERVICE_RETURN_TO_BASE, blocking=True) assert str(mock_mirobo_is_off.mock_calls[-2]) == 'call.Vacuum().home()' assert str(mock_mirobo_is_off.mock_calls[-1]) == 'call.Vacuum().status()' yield from hass.services.async_call(DOMAIN, SERVICE_LOCATE, blocking=True) assert str(mock_mirobo_is_off.mock_calls[-2]) == 'call.Vacuum().find()' assert str(mock_mirobo_is_off.mock_calls[-1]) == 'call.Vacuum().status()' yield from hass.services.async_call(DOMAIN, SERVICE_CLEAN_SPOT, {}, blocking=True) assert str(mock_mirobo_is_off.mock_calls[-2]) == 'call.Vacuum().spot()' assert str(mock_mirobo_is_off.mock_calls[-1]) == 'call.Vacuum().status()' # Set speed service: yield from hass.services.async_call(DOMAIN, SERVICE_SET_FAN_SPEED, {"fan_speed": 60}, blocking=True) assert (str( mock_mirobo_is_off.mock_calls[-2]) == 'call.Vacuum().set_fan_speed(60)' ) assert str(mock_mirobo_is_off.mock_calls[-1]) == 'call.Vacuum().status()' yield from hass.services.async_call(DOMAIN, SERVICE_SET_FAN_SPEED, {"fan_speed": "turbo"}, blocking=True) assert (str( mock_mirobo_is_off.mock_calls[-2]) == 'call.Vacuum().set_fan_speed(77)' ) assert str(mock_mirobo_is_off.mock_calls[-1]) == 'call.Vacuum().status()' assert 'ERROR' not in caplog.text yield from hass.services.async_call(DOMAIN, SERVICE_SET_FAN_SPEED, {"fan_speed": "invent"}, blocking=True) assert 'ERROR' in caplog.text yield from hass.services.async_call(DOMAIN, SERVICE_SEND_COMMAND, {"command": "raw"}, blocking=True) assert (str(mock_mirobo_is_off.mock_calls[-2]) == "call.Vacuum().raw_command('raw', None)") assert str(mock_mirobo_is_off.mock_calls[-1]) == 'call.Vacuum().status()' yield from hass.services.async_call(DOMAIN, SERVICE_SEND_COMMAND, { "command": "raw", "params": { "k1": 2 } }, blocking=True) assert (str(mock_mirobo_is_off.mock_calls[-2]) == "call.Vacuum().raw_command('raw', {'k1': 2})") assert str(mock_mirobo_is_off.mock_calls[-1]) == 'call.Vacuum().status()'
def test_config_setup(hass, loop): """Test it sets up hassbian.""" yield from async_setup_component(hass, "config", {}) assert "config" in hass.config.components
def setup_frontend(hass): """Fixture to setup the frontend.""" hass.loop.run_until_complete(async_setup_component(hass, 'frontend', {}))
def mock_stream_fixture(hass): """Initialize a demo camera platform with streaming.""" assert hass.loop.run_until_complete( async_setup_component(hass, "stream", {"stream": {}}) )
def test_if_demo_state_shows_by_default(hass, minimize_demo_platforms): """Test if demo state shows if we give no configuration.""" yield from async_setup_component(hass, demo.DOMAIN, {demo.DOMAIN: {}}) assert hass.states.get('a.Demo_Mode') is not None
def hass_hue(loop, hass): """Setup a hass instance for these tests.""" # We need to do this to get access to homeassistant/turn_(on,off) loop.run_until_complete( core_components.async_setup(hass, {core.DOMAIN: {}})) loop.run_until_complete( setup.async_setup_component( hass, http.DOMAIN, {http.DOMAIN: { http.CONF_SERVER_PORT: HTTP_SERVER_PORT }})) with patch('homeassistant.components' '.emulated_hue.UPNPResponderThread'): loop.run_until_complete( setup.async_setup_component( hass, emulated_hue.DOMAIN, { emulated_hue.DOMAIN: { emulated_hue.CONF_LISTEN_PORT: BRIDGE_SERVER_PORT, emulated_hue.CONF_EXPOSE_BY_DEFAULT: True } })) loop.run_until_complete( setup.async_setup_component(hass, light.DOMAIN, {'light': [{ 'platform': 'demo', }]})) loop.run_until_complete( setup.async_setup_component( hass, script.DOMAIN, { 'script': { 'set_kitchen_light': { 'sequence': [{ 'service_template': "light.turn_{{ requested_state }}", 'data_template': { 'entity_id': 'light.kitchen_lights', 'brightness': "{{ requested_level }}" } }] } } })) loop.run_until_complete( setup.async_setup_component(hass, media_player.DOMAIN, {'media_player': [{ 'platform': 'demo', }]})) loop.run_until_complete( setup.async_setup_component(hass, fan.DOMAIN, {'fan': [{ 'platform': 'demo', }]})) # Kitchen light is explicitly excluded from being exposed kitchen_light_entity = hass.states.get('light.kitchen_lights') attrs = dict(kitchen_light_entity.attributes) attrs[emulated_hue.ATTR_EMULATED_HUE] = False hass.states.async_set(kitchen_light_entity.entity_id, kitchen_light_entity.state, attributes=attrs) # Ceiling Fan is explicitly excluded from being exposed ceiling_fan_entity = hass.states.get('fan.ceiling_fan') attrs = dict(ceiling_fan_entity.attributes) attrs[emulated_hue.ATTR_EMULATED_HUE_HIDDEN] = True hass.states.async_set(ceiling_fan_entity.entity_id, ceiling_fan_entity.state, attributes=attrs) # Expose the script script_entity = hass.states.get('script.set_kitchen_light') attrs = dict(script_entity.attributes) attrs[emulated_hue.ATTR_EMULATED_HUE] = True hass.states.async_set(script_entity.entity_id, script_entity.state, attributes=attrs) return hass
def test_cors_middleware_not_loaded_by_default(hass): """Test accessing to server from banned IP when feature is off.""" with patch('homeassistant.components.http.setup_cors') as mock_setup: yield from async_setup_component(hass, 'http', {'http': {}}) assert len(mock_setup.mock_calls) == 0
def test_camera_content_type(hass, aiohttp_client): """Test local_file camera content_type.""" cam_config_jpg = { 'name': 'test_jpg', 'platform': 'local_file', 'file_path': '/path/to/image.jpg', } cam_config_png = { 'name': 'test_png', 'platform': 'local_file', 'file_path': '/path/to/image.png', } cam_config_svg = { 'name': 'test_svg', 'platform': 'local_file', 'file_path': '/path/to/image.svg', } cam_config_noext = { 'name': 'test_no_ext', 'platform': 'local_file', 'file_path': '/path/to/image', } yield from async_setup_component( hass, 'camera', { 'camera': [cam_config_jpg, cam_config_png, cam_config_svg, cam_config_noext] }) client = yield from aiohttp_client(hass.http.app) image = 'hello' m_open = MockOpen(read_data=image.encode()) with mock.patch('homeassistant.components.camera.local_file.open', m_open, create=True): resp_1 = yield from client.get('/api/camera_proxy/camera.test_jpg') resp_2 = yield from client.get('/api/camera_proxy/camera.test_png') resp_3 = yield from client.get('/api/camera_proxy/camera.test_svg') resp_4 = yield from client.get('/api/camera_proxy/camera.test_no_ext') assert resp_1.status == 200 assert resp_1.content_type == 'image/jpeg' body = yield from resp_1.text() assert body == image assert resp_2.status == 200 assert resp_2.content_type == 'image/png' body = yield from resp_2.text() assert body == image assert resp_3.status == 200 assert resp_3.content_type == 'image/svg+xml' body = yield from resp_3.text() assert body == image # default mime type assert resp_4.status == 200 assert resp_4.content_type == 'image/jpeg' body = yield from resp_4.text() assert body == image
def async_from_config_dict(config: Dict[str, Any], hass: core.HomeAssistant, config_dir: Optional[str]=None, enable_log: bool=True, verbose: bool=False, skip_pip: bool=False, log_rotate_days: Any=None) \ -> Optional[core.HomeAssistant]: """Try to configure Home Assistant from a config dict. Dynamically loads required components and its dependencies. This method is a coroutine. """ start = time() core_config = config.get(core.DOMAIN, {}) try: yield from conf_util.async_process_ha_core_config(hass, core_config) except vol.Invalid as ex: conf_util.async_log_exception(ex, 'homeassistant', core_config, hass) return None yield from hass.async_add_job(conf_util.process_ha_config_upgrade, hass) if enable_log: async_enable_logging(hass, verbose, log_rotate_days) hass.config.skip_pip = skip_pip if skip_pip: _LOGGER.warning('Skipping pip installation of required modules. ' 'This may cause issues.') if not loader.PREPARED: yield from hass.async_add_job(loader.prepare, hass) # Merge packages conf_util.merge_packages_config( config, core_config.get(conf_util.CONF_PACKAGES, {})) # Make a copy because we are mutating it. # Use OrderedDict in case original one was one. # Convert values to dictionaries if they are None new_config = OrderedDict() for key, value in config.items(): new_config[key] = value or {} config = new_config # Filter out the repeating and common config section [homeassistant] components = set( key.split(' ')[0] for key in config.keys() if key != core.DOMAIN) # setup components # pylint: disable=not-an-iterable res = yield from core_components.async_setup(hass, config) if not res: _LOGGER.error('Home Assistant core failed to initialize. ' 'Further initialization aborted.') return hass yield from persistent_notification.async_setup(hass, config) _LOGGER.info('Home Assistant core initialized') # stage 1 for component in components: if component not in FIRST_INIT_COMPONENT: continue hass.async_add_job(async_setup_component(hass, component, config)) yield from hass.async_block_till_done() # stage 2 for component in components: if component in FIRST_INIT_COMPONENT: continue hass.async_add_job(async_setup_component(hass, component, config)) yield from hass.async_block_till_done() stop = time() _LOGGER.info('Home Assistant initialized in %.2fs', stop - start) async_register_signal_handling(hass) return hass