diff --git a/tests/components/samsungtv/test_config_flow.py b/tests/components/samsungtv/test_config_flow.py index 30bb1052702..6679f1d786e 100644 --- a/tests/components/samsungtv/test_config_flow.py +++ b/tests/components/samsungtv/test_config_flow.py @@ -1,4 +1,5 @@ """Tests for Samsung TV config flow.""" +from collections.abc import Generator import socket from unittest.mock import ANY, AsyncMock, Mock, call, patch @@ -60,7 +61,6 @@ from homeassistant.core import HomeAssistant from homeassistant.data_entry_flow import FlowResultType from homeassistant.setup import async_setup_component -from . import setup_samsungtv_entry from .const import ( MOCK_CONFIG_ENCRYPTED_WS, MOCK_ENTRYDATA_ENCRYPTED_WS, @@ -217,6 +217,15 @@ DEVICEINFO_WEBSOCKET_NO_SSL = { } +@pytest.fixture(autouse=True, name="mock_setup_entry") +def override_async_setup_entry() -> Generator[AsyncMock, None, None]: + """Override async_setup_entry.""" + with patch( + "homeassistant.components.samsungtv.async_setup_entry", return_value=True + ) as mock_setup_entry: + yield mock_setup_entry + + @pytest.mark.usefixtures("remote", "rest_api_failing") async def test_user_legacy(hass: HomeAssistant) -> None: """Test starting a flow by user.""" @@ -933,7 +942,9 @@ async def test_import_legacy(hass: HomeAssistant) -> None: @pytest.mark.usefixtures("remote", "remotews", "rest_api_failing") -async def test_import_legacy_without_name(hass: HomeAssistant) -> None: +async def test_import_legacy_without_name( + hass: HomeAssistant, mock_setup_entry: AsyncMock +) -> None: """Test importing from yaml without a name.""" with patch( "homeassistant.components.samsungtv.bridge.SamsungTVEncryptedWSAsyncRemote.start_listening", @@ -951,10 +962,13 @@ async def test_import_legacy_without_name(hass: HomeAssistant) -> None: assert result["data"][CONF_MANUFACTURER] == "Samsung" assert result["result"].unique_id is None + mock_setup_entry.assert_called_once() entries = hass.config_entries.async_entries(DOMAIN) assert len(entries) == 1 - assert entries[0].data[CONF_METHOD] == METHOD_LEGACY - assert entries[0].data[CONF_PORT] == LEGACY_PORT + # METHOD / PORT failed during import + # They will get checked/set on setup + assert CONF_METHOD not in entries[0].data + assert CONF_PORT not in entries[0].data @pytest.mark.usefixtures("remotews", "rest_api") @@ -1382,7 +1396,7 @@ async def test_update_old_entry(hass: HomeAssistant) -> None: @pytest.mark.usefixtures("remotews", "rest_api", "remoteencws_failing") async def test_update_missing_mac_unique_id_added_from_dhcp( - hass: HomeAssistant, + hass: HomeAssistant, mock_setup_entry: AsyncMock ) -> None: """Test missing mac and unique id added.""" entry = MockConfigEntry(domain=DOMAIN, data=MOCK_OLD_ENTRY, unique_id=None) @@ -1390,10 +1404,7 @@ async def test_update_missing_mac_unique_id_added_from_dhcp( with patch( "homeassistant.components.samsungtv.async_setup", return_value=True, - ) as mock_setup, patch( - "homeassistant.components.samsungtv.async_setup_entry", - return_value=True, - ) as mock_setup_entry: + ) as mock_setup: result = await hass.config_entries.flow.async_init( DOMAIN, context={"source": config_entries.SOURCE_DHCP}, @@ -1411,7 +1422,7 @@ async def test_update_missing_mac_unique_id_added_from_dhcp( @pytest.mark.usefixtures("remotews", "rest_api", "remoteencws_failing") async def test_update_missing_mac_unique_id_added_from_zeroconf( - hass: HomeAssistant, + hass: HomeAssistant, mock_setup_entry: AsyncMock ) -> None: """Test missing mac and unique id added.""" entry = MockConfigEntry(domain=DOMAIN, data=MOCK_OLD_ENTRY, unique_id=None) @@ -1419,10 +1430,7 @@ async def test_update_missing_mac_unique_id_added_from_zeroconf( with patch( "homeassistant.components.samsungtv.async_setup", return_value=True, - ) as mock_setup, patch( - "homeassistant.components.samsungtv.async_setup_entry", - return_value=True, - ) as mock_setup_entry: + ) as mock_setup: result = await hass.config_entries.flow.async_init( DOMAIN, context={"source": config_entries.SOURCE_ZEROCONF}, @@ -1438,7 +1446,9 @@ async def test_update_missing_mac_unique_id_added_from_zeroconf( @pytest.mark.usefixtures("remote", "rest_api_failing") -async def test_update_missing_model_added_from_ssdp(hass: HomeAssistant) -> None: +async def test_update_missing_model_added_from_ssdp( + hass: HomeAssistant, mock_setup_entry: AsyncMock +) -> None: """Test missing model added via ssdp on legacy models.""" entry = MockConfigEntry( domain=DOMAIN, @@ -1449,10 +1459,7 @@ async def test_update_missing_model_added_from_ssdp(hass: HomeAssistant) -> None with patch( "homeassistant.components.samsungtv.async_setup", return_value=True, - ) as mock_setup, patch( - "homeassistant.components.samsungtv.async_setup_entry", - return_value=True, - ) as mock_setup_entry: + ) as mock_setup: result = await hass.config_entries.flow.async_init( DOMAIN, context={"source": config_entries.SOURCE_SSDP}, @@ -1469,7 +1476,7 @@ async def test_update_missing_model_added_from_ssdp(hass: HomeAssistant) -> None @pytest.mark.usefixtures("remotews", "rest_api", "remoteencws_failing") async def test_update_missing_mac_unique_id_ssdp_location_added_from_ssdp( - hass: HomeAssistant, + hass: HomeAssistant, mock_setup_entry: AsyncMock ) -> None: """Test missing mac, ssdp_location, and unique id added via ssdp.""" entry = MockConfigEntry(domain=DOMAIN, data=MOCK_OLD_ENTRY, unique_id=None) @@ -1477,10 +1484,7 @@ async def test_update_missing_mac_unique_id_ssdp_location_added_from_ssdp( with patch( "homeassistant.components.samsungtv.async_setup", return_value=True, - ) as mock_setup, patch( - "homeassistant.components.samsungtv.async_setup_entry", - return_value=True, - ) as mock_setup_entry: + ) as mock_setup: result = await hass.config_entries.flow.async_init( DOMAIN, context={"source": config_entries.SOURCE_SSDP}, @@ -1525,7 +1529,7 @@ async def test_update_zeroconf_discovery_preserved_unique_id( @pytest.mark.usefixtures("remotews", "rest_api", "remoteencws_failing") async def test_update_missing_mac_unique_id_added_ssdp_location_updated_from_ssdp( - hass: HomeAssistant, + hass: HomeAssistant, mock_setup_entry: AsyncMock ) -> None: """Test missing mac and unique id with outdated ssdp_location with the wrong st added via ssdp.""" entry = MockConfigEntry( @@ -1540,10 +1544,7 @@ async def test_update_missing_mac_unique_id_added_ssdp_location_updated_from_ssd with patch( "homeassistant.components.samsungtv.async_setup", return_value=True, - ) as mock_setup, patch( - "homeassistant.components.samsungtv.async_setup_entry", - return_value=True, - ) as mock_setup_entry: + ) as mock_setup: result = await hass.config_entries.flow.async_init( DOMAIN, context={"source": config_entries.SOURCE_SSDP}, @@ -1565,7 +1566,7 @@ async def test_update_missing_mac_unique_id_added_ssdp_location_updated_from_ssd @pytest.mark.usefixtures("remotews", "rest_api", "remoteencws_failing") async def test_update_missing_mac_unique_id_added_ssdp_location_rendering_st_updated_from_ssdp( - hass: HomeAssistant, + hass: HomeAssistant, mock_setup_entry: AsyncMock ) -> None: """Test missing mac and unique id with outdated ssdp_location with the correct st added via ssdp.""" entry = MockConfigEntry( @@ -1580,10 +1581,7 @@ async def test_update_missing_mac_unique_id_added_ssdp_location_rendering_st_upd with patch( "homeassistant.components.samsungtv.async_setup", return_value=True, - ) as mock_setup, patch( - "homeassistant.components.samsungtv.async_setup_entry", - return_value=True, - ) as mock_setup_entry: + ) as mock_setup: result = await hass.config_entries.flow.async_init( DOMAIN, context={"source": config_entries.SOURCE_SSDP}, @@ -1606,7 +1604,7 @@ async def test_update_missing_mac_unique_id_added_ssdp_location_rendering_st_upd @pytest.mark.usefixtures("remotews", "rest_api", "remoteencws_failing") async def test_update_missing_mac_unique_id_added_ssdp_location_main_tv_agent_st_updated_from_ssdp( - hass: HomeAssistant, + hass: HomeAssistant, mock_setup_entry: AsyncMock ) -> None: """Test missing mac and unique id with outdated ssdp_location with the correct st added via ssdp.""" entry = MockConfigEntry( @@ -1622,10 +1620,7 @@ async def test_update_missing_mac_unique_id_added_ssdp_location_main_tv_agent_st with patch( "homeassistant.components.samsungtv.async_setup", return_value=True, - ) as mock_setup, patch( - "homeassistant.components.samsungtv.async_setup_entry", - return_value=True, - ) as mock_setup_entry: + ) as mock_setup: result = await hass.config_entries.flow.async_init( DOMAIN, context={"source": config_entries.SOURCE_SSDP}, @@ -1652,7 +1647,7 @@ async def test_update_missing_mac_unique_id_added_ssdp_location_main_tv_agent_st @pytest.mark.usefixtures("remotews", "rest_api", "remoteencws_failing") async def test_update_ssdp_location_rendering_st_updated_from_ssdp( - hass: HomeAssistant, + hass: HomeAssistant, mock_setup_entry: AsyncMock ) -> None: """Test with outdated ssdp_location with the correct st added via ssdp.""" entry = MockConfigEntry( @@ -1664,10 +1659,7 @@ async def test_update_ssdp_location_rendering_st_updated_from_ssdp( with patch( "homeassistant.components.samsungtv.async_setup", return_value=True, - ) as mock_setup, patch( - "homeassistant.components.samsungtv.async_setup_entry", - return_value=True, - ) as mock_setup_entry: + ) as mock_setup: result = await hass.config_entries.flow.async_init( DOMAIN, context={"source": config_entries.SOURCE_SSDP}, @@ -1690,7 +1682,7 @@ async def test_update_ssdp_location_rendering_st_updated_from_ssdp( @pytest.mark.usefixtures("remotews", "rest_api", "remoteencws_failing") async def test_update_main_tv_ssdp_location_rendering_st_updated_from_ssdp( - hass: HomeAssistant, + hass: HomeAssistant, mock_setup_entry: AsyncMock ) -> None: """Test with outdated ssdp_location with the correct st added via ssdp.""" entry = MockConfigEntry( @@ -1702,10 +1694,7 @@ async def test_update_main_tv_ssdp_location_rendering_st_updated_from_ssdp( with patch( "homeassistant.components.samsungtv.async_setup", return_value=True, - ) as mock_setup, patch( - "homeassistant.components.samsungtv.async_setup_entry", - return_value=True, - ) as mock_setup_entry: + ) as mock_setup: result = await hass.config_entries.flow.async_init( DOMAIN, context={"source": config_entries.SOURCE_SSDP}, @@ -1728,7 +1717,7 @@ async def test_update_main_tv_ssdp_location_rendering_st_updated_from_ssdp( @pytest.mark.usefixtures("remotews", "rest_api") async def test_update_missing_mac_added_unique_id_preserved_from_zeroconf( - hass: HomeAssistant, + hass: HomeAssistant, mock_setup_entry: AsyncMock ) -> None: """Test missing mac and unique id added.""" entry = MockConfigEntry( @@ -1740,10 +1729,7 @@ async def test_update_missing_mac_added_unique_id_preserved_from_zeroconf( with patch( "homeassistant.components.samsungtv.async_setup", return_value=True, - ) as mock_setup, patch( - "homeassistant.components.samsungtv.async_setup_entry", - return_value=True, - ) as mock_setup_entry: + ) as mock_setup: result = await hass.config_entries.flow.async_init( DOMAIN, context={"source": config_entries.SOURCE_ZEROCONF}, @@ -1759,7 +1745,9 @@ async def test_update_missing_mac_added_unique_id_preserved_from_zeroconf( @pytest.mark.usefixtures("remote") -async def test_update_legacy_missing_mac_from_dhcp(hass: HomeAssistant) -> None: +async def test_update_legacy_missing_mac_from_dhcp( + hass: HomeAssistant, mock_setup_entry: AsyncMock +) -> None: """Test missing mac added.""" entry = MockConfigEntry( domain=DOMAIN, @@ -1770,10 +1758,7 @@ async def test_update_legacy_missing_mac_from_dhcp(hass: HomeAssistant) -> None: with patch( "homeassistant.components.samsungtv.async_setup", return_value=True, - ) as mock_setup, patch( - "homeassistant.components.samsungtv.async_setup_entry", - return_value=True, - ) as mock_setup_entry: + ) as mock_setup: result = await hass.config_entries.flow.async_init( DOMAIN, context={"source": config_entries.SOURCE_DHCP}, @@ -1792,7 +1777,7 @@ async def test_update_legacy_missing_mac_from_dhcp(hass: HomeAssistant) -> None: @pytest.mark.usefixtures("remote") async def test_update_legacy_missing_mac_from_dhcp_no_unique_id( - hass: HomeAssistant, rest_api: Mock + hass: HomeAssistant, rest_api: Mock, mock_setup_entry: AsyncMock ) -> None: """Test missing mac added when there is no unique id.""" rest_api.rest_device_info.side_effect = HttpApiError @@ -1810,10 +1795,7 @@ async def test_update_legacy_missing_mac_from_dhcp_no_unique_id( ), patch( "homeassistant.components.samsungtv.async_setup", return_value=True, - ) as mock_setup, patch( - "homeassistant.components.samsungtv.async_setup_entry", - return_value=True, - ) as mock_setup_entry: + ) as mock_setup: result = await hass.config_entries.flow.async_init( DOMAIN, context={"source": config_entries.SOURCE_DHCP}, @@ -1832,7 +1814,7 @@ async def test_update_legacy_missing_mac_from_dhcp_no_unique_id( @pytest.mark.usefixtures("remotews", "rest_api", "remoteencws_failing") async def test_update_ssdp_location_unique_id_added_from_ssdp( - hass: HomeAssistant, + hass: HomeAssistant, mock_setup_entry: AsyncMock ) -> None: """Test missing ssdp_location, and unique id added via ssdp.""" entry = MockConfigEntry( @@ -1844,10 +1826,7 @@ async def test_update_ssdp_location_unique_id_added_from_ssdp( with patch( "homeassistant.components.samsungtv.async_setup", return_value=True, - ) as mock_setup, patch( - "homeassistant.components.samsungtv.async_setup_entry", - return_value=True, - ) as mock_setup_entry: + ) as mock_setup: result = await hass.config_entries.flow.async_init( DOMAIN, context={"source": config_entries.SOURCE_SSDP}, @@ -1867,7 +1846,7 @@ async def test_update_ssdp_location_unique_id_added_from_ssdp( @pytest.mark.usefixtures("remotews", "rest_api", "remoteencws_failing") async def test_update_ssdp_location_unique_id_added_from_ssdp_with_rendering_control_st( - hass: HomeAssistant, + hass: HomeAssistant, mock_setup_entry: AsyncMock ) -> None: """Test missing ssdp_location, and unique id added via ssdp with rendering control st.""" entry = MockConfigEntry( @@ -1879,10 +1858,7 @@ async def test_update_ssdp_location_unique_id_added_from_ssdp_with_rendering_con with patch( "homeassistant.components.samsungtv.async_setup", return_value=True, - ) as mock_setup, patch( - "homeassistant.components.samsungtv.async_setup_entry", - return_value=True, - ) as mock_setup_entry: + ) as mock_setup: result = await hass.config_entries.flow.async_init( DOMAIN, context={"source": config_entries.SOURCE_SSDP}, @@ -2018,15 +1994,17 @@ async def test_form_reauth_encrypted(hass: HomeAssistant) -> None: del encrypted_entry_data[CONF_TOKEN] del encrypted_entry_data[CONF_SESSION_ID] - entry = await setup_samsungtv_entry(hass, encrypted_entry_data) - assert entry.state == config_entries.ConfigEntryState.SETUP_ERROR - flows_in_progress = [ - flow - for flow in hass.config_entries.flow.async_progress() - if flow["context"]["source"] == "reauth" - ] - assert len(flows_in_progress) == 1 - result = flows_in_progress[0] + entry = MockConfigEntry(domain=DOMAIN, data=encrypted_entry_data) + entry.add_to_hass(hass) + assert entry.state == config_entries.ConfigEntryState.NOT_LOADED + + result = await hass.config_entries.flow.async_init( + DOMAIN, + context={"entry_id": entry.entry_id, "source": config_entries.SOURCE_REAUTH}, + data=entry.data, + ) + assert result["type"] == "form" + assert result["errors"] == {} with patch( "homeassistant.components.samsungtv.config_flow.SamsungTVEncryptedWSAsyncAuthenticator", @@ -2085,7 +2063,7 @@ async def test_form_reauth_encrypted(hass: HomeAssistant) -> None: @pytest.mark.usefixtures("remotews", "rest_api", "remoteencws_failing") async def test_update_incorrect_udn_matching_upnp_udn_unique_id_added_from_ssdp( - hass: HomeAssistant, + hass: HomeAssistant, mock_setup_entry: AsyncMock ) -> None: """Test updating the wrong udn from ssdp via upnp udn match.""" entry = MockConfigEntry( @@ -2097,10 +2075,7 @@ async def test_update_incorrect_udn_matching_upnp_udn_unique_id_added_from_ssdp( with patch( "homeassistant.components.samsungtv.async_setup", return_value=True, - ) as mock_setup, patch( - "homeassistant.components.samsungtv.async_setup_entry", - return_value=True, - ) as mock_setup_entry: + ) as mock_setup: result = await hass.config_entries.flow.async_init( DOMAIN, context={"source": config_entries.SOURCE_SSDP}, @@ -2118,7 +2093,7 @@ async def test_update_incorrect_udn_matching_upnp_udn_unique_id_added_from_ssdp( @pytest.mark.usefixtures("remotews", "rest_api", "remoteencws_failing") async def test_update_incorrect_udn_matching_mac_unique_id_added_from_ssdp( - hass: HomeAssistant, + hass: HomeAssistant, mock_setup_entry: AsyncMock ) -> None: """Test updating the wrong udn from ssdp via mac match.""" entry = MockConfigEntry( @@ -2130,10 +2105,7 @@ async def test_update_incorrect_udn_matching_mac_unique_id_added_from_ssdp( with patch( "homeassistant.components.samsungtv.async_setup", return_value=True, - ) as mock_setup, patch( - "homeassistant.components.samsungtv.async_setup_entry", - return_value=True, - ) as mock_setup_entry: + ) as mock_setup: result = await hass.config_entries.flow.async_init( DOMAIN, context={"source": config_entries.SOURCE_SSDP}, @@ -2151,7 +2123,7 @@ async def test_update_incorrect_udn_matching_mac_unique_id_added_from_ssdp( @pytest.mark.usefixtures("remotews", "rest_api", "remoteencws_failing") async def test_update_incorrect_udn_matching_mac_from_dhcp( - hass: HomeAssistant, + hass: HomeAssistant, mock_setup_entry: AsyncMock ) -> None: """Test that DHCP updates the wrong udn from ssdp via mac match.""" entry = MockConfigEntry( @@ -2164,10 +2136,7 @@ async def test_update_incorrect_udn_matching_mac_from_dhcp( with patch( "homeassistant.components.samsungtv.async_setup", return_value=True, - ) as mock_setup, patch( - "homeassistant.components.samsungtv.async_setup_entry", - return_value=True, - ) as mock_setup_entry: + ) as mock_setup: result = await hass.config_entries.flow.async_init( DOMAIN, context={"source": config_entries.SOURCE_DHCP}, @@ -2185,7 +2154,7 @@ async def test_update_incorrect_udn_matching_mac_from_dhcp( @pytest.mark.usefixtures("remotews", "rest_api", "remoteencws_failing") async def test_no_update_incorrect_udn_not_matching_mac_from_dhcp( - hass: HomeAssistant, + hass: HomeAssistant, mock_setup_entry: AsyncMock ) -> None: """Test that DHCP does not update the wrong udn from ssdp via host match.""" entry = MockConfigEntry( @@ -2198,10 +2167,7 @@ async def test_no_update_incorrect_udn_not_matching_mac_from_dhcp( with patch( "homeassistant.components.samsungtv.async_setup", return_value=True, - ) as mock_setup, patch( - "homeassistant.components.samsungtv.async_setup_entry", - return_value=True, - ) as mock_setup_entry: + ) as mock_setup: result = await hass.config_entries.flow.async_init( DOMAIN, context={"source": config_entries.SOURCE_DHCP}, diff --git a/tests/components/samsungtv/test_init.py b/tests/components/samsungtv/test_init.py index 3b4e33ebf3e..710d421c97c 100644 --- a/tests/components/samsungtv/test_init.py +++ b/tests/components/samsungtv/test_init.py @@ -5,10 +5,14 @@ import pytest from homeassistant.components.media_player import DOMAIN, SUPPORT_TURN_ON from homeassistant.components.samsungtv.const import ( + CONF_MANUFACTURER, CONF_ON_ACTION, + CONF_SESSION_ID, CONF_SSDP_MAIN_TV_AGENT_LOCATION, CONF_SSDP_RENDERING_CONTROL_LOCATION, DOMAIN as SAMSUNGTV_DOMAIN, + LEGACY_PORT, + METHOD_LEGACY, METHOD_WEBSOCKET, UPNP_SVC_MAIN_TV_AGENT, UPNP_SVC_RENDERING_CONTROL, @@ -22,12 +26,16 @@ from homeassistant.const import ( CONF_MAC, CONF_METHOD, CONF_NAME, + CONF_PORT, + CONF_TOKEN, SERVICE_VOLUME_UP, ) from homeassistant.core import HomeAssistant from homeassistant.setup import async_setup_component +from . import setup_samsungtv_entry from .const import ( + MOCK_ENTRYDATA_ENCRYPTED_WS, MOCK_ENTRYDATA_WS, MOCK_SSDP_DATA_MAIN_TV_AGENT_ST, MOCK_SSDP_DATA_RENDERING_CONTROL_ST, @@ -193,3 +201,33 @@ async def test_setup_updates_from_ssdp(hass: HomeAssistant) -> None: entry.data[CONF_SSDP_RENDERING_CONTROL_LOCATION] == "https://fake_host:12345/test" ) + + +@pytest.mark.usefixtures("remoteencws", "rest_api") +async def test_reauth_triggered_encrypted(hass: HomeAssistant) -> None: + """Test reauth flow is triggered for encrypted TVs.""" + encrypted_entry_data = {**MOCK_ENTRYDATA_ENCRYPTED_WS} + del encrypted_entry_data[CONF_TOKEN] + del encrypted_entry_data[CONF_SESSION_ID] + + entry = await setup_samsungtv_entry(hass, encrypted_entry_data) + assert entry.state == ConfigEntryState.SETUP_ERROR + flows_in_progress = [ + flow + for flow in hass.config_entries.flow.async_progress() + if flow["context"]["source"] == "reauth" + ] + assert len(flows_in_progress) == 1 + + +@pytest.mark.usefixtures("remote", "remotews", "rest_api_failing") +async def test_update_imported_legacy_without_method(hass: HomeAssistant) -> None: + """Test updating an imported legacy entry without a method.""" + await setup_samsungtv_entry( + hass, {CONF_HOST: "fake_host", CONF_MANUFACTURER: "Samsung"} + ) + + entries = hass.config_entries.async_entries(SAMSUNGTV_DOMAIN) + assert len(entries) == 1 + assert entries[0].data[CONF_METHOD] == METHOD_LEGACY + assert entries[0].data[CONF_PORT] == LEGACY_PORT