async def test_continue_flow_unauth(hass, client, hass_admin_user): """Test we can't 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 == 200 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, } hass_admin_user.groups = [] resp = await client.post( f"/api/config/config_entries/flow/{flow_id}", json={"user_title": "user-title"}, ) assert resp.status == 401
async def test_zeroconf(hass): """Test we get the form.""" await setup.async_setup_component(hass, "persistent_notification", {}) with patch( "aioshelly.get_info", return_value={ "mac": "test-mac", "type": "SHSW-1", "auth": False }, ): result = await hass.config_entries.flow.async_init( DOMAIN, data=DISCOVERY_INFO, context={"source": config_entries.SOURCE_ZEROCONF}, ) assert result["type"] == "form" assert result["errors"] == {} context = next(flow["context"] for flow in hass.config_entries.flow.async_progress() if flow["flow_id"] == result["flow_id"]) assert context["title_placeholders"]["name"] == "shelly1pm-12345" with patch( "aioshelly.Device.create", new=AsyncMock(return_value=Mock(settings=MOCK_SETTINGS, )), ), patch("homeassistant.components.shelly.async_setup", return_value=True) as mock_setup, patch( "homeassistant.components.shelly.async_setup_entry", return_value=True, ) as mock_setup_entry: result2 = await hass.config_entries.flow.async_configure( result["flow_id"], {}, ) await hass.async_block_till_done() assert result2["type"] == "create_entry" assert result2["title"] == "Test name" assert result2["data"] == { "host": "1.1.1.1", } assert len(mock_setup.mock_calls) == 1 assert len(mock_setup_entry.mock_calls) == 1
def patch_cluster(cluster): """Patch a cluster for testing.""" cluster.bind = AsyncMock(return_value=[0]) cluster.configure_reporting = AsyncMock(return_value=[0]) cluster.deserialize = Mock() cluster.handle_cluster_request = Mock() cluster.read_attributes = AsyncMock(return_value=[{}, {}]) cluster.read_attributes_raw = Mock() cluster.unbind = AsyncMock(return_value=[0]) cluster.write_attributes = AsyncMock( return_value=[zcl_f.WriteAttributesResponse.deserialize(b"\x00")[0]]) if cluster.cluster_id == 4: cluster.add = AsyncMock(return_value=[0])
async def test_immediate_works(hass): """Test immediate works.""" calls = [] debouncer = debounce.Debouncer( hass, None, cooldown=0.01, immediate=True, function=AsyncMock(side_effect=lambda: calls.append(None)), ) # Call when nothing happening await debouncer.async_call() assert len(calls) == 1 assert debouncer._timer_task is not None assert debouncer._execute_at_end_of_timer is False # Call when cooldown active setting execute at end to True await debouncer.async_call() assert len(calls) == 1 assert debouncer._timer_task is not None assert debouncer._execute_at_end_of_timer is True # Canceling debounce in cooldown debouncer.async_cancel() assert debouncer._timer_task is None assert debouncer._execute_at_end_of_timer is False # Call and let timer run out await debouncer.async_call() assert len(calls) == 2 await debouncer._handle_timer_finish() assert len(calls) == 2 assert debouncer._timer_task is None assert debouncer._execute_at_end_of_timer is False # Test calling doesn't execute/cooldown if currently executing. await debouncer._execute_lock.acquire() await debouncer.async_call() assert len(calls) == 2 assert debouncer._timer_task is None assert debouncer._execute_at_end_of_timer is False debouncer._execute_lock.release()
async def test_discovery_cannot_connect_ws(hass): """Test discovery aborts if cannot connect to websocket.""" with patch( "homeassistant.components.kodi.config_flow.Kodi.ping", return_value=True, ), patch.object( MockWSConnection, "connect", AsyncMock(side_effect=CannotConnectError), ), patch( "homeassistant.components.kodi.config_flow.get_kodi_connection", new=get_kodi_connection, ): result = await hass.config_entries.flow.async_init( DOMAIN, context={"source": "zeroconf"}, data=TEST_DISCOVERY) assert result["type"] == "form" assert result["step_id"] == "ws_port" assert result["errors"] == {}
async def test_call_with_one_of_required_features(hass, mock_entities): """Test service calls invoked with one entity having the required features.""" test_service_mock = AsyncMock(return_value=None) await service.entity_service_call( hass, [Mock(entities=mock_entities)], test_service_mock, ha.ServiceCall("test_domain", "test_service", {"entity_id": "all"}), required_features=[SUPPORT_A, SUPPORT_C], ) assert test_service_mock.call_count == 3 expected = [ mock_entities["light.kitchen"], mock_entities["light.bedroom"], mock_entities["light.bathroom"], ] actual = [call[0][0] for call in test_service_mock.call_args_list] assert all(entity in actual for entity in expected)
async def test_handle_unauthorized(hass): """Test handling an unauthorized error on update.""" entry = Mock(async_setup=AsyncMock()) entry.data = {"host": "1.2.3.4", "username": "******"} hue_bridge = bridge.HueBridge(hass, entry, False, False) with patch.object(bridge, "authenticate_bridge", return_value=Mock()), patch("aiohue.Bridge", return_value=Mock()): assert await hue_bridge.async_setup() is True assert hue_bridge.authorized is True with patch.object(bridge, "create_config_flow") as mock_create: await hue_bridge.handle_unauthorized_error() assert hue_bridge.authorized is False assert len(mock_create.mock_calls) == 1 assert mock_create.mock_calls[0][1][1] == "1.2.3.4"
async def test_form_errors_test_connection(hass, error): """Test we handle errors.""" exc, base_error = error result = await hass.config_entries.flow.async_init( DOMAIN, context={"source": config_entries.SOURCE_USER}) with patch("aioshelly.get_info", return_value={ "mac": "test-mac", "auth": False }), patch("aioshelly.Device.create", new=AsyncMock(side_effect=exc)): result2 = await hass.config_entries.flow.async_configure( result["flow_id"], {"host": "1.1.1.1"}, ) assert result2["type"] == "form" assert result2["errors"] == {"base": base_error}
async def test_yaml_updates_update_config_entry_for_name(hass): """Test async_setup with imported config.""" entry = MockConfigEntry( domain=DOMAIN, source=SOURCE_IMPORT, data={ CONF_NAME: BRIDGE_NAME, CONF_PORT: DEFAULT_PORT }, 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: BRIDGE_NAME, CONF_PORT: 12345 }}) await hass.async_block_till_done() mock_homekit.assert_any_call( hass, BRIDGE_NAME, 12345, None, ANY, {}, DEFAULT_SAFE_MODE, 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()
async def test_bridge_setup(hass): """Test a successful setup.""" entry = Mock() api = Mock(initialize=AsyncMock()) entry.data = {"host": "1.2.3.4", "username": "******"} entry.options = { CONF_ALLOW_HUE_GROUPS: False, CONF_ALLOW_UNREACHABLE: False } hue_bridge = bridge.HueBridge(hass, entry) with patch("aiohue.Bridge", return_value=api), patch.object( hass.config_entries, "async_forward_entry_setup") as mock_forward: assert await hue_bridge.async_setup() is True assert hue_bridge.api is api assert len(mock_forward.mock_calls) == 3 forward_entries = {c[1][1] for c in mock_forward.mock_calls} assert forward_entries == {"light", "binary_sensor", "sensor"}
async def test_only_valid_components(hass, mqtt_mock, caplog): """Test for a valid component.""" with patch("homeassistant.components.mqtt.discovery.async_dispatcher_send" ) as mock_dispatcher_send: entry = hass.config_entries.async_entries(mqtt.DOMAIN)[0] invalid_component = "timer" mock_dispatcher_send = AsyncMock(return_value=None) await async_start(hass, "homeassistant", entry) async_fire_mqtt_message( hass, f"homeassistant/{invalid_component}/bla/config", "{}") await hass.async_block_till_done() assert f"Integration {invalid_component} is not supported" in caplog.text assert not mock_dispatcher_send.called
async def test_form_empty_ws_port(hass, user_flow): """Test we handle an empty websocket port input.""" with patch( "homeassistant.components.kodi.config_flow.Kodi.ping", return_value=True, ), patch.object( MockWSConnection, "connect", AsyncMock(side_effect=CannotConnectError), ), patch( "homeassistant.components.kodi.config_flow.get_kodi_connection", new=get_kodi_connection, ): result = await hass.config_entries.flow.async_configure(user_flow, TEST_HOST) assert result["type"] == "form" assert result["step_id"] == "ws_port" assert result["errors"] == {} with patch( "homeassistant.components.kodi.async_setup", return_value=True ) as mock_setup, patch( "homeassistant.components.kodi.async_setup_entry", return_value=True, ) as mock_setup_entry: result = await hass.config_entries.flow.async_configure( result["flow_id"], {"ws_port": 0} ) assert result["type"] == "create_entry" assert result["title"] == TEST_HOST["host"] assert result["data"] == { **TEST_HOST, "ws_port": None, "password": None, "username": None, "name": None, "timeout": DEFAULT_TIMEOUT, } await hass.async_block_till_done() assert len(mock_setup.mock_calls) == 1 assert len(mock_setup_entry.mock_calls) == 1
async def test_no_interface(hass): """Test creating an AsusWRT scanner using no interface.""" with patch("homeassistant.components.asuswrt.AsusWrt") as AsusWrt: AsusWrt().connection.async_connect = AsyncMock() AsusWrt().is_connected = False result = await async_setup_component( hass, DOMAIN, { DOMAIN: { CONF_HOST: "fake_host", CONF_USERNAME: "******", CONF_PASSWORD: "******", CONF_DNSMASQ: "/", CONF_INTERFACE: None, } }, ) assert not result
async def test_flow_link_unknown_host(hass): """Test config flow .""" mock_bridge = get_mock_bridge(mock_create_user=AsyncMock( side_effect=client_exceptions.ClientOSError), ) with patch( "homeassistant.components.hue.config_flow.discover_nupnp", return_value=[mock_bridge], ): result = await hass.config_entries.flow.async_init( const.DOMAIN, context={"source": "user"}) result = await hass.config_entries.flow.async_configure( result["flow_id"], user_input={"id": mock_bridge.id}) result = await hass.config_entries.flow.async_configure(result["flow_id"], user_input={}) assert result["type"] == "abort" assert result["reason"] == "cannot_connect"
async def test_title_without_name_and_prefix(hass): """Test we set the title to the hostname when the device doesn't have a name.""" await setup.async_setup_component(hass, "persistent_notification", {}) result = await hass.config_entries.flow.async_init( DOMAIN, context={"source": config_entries.SOURCE_USER} ) assert result["type"] == "form" assert result["errors"] == {} settings = MOCK_SETTINGS.copy() settings["name"] = None settings["device"] = settings["device"].copy() settings["device"]["hostname"] = "shelly1pm-12345" with patch( "aioshelly.get_info", return_value={"mac": "test-mac", "type": "SHSW-1", "auth": False}, ), patch( "aioshelly.Device.create", new=AsyncMock( return_value=Mock( settings=settings, ) ), ), patch( "homeassistant.components.shelly.async_setup", return_value=True ) as mock_setup, patch( "homeassistant.components.shelly.async_setup_entry", return_value=True, ) as mock_setup_entry: result2 = await hass.config_entries.flow.async_configure( result["flow_id"], {"host": "1.1.1.1"}, ) await hass.async_block_till_done() assert result2["type"] == "create_entry" assert result2["title"] == "shelly1pm-12345" assert result2["data"] == { "host": "1.1.1.1", } assert len(mock_setup.mock_calls) == 1 assert len(mock_setup_entry.mock_calls) == 1
async def test_turn_on_failure(feature, hass, config, caplog): """Test that turn_on failures are logged.""" caplog.set_level(logging.ERROR) feature_mock, entity_id = feature feature_mock.async_on = AsyncMock( side_effect=blebox_uniapi.error.BadOnValueError) await async_setup_entity(hass, config, entity_id) feature_mock.sensible_on_value = 123 await hass.services.async_call( "light", SERVICE_TURN_ON, {"entity_id": entity_id}, blocking=True, ) assert (f"Turning on '{feature_mock.full_name}' failed: Bad value 123 ()" in caplog.text)
async def test_multiple_refreshing(): EXPIRED_TOKEN = "old access token" REFRESHED_TOKEN = "refreshed access token" def raise_on_old_token(*args, **kwargs): if http_client._access_token == EXPIRED_TOKEN: raise AuthenticationRequired() return 'ok' http_client = AuthenticatedHttpClient(Mock, Mock) http_client._access_token = EXPIRED_TOKEN http_client.get_access_token = AsyncMockDelayed( return_value=REFRESHED_TOKEN) http_client._oauth_request = AsyncMock(side_effect=raise_on_old_token) responses = await asyncio.gather( http_client.request('url'), http_client.request('url'), ) for i in responses: assert i == 'ok'
def test_install_game_game_installed(create_authenticated_plugin): loop = asyncio.get_event_loop() pg = create_authenticated_plugin() new_game = NewGame() new_game.status = "Installed" pg.user_can_perform_actions.return_value = True pg.games_collection = [new_game] pg.open_uplay_client = mock.create_autospec(pg.open_uplay_client) pg.launch_game = AsyncMock(return_value=None) with mock.patch("plugin.subprocess.Popen") as pop: loop.run_until_complete(pg.install_game("321")) pop.assert_not_called() pg.launch_game.asert_called()
async def test_flow_link_unknown_error(hass): """Test if a unknown error happened during the linking processes.""" mock_bridge = get_mock_bridge( mock_create_user=AsyncMock(side_effect=OSError), ) with patch( "homeassistant.components.hue.config_flow.discover_nupnp", return_value=[mock_bridge], ): result = await hass.config_entries.flow.async_init( const.DOMAIN, context={"source": "user"}) result = await hass.config_entries.flow.async_configure( result["flow_id"], user_input={"id": mock_bridge.id}) result = await hass.config_entries.flow.async_configure(result["flow_id"], user_input={}) assert result["type"] == "form" assert result["step_id"] == "link" assert result["errors"] == {"base": "linking"}
async def test_update(airsensor, hass, config): """Test air quality sensor state after update.""" feature_mock, entity_id = airsensor def initial_update(): feature_mock.pm1 = 49 feature_mock.pm2_5 = 222 feature_mock.pm10 = 333 feature_mock.async_update = AsyncMock(side_effect=initial_update) await async_setup_entity(hass, config, entity_id) state = hass.states.get(entity_id) assert state.attributes[ATTR_PM_0_1] == 49 assert state.attributes[ATTR_PM_2_5] == 222 assert state.attributes[ATTR_PM_10] == 333 assert state.state == "222"
async def test_flow_link_button_not_pressed(hass): """Test config flow .""" mock_bridge = get_mock_bridge( mock_create_user=AsyncMock(side_effect=aiohue.LinkButtonNotPressed), ) with patch( "homeassistant.components.hue.config_flow.discover_nupnp", return_value=[mock_bridge], ): result = await hass.config_entries.flow.async_init( const.DOMAIN, context={"source": "user"}) result = await hass.config_entries.flow.async_configure( result["flow_id"], user_input={"id": mock_bridge.id}) result = await hass.config_entries.flow.async_configure(result["flow_id"], user_input={}) assert result["type"] == "form" assert result["step_id"] == "link" assert result["errors"] == {"base": "register_failed"}
async def test_login_recovers_bad_internet(hass, caplog): """Test Alexa can recover bad auth.""" prefs = Mock( alexa_enabled=True, google_enabled=False, async_set_username=AsyncMock(return_value=None), ) client = CloudClient(hass, prefs, None, {}, {}) client.cloud = Mock() client._alexa_config = Mock( async_enable_proactive_mode=Mock(side_effect=aiohttp.ClientError) ) await client.logged_in() assert len(client._alexa_config.async_enable_proactive_mode.mock_calls) == 1 assert "Unable to activate Alexa Report State" in caplog.text async_fire_time_changed(hass, dt_util.utcnow() + timedelta(seconds=30)) await hass.async_block_till_done() assert len(client._alexa_config.async_enable_proactive_mode.mock_calls) == 2
async def test_import_cannot_connect(hass: HomeAssistantType) -> None: """Check an import flow that cannot connect.""" client = create_mock_client() client.async_client_connect = AsyncMock(return_value=False) with patch("homeassistant.components.hyperion.client.HyperionClient", return_value=client): result = await _init_flow( hass, source=SOURCE_IMPORT, data={ CONF_HOST: TEST_HOST, CONF_PORT: TEST_PORT, }, ) await hass.async_block_till_done() assert result["type"] == data_entry_flow.RESULT_TYPE_ABORT assert result["reason"] == "cannot_connect"
async def test_zeroconf(hass): """Test we get the form.""" await setup.async_setup_component(hass, "persistent_notification", {}) with patch( "aioshelly.get_info", return_value={"mac": "test-mac", "type": "SHSW-1", "auth": False}, ): result = await hass.config_entries.flow.async_init( DOMAIN, data={"host": "1.1.1.1", "name": "shelly1pm-12345"}, context={"source": config_entries.SOURCE_ZEROCONF}, ) assert result["type"] == "form" assert result["errors"] == {} with patch( "aioshelly.Device.create", return_value=Mock( shutdown=AsyncMock(), settings={"name": "Test name", "device": {"mac": "test-mac"}}, ), ), patch( "homeassistant.components.shelly.async_setup", return_value=True ) as mock_setup, patch( "homeassistant.components.shelly.async_setup_entry", return_value=True, ) as mock_setup_entry: result2 = await hass.config_entries.flow.async_configure( result["flow_id"], {}, ) assert result2["type"] == "create_entry" assert result2["title"] == "Test name" assert result2["data"] == { "host": "1.1.1.1", } await hass.async_block_till_done() assert len(mock_setup.mock_calls) == 1 assert len(mock_setup_entry.mock_calls) == 1
async def test_setup_entry(hass): """Test setup entry calls async_setup_entry on platform.""" mock_setup_entry = AsyncMock(return_value=True) mock_entity_platform( hass, "test_domain.entry_domain", MockPlatform(async_setup_entry=mock_setup_entry, scan_interval=timedelta(seconds=5)), ) component = EntityComponent(_LOGGER, DOMAIN, hass) entry = MockConfigEntry(domain="entry_domain") assert await component.async_setup_entry(entry) assert len(mock_setup_entry.mock_calls) == 1 p_hass, p_entry, _ = mock_setup_entry.mock_calls[0][1] assert p_hass is hass assert p_entry is entry assert component._platforms[entry.entry_id].scan_interval == timedelta( seconds=5)
def cast_mock(): """Mock pychromecast.""" pycast_mock = MagicMock() pycast_mock.start_discovery.return_value = (None, Mock()) dial_mock = MagicMock(name="XXX") dial_mock.get_device_status.return_value.uuid = "fake_uuid" dial_mock.get_device_status.return_value.manufacturer = "fake_manufacturer" dial_mock.get_device_status.return_value.model_name = "fake_model_name" dial_mock.get_device_status.return_value.friendly_name = "fake_friendly_name" with patch( "homeassistant.components.cast.media_player.pychromecast", pycast_mock ), patch( "homeassistant.components.cast.discovery.pychromecast", pycast_mock ), patch( "homeassistant.components.cast.media_player.MultizoneManager", MagicMock() ), patch( "homeassistant.components.cast.media_player.zeroconf.async_get_instance", AsyncMock(), ): yield
def get_mock_bridge( bridge_id="aabbccddeeff", host="1.2.3.4", mock_create_user=None, username=None ): """Return a mock bridge.""" mock_bridge = Mock() mock_bridge.host = host mock_bridge.username = username mock_bridge.config.name = "Mock Bridge" mock_bridge.id = bridge_id if not mock_create_user: async def create_user(username): mock_bridge.username = username mock_create_user = create_user mock_bridge.create_user = mock_create_user mock_bridge.initialize = AsyncMock() return mock_bridge
def mock_api_fixture() -> Generator[AsyncMock, Any, None]: """Fixture for mocking aioswitcher.api.SwitcherV2Api.""" mock_api = AsyncMock() patchers = [ patch( "homeassistant.components.switcher_kis.SwitcherV2Api.connect", new=mock_api ), patch( "homeassistant.components.switcher_kis.SwitcherV2Api.disconnect", new=mock_api, ), ] for patcher in patchers: patcher.start() yield for patcher in patchers: patcher.stop()
def create_valid_feature_mock(path="homeassistant.components.blebox.Products"): """Return a valid, complete BleBox feature mock.""" feature = mock_only_feature( blebox_uniapi.cover.Cover, unique_id="BleBox-gateBox-1afe34db9437-0.position", full_name="gateBox-0.position", device_class="gate", state=0, async_update=AsyncMock(), current=None, ) product = setup_product_mock("covers", [feature], path) type(product).name = PropertyMock(return_value="My gate controller") type(product).model = PropertyMock(return_value="gateController") type(product).type = PropertyMock(return_value="gateBox") type(product).brand = PropertyMock(return_value="BleBox") type(product).firmware_version = PropertyMock(return_value="1.23") type(product).unique_id = PropertyMock(return_value="abcd0123ef5678") return feature
async def test_unload_entry_resets_platform(hass): """Test unloading an entry removes all entities.""" mock_setup_entry = AsyncMock(return_value=True) mock_entity_platform( hass, "test_domain.entry_domain", MockPlatform(async_setup_entry=mock_setup_entry), ) component = EntityComponent(_LOGGER, DOMAIN, hass) entry = MockConfigEntry(domain="entry_domain") assert await component.async_setup_entry(entry) assert len(mock_setup_entry.mock_calls) == 1 add_entities = mock_setup_entry.mock_calls[0][1][2] add_entities([MockEntity()]) await hass.async_block_till_done() assert len(hass.states.async_entity_ids()) == 1 assert await component.async_unload_entry(entry) assert len(hass.states.async_entity_ids()) == 0