def test_update_timeout(self, aioclient_mock): """Test update when timeout occurs.""" aioclient_mock.get(self.resource, exc=asyncio.TimeoutError()) run_coroutine_threadsafe( self.switch.async_update(), self.hass.loop).result() assert self.switch.is_on is None
def test_loading_configuration_from_packages(self): """Test loading packages config onto hass object config.""" self.hass.config = mock.Mock() run_coroutine_threadsafe( config_util.async_process_ha_core_config(self.hass, { 'latitude': 39, 'longitude': -1, 'elevation': 500, 'name': 'Huis', CONF_TEMPERATURE_UNIT: 'C', 'time_zone': 'Europe/Madrid', 'packages': { 'package_1': {'wake_on_lan': None}, 'package_2': {'light': {'platform': 'hue'}, 'media_extractor': None, 'sun': None}}, }), self.hass.loop).result() # Empty packages not allowed with pytest.raises(MultipleInvalid): run_coroutine_threadsafe( config_util.async_process_ha_core_config(self.hass, { 'latitude': 39, 'longitude': -1, 'elevation': 500, 'name': 'Huis', CONF_TEMPERATURE_UNIT: 'C', 'time_zone': 'Europe/Madrid', 'packages': {'empty_package': None}, }), self.hass.loop).result()
def test_update_when_unknown(self, aioclient_mock): """Test update when unknown status returned.""" aioclient_mock.get(self.resource, text='unknown status') run_coroutine_threadsafe( self.switch.async_update(), self.hass.loop).result() assert self.switch.is_on is None
def test_update_when_off(self, aioclient_mock): """Test update when switch is off.""" aioclient_mock.get(self.resource, text=self.body_off.template) run_coroutine_threadsafe( self.switch.async_update(), self.hass.loop).result() assert not self.switch.is_on
def test_platform_setup(self): """Test platform setup.""" config = {'name': 'test', 'platform': 'universal'} bad_config = {'platform': 'universal'} entities = [] def add_entities(new_entities): """Add devices to list.""" for dev in new_entities: entities.append(dev) setup_ok = True try: run_coroutine_threadsafe( universal.async_setup_platform( self.hass, validate_config(bad_config), add_entities), self.hass.loop).result() except MultipleInvalid: setup_ok = False assert not setup_ok assert 0 == len(entities) run_coroutine_threadsafe( universal.async_setup_platform( self.hass, validate_config(config), add_entities), self.hass.loop).result() assert 1 == len(entities) assert 'test' == entities[0].name
def test_supported_features_children_and_cmds(self): """Test supported media commands with children and attrs.""" config = copy(self.config_children_and_attr) excmd = {'service': 'media_player.test', 'data': {'entity_id': 'test'}} config['commands'] = { 'turn_on': excmd, 'turn_off': excmd, 'volume_up': excmd, 'volume_down': excmd, 'volume_mute': excmd, 'volume_set': excmd, 'select_source': excmd, 'shuffle_set': excmd } config = validate_config(config) ump = universal.UniversalMediaPlayer(self.hass, **config) ump.entity_id = media_player.ENTITY_ID_FORMAT.format(config['name']) run_coroutine_threadsafe(ump.async_update(), self.hass.loop).result() self.mock_mp_1._state = STATE_PLAYING self.mock_mp_1.schedule_update_ha_state() self.hass.block_till_done() run_coroutine_threadsafe(ump.async_update(), self.hass.loop).result() check_flags = universal.SUPPORT_TURN_ON | universal.SUPPORT_TURN_OFF \ | universal.SUPPORT_VOLUME_STEP | universal.SUPPORT_VOLUME_MUTE \ | universal.SUPPORT_SELECT_SOURCE | universal.SUPPORT_SHUFFLE_SET assert check_flags == ump.supported_features
def test_scan_devices_parse_error(self, aioclient_mock): """Set up a upc platform and scan device with parse error.""" aioclient_mock.get( "http://{}/common_page/login.html".format(self.host), cookies={'sessionToken': '654321'} ) aioclient_mock.post( "http://{}/xml/getter.xml".format(self.host), content=b'successful', cookies={'sessionToken': '654321'} ) scanner = run_coroutine_threadsafe(platform.async_get_scanner( self.hass, {DOMAIN: { CONF_PLATFORM: 'upc_connect', CONF_HOST: self.host }} ), self.hass.loop).result() assert len(aioclient_mock.mock_calls) == 1 aioclient_mock.clear_requests() aioclient_mock.post( "http://{}/xml/getter.xml".format(self.host), text="Blablebla blabalble", cookies={'sessionToken': '1235678'} ) mac_list = run_coroutine_threadsafe( scanner.async_scan_devices(), self.hass.loop).result() assert len(aioclient_mock.mock_calls) == 1 assert aioclient_mock.mock_calls[0][2] == 'token=654321&fun=123' assert scanner.token is None assert mac_list == []
def test_scan_devices(self, aioclient_mock): """Set up a upc platform and scan device.""" aioclient_mock.get( "http://{}/common_page/login.html".format(self.host), cookies={'sessionToken': '654321'} ) aioclient_mock.post( "http://{}/xml/getter.xml".format(self.host), content=b'successful', cookies={'sessionToken': '654321'} ) scanner = run_coroutine_threadsafe(platform.async_get_scanner( self.hass, {DOMAIN: { CONF_PLATFORM: 'upc_connect', CONF_HOST: self.host }} ), self.hass.loop).result() assert len(aioclient_mock.mock_calls) == 1 aioclient_mock.clear_requests() aioclient_mock.post( "http://{}/xml/getter.xml".format(self.host), text=load_fixture('upc_connect.xml'), cookies={'sessionToken': '1235678'} ) mac_list = run_coroutine_threadsafe( scanner.async_scan_devices(), self.hass.loop).result() assert len(aioclient_mock.mock_calls) == 1 assert aioclient_mock.mock_calls[0][2] == 'token=654321&fun=123' assert mac_list == ['30:D3:2D:0:69:21', '5C:AA:FD:25:32:02', '70:EE:50:27:A1:38']
def test_turn_on_timeout(self, aioclient_mock): """Test turn_on when timeout occurs.""" aioclient_mock.post(self.resource, status=500) run_coroutine_threadsafe( self.switch.async_turn_on(), self.hass.loop).result() assert self.switch.is_on is None
def test_get_image_fails(self): """Try to get image with timeout.""" with patch('homeassistant.components.camera.Camera.async_camera_image', return_value=mock_coro(None)), \ pytest.raises(HomeAssistantError): run_coroutine_threadsafe(camera.async_get_image( self.hass, 'camera.demo_camera'), self.hass.loop).result()
def test_get_image_with_timeout(self): """Try to get image with timeout.""" with patch('homeassistant.components.camera.Camera.async_camera_image', side_effect=asyncio.TimeoutError), \ pytest.raises(HomeAssistantError): run_coroutine_threadsafe(camera.async_get_image( self.hass, 'camera.demo_camera'), self.hass.loop).result()
def test_get_image_without_exists_camera(self): """Try to get image without exists camera.""" with patch('homeassistant.helpers.entity_component.EntityComponent.' 'get_entity', return_value=None), \ pytest.raises(HomeAssistantError): run_coroutine_threadsafe(camera.async_get_image( self.hass, 'camera.demo_camera'), self.hass.loop).result()
def test_async_add_job_pending_tasks_callback(self): """Run a callback in pending tasks.""" call_count = [] @ha.callback def test_callback(): """Test callback.""" call_count.append('call') @asyncio.coroutine def wait_finish_callback(): """Wait until all stuff is scheduled.""" yield from asyncio.sleep(0, loop=self.hass.loop) yield from asyncio.sleep(0, loop=self.hass.loop) for _ in range(2): self.hass.add_job(test_callback) run_coroutine_threadsafe( wait_finish_callback(), self.hass.loop).result() self.hass.block_till_done() assert len(self.hass._pending_tasks) == 0 assert len(call_count) == 2
def test_volume_down(self): """Test the volume_down helper function.""" assert self.player.volume_level == 0 self.player.set_volume_level(0.5) assert self.player.volume_level == 0.5 run_coroutine_threadsafe( self.player.async_volume_down(), self.hass.loop).result() assert self.player.volume_level == 0.3
def test_volume_down(self): """Test the volume_down helper function.""" self.assertEqual(self.player.volume_level, 0) self.player.set_volume_level(0.5) self.assertEqual(self.player.volume_level, 0.5) run_coroutine_threadsafe( self.player.async_volume_down(), self.hass.loop).result() self.assertEqual(self.player.volume_level, 0.3)
def test_toggle(self): """Test the toggle helper function.""" assert self.player.state == STATE_OFF run_coroutine_threadsafe( self.player.async_toggle(), self.hass.loop).result() assert self.player.state == STATE_ON run_coroutine_threadsafe( self.player.async_toggle(), self.hass.loop).result() assert self.player.state == STATE_OFF
def test_toggle(self): """Test the toggle helper function.""" self.assertEqual(self.player.state, STATE_OFF) run_coroutine_threadsafe( self.player.async_toggle(), self.hass.loop).result() self.assertEqual(self.player.state, STATE_ON) run_coroutine_threadsafe( self.player.async_toggle(), self.hass.loop).result() self.assertEqual(self.player.state, STATE_OFF)
def test_turn_off_success(self, aioclient_mock): """Test turn_off.""" aioclient_mock.post(self.resource, status=200) run_coroutine_threadsafe( self.switch.async_turn_off(), self.hass.loop).result() assert self.body_off.template == \ aioclient_mock.mock_calls[-1][2].decode() assert not self.switch.is_on
def test_media_play_pause(self): """Test the media_play_pause helper function.""" assert self.player.state == STATE_OFF run_coroutine_threadsafe( self.player.async_media_play_pause(), self.hass.loop).result() assert self.player.state == STATE_PLAYING run_coroutine_threadsafe( self.player.async_media_play_pause(), self.hass.loop).result() assert self.player.state == STATE_PAUSED
def test_turn_off_status_not_ok(self, aioclient_mock): """Test turn_off when error status returned.""" aioclient_mock.post(self.resource, status=500) run_coroutine_threadsafe( self.switch.async_turn_off(), self.hass.loop).result() assert self.body_off.template == \ aioclient_mock.mock_calls[-1][2].decode() assert self.switch.is_on is None
def add_entities(self, new_entities, update_before_add=False): """Add entities for a single platform.""" # That avoid deadlocks if update_before_add: self.logger.warning( "Call 'add_entities' with update_before_add=True " "only inside tests or you can run into a deadlock!") run_coroutine_threadsafe( self.async_add_entities(list(new_entities), update_before_add), self.hass.loop).result()
def test_jewish_calendar_sensor_holyness(self): """Test Jewish calendar sensor date output in hebrew.""" test_time = dt(2018, 9, 10) sensor = JewishCalSensor( name='test', language='hebrew', sensor_type='holyness', latitude=self.TEST_LATITUDE, longitude=self.TEST_LONGITUDE, diaspora=False) with patch('homeassistant.util.dt.now', return_value=test_time): run_coroutine_threadsafe( sensor.async_update(), self.hass.loop).result() self.assertEqual(sensor.state, 1)
def _compute_state(self, config): run_coroutine_threadsafe( config_util.async_process_ha_core_config(self.hass, config), self.hass.loop).result() entity = Entity() entity.entity_id = 'test.test' entity.hass = self.hass entity.schedule_update_ha_state() self.hass.block_till_done() return self.hass.states.get('test.test')
def test_run_coroutine_threadsafe_from_inside_event_loop( mock_ident, _, mock_iscoroutine): """Testing calling run_coroutine_threadsafe from inside an event loop.""" coro = MagicMock() loop = MagicMock() loop._thread_ident = None mock_ident.return_value = 5 mock_iscoroutine.return_value = True hasync.run_coroutine_threadsafe(coro, loop) assert len(loop.call_soon_threadsafe.mock_calls) == 1 loop._thread_ident = 5 mock_ident.return_value = 5 mock_iscoroutine.return_value = True with pytest.raises(RuntimeError): hasync.run_coroutine_threadsafe(coro, loop) assert len(loop.call_soon_threadsafe.mock_calls) == 1 loop._thread_ident = 1 mock_ident.return_value = 5 mock_iscoroutine.return_value = False with pytest.raises(TypeError): hasync.run_coroutine_threadsafe(coro, loop) assert len(loop.call_soon_threadsafe.mock_calls) == 1 loop._thread_ident = 1 mock_ident.return_value = 5 mock_iscoroutine.return_value = True hasync.run_coroutine_threadsafe(coro, loop) assert len(loop.call_soon_threadsafe.mock_calls) == 2
def test_active_child_state(self): """Test active child state property.""" config = validate_config(self.config_children_only) ump = universal.UniversalMediaPlayer(self.hass, **config) ump.entity_id = media_player.ENTITY_ID_FORMAT.format(config['name']) run_coroutine_threadsafe(ump.async_update(), self.hass.loop).result() assert ump._child_state is None self.mock_mp_1._state = STATE_PLAYING self.mock_mp_1.schedule_update_ha_state() self.hass.block_till_done() run_coroutine_threadsafe(ump.async_update(), self.hass.loop).result() assert self.mock_mp_1.entity_id == \ ump._child_state.entity_id self.mock_mp_2._state = STATE_PLAYING self.mock_mp_2.schedule_update_ha_state() self.hass.block_till_done() run_coroutine_threadsafe(ump.async_update(), self.hass.loop).result() assert self.mock_mp_1.entity_id == \ ump._child_state.entity_id self.mock_mp_1._state = STATE_OFF self.mock_mp_1.schedule_update_ha_state() self.hass.block_till_done() run_coroutine_threadsafe(ump.async_update(), self.hass.loop).result() assert self.mock_mp_2.entity_id == \ ump._child_state.entity_id
def hdl_kill_evt(self, e): if e.data.get('entity_id', None) is not None: if e.data.get('entity_id') == self.entity_id: _LOGGER.debug(f"{dbg()}:evt_energy_asset_kill: {self.entity_id} to be removed from ha") for l in self.listeners: _LOGGER.debug(f"{dbg()}:evt_energy_asset_kill: unregister listener: {l}") l() self._asset.rm_update_listener(self.update_callback) run_coroutine_threadsafe(self.async_remove(), self._hass.loop).result() self._hass.states.remove(self.entity_id) self._hass.bus.fire(EVENT_ENERGY_ASSET_KILLED, {"entity_id": self.entity_id})
def test_mac_vendor_lookup_unknown(self): """Prevent another mac vendor lookup if was not found first time.""" mac = 'B8:27:EB:00:00:00' device = device_tracker.Device( self.hass, timedelta(seconds=180), True, 'test', mac, 'Test name') with mock_aiohttp_client() as aioclient_mock: aioclient_mock.get('http://api.macvendors.com/b8:27:eb', status=404) run_coroutine_threadsafe(device.set_vendor_for_mac(), self.hass.loop).result() self.assertEqual(device.vendor, 'unknown')
def test_state_children_only(self): """Test media player state with only children.""" config = validate_config(self.config_children_only) ump = universal.UniversalMediaPlayer(self.hass, **config) ump.entity_id = media_player.ENTITY_ID_FORMAT.format(config['name']) run_coroutine_threadsafe(ump.async_update(), self.hass.loop).result() assert ump.state, STATE_OFF self.mock_mp_1._state = STATE_PLAYING self.mock_mp_1.schedule_update_ha_state() self.hass.block_till_done() run_coroutine_threadsafe(ump.async_update(), self.hass.loop).result() assert STATE_PLAYING == ump.state
def test_mac_vendor_lookup_exception(self): """Prevent another lookup if exception during API call.""" mac = 'B8:27:EB:00:00:00' device = device_tracker.Device( self.hass, timedelta(seconds=180), True, 'test', mac, 'Test name') with mock_aiohttp_client() as aioclient_mock: aioclient_mock.get('http://api.macvendors.com/b8:27:eb', exc=asyncio.TimeoutError()) run_coroutine_threadsafe(device.set_vendor_for_mac(), self.hass.loop).result() self.assertEqual(device.vendor, 'unknown')
def test_check_ha_config_file_correct(self, mock_check): """Check that restart propagates to stop.""" mock_check.return_value = check_config.HomeAssistantConfig() assert run_coroutine_threadsafe( config_util.async_check_ha_config_file(self.hass), self.hass.loop ).result() is None
def zones_from_places(api, home_place_name, add_zones, zones): _LOGGER.debug('Checking Places') places = get_places(api) if places is None: return # See if there is a Life360 Place whose name matches CONF_HOME_PLACE. # If there is, remove it from set and handle it specially. home_place = None for place in places.copy(): if place.name.lower() == home_place_name: home_place = place places.discard(place) # If a "Home Place" was found, and user wants to update zone.home with # it, and if it is indeed different, then update zone.home. if home_place and add_zones in (AZ_ONLY_HOME, AZ_ALL): hz_attrs = hass.states.get(ENTITY_ID_HOME).attributes if home_place != Place(hz_attrs[ATTR_FRIENDLY_NAME], hz_attrs[ATTR_LATITUDE], hz_attrs[ATTR_LONGITUDE], hz_attrs[ATTR_RADIUS]): log_places('Updating', [home_place]) zone_from_place(home_place, ENTITY_ID_HOME) if add_zones in (AZ_EXCEPT_HOME, AZ_ALL): # Do any of the Life360 Places that we created HA zones from no # longer exist? If so, remove the corresponding zones. remove_places = set(zones.keys()) - places if remove_places: log_places('Removing', remove_places) for remove_place in remove_places: run_coroutine_threadsafe( zones.pop(remove_place).async_remove(), hass.loop).result() # Are there any newly defined Life360 Places since the last time we # checked? If so, create HA zones for them. add_places = places - set(zones.keys()) if add_places: log_places('Adding', add_places) for add_place in add_places: zones[add_place] = zone_from_place(add_place)
def test_discovering_configuration(self, mock_detect, mock_elevation): """Test auto discovery for missing core configs.""" self.hass.config.latitude = None self.hass.config.longitude = None self.hass.config.elevation = None self.hass.config.location_name = None self.hass.config.time_zone = None run_coroutine_threadsafe( config_util.async_process_ha_core_config(self.hass, {}), self.hass.loop).result() assert self.hass.config.latitude == 32.8594 assert self.hass.config.longitude == -117.2073 assert self.hass.config.elevation == 101 assert self.hass.config.location_name == 'San Diego' assert self.hass.config.units.name == CONF_UNIT_SYSTEM_METRIC assert self.hass.config.units.is_metric assert self.hass.config.time_zone.zone == 'America/Los_Angeles'
def test_pending_sheduler(self): """Add a coro to pending tasks.""" call_count = [] @asyncio.coroutine def test_coro(): """Test Coro.""" call_count.append('call') for _ in range(3): self.hass.add_job(test_coro()) run_coroutine_threadsafe( asyncio.wait(self.hass._pending_tasks, loop=self.hass.loop), loop=self.hass.loop ).result() assert len(self.hass._pending_tasks) == 3 assert len(call_count) == 3
def test_get_image_from_camera(self, mock_camera): """Grab an image from camera entity.""" self.hass.start() image = run_coroutine_threadsafe( camera.async_get_image(self.hass, 'camera.demo_camera'), self.hass.loop).result() assert mock_camera.called assert image.content == b'Test'
def test_discovering_configuration_auto_detect_fails( self, mock_detect, mock_elevation): """Test config remains unchanged if discovery fails.""" self.hass.config = Config() self.hass.config.config_dir = "/test/config" run_coroutine_threadsafe( config_util.async_process_ha_core_config(self.hass, {}), self.hass.loop).result() blankConfig = Config() assert self.hass.config.latitude == blankConfig.latitude assert self.hass.config.longitude == blankConfig.longitude assert self.hass.config.elevation == blankConfig.elevation assert self.hass.config.location_name == blankConfig.location_name assert self.hass.config.units == blankConfig.units assert self.hass.config.time_zone == blankConfig.time_zone assert len(self.hass.config.whitelist_external_dirs) == 1 assert "/test/config/www" in self.hass.config.whitelist_external_dirs
def test_media_image_url(self): """Test media_image_url property.""" test_url = "test_url" config = validate_config(self.config_children_only) ump = universal.UniversalMediaPlayer(self.hass, **config) ump.entity_id = media_player.ENTITY_ID_FORMAT.format(config['name']) run_coroutine_threadsafe(ump.async_update(), self.hass.loop).result() assert ump.media_image_url is None self.mock_mp_1._state = STATE_PLAYING self.mock_mp_1._media_image_url = test_url self.mock_mp_1.schedule_update_ha_state() self.hass.block_till_done() run_coroutine_threadsafe(ump.async_update(), self.hass.loop).result() # mock_mp_1 will convert the url to the api proxy url. This test # ensures ump passes through the same url without an additional proxy. assert self.mock_mp_1.entity_picture == ump.entity_picture
def test_setup_timeout(self, aioclient_mock): """Test setup when connection timeout occurs.""" aioclient_mock.get("http://localhost", exc=asyncio.TimeoutError()) assert not run_coroutine_threadsafe( rest.async_setup_platform(self.hass, { "platform": "rest", "resource": "http://localhost" }, None), self.hass.loop, ).result()
def test_loading_configuration_from_packages(self): """Test loading packages config onto hass object config.""" self.hass.config = mock.Mock() run_coroutine_threadsafe( config_util.async_process_ha_core_config( self.hass, { 'latitude': 39, 'longitude': -1, 'elevation': 500, 'name': 'Huis', CONF_TEMPERATURE_UNIT: 'C', 'time_zone': 'Europe/Madrid', 'packages': { 'package_1': { 'wake_on_lan': None }, 'package_2': { 'light': { 'platform': 'hue' }, 'media_extractor': None, 'sun': None } }, }), self.hass.loop).result() # Empty packages not allowed with pytest.raises(MultipleInvalid): run_coroutine_threadsafe( config_util.async_process_ha_core_config( self.hass, { 'latitude': 39, 'longitude': -1, 'elevation': 500, 'name': 'Huis', CONF_TEMPERATURE_UNIT: 'C', 'time_zone': 'Europe/Madrid', 'packages': { 'empty_package': None }, }), self.hass.loop).result()
def validate_login(self, username: str, password: str) -> None: """Validate a username and password. Raises InvalidAuth if auth invalid. """ dummy = b'$2b$12$CiuFGszHx9eNHxPuQcwBWez4CwDTOcLTX5CbOpV6gef2nYuXkY7BO' found = None # Compare all users to avoid timing attacks. for user in self.users: if username == user['username']: found = user if found is None: # check a hash to make timing the same as if user was found bcrypt.checkpw(b'foo', dummy) raise InvalidAuth user_hash = base64.b64decode(found['password']) # if the hash is not a bcrypt hash... # provide a transparant upgrade for old pbkdf2 hash format if not (user_hash.startswith(b'$2a$') or user_hash.startswith(b'$2b$') or user_hash.startswith(b'$2x$') or user_hash.startswith(b'$2y$')): # IMPORTANT! validate the login, bail if invalid hashed = self.legacy_hash_password(password) if not hmac.compare_digest(hashed, user_hash): raise InvalidAuth # then re-hash the valid password with bcrypt self.change_password(found['username'], password) run_coroutine_threadsafe( self.async_save(), self.hass.loop ).result() user_hash = base64.b64decode(found['password']) # bcrypt.checkpw is timing-safe if not bcrypt.checkpw(password.encode(), user_hash): raise InvalidAuth
def test_jewish_calendar_sensor(self, time, tzname, latitude, longitude, language, sensor, diaspora, result): """Test Jewish calendar sensor output.""" tz = get_time_zone(tzname) set_default_time_zone(tz) test_time = tz.localize(time) self.hass.config.latitude = latitude self.hass.config.longitude = longitude sensor = JewishCalSensor(name='test', language=language, sensor_type=sensor, latitude=latitude, longitude=longitude, timezone=tz, diaspora=diaspora) sensor.hass = self.hass with patch('homeassistant.util.dt.now', return_value=test_time): run_coroutine_threadsafe(sensor.async_update(), self.hass.loop).result() assert sensor.state == result
def test_loading_configuration_temperature_unit(self): """Test backward compatibility when loading core config.""" self.hass.config = mock.Mock() run_coroutine_threadsafe( config_util.async_process_ha_core_config(self.hass, { 'latitude': 60, 'longitude': 50, 'elevation': 25, 'name': 'Huis', CONF_TEMPERATURE_UNIT: 'C', 'time_zone': 'America/New_York', }), self.hass.loop).result() assert self.hass.config.latitude == 60 assert self.hass.config.longitude == 50 assert self.hass.config.elevation == 25 assert self.hass.config.location_name == 'Huis' assert self.hass.config.units.name == CONF_UNIT_SYSTEM_METRIC assert self.hass.config.time_zone.zone == 'America/New_York'
def test_omer_sensor(self, now, candle_lighting, havdalah, diaspora, tzname, latitude, longitude, result): """Test Omer Count sensor output.""" time_zone = get_time_zone(tzname) set_default_time_zone(time_zone) test_time = time_zone.localize(now) self.hass.config.latitude = latitude self.hass.config.longitude = longitude sensor = JewishCalSensor(name='test', language='english', sensor_type='omer_count', latitude=latitude, longitude=longitude, timezone=time_zone, diaspora=diaspora) sensor.hass = self.hass with patch('homeassistant.util.dt.now', return_value=test_time): run_coroutine_threadsafe(sensor.async_update(), self.hass.loop).result() assert sensor.state == result
def test_shabbat_times_sensor(self, now, candle_lighting, havdalah, diaspora, tzname, latitude, longitude, result): """Test sensor output for upcoming shabbat/yomtov times.""" time_zone = get_time_zone(tzname) set_default_time_zone(time_zone) test_time = time_zone.localize(now) for sensor_type, value in result.items(): if isinstance(value, dt): result[sensor_type] = time_zone.localize(value) self.hass.config.latitude = latitude self.hass.config.longitude = longitude if ('upcoming_shabbat_candle_lighting' in result and 'upcoming_candle_lighting' not in result): result['upcoming_candle_lighting'] = \ result['upcoming_shabbat_candle_lighting'] if ('upcoming_shabbat_havdalah' in result and 'upcoming_havdalah' not in result): result['upcoming_havdalah'] = result['upcoming_shabbat_havdalah'] for sensor_type, result_value in result.items(): language = 'english' if sensor_type.startswith('hebrew_'): language = 'hebrew' sensor_type = sensor_type.replace('hebrew_', '') sensor = JewishCalSensor(name='test', language=language, sensor_type=sensor_type, latitude=latitude, longitude=longitude, timezone=time_zone, diaspora=diaspora, havdalah_offset=havdalah, candle_lighting_offset=candle_lighting) sensor.hass = self.hass with patch('homeassistant.util.dt.now', return_value=test_time): run_coroutine_threadsafe(sensor.async_update(), self.hass.loop).result() assert sensor.state == result_value, "Value for {}".format( sensor_type)
def test_send_message_with_data(self): """Test sending a message with to a notify group.""" run_coroutine_threadsafe( self.service.async_send_message( "Hello", title="Test notification", data={"hello": "world"} ), self.hass.loop, ).result() self.hass.block_till_done() assert self.service1.send_message.mock_calls[0][1][0] == "Hello" assert self.service1.send_message.mock_calls[0][2] == { "title": "Test notification", "data": {"hello": "world"}, } assert self.service2.send_message.mock_calls[0][1][0] == "Hello" assert self.service2.send_message.mock_calls[0][2] == { "target": ["unnamed device"], "title": "Test notification", "data": {"hello": "world", "test": "message"}, }
def setUpClass(cls): """Setup the class.""" cls.hass = hass = get_test_home_assistant() # We need to do this to get access to homeassistant/turn_(on,off) run_coroutine_threadsafe( core_components.async_setup(hass, {core.DOMAIN: {}}), hass.loop ).result() setup.setup_component( hass, http.DOMAIN, {http.DOMAIN: {http.CONF_SERVER_PORT: HTTP_SERVER_PORT}}) with patch('homeassistant.components' '.emulated_hue.UPNPResponderThread'): setup.setup_component(hass, emulated_hue.DOMAIN, { emulated_hue.DOMAIN: { emulated_hue.CONF_LISTEN_PORT: BRIDGE_SERVER_PORT }}) cls.hass.start()
def test_mac_vendor_mac_formats(self): """Verify all variations of MAC addresses are handled correctly.""" vendor_string = 'Raspberry Pi Foundation' with mock_aiohttp_client() as aioclient_mock: aioclient_mock.get('http://api.macvendors.com/b8:27:eb', text=vendor_string) aioclient_mock.get('http://api.macvendors.com/00:27:eb', text=vendor_string) mac = 'B8:27:EB:00:00:00' device = device_tracker.Device(self.hass, timedelta(seconds=180), True, 'test', mac, 'Test name') run_coroutine_threadsafe(device.set_vendor_for_mac(), self.hass.loop).result() self.assertEqual(device.vendor, vendor_string) mac = '0:27:EB:00:00:00' device = device_tracker.Device(self.hass, timedelta(seconds=180), True, 'test', mac, 'Test name') run_coroutine_threadsafe(device.set_vendor_for_mac(), self.hass.loop).result() self.assertEqual(device.vendor, vendor_string) mac = 'PREFIXED_B8:27:EB:00:00:00' device = device_tracker.Device(self.hass, timedelta(seconds=180), True, 'test', mac, 'Test name') run_coroutine_threadsafe(device.set_vendor_for_mac(), self.hass.loop).result() self.assertEqual(device.vendor, vendor_string)
def test_scan_devices_without_session(self, aioclient_mock): """Setup a upc platform and scan device with no token.""" aioclient_mock.get( "http://{}/common_page/login.html".format(self.host), cookies={'sessionToken': '654321'} ) aioclient_mock.post( "http://{}/xml/getter.xml".format(self.host), content=b'successful', cookies={'sessionToken': '654321'} ) scanner = run_coroutine_threadsafe(platform.async_get_scanner( self.hass, {DOMAIN: { CONF_PLATFORM: 'upc_connect', CONF_HOST: self.host }} ), self.hass.loop).result() assert len(aioclient_mock.mock_calls) == 1 aioclient_mock.clear_requests() aioclient_mock.get( "http://{}/common_page/login.html".format(self.host), cookies={'sessionToken': '654321'} ) aioclient_mock.post( "http://{}/xml/getter.xml".format(self.host), text=load_fixture('upc_connect.xml'), cookies={'sessionToken': '1235678'} ) scanner.token = None mac_list = run_coroutine_threadsafe( scanner.async_scan_devices(), self.hass.loop).result() assert len(aioclient_mock.mock_calls) == 2 assert aioclient_mock.mock_calls[1][2] == 'token=654321&fun=123' assert mac_list == ['30:D3:2D:0:69:21', '5C:AA:FD:25:32:02', '70:EE:50:27:A1:38']
def setup(hass, config=None): """Set up the component.""" rpa = RedpointAgent(ConfigPath=hass.config.config_dir) token = '/%s' % (str(uuid.uuid4())) views = { "Redpoint:root": ["/redpoint", True, RedpointRootView], "Redpoint:redirect": ["%s/redpoint/redirect" % (token), False, RedpointRedirectView], "Redpoint:check": ["%s/redpoint/check" % (token), False, RedpointCheckView], "Redpoint:configuration": [ "%s/redpoint/configuration" % (token), False, RedpointConfigurationView], "Redpoint:info": ["%s/redpoint/info" % (token), False, RedpointInfoView], "Redpoint:version": ["%s/redpoint/version" % (token), False, RedpointVersionView], "Redpoint:publish": ["%s/redpoint/publish" % (token), False, RedpointPublishView], "Redpoint:restart": ["%s/redpoint/restart" % (token), False, RedpointRestartView], "Redpoint:sourcecode": ["%s/redpoint/sourcecode" % (token), False, RedpointSourcecodeView], } for name, t in views.items(): view = t[2]() setattr(view, 'name', name) setattr(view, 'url', t[0]) setattr(view, 'requires_auth', t[1]) setattr(view, 'cors_allowed', True) setattr(view, 'rpa', rpa) setattr(view, 'token', token) setattr(view, 'hass', hass) hass.http.register_view(view) run_coroutine_threadsafe( hass.components.frontend.async_register_built_in_panel( 'iframe', "红点", "mdi:hand-pointing-right", 'redpoint_config', {'url': views["Redpoint:redirect"][0]} ), hass.loop ) return True
def test_scan_devices_without_session_wrong_re(self, aioclient_mock): """Setup a upc platform and scan device with no token and wrong.""" aioclient_mock.get( "http://{}/common_page/login.html".format(self.host), cookies={'sessionToken': '654321'} ) aioclient_mock.post( "http://{}/xml/getter.xml".format(self.host), content=b'successful', cookies={'sessionToken': '654321'} ) scanner = run_coroutine_threadsafe(platform.async_get_scanner( self.hass, {DOMAIN: { CONF_PLATFORM: 'upc_connect', CONF_HOST: self.host }} ), self.hass.loop).result() assert len(aioclient_mock.mock_calls) == 1 aioclient_mock.clear_requests() aioclient_mock.get( "http://{}/common_page/login.html".format(self.host), cookies={'sessionToken': '654321'} ) aioclient_mock.post( "http://{}/xml/getter.xml".format(self.host), status=400, cookies={'sessionToken': '1235678'} ) scanner.token = None mac_list = run_coroutine_threadsafe( scanner.async_scan_devices(), self.hass.loop).result() assert len(aioclient_mock.mock_calls) == 2 assert aioclient_mock.mock_calls[1][2] == 'token=654321&fun=123' assert mac_list == []
def test_check_ha_config_file_correct(self, mock_create): """Check that restart propagates to stop.""" process_mock = mock.MagicMock() attrs = { 'communicate.return_value': mock_coro((b'output', None)), 'wait.return_value': mock_coro(0) } process_mock.configure_mock(**attrs) mock_create.return_value = mock_coro(process_mock) assert run_coroutine_threadsafe( config_util.async_check_ha_config_file(self.hass), self.hass.loop).result() is None
def subscribe(hass: HomeAssistantType, topic: str, msg_callback: MessageCallbackType, qos: int = DEFAULT_QOS, encoding: str = 'utf-8') -> Callable[[], None]: """Subscribe to an MQTT topic.""" async_remove = run_coroutine_threadsafe( async_subscribe(hass, topic, msg_callback, qos, encoding), hass.loop ).result() def remove(): """Remove listener convert.""" run_callback_threadsafe(hass.loop, async_remove).result() return remove
def async_setup_platform(hass, config, async_add_devices, discovery_info=None): """ Setup the Rotel platform, and the related transport Ask for async link as soon as transport is ready """ _LOGGER.debug('ROTEL : starting') rotel = RotelDevice(config.get(CONF_NAME), config.get(CONF_HOST), config.get(CONF_PORT), hass.loop) async_add_devices([rotel]) coro = hass.loop.create_connection(RotelProtocol, config.get(CONF_HOST), config.get(CONF_PORT)) futur = hasync.run_coroutine_threadsafe(coro, hass.loop) futur.add_done_callback(partial(bind_transport_to_device, rotel))
def test_loading_configuration(self): """Test loading core config onto hass object.""" self.hass.config = mock.Mock() run_coroutine_threadsafe( config_util.async_process_ha_core_config(self.hass, { 'latitude': 60, 'longitude': 50, 'elevation': 25, 'name': 'Huis', CONF_UNIT_SYSTEM: CONF_UNIT_SYSTEM_IMPERIAL, 'time_zone': 'America/New_York', 'whitelist_external_dirs': '/tmp', }), self.hass.loop).result() assert self.hass.config.latitude == 60 assert self.hass.config.longitude == 50 assert self.hass.config.elevation == 25 assert self.hass.config.location_name == 'Huis' assert self.hass.config.units.name == CONF_UNIT_SYSTEM_IMPERIAL assert self.hass.config.time_zone.zone == 'America/New_York' assert len(self.hass.config.whitelist_external_dirs) == 2 assert '/tmp' in self.hass.config.whitelist_external_dirs
def test_async_add_job_pending_tasks_executor(self): """Run an executor in pending tasks.""" call_count = [] def test_executor(): """Test executor.""" call_count.append('call') @asyncio.coroutine def wait_finish_callback(): """Wait until all stuff is scheduled.""" yield from asyncio.sleep(0, loop=self.hass.loop) yield from asyncio.sleep(0, loop=self.hass.loop) for _ in range(2): self.hass.add_job(test_executor) run_coroutine_threadsafe(wait_finish_callback(), self.hass.loop).result() assert len(self.hass._pending_tasks) == 2 self.hass.block_till_done() assert len(call_count) == 2
def create_group(hass, name, entity_ids=None, user_defined=True, visible=True, icon=None, view=False, control=None, object_id=None): """Initialize a group.""" return run_coroutine_threadsafe( Group.async_create_group(hass, name, entity_ids, user_defined, visible, icon, view, control, object_id), hass.loop).result()
def setUp(self): # pylint: disable=invalid-name """Set up things to be run when tests are started.""" self.hass = get_test_home_assistant() self.events = [] self.service1 = demo.DemoNotificationService(self.hass) self.service2 = demo.DemoNotificationService(self.hass) self.service1.send_message = MagicMock(autospec=True) self.service2.send_message = MagicMock(autospec=True) def mock_get_service(hass, config, discovery_info=None): if config["name"] == "demo1": return self.service1 return self.service2 with assert_setup_component(2, notify.DOMAIN), patch.object( demo, "get_service", mock_get_service ): setup_component( self.hass, notify.DOMAIN, { "notify": [ {"name": "demo1", "platform": "demo"}, {"name": "demo2", "platform": "demo"}, ] }, ) self.service = run_coroutine_threadsafe( group.async_get_service( self.hass, { "services": [ {"service": "demo1"}, { "service": "demo2", "data": { "target": "unnamed device", "data": {"test": "message"}, }, }, ] }, ), self.hass.loop, ).result() assert self.service is not None
def test_check_ha_config_file_wrong(self, mock_create): """Check that restart with a bad config doesn't propagate to stop.""" process_mock = mock.MagicMock() attrs = { 'communicate.return_value': mock_coro(('\033[34mhello'.encode('utf-8'), None)), 'wait.return_value': mock_coro(1) } process_mock.configure_mock(**attrs) mock_create.return_value = mock_coro(process_mock) assert run_coroutine_threadsafe( config_util.async_check_ha_config_file(self.hass), self.hass.loop).result() == 'hello'
def test_async_add_job_pending_tasks_coro(self): """Add a coro to pending tasks.""" call_count = [] @asyncio.coroutine def test_coro(): """Test Coro.""" call_count.append('call') for _ in range(2): self.hass.add_job(test_coro()) @asyncio.coroutine def wait_finish_callback(): """Wait until all stuff is scheduled.""" yield from asyncio.sleep(0) yield from asyncio.sleep(0) run_coroutine_threadsafe(wait_finish_callback(), self.hass.loop).result() assert len(self.hass._pending_tasks) == 2 self.hass.block_till_done() assert len(call_count) == 2
def setUp(self): # pylint: disable=invalid-name """Setup things to be run when tests are started.""" self.hass = get_test_home_assistant() self.events = [] self.service1 = demo.DemoNotificationService(self.hass) self.service2 = demo.DemoNotificationService(self.hass) self.service1.send_message = MagicMock(autospec=True) self.service2.send_message = MagicMock(autospec=True) def mock_get_service(hass, config, discovery_info=None): if config['name'] == 'demo1': return self.service1 else: return self.service2 with assert_setup_component(2), \ patch.object(demo, 'get_service', mock_get_service): setup_component( self.hass, notify.DOMAIN, { 'notify': [{ 'name': 'demo1', 'platform': 'demo' }, { 'name': 'demo2', 'platform': 'demo' }] }) self.service = run_coroutine_threadsafe( group.async_get_service( self.hass, { 'services': [{ 'service': 'demo1' }, { 'service': 'demo2', 'data': { 'target': 'unnamed device', 'data': { 'test': 'message' } } }] }), self.hass.loop).result() assert self.service is not None
def call(self, domain, service, service_data=None, blocking=False): """ Call a service. Specify blocking=True to wait till service is executed. Waits a maximum of SERVICE_CALL_LIMIT. If blocking = True, will return boolean if service executed successfully within SERVICE_CALL_LIMIT. This method will fire an event to call the service. This event will be picked up by this ServiceRegistry and any other ServiceRegistry that is listening on the EventBus. Because the service is sent as an event you are not allowed to use the keys ATTR_DOMAIN and ATTR_SERVICE in your service_data. """ return run_coroutine_threadsafe( self.async_call(domain, service, service_data, blocking), self._hass.loop).result()