async def test_start_hook_stop_agent_ok(dummy_hook): dummy_hook.hook = MagicMock(pre_stop=AsyncMock()) await dummy_hook.stop() dummy_hook.hook.pre_stop.assert_called_once()
def mock_run_code(mocker): async_mock = AsyncMock(return_value=str(uuid.uuid4())) mocker.patch("grpc_client.GRPCClient.run_code", side_effect=async_mock) return async_mock
def mock_get_run_error(mocker): async_mock = AsyncMock(return_value="MOCK_ERROR") mocker.patch("grpc_client.GRPCClient.get_run_error", side_effect=async_mock) return async_mock
def dummy_soco_service_fixture(): """Create dummy_soco_service fixture.""" service = Mock() service.subscribe = AsyncMock() return service
async def test_setup_imported(hass, mock_zeroconf): """Test async_setup with imported config options.""" legacy_persist_file_path = hass.config.path(HOMEKIT_FILE) legacy_aid_storage_path = hass.config.path(STORAGE_DIR, "homekit.aids") legacy_homekit_state_contents = {"homekit.state": 1} legacy_homekit_aids_contents = {"homekit.aids": 1} await hass.async_add_executor_job( _write_data, legacy_persist_file_path, legacy_homekit_state_contents ) await hass.async_add_executor_job( _write_data, legacy_aid_storage_path, legacy_homekit_aids_contents ) entry = MockConfigEntry( domain=DOMAIN, source=SOURCE_IMPORT, data={CONF_NAME: BRIDGE_NAME, CONF_PORT: DEFAULT_PORT, CONF_ENTRY_INDEX: 0}, options={}, ) entry.add_to_hass(hass) with patch(f"{PATH_HOMEKIT}.HomeKit") as mock_homekit: mock_homekit.return_value = homekit = Mock() type(homekit).async_start = AsyncMock() assert await hass.config_entries.async_setup(entry.entry_id) await hass.async_block_till_done() mock_homekit.assert_any_call( hass, BRIDGE_NAME, DEFAULT_PORT, None, ANY, {}, HOMEKIT_MODE_BRIDGE, None, entry.entry_id, ) assert mock_homekit().setup.called is True # Test auto start enabled mock_homekit.reset_mock() hass.bus.async_fire(EVENT_HOMEASSISTANT_START) await hass.async_block_till_done() mock_homekit().async_start.assert_called() migrated_persist_file_path = get_persist_fullpath_for_entry_id(hass, entry.entry_id) assert ( await hass.async_add_executor_job( json_util.load_json, migrated_persist_file_path ) == legacy_homekit_state_contents ) os.unlink(migrated_persist_file_path) migrated_aid_file_path = get_aid_storage_fullpath_for_entry_id(hass, entry.entry_id) assert ( await hass.async_add_executor_job(json_util.load_json, migrated_aid_file_path) == legacy_homekit_aids_contents ) os.unlink(migrated_aid_file_path)
async def test_two_step_flow(hass, client, enable_custom_integrations): """Test we can finish a two step flow.""" mock_integration( hass, MockModule("test", async_setup_entry=AsyncMock(return_value=True)) ) mock_entity_platform(hass, "config_flow.test", None) class TestFlow(core_ce.ConfigFlow): VERSION = 1 async def async_step_user(self, user_input=None): return self.async_show_form( step_id="account", data_schema=vol.Schema({"user_title": str}) ) async def async_step_account(self, user_input=None): return self.async_create_entry( title=user_input["user_title"], data={"secret": "account_token"} ) with patch.dict(HANDLERS, {"test": TestFlow}): resp = await client.post( "/api/config/config_entries/flow", json={"handler": "test"} ) assert resp.status == HTTPStatus.OK data = await resp.json() flow_id = data.pop("flow_id") assert data == { "type": "form", "handler": "test", "step_id": "account", "data_schema": [{"name": "user_title", "type": "string"}], "description_placeholders": None, "errors": None, "last_step": None, } with patch.dict(HANDLERS, {"test": TestFlow}): resp = await client.post( f"/api/config/config_entries/flow/{flow_id}", json={"user_title": "user-title"}, ) assert resp.status == HTTPStatus.OK entries = hass.config_entries.async_entries("test") assert len(entries) == 1 data = await resp.json() data.pop("flow_id") assert data == { "handler": "test", "type": "create_entry", "title": "user-title", "version": 1, "result": { "disabled_by": None, "domain": "test", "entry_id": entries[0].entry_id, "source": core_ce.SOURCE_USER, "state": core_ce.ConfigEntryState.LOADED.value, "supports_options": False, "supports_unload": False, "pref_disable_new_entities": False, "pref_disable_polling": False, "title": "user-title", "reason": None, }, "description": None, "description_placeholders": None, "options": {}, }
async def test_options_flow_with_invalid_data(hass, client): """Test an options flow with invalid_data.""" mock_integration( hass, MockModule("test", async_setup_entry=AsyncMock(return_value=True)) ) class TestFlow(core_ce.ConfigFlow): @staticmethod @callback def async_get_options_flow(config_entry): class OptionsFlowHandler(data_entry_flow.FlowHandler): async def async_step_init(self, user_input=None): return self.async_show_form( step_id="finish", data_schema=vol.Schema( { vol.Required( "choices", default=["invalid", "valid"] ): cv.multi_select({"valid": "Valid"}) } ), ) async def async_step_finish(self, user_input=None): return self.async_create_entry( title="Enable disable", data=user_input ) return OptionsFlowHandler() MockConfigEntry( domain="test", entry_id="test1", source="bla", ).add_to_hass(hass) entry = hass.config_entries.async_entries()[0] with patch.dict(HANDLERS, {"test": TestFlow}): url = "/api/config/config_entries/options/flow" resp = await client.post(url, json={"handler": entry.entry_id}) assert resp.status == HTTPStatus.OK data = await resp.json() flow_id = data.pop("flow_id") assert data == { "type": "form", "handler": "test1", "step_id": "finish", "data_schema": [ { "default": ["invalid", "valid"], "name": "choices", "options": {"valid": "Valid"}, "required": True, "type": "multi_select", } ], "description_placeholders": None, "errors": None, "last_step": None, } with patch.dict(HANDLERS, {"test": TestFlow}): resp = await client.post( f"/api/config/config_entries/options/flow/{flow_id}", json={"choices": ["valid", "invalid"]}, ) assert resp.status == HTTPStatus.BAD_REQUEST data = await resp.json() assert data == { "message": "User input malformed: invalid is not a valid option for " "dictionary value @ data['choices']" }
async def __aexit__(self, *error_info): return self async def json(self): return self.expected_result # For api calls that support rate-limiting (e.g. api.get_users()): class AsyncSleep(MagicMock): async def __call__(self, *args, **kwargs): return super(AsyncSleep, self).__call__(*args, **kwargs) SLEEP_PATCH = patch("asyncio.sleep", new_callable=AsyncSleep) SESSION_PATCH = patch("aiohttp_retry.ClientSession", return_value=AsyncMock(ClientSession)) class TestAPI(IsolatedAsyncioTestCase): def setUp(self): with SESSION_PATCH: self.api = INatAPI() async def test_get_taxa_by_id(self): """Test get_taxa by id.""" expected_result = {"results": [{"name": "Animalia"}]} with API_REQUESTS_PATCH as mock_get: mock_get.return_value = ResponseMock(expected_result) taxon = await self.api.get_taxa(1) self.assertEqual(taxon["results"][0]["name"], "Animalia")
async def test_switch_power(opp): """Test a configuration using a simple float.""" config = CONFIG_SWITCH_NO_POWER[DOMAIN][CONF_ENTITIES] assert await async_setup_component( opp, SWITCH_DOMAIN, {SWITCH_DOMAIN: { "platform": "demo" }}, ) with patch( "sense_energy.SenseLink", return_value=Mock(start=AsyncMock(), close=AsyncMock()), ): assert await async_setup_component(opp, DOMAIN, CONFIG_SWITCH_NO_POWER) is True await opp.async_block_till_done() await emulated_kasa.validate_configs(opp, config) # Turn switch on await opp.services.async_call(SWITCH_DOMAIN, SERVICE_TURN_ON, {ATTR_ENTITY_ID: ENTITY_SWITCH}, blocking=True) switch = opp.states.get(ENTITY_SWITCH) assert switch.state == STATE_ON power = switch.attributes[ATTR_CURRENT_POWER_W] assert power == 100 assert switch.name == "AC" plug_it = emulated_kasa.get_plug_devices(opp, config) plug = next(plug_it).generate_response() assert nested_value(plug, "system", "get_sysinfo", "alias") == "AC" power = nested_value(plug, "emeter", "get_realtime", "power") assert math.isclose(power, power) opp.states.async_set( ENTITY_SWITCH, STATE_ON, attributes={ ATTR_CURRENT_POWER_W: 120, ATTR_FRIENDLY_NAME: "AC" }, ) plug_it = emulated_kasa.get_plug_devices(opp, config) plug = next(plug_it).generate_response() assert nested_value(plug, "system", "get_sysinfo", "alias") == "AC" power = nested_value(plug, "emeter", "get_realtime", "power") assert math.isclose(power, 120) # Turn off await opp.services.async_call(SWITCH_DOMAIN, SERVICE_TURN_OFF, {ATTR_ENTITY_ID: ENTITY_SWITCH}, blocking=True) plug_it = emulated_kasa.get_plug_devices(opp, config) plug = next(plug_it).generate_response() assert nested_value(plug, "system", "get_sysinfo", "alias") == "AC" power = nested_value(plug, "emeter", "get_realtime", "power") assert math.isclose(power, 0)
def patched_get(mock_async_get_request, side_effect=None): """Return a patched version of aiohttp.ClientSession.get().""" mock = AsyncMock(side_effect=side_effect) if side_effect else AsyncMock(return_value=mock_async_get_request) if not side_effect: mock_async_get_request.close = Mock() return patch("aiohttp.ClientSession.get", mock)
def __init__(self, service_type): """Initialize the instance.""" self.service_type = service_type self.subscribe = AsyncMock()
def test_start(mocker, metadata_manager: MetadataManager): cache_manager = get_cache_manager() test_host = "test_host" cache_manager._hosts = [] cache_manager.domain = test_host message = { MESSAGE_SHARED_MEMORY_NAME: "test", MESSAGE_URL: "empty_url", MESSAGE_BYPASS_CACHE: "f", MESSAGE_ALLOW_LIST: {}, MESSAGE_HTML: "test_html", MESSAGE_HEADERS: "", } log_spy = mocker.spy(metadata_manager, "_logger") with mock.patch("core.metadata_manager.shared_memory.ShareableList" ) as shareable_list: with mock.patch( "core.metadata_manager.WebsiteManager") as website_manager: with mock.patch( "cache.cache_manager.CacheManager._class.update_to_current_domain" ): async_mock = AsyncMock(return_value={}) with mock.patch( "core.metadata_manager.MetadataManager._class._extract_meta_data", side_effect=async_mock, ) as extract_meta_data: with mock.patch( "core.metadata_manager.MetadataManager._class.cache_data" ): with mock.patch( "core.metadata_manager.WebsiteManager._class.load_website_data" ): website_manager.get_instance( ).website_data.html = ("non-empty html") shareable_list.return_value = [0, ""] output = metadata_manager.start(message) assert MESSAGE_EXCEPTION not in output.keys() assert "time_for_extraction" in output.keys() assert log_spy.debug.call_count == 6 assert log_spy.exception.call_count == 0 extract_meta_data.side_effect = ConnectionError output = metadata_manager.start(message) assert MESSAGE_EXCEPTION in output.keys() assert ("Connection error extracting metadata:" in output[MESSAGE_EXCEPTION]) assert log_spy.exception.call_count == 1 extract_meta_data.side_effect = Exception output = metadata_manager.start(message) assert MESSAGE_EXCEPTION in output.keys() assert ( "Unknown exception from extracting metadata:" in output[MESSAGE_EXCEPTION]) assert log_spy.exception.call_count == 2 website_manager.get_instance( ).website_data.html = ("") output = metadata_manager.start(message) assert MESSAGE_EXCEPTION in output.keys() assert ("Empty html. Potentially, splash failed." in output[MESSAGE_EXCEPTION]) website_manager.reset()
def mock_client(): """Define a fixture for a client creation coroutine.""" return AsyncMock(return_value=None)
async def test_duplicate_error(hass): """Test that errors are shown when duplicates are added.""" conf = {CONF_USERNAME: "******", CONF_PASSWORD: "******"} MockConfigEntry(domain=DOMAIN, unique_id="*****@*****.**", data=conf).add_to_hass(hass) result = await hass.config_entries.flow.async_init( DOMAIN, context={"source": SOURCE_USER}, data=conf) assert result["type"] == data_entry_flow.RESULT_TYPE_ABORT assert result["reason"] == "already_configured" @pytest.mark.parametrize("mock_client", [AsyncMock(side_effect=aionotion.errors.NotionError)]) async def test_invalid_credentials(hass, mock_aionotion): """Test that an invalid API/App Key throws an error.""" conf = {CONF_USERNAME: "******", CONF_PASSWORD: "******"} flow = config_flow.NotionFlowHandler() flow.hass = hass flow.context = {"source": SOURCE_USER} result = await flow.async_step_user(user_input=conf) assert result["errors"] == {"base": "invalid_auth"} async def test_show_form(hass): """Test that the form is served with no input.""" flow = config_flow.NotionFlowHandler()
async def test_setup_camera_client_error(hass: HomeAssistant) -> None: """Test a successful camera.""" client = create_mock_motioneye_client() client.async_client_login = AsyncMock(side_effect=MotionEyeClientError) await setup_mock_motioneye_config_entry(hass, client=client) assert not hass.states.get(TEST_CAMERA_ENTITY_ID)
async def test_template(opp): """Test a configuration using a complex template.""" config = CONFIG_FAN[DOMAIN][CONF_ENTITIES] assert await async_setup_component(opp, FAN_DOMAIN, {FAN_DOMAIN: { "platform": "demo" }}) with patch( "sense_energy.SenseLink", return_value=Mock(start=AsyncMock(), close=AsyncMock()), ): assert await async_setup_component(opp, DOMAIN, CONFIG_FAN) is True await opp.async_block_till_done() await emulated_kasa.validate_configs(opp, config) # Turn all devices on to known state await opp.services.async_call(FAN_DOMAIN, SERVICE_TURN_ON, {ATTR_ENTITY_ID: ENTITY_FAN}, blocking=True) await opp.services.async_call( FAN_DOMAIN, SERVICE_SET_SPEED, { ATTR_ENTITY_ID: ENTITY_FAN, ATTR_SPEED: "low" }, blocking=True, ) fan = opp.states.get(ENTITY_FAN) assert fan.state == STATE_ON # Fan low: plug_it = emulated_kasa.get_plug_devices(opp, config) plug = next(plug_it).generate_response() assert nested_value(plug, "system", "get_sysinfo", "alias") == ENTITY_FAN_NAME power = nested_value(plug, "emeter", "get_realtime", "power") assert math.isclose(power, ENTITY_FAN_SPEED_LOW) # Fan High: await opp.services.async_call( FAN_DOMAIN, SERVICE_SET_SPEED, { ATTR_ENTITY_ID: ENTITY_FAN, ATTR_SPEED: "high" }, blocking=True, ) plug_it = emulated_kasa.get_plug_devices(opp, config) plug = next(plug_it).generate_response() assert nested_value(plug, "system", "get_sysinfo", "alias") == ENTITY_FAN_NAME power = nested_value(plug, "emeter", "get_realtime", "power") assert math.isclose(power, ENTITY_FAN_SPEED_HIGH) # Fan off: await opp.services.async_call(FAN_DOMAIN, SERVICE_TURN_OFF, {ATTR_ENTITY_ID: ENTITY_FAN}, blocking=True) plug_it = emulated_kasa.get_plug_devices(opp, config) plug = next(plug_it).generate_response() assert nested_value(plug, "system", "get_sysinfo", "alias") == ENTITY_FAN_NAME power = nested_value(plug, "emeter", "get_realtime", "power") assert math.isclose(power, 0)
async def test_setup_camera_empty_data(hass: HomeAssistant) -> None: """Test a successful camera.""" client = create_mock_motioneye_client() client.async_get_cameras = AsyncMock(return_value={}) await setup_mock_motioneye_config_entry(hass, client=client) assert not hass.states.get(TEST_CAMERA_ENTITY_ID)
async def test_sensor(opp): """Test a configuration using a sensor in a template.""" config = CONFIG_LIGHT[DOMAIN][CONF_ENTITIES] assert await async_setup_component(opp, LIGHT_DOMAIN, {LIGHT_DOMAIN: { "platform": "demo" }}) assert await async_setup_component( opp, SENSOR_DOMAIN, {SENSOR_DOMAIN: { "platform": "demo" }}, ) with patch( "sense_energy.SenseLink", return_value=Mock(start=AsyncMock(), close=AsyncMock()), ): assert await async_setup_component(opp, DOMAIN, CONFIG_LIGHT) is True await opp.async_block_till_done() await emulated_kasa.validate_configs(opp, config) await opp.services.async_call(LIGHT_DOMAIN, SERVICE_TURN_ON, {ATTR_ENTITY_ID: ENTITY_LIGHT}, blocking=True) opp.states.async_set(ENTITY_SENSOR, 35) light = opp.states.get(ENTITY_LIGHT) assert light.state == STATE_ON sensor = opp.states.get(ENTITY_SENSOR) assert sensor.state == "35" # light plug_it = emulated_kasa.get_plug_devices(opp, config) plug = next(plug_it).generate_response() assert nested_value(plug, "system", "get_sysinfo", "alias") == ENTITY_LIGHT_NAME power = nested_value(plug, "emeter", "get_realtime", "power") assert math.isclose(power, 35) # change power sensor opp.states.async_set(ENTITY_SENSOR, 40) plug_it = emulated_kasa.get_plug_devices(opp, config) plug = next(plug_it).generate_response() assert nested_value(plug, "system", "get_sysinfo", "alias") == ENTITY_LIGHT_NAME power = nested_value(plug, "emeter", "get_realtime", "power") assert math.isclose(power, 40) # report 0 if device is off await opp.services.async_call(LIGHT_DOMAIN, SERVICE_TURN_OFF, {ATTR_ENTITY_ID: ENTITY_LIGHT}, blocking=True) plug_it = emulated_kasa.get_plug_devices(opp, config) plug = next(plug_it).generate_response() assert nested_value(plug, "system", "get_sysinfo", "alias") == ENTITY_LIGHT_NAME power = nested_value(plug, "emeter", "get_realtime", "power") assert math.isclose(power, 0)
async def test_two_step_options_flow(hass, client): """Test we can finish a two step options flow.""" mock_integration( hass, MockModule("test", async_setup_entry=AsyncMock(return_value=True)) ) class TestFlow(core_ce.ConfigFlow): @staticmethod @callback def async_get_options_flow(config_entry): class OptionsFlowHandler(data_entry_flow.FlowHandler): async def async_step_init(self, user_input=None): return self.async_show_form( step_id="finish", data_schema=vol.Schema({"enabled": bool}) ) async def async_step_finish(self, user_input=None): return self.async_create_entry( title="Enable disable", data=user_input ) return OptionsFlowHandler() MockConfigEntry( domain="test", entry_id="test1", source="bla", ).add_to_hass(hass) entry = hass.config_entries.async_entries()[0] with patch.dict(HANDLERS, {"test": TestFlow}): url = "/api/config/config_entries/options/flow" resp = await client.post(url, json={"handler": entry.entry_id}) assert resp.status == HTTPStatus.OK data = await resp.json() flow_id = data.pop("flow_id") assert data == { "type": "form", "handler": "test1", "step_id": "finish", "data_schema": [{"name": "enabled", "type": "boolean"}], "description_placeholders": None, "errors": None, "last_step": None, } with patch.dict(HANDLERS, {"test": TestFlow}): resp = await client.post( f"/api/config/config_entries/options/flow/{flow_id}", json={"enabled": True}, ) assert resp.status == HTTPStatus.OK data = await resp.json() data.pop("flow_id") assert data == { "handler": "test1", "type": "create_entry", "title": "Enable disable", "version": 1, "description": None, "description_placeholders": None, }
async def test_multiple_devices(opp): """Test that devices are reported correctly.""" config = CONFIG[DOMAIN][CONF_ENTITIES] assert await async_setup_component(opp, SWITCH_DOMAIN, {SWITCH_DOMAIN: { "platform": "demo" }}) assert await async_setup_component(opp, LIGHT_DOMAIN, {LIGHT_DOMAIN: { "platform": "demo" }}) assert await async_setup_component(opp, FAN_DOMAIN, {FAN_DOMAIN: { "platform": "demo" }}) assert await async_setup_component( opp, SENSOR_DOMAIN, {SENSOR_DOMAIN: { "platform": "demo" }}, ) with patch( "sense_energy.SenseLink", return_value=Mock(start=AsyncMock(), close=AsyncMock()), ): assert await emulated_kasa.async_setup(opp, CONFIG) is True await opp.async_block_till_done() await emulated_kasa.validate_configs(opp, config) # Turn all devices on to known state await opp.services.async_call(SWITCH_DOMAIN, SERVICE_TURN_ON, {ATTR_ENTITY_ID: ENTITY_SWITCH}, blocking=True) await opp.services.async_call(LIGHT_DOMAIN, SERVICE_TURN_ON, {ATTR_ENTITY_ID: ENTITY_LIGHT}, blocking=True) opp.states.async_set(ENTITY_SENSOR, 35) await opp.services.async_call(FAN_DOMAIN, SERVICE_TURN_ON, {ATTR_ENTITY_ID: ENTITY_FAN}, blocking=True) await opp.services.async_call( FAN_DOMAIN, SERVICE_SET_SPEED, { ATTR_ENTITY_ID: ENTITY_FAN, ATTR_SPEED: "medium" }, blocking=True, ) # All of them should now be on switch = opp.states.get(ENTITY_SWITCH) assert switch.state == STATE_ON light = opp.states.get(ENTITY_LIGHT) assert light.state == STATE_ON sensor = opp.states.get(ENTITY_SENSOR) assert sensor.state == "35" fan = opp.states.get(ENTITY_FAN) assert fan.state == STATE_ON plug_it = emulated_kasa.get_plug_devices(opp, config) # switch plug = next(plug_it).generate_response() assert nested_value(plug, "system", "get_sysinfo", "alias") == ENTITY_SWITCH_NAME power = nested_value(plug, "emeter", "get_realtime", "power") assert math.isclose(power, ENTITY_SWITCH_POWER) # light plug = next(plug_it).generate_response() assert nested_value(plug, "system", "get_sysinfo", "alias") == ENTITY_LIGHT_NAME power = nested_value(plug, "emeter", "get_realtime", "power") assert math.isclose(power, 35) # fan plug = next(plug_it).generate_response() assert nested_value(plug, "system", "get_sysinfo", "alias") == ENTITY_FAN_NAME power = nested_value(plug, "emeter", "get_realtime", "power") assert math.isclose(power, ENTITY_FAN_SPEED_MED) # No more devices assert next(plug_it, None) is None
def mock_profiles_class(opp): profiles = Profiles(opp) profiles.data = data profiles.async_initialize = AsyncMock() return profiles
class MockGroupConnection(GroupConnection): """Fake a LCN group connection.""" send_command = AsyncMock(return_value=True)
async def test_reload(hass, mock_zeroconf): """Test we can reload from yaml.""" entry = MockConfigEntry( domain=DOMAIN, source=SOURCE_IMPORT, data={CONF_NAME: "reloadable", CONF_PORT: 12345}, options={}, ) entry.add_to_hass(hass) with patch(f"{PATH_HOMEKIT}.HomeKit") as mock_homekit: mock_homekit.return_value = homekit = Mock() type(homekit).async_start = AsyncMock() assert await async_setup_component( hass, "homekit", {"homekit": {CONF_NAME: "reloadable", CONF_PORT: 12345}} ) await hass.async_block_till_done() mock_homekit.assert_any_call( hass, "reloadable", 12345, None, ANY, {}, HOMEKIT_MODE_BRIDGE, None, entry.entry_id, ) assert mock_homekit().setup.called is True yaml_path = os.path.join( _get_fixtures_base_path(), "fixtures", "homekit/configuration.yaml", ) with patch.object(hass_config, "YAML_CONFIG_FILE", yaml_path), patch( f"{PATH_HOMEKIT}.HomeKit" ) as mock_homekit2, patch.object(homekit.bridge, "add_accessory"), patch( f"{PATH_HOMEKIT}.show_setup_message" ), patch( f"{PATH_HOMEKIT}.get_accessory" ), patch( "pyhap.accessory_driver.AccessoryDriver.start_service" ): mock_homekit2.return_value = homekit = Mock() type(homekit).async_start = AsyncMock() await hass.services.async_call( "homekit", SERVICE_RELOAD, {}, blocking=True, ) await hass.async_block_till_done() mock_homekit2.assert_any_call( hass, "reloadable", 45678, None, ANY, {}, HOMEKIT_MODE_BRIDGE, None, entry.entry_id, ) assert mock_homekit2().setup.called is True
async def test_priority_light_prior_color_preserved_after_black( hass: HomeAssistant, ) -> None: """Test that color is preserved in an on->off->on cycle for a HyperionPriorityLight. For a HyperionPriorityLight the color black is used to indicate off. This test ensures that a cycle through 'off' will preserve the original color. """ priority_template = { const.KEY_ACTIVE: True, const.KEY_VISIBLE: True, const.KEY_PRIORITY: TEST_PRIORITY, const.KEY_COMPONENTID: const.KEY_COMPONENTID_COLOR, } client = create_mock_client() client.async_send_set_color = AsyncMock(return_value=True) client.async_send_clear = AsyncMock(return_value=True) client.priorities = [] client.visible_priority = None register_test_entity( hass, LIGHT_DOMAIN, TYPE_HYPERION_PRIORITY_LIGHT, TEST_PRIORITY_LIGHT_ENTITY_ID_1, ) await setup_test_config_entry(hass, hyperion_client=client) # Turn the light on full green... # On (=), 100% (=), solid (=), [0,0,255] (=) hs_color = (240.0, 100.0) rgb_color = (0, 0, 255) await hass.services.async_call( LIGHT_DOMAIN, SERVICE_TURN_ON, {ATTR_ENTITY_ID: TEST_PRIORITY_LIGHT_ENTITY_ID_1, ATTR_HS_COLOR: hs_color}, blocking=True, ) assert client.async_send_set_color.call_args == call( **{ const.KEY_PRIORITY: TEST_PRIORITY, const.KEY_COLOR: rgb_color, const.KEY_ORIGIN: DEFAULT_ORIGIN, } ) client.priorities = [ { **priority_template, const.KEY_VALUE: {const.KEY_RGB: rgb_color}, } ] client.visible_priority = client.priorities[0] call_registered_callback(client, "priorities-update") entity_state = hass.states.get(TEST_PRIORITY_LIGHT_ENTITY_ID_1) assert entity_state assert entity_state.state == "on" assert entity_state.attributes["hs_color"] == hs_color # Then turn it off. await hass.services.async_call( LIGHT_DOMAIN, SERVICE_TURN_OFF, {ATTR_ENTITY_ID: TEST_PRIORITY_LIGHT_ENTITY_ID_1}, blocking=True, ) assert client.async_send_set_color.call_args == call( **{ const.KEY_PRIORITY: TEST_PRIORITY, const.KEY_COLOR: COLOR_BLACK, const.KEY_ORIGIN: DEFAULT_ORIGIN, } ) client.priorities = [ { **priority_template, const.KEY_VALUE: {const.KEY_RGB: COLOR_BLACK}, } ] client.visible_priority = client.priorities[0] call_registered_callback(client, "priorities-update") entity_state = hass.states.get(TEST_PRIORITY_LIGHT_ENTITY_ID_1) assert entity_state assert entity_state.state == "off" # Then turn it back on and ensure it's still green. # On (=), 100% (=), solid (=), [0,0,255] (=) await hass.services.async_call( LIGHT_DOMAIN, SERVICE_TURN_ON, {ATTR_ENTITY_ID: TEST_PRIORITY_LIGHT_ENTITY_ID_1}, blocking=True, ) assert client.async_send_set_color.call_args == call( **{ const.KEY_PRIORITY: TEST_PRIORITY, const.KEY_COLOR: rgb_color, const.KEY_ORIGIN: DEFAULT_ORIGIN, } ) client.priorities = [ { **priority_template, const.KEY_VALUE: {const.KEY_RGB: rgb_color}, } ] client.visible_priority = client.priorities[0] call_registered_callback(client, "priorities-update") entity_state = hass.states.get(TEST_PRIORITY_LIGHT_ENTITY_ID_1) assert entity_state assert entity_state.state == "on" assert entity_state.attributes["hs_color"] == hs_color
async def connect(self): """Connect and call the appropriate callbacks.""" self._callbacks.connect(None) return AsyncMock(return_value=(True))
async def test_light_async_turn_on(hass: HomeAssistant) -> None: """Test turning the light on.""" client = create_mock_client() await setup_test_config_entry(hass, hyperion_client=client) # On (=), 100% (=), solid (=), [255,255,255] (=) client.async_send_set_color = AsyncMock(return_value=True) await hass.services.async_call( LIGHT_DOMAIN, SERVICE_TURN_ON, {ATTR_ENTITY_ID: TEST_ENTITY_ID_1}, blocking=True ) assert client.async_send_set_color.call_args == call( **{ const.KEY_PRIORITY: TEST_PRIORITY, const.KEY_COLOR: [255, 255, 255], const.KEY_ORIGIN: DEFAULT_ORIGIN, } ) # On (=), 50% (!), solid (=), [255,255,255] (=) # === brightness = 128 client.async_send_set_color = AsyncMock(return_value=True) client.async_send_set_adjustment = AsyncMock(return_value=True) client.adjustment = [{const.KEY_ID: TEST_ID}] await hass.services.async_call( LIGHT_DOMAIN, SERVICE_TURN_ON, {ATTR_ENTITY_ID: TEST_ENTITY_ID_1, ATTR_BRIGHTNESS: brightness}, blocking=True, ) assert client.async_send_set_adjustment.call_args == call( **{const.KEY_ADJUSTMENT: {const.KEY_BRIGHTNESS: 50, const.KEY_ID: TEST_ID}} ) assert client.async_send_set_color.call_args == call( **{ const.KEY_PRIORITY: TEST_PRIORITY, const.KEY_COLOR: [255, 255, 255], const.KEY_ORIGIN: DEFAULT_ORIGIN, } ) # Simulate a false return of async_send_set_adjustment client.async_send_set_adjustment = AsyncMock(return_value=False) client.adjustment = [{const.KEY_ID: TEST_ID}] await hass.services.async_call( LIGHT_DOMAIN, SERVICE_TURN_ON, {ATTR_ENTITY_ID: TEST_ENTITY_ID_1, ATTR_BRIGHTNESS: brightness}, blocking=True, ) # Simulate a state callback from Hyperion. client.adjustment = [{const.KEY_BRIGHTNESS: 50}] call_registered_callback(client, "adjustment-update") entity_state = hass.states.get(TEST_ENTITY_ID_1) assert entity_state assert entity_state.state == "on" assert entity_state.attributes["brightness"] == brightness # On (=), 50% (=), solid (=), [0,255,255] (!) hs_color = (180.0, 100.0) client.async_send_set_color = AsyncMock(return_value=True) await hass.services.async_call( LIGHT_DOMAIN, SERVICE_TURN_ON, {ATTR_ENTITY_ID: TEST_ENTITY_ID_1, ATTR_HS_COLOR: hs_color}, blocking=True, ) assert client.async_send_set_color.call_args == call( **{ const.KEY_PRIORITY: TEST_PRIORITY, const.KEY_COLOR: (0, 255, 255), const.KEY_ORIGIN: DEFAULT_ORIGIN, } ) # Simulate a state callback from Hyperion. client.visible_priority = { const.KEY_COMPONENTID: const.KEY_COMPONENTID_COLOR, const.KEY_VALUE: {const.KEY_RGB: (0, 255, 255)}, } call_registered_callback(client, "priorities-update") entity_state = hass.states.get(TEST_ENTITY_ID_1) assert entity_state assert entity_state.attributes["hs_color"] == hs_color assert entity_state.attributes["icon"] == hyperion_light.ICON_LIGHTBULB # On (=), 100% (!), solid, [0,255,255] (=) brightness = 255 client.async_send_set_color = AsyncMock(return_value=True) client.async_send_set_adjustment = AsyncMock(return_value=True) client.adjustment = [{const.KEY_ID: TEST_ID}] await hass.services.async_call( LIGHT_DOMAIN, SERVICE_TURN_ON, {ATTR_ENTITY_ID: TEST_ENTITY_ID_1, ATTR_BRIGHTNESS: brightness}, blocking=True, ) assert client.async_send_set_adjustment.call_args == call( **{const.KEY_ADJUSTMENT: {const.KEY_BRIGHTNESS: 100, const.KEY_ID: TEST_ID}} ) assert client.async_send_set_color.call_args == call( **{ const.KEY_PRIORITY: TEST_PRIORITY, const.KEY_COLOR: (0, 255, 255), const.KEY_ORIGIN: DEFAULT_ORIGIN, } ) client.adjustment = [{const.KEY_BRIGHTNESS: 100}] call_registered_callback(client, "adjustment-update") entity_state = hass.states.get(TEST_ENTITY_ID_1) assert entity_state assert entity_state.attributes["brightness"] == brightness # On (=), 100% (=), "USB Capture (!), [0,255,255] (=) component = "V4L" effect = const.KEY_COMPONENTID_TO_NAME[component] client.async_send_clear = AsyncMock(return_value=True) client.async_send_set_component = AsyncMock(return_value=True) await hass.services.async_call( LIGHT_DOMAIN, SERVICE_TURN_ON, {ATTR_ENTITY_ID: TEST_ENTITY_ID_1, ATTR_EFFECT: effect}, blocking=True, ) assert client.async_send_clear.call_args == call( **{const.KEY_PRIORITY: TEST_PRIORITY} ) assert client.async_send_set_component.call_args_list == [ call( **{ const.KEY_COMPONENTSTATE: { const.KEY_COMPONENT: const.KEY_COMPONENTID_EXTERNAL_SOURCES[0], const.KEY_STATE: False, } } ), call( **{ const.KEY_COMPONENTSTATE: { const.KEY_COMPONENT: const.KEY_COMPONENTID_EXTERNAL_SOURCES[1], const.KEY_STATE: False, } } ), call( **{ const.KEY_COMPONENTSTATE: { const.KEY_COMPONENT: const.KEY_COMPONENTID_EXTERNAL_SOURCES[2], const.KEY_STATE: True, } } ), ] client.visible_priority = {const.KEY_COMPONENTID: component} call_registered_callback(client, "priorities-update") entity_state = hass.states.get(TEST_ENTITY_ID_1) assert entity_state assert entity_state.attributes["icon"] == hyperion_light.ICON_EXTERNAL_SOURCE assert entity_state.attributes["effect"] == effect # On (=), 100% (=), "Warm Blobs" (!), [0,255,255] (=) effect = "Warm Blobs" client.async_send_clear = AsyncMock(return_value=True) client.async_send_set_effect = AsyncMock(return_value=True) await hass.services.async_call( LIGHT_DOMAIN, SERVICE_TURN_ON, {ATTR_ENTITY_ID: TEST_ENTITY_ID_1, ATTR_EFFECT: effect}, blocking=True, ) assert client.async_send_clear.call_args == call( **{const.KEY_PRIORITY: TEST_PRIORITY} ) assert client.async_send_set_effect.call_args == call( **{ const.KEY_PRIORITY: TEST_PRIORITY, const.KEY_EFFECT: {const.KEY_NAME: effect}, const.KEY_ORIGIN: DEFAULT_ORIGIN, } ) client.visible_priority = { const.KEY_COMPONENTID: const.KEY_COMPONENTID_EFFECT, const.KEY_OWNER: effect, } call_registered_callback(client, "priorities-update") entity_state = hass.states.get(TEST_ENTITY_ID_1) assert entity_state assert entity_state.attributes["icon"] == hyperion_light.ICON_EFFECT assert entity_state.attributes["effect"] == effect # On (=), 100% (=), [0,0,255] (!) # Ensure changing the color will move the effect to 'Solid' automatically. hs_color = (240.0, 100.0) client.async_send_set_color = AsyncMock(return_value=True) await hass.services.async_call( LIGHT_DOMAIN, SERVICE_TURN_ON, {ATTR_ENTITY_ID: TEST_ENTITY_ID_1, ATTR_HS_COLOR: hs_color}, blocking=True, ) assert client.async_send_set_color.call_args == call( **{ const.KEY_PRIORITY: TEST_PRIORITY, const.KEY_COLOR: (0, 0, 255), const.KEY_ORIGIN: DEFAULT_ORIGIN, } ) # Simulate a state callback from Hyperion. client.visible_priority = { const.KEY_COMPONENTID: const.KEY_COMPONENTID_COLOR, const.KEY_VALUE: {const.KEY_RGB: (0, 0, 255)}, } call_registered_callback(client, "priorities-update") entity_state = hass.states.get(TEST_ENTITY_ID_1) assert entity_state assert entity_state.attributes["hs_color"] == hs_color assert entity_state.attributes["icon"] == hyperion_light.ICON_LIGHTBULB assert entity_state.attributes["effect"] == hyperion_light.KEY_EFFECT_SOLID # No calls if disconnected. client.has_loaded_state = False call_registered_callback(client, "client-update", {"loaded-state": False}) client.async_send_clear = AsyncMock(return_value=True) client.async_send_set_effect = AsyncMock(return_value=True) await hass.services.async_call( LIGHT_DOMAIN, SERVICE_TURN_ON, {ATTR_ENTITY_ID: TEST_ENTITY_ID_1}, blocking=True ) assert not client.async_send_clear.called assert not client.async_send_set_effect.called
def mock_check_status(mocker): async_mock = AsyncMock(return_value=api_pb2.STATUS_FINISHED) mocker.patch("grpc_client.GRPCClient.check_status", side_effect=async_mock) return async_mock
endpoint, reported_error): # test that if no connection to GUI, then `on_tribler_exception` will store # only the very first `reported_error` first_reported_error = reported_error endpoint.on_tribler_exception(first_reported_error) second_reported_error = ReportedError('second_type', 'second_text', {}) endpoint.on_tribler_exception(second_reported_error) assert endpoint.undelivered_error == endpoint.error_message( first_reported_error) @pytest.mark.asyncio @patch.object(EventsEndpoint, 'register_anonymous_task', new=AsyncMock(side_effect=CancelledError)) @patch.object(RESTStreamResponse, 'prepare', new=AsyncMock()) @patch.object(RESTStreamResponse, 'write', new_callable=AsyncMock) @patch.object(EventsEndpoint, 'encode_message') async def test_get_events_has_undelivered_error(mocked_encode_message, mocked_write, endpoint): # test that in case `self.undelivered_error` is not None, then it will be sent endpoint.undelivered_error = {'undelivered': 'error'} await endpoint.get_events(MagicMock()) mocked_write.assert_called() mocked_encode_message.assert_called_with({'undelivered': 'error'}) assert not endpoint.undelivered_error
def mock_get_run_output(mocker): async_mock = AsyncMock(return_value="MOCK_RUN_OUTPUT") mocker.patch("grpc_client.GRPCClient.get_run_output", side_effect=async_mock) return async_mock
def __init__(self, *args, **kwargs): """Init a mock session.""" self.get_user = AsyncMock() self.invoke = AsyncMock() self.publish = AsyncMock() self.send_message = AsyncMock()