text: """Tests for Samsung TV config flow."""
  import socket
  from unittest.mock import ANY, AsyncMock, Mock, call, patch
  
  import pytest
  from samsungctl.exceptions import AccessDenied, UnhandledResponse
  from samsungtvws.async_remote import SamsungTVWSAsyncRemote
  from samsungtvws.exceptions import (
      ConnectionFailure,
      HttpApiError,
      ResponseError,
      UnauthorizedError,
  )
  from websockets import frames
  from websockets.exceptions import (
      ConnectionClosedError,
      WebSocketException,
      WebSocketProtocolError,
  )
  
  from homeassistant import config_entries
  from homeassistant.components import dhcp, ssdp, zeroconf
  from homeassistant.components.samsungtv.const import (
      CONF_MANUFACTURER,
      CONF_SESSION_ID,
      CONF_SSDP_MAIN_TV_AGENT_LOCATION,
      CONF_SSDP_RENDERING_CONTROL_LOCATION,
      DEFAULT_MANUFACTURER,
      DOMAIN,
      LEGACY_PORT,
      METHOD_ENCRYPTED_WEBSOCKET,
      METHOD_LEGACY,
      METHOD_WEBSOCKET,
      RESULT_AUTH_MISSING,
      RESULT_CANNOT_CONNECT,
      RESULT_NOT_SUPPORTED,
      RESULT_UNKNOWN_HOST,
      TIMEOUT_REQUEST,
      TIMEOUT_WEBSOCKET,
  )
  from homeassistant.components.ssdp import (
      ATTR_UPNP_FRIENDLY_NAME,
      ATTR_UPNP_MANUFACTURER,
      ATTR_UPNP_MODEL_NAME,
      ATTR_UPNP_UDN,
      SsdpServiceInfo,
  )
  from homeassistant.const import (
      CONF_HOST,
      CONF_ID,
      CONF_IP_ADDRESS,
      CONF_MAC,
      CONF_METHOD,
      CONF_MODEL,
      CONF_NAME,
      CONF_PORT,
      CONF_TOKEN,
  )
  from homeassistant.core import HomeAssistant
  from homeassistant.data_entry_flow import (
      RESULT_TYPE_ABORT,
      RESULT_TYPE_CREATE_ENTRY,
      RESULT_TYPE_FORM,
  )
  from homeassistant.setup import async_setup_component
  
  from . import setup_samsungtv_entry
  from .const import (
      MOCK_CONFIG_ENCRYPTED_WS,
      MOCK_ENTRYDATA_ENCRYPTED_WS,
      MOCK_ENTRYDATA_WS,
      MOCK_SSDP_DATA_MAIN_TV_AGENT_ST,
      MOCK_SSDP_DATA_RENDERING_CONTROL_ST,
      SAMPLE_DEVICE_INFO_FRAME,
  )
  
  from tests.common import MockConfigEntry
  
  RESULT_ALREADY_CONFIGURED = "already_configured"
  RESULT_ALREADY_IN_PROGRESS = "already_in_progress"
  
  MOCK_IMPORT_DATA = {
      CONF_HOST: "fake_host",
      CONF_NAME: "fake",
      CONF_PORT: 55000,
  }
  MOCK_IMPORT_DATA_WITHOUT_NAME = {
      CONF_HOST: "fake_host",
  }
  MOCK_IMPORT_WSDATA = {
      CONF_HOST: "fake_host",
      CONF_NAME: "fake",
      CONF_PORT: 8002,
  }
  MOCK_USER_DATA = {CONF_HOST: "fake_host", CONF_NAME: "fake_name"}
  MOCK_SSDP_DATA = ssdp.SsdpServiceInfo(
      ssdp_usn="mock_usn",
      ssdp_st="mock_st",
      ssdp_location="https://fake_host:12345/test",
      upnp={
          ATTR_UPNP_FRIENDLY_NAME: "[TV] fake_name",
          ATTR_UPNP_MANUFACTURER: "Samsung fake_manufacturer",
          ATTR_UPNP_MODEL_NAME: "fake_model",
          ATTR_UPNP_UDN: "uuid:0d1cef00-00dc-1000-9c80-4844f7b172de",
      },
  )
  
  MOCK_SSDP_DATA_NOPREFIX = ssdp.SsdpServiceInfo(
      ssdp_usn="mock_usn",
      ssdp_st="mock_st",
      ssdp_location="http://fake2_host:12345/test",
      upnp={
          ATTR_UPNP_FRIENDLY_NAME: "fake2_name",
          ATTR_UPNP_MANUFACTURER: "Samsung fake2_manufacturer",
          ATTR_UPNP_MODEL_NAME: "fake2_model",
          ATTR_UPNP_UDN: "uuid:0d1cef00-00dc-1000-9c80-4844f7b172df",
      },
  )
  MOCK_SSDP_DATA_WRONGMODEL = ssdp.SsdpServiceInfo(
      ssdp_usn="mock_usn",
      ssdp_st="mock_st",
      ssdp_location="http://fake2_host:12345/test",
      upnp={
          ATTR_UPNP_FRIENDLY_NAME: "fake2_name",
          ATTR_UPNP_MANUFACTURER: "fake2_manufacturer",
          ATTR_UPNP_MODEL_NAME: "HW-Qfake",
          ATTR_UPNP_UDN: "uuid:0d1cef00-00dc-1000-9c80-4844f7b172df",
      },
  )
  MOCK_DHCP_DATA = dhcp.DhcpServiceInfo(
      ip="fake_host", macaddress="aa:bb:dd:hh:cc:pp", hostname="fake_hostname"
  )
  EXISTING_IP = "192.168.40.221"
  MOCK_ZEROCONF_DATA = zeroconf.ZeroconfServiceInfo(
      host="fake_host",
      addresses=["fake_host"],
      hostname="mock_hostname",
      name="mock_name",
      port=1234,
      properties={
          "deviceid": "aa:bb:zz:ee:rr:oo",
          "manufacturer": "fake_manufacturer",
          "model": "fake_model",
          "serialNumber": "fake_serial",
      },
      type="mock_type",
  )
  MOCK_OLD_ENTRY = {
      CONF_HOST: "fake_host",
      CONF_ID: "0d1cef00-00dc-1000-9c80-4844f7b172de_old",
      CONF_IP_ADDRESS: EXISTING_IP,
      CONF_METHOD: "legacy",
      CONF_PORT: None,
  }
  MOCK_LEGACY_ENTRY = {
      CONF_HOST: EXISTING_IP,
      CONF_ID: "0d1cef00-00dc-1000-9c80-4844f7b172de_old",
      CONF_METHOD: "legacy",
      CONF_PORT: None,
  }
  MOCK_DEVICE_INFO = {
      "device": {
          "type": "Samsung SmartTV",
          "name": "fake_name",
          "modelName": "fake_model",
      },
      "id": "123",
  }
  MOCK_DEVICE_INFO_2 = {
      "device": {
          "type": "Samsung SmartTV",
          "name": "fake2_name",
          "modelName": "fake2_model",
      },
      "id": "345",
  }
  
  AUTODETECT_LEGACY = {
      "name": "HomeAssistant",
      "description": "HomeAssistant",
      "id": "ha.component.samsung",
      "method": "legacy",
      "port": None,
      "host": "fake_host",
      "timeout": TIMEOUT_REQUEST,
  }
  AUTODETECT_WEBSOCKET_PLAIN = {
      "host": "fake_host",
      "name": "HomeAssistant",
      "port": 8001,
      "timeout": TIMEOUT_REQUEST,
      "token": None,
  }
  AUTODETECT_WEBSOCKET_SSL = {
      "host": "fake_host",
      "name": "HomeAssistant",
      "port": 8002,
      "timeout": TIMEOUT_REQUEST,
      "token": None,
  }
  DEVICEINFO_WEBSOCKET_SSL = {
      "host": "fake_host",
      "session": ANY,
      "port": 8002,
      "timeout": TIMEOUT_WEBSOCKET,
  }
  DEVICEINFO_WEBSOCKET_NO_SSL = {
      "host": "fake_host",
      "session": ANY,
      "port": 8001,
      "timeout": TIMEOUT_WEBSOCKET,
  }
  
  
  @pytest.mark.usefixtures("remote", "rest_api_failing")
  async def test_user_legacy(hass: HomeAssistant) -> None:
      """Test starting a flow by user."""
      # show form
      result = await hass.config_entries.flow.async_init(
          DOMAIN, context={"source": config_entries.SOURCE_USER}
      )
      assert result["type"] == "form"
      assert result["step_id"] == "user"
  
      # entry was added
      result = await hass.config_entries.flow.async_configure(
          result["flow_id"], user_input=MOCK_USER_DATA
      )
      # legacy tv entry created
      assert result["type"] == "create_entry"
      assert result["title"] == "fake_name"
      assert result["data"][CONF_HOST] == "fake_host"
      assert result["data"][CONF_NAME] == "fake_name"
      assert result["data"][CONF_METHOD] == "legacy"
      assert result["data"][CONF_MANUFACTURER] == DEFAULT_MANUFACTURER
      assert result["data"][CONF_MODEL] is None
      assert result["result"].unique_id is None
  
  
  @pytest.mark.usefixtures("rest_api_failing")
  async def test_user_legacy_does_not_ok_first_time(hass: HomeAssistant) -> None:
      """Test starting a flow by user."""
      # show form
      with patch(
          "homeassistant.components.samsungtv.bridge.Remote",
          side_effect=AccessDenied("Boom"),
      ):
          result = await hass.config_entries.flow.async_init(
              DOMAIN, context={"source": config_entries.SOURCE_USER}
          )
          assert result["type"] == "form"
          assert result["step_id"] == "user"
          # entry was added
          result2 = await hass.config_entries.flow.async_configure(
              result["flow_id"], user_input=MOCK_USER_DATA
          )
  
      with patch("homeassistant.components.samsungtv.bridge.Remote"):
          # entry was added
          result3 = await hass.config_entries.flow.async_configure(
              result2["flow_id"], user_input={}
          )
  
      # legacy tv entry created
      assert result3["type"] == "create_entry"
      assert result3["title"] == "fake_name"
      assert result3["data"][CONF_HOST] == "fake_host"
      assert result3["data"][CONF_NAME] == "fake_name"
      assert result3["data"][CONF_METHOD] == "legacy"
      assert result3["data"][CONF_MANUFACTURER] == DEFAULT_MANUFACTURER
      assert result3["data"][CONF_MODEL] is None
      assert result3["result"].unique_id is None
  
  
  @pytest.mark.usefixtures("remotews", "rest_api", "remoteencws_failing")
  async def test_user_websocket(hass: HomeAssistant) -> None:
      """Test starting a flow by user."""
      with patch(
          "homeassistant.components.samsungtv.bridge.Remote", side_effect=OSError("Boom")
      ):
          # show form
          result = await hass.config_entries.flow.async_init(
              DOMAIN, context={"source": config_entries.SOURCE_USER}
          )
          assert result["type"] == "form"
          assert result["step_id"] == "user"
  
          # entry was added
          result = await hass.config_entries.flow.async_configure(
              result["flow_id"], user_input=MOCK_USER_DATA
          )
          # websocket tv entry created
          assert result["type"] == "create_entry"
          assert result["title"] == "Living Room (82GXARRS)"
          assert result["data"][CONF_HOST] == "fake_host"
          assert result["data"][CONF_NAME] == "Living Room"
          assert result["data"][CONF_METHOD] == "websocket"
          assert result["data"][CONF_MANUFACTURER] == "Samsung"
          assert result["data"][CONF_MODEL] == "82GXARRS"
          assert result["result"].unique_id == "be9554b9-c9fb-41f4-8920-22da015376a4"
  
  
  @pytest.mark.usefixtures("remoteencws", "rest_api_non_ssl_only")
  async def test_user_encrypted_websocket(
      hass: HomeAssistant,
  ) -> None:
      """Test starting a flow from ssdp for a supported device populates the mac."""
      # show form
      result = await hass.config_entries.flow.async_init(
          DOMAIN, context={"source": config_entries.SOURCE_USER}
      )
      assert result["type"] == "form"
      assert result["step_id"] == "user"
  
      with patch(
          "homeassistant.components.samsungtv.config_flow.SamsungTVEncryptedWSAsyncAuthenticator",
          autospec=True,
      ) as authenticator_mock:
          authenticator_mock.return_value.try_pin.side_effect = [
              None,
              "037739871315caef138547b03e348b72",
          ]
          authenticator_mock.return_value.get_session_id_and_close.return_value = "1"
  
          # entry was added
          result2 = await hass.config_entries.flow.async_configure(
              result["flow_id"], user_input=MOCK_USER_DATA
          )
          assert result2["type"] == "form"
          assert result2["step_id"] == "encrypted_pairing"
  
          result3 = await hass.config_entries.flow.async_configure(
              result2["flow_id"], user_input={"pin": "invalid"}
          )
          assert result3["step_id"] == "encrypted_pairing"
          assert result3["errors"] == {"base": "invalid_pin"}
  
          result4 = await hass.config_entries.flow.async_configure(
              result3["flow_id"], user_input={"pin": "1234"}
          )
  
      assert result4["type"] == "create_entry"
      assert result4["title"] == "TV-UE48JU6470 (UE48JU6400)"
      assert result4["data"][CONF_HOST] == "fake_host"
      assert result4["data"][CONF_NAME] == "TV-UE48JU6470"
      assert result4["data"][CONF_MAC] == "aa:bb:ww:ii:ff:ii"
      assert result4["data"][CONF_MANUFACTURER] == "Samsung"
      assert result4["data"][CONF_MODEL] == "UE48JU6400"
      assert result4["data"][CONF_SSDP_RENDERING_CONTROL_LOCATION] is None
      assert result4["data"][CONF_TOKEN] == "037739871315caef138547b03e348b72"
      assert result4["data"][CONF_SESSION_ID] == "1"
      assert result4["result"].unique_id == "223da676-497a-4e06-9507-5e27ec4f0fb3"
  
  
  @pytest.mark.usefixtures("rest_api_failing")
  async def test_user_legacy_missing_auth(hass: HomeAssistant) -> None:
      """Test starting a flow by user with authentication."""
      with patch(
          "homeassistant.components.samsungtv.bridge.Remote",
          side_effect=AccessDenied("Boom"),
      ):
          # legacy device missing authentication
          result = await hass.config_entries.flow.async_init(
              DOMAIN, context={"source": config_entries.SOURCE_USER}, data=MOCK_USER_DATA
          )
          assert result["type"] == RESULT_TYPE_FORM
          assert result["step_id"] == "pairing"
          assert result["errors"] == {"base": "auth_missing"}
  
      with patch(
          "homeassistant.components.samsungtv.bridge.Remote",
          side_effect=OSError,
      ):
          # legacy device fails to connect after auth failed
          result2 = await hass.config_entries.flow.async_configure(
              result["flow_id"], user_input={}
          )
          assert result2["type"] == RESULT_TYPE_ABORT
          assert result2["reason"] == RESULT_CANNOT_CONNECT
  
  
  @pytest.mark.usefixtures("rest_api_failing")
  async def test_user_legacy_not_supported(hass: HomeAssistant) -> None:
      """Test starting a flow by user for not supported device."""
      with patch(
          "homeassistant.components.samsungtv.bridge.Remote",
          side_effect=UnhandledResponse("Boom"),
      ):
          # legacy device not supported
          result = await hass.config_entries.flow.async_init(
              DOMAIN, context={"source": config_entries.SOURCE_USER}, data=MOCK_USER_DATA
          )
          assert result["type"] == "abort"
          assert result["reason"] == RESULT_NOT_SUPPORTED
  
  
  @pytest.mark.usefixtures("rest_api", "remoteencws_failing")
  async def test_user_websocket_not_supported(hass: HomeAssistant) -> None:
      """Test starting a flow by user for not supported device."""
      with patch(
          "homeassistant.components.samsungtv.bridge.Remote",
          side_effect=OSError("Boom"),
      ), patch(
          "homeassistant.components.samsungtv.bridge.SamsungTVWSAsyncRemote.open",
          side_effect=WebSocketProtocolError("Boom"),
      ):
          # websocket device not supported
          result = await hass.config_entries.flow.async_init(
              DOMAIN, context={"source": config_entries.SOURCE_USER}, data=MOCK_USER_DATA
          )
          assert result["type"] == "abort"
          assert result["reason"] == RESULT_NOT_SUPPORTED
  
  
  @pytest.mark.usefixtures("rest_api", "remoteencws_failing")
  async def test_user_websocket_access_denied(
      hass: HomeAssistant, caplog: pytest.LogCaptureFixture
  ) -> None:
      """Test starting a flow by user for not supported device."""
      with patch(
          "homeassistant.components.samsungtv.bridge.Remote",
          side_effect=OSError("Boom"),
      ), patch(
          "homeassistant.components.samsungtv.bridge.SamsungTVWSAsyncRemote.open",
          side_effect=ConnectionClosedError(rcvd=None, sent=frames.Close(1002, "")),
      ):
          # websocket device not supported
          result = await hass.config_entries.flow.async_init(
              DOMAIN, context={"source": config_entries.SOURCE_USER}, data=MOCK_USER_DATA
          )
      assert result["type"] == "abort"
      assert result["reason"] == RESULT_NOT_SUPPORTED
      assert "Please check the Device Connection Manager on your TV" in caplog.text
  
  
  @pytest.mark.usefixtures("rest_api", "remoteencws_failing")
  async def test_user_websocket_auth_retry(hass: HomeAssistant) -> None:
      """Test starting a flow by user for not supported device."""
      with patch(
          "homeassistant.components.samsungtv.bridge.Remote",
          side_effect=OSError("Boom"),
      ), patch(
          "homeassistant.components.samsungtv.bridge.SamsungTVWSAsyncRemote.open",
          side_effect=UnauthorizedError,
      ):
          # websocket device not supported
          result = await hass.config_entries.flow.async_init(
              DOMAIN, context={"source": config_entries.SOURCE_USER}, data=MOCK_USER_DATA
          )
      assert result["type"] == RESULT_TYPE_FORM
      assert result["step_id"] == "pairing"
      assert result["errors"] == {"base": "auth_missing"}
      with patch(
          "homeassistant.components.samsungtv.bridge.Remote",
          side_effect=OSError("Boom"),
      ), patch(
          "homeassistant.components.samsungtv.bridge.SamsungTVWSAsyncRemote.open",
      ):
          result = await hass.config_entries.flow.async_configure(
              result["flow_id"], user_input={}
          )
      assert result["type"] == RESULT_TYPE_CREATE_ENTRY
      assert result["title"] == "Living Room (82GXARRS)"
      assert result["data"][CONF_HOST] == "fake_host"
      assert result["data"][CONF_NAME] == "Living Room"
      assert result["data"][CONF_MANUFACTURER] == "Samsung"
      assert result["data"][CONF_MODEL] == "82GXARRS"
      assert result["result"].unique_id == "be9554b9-c9fb-41f4-8920-22da015376a4"
  
  
  @pytest.mark.usefixtures("rest_api_failing")
  async def test_user_not_successful(hass: HomeAssistant) -> None:
      """Test starting a flow by user but no connection found."""
      with patch(
          "homeassistant.components.samsungtv.bridge.Remote",
          side_effect=OSError("Boom"),
      ), patch(
          "homeassistant.components.samsungtv.bridge.SamsungTVWSAsyncRemote.open",
          side_effect=OSError("Boom"),
      ):
          result = await hass.config_entries.flow.async_init(
              DOMAIN, context={"source": config_entries.SOURCE_USER}, data=MOCK_USER_DATA
          )
          assert result["type"] == "abort"
          assert result["reason"] == RESULT_CANNOT_CONNECT
  
  
  @pytest.mark.usefixtures("rest_api_failing")
  async def test_user_not_successful_2(hass: HomeAssistant) -> None:
      """Test starting a flow by user but no connection found."""
      with patch(
          "homeassistant.components.samsungtv.bridge.Remote",
          side_effect=OSError("Boom"),
      ), patch(
          "homeassistant.components.samsungtv.bridge.SamsungTVWSAsyncRemote.open",
          side_effect=ConnectionFailure("Boom"),
      ):
          result = await hass.config_entries.flow.async_init(
              DOMAIN, context={"source": config_entries.SOURCE_USER}, data=MOCK_USER_DATA
          )
          assert result["type"] == "abort"
          assert result["reason"] == RESULT_CANNOT_CONNECT
  
  
  @pytest.mark.usefixtures("remote", "rest_api_failing")
  async def test_ssdp(hass: HomeAssistant) -> None:
      """Test starting a flow from discovery."""
      # confirm to add the entry
      result = await hass.config_entries.flow.async_init(
          DOMAIN, context={"source": config_entries.SOURCE_SSDP}, data=MOCK_SSDP_DATA
      )
      assert result["type"] == "form"
      assert result["step_id"] == "confirm"
  
      # entry was added
      result = await hass.config_entries.flow.async_configure(
          result["flow_id"], user_input="whatever"
      )
      assert result["type"] == "create_entry"
      assert result["title"] == "fake_model"
      assert result["data"][CONF_HOST] == "fake_host"
      assert result["data"][CONF_NAME] == "fake_model"
      assert result["data"][CONF_MANUFACTURER] == "Samsung fake_manufacturer"
      assert result["data"][CONF_MODEL] == "fake_model"
      assert result["result"].unique_id == "0d1cef00-00dc-1000-9c80-4844f7b172de"
  
  
  @pytest.mark.parametrize(
      "data", [MOCK_SSDP_DATA_MAIN_TV_AGENT_ST, MOCK_SSDP_DATA_RENDERING_CONTROL_ST]
  )
  @pytest.mark.usefixtures("remote", "rest_api_failing")
  async def test_ssdp_legacy_not_remote_control_receiver_udn(
      hass: HomeAssistant, data: SsdpServiceInfo
  ) -> None:
      """Test we abort if the st is not usable for legacy discovery since it will have a different UDN."""
      result = await hass.config_entries.flow.async_init(
          DOMAIN, context={"source": config_entries.SOURCE_SSDP}, data=data
      )
      assert result["type"] == RESULT_TYPE_ABORT
      assert result["reason"] == RESULT_NOT_SUPPORTED
  
  
  @pytest.mark.usefixtures("remote", "rest_api_failing")
  async def test_ssdp_noprefix(hass: HomeAssistant) -> None:
      """Test starting a flow from discovery without prefixes."""
      # confirm to add the entry
      result = await hass.config_entries.flow.async_init(
          DOMAIN,
          context={"source": config_entries.SOURCE_SSDP},
          data=MOCK_SSDP_DATA_NOPREFIX,
      )
      assert result["type"] == "form"
      assert result["step_id"] == "confirm"
      # entry was added
      result = await hass.config_entries.flow.async_configure(
          result["flow_id"], user_input="whatever"
      )
      assert result["type"] == "create_entry"
      assert result["title"] == "fake2_model"
      assert result["data"][CONF_HOST] == "fake2_host"
      assert result["data"][CONF_NAME] == "fake2_model"
      assert result["data"][CONF_MANUFACTURER] == "Samsung fake2_manufacturer"
      assert result["data"][CONF_MODEL] == "fake2_model"
      assert result["result"].unique_id == "0d1cef00-00dc-1000-9c80-4844f7b172df"
  
  
  @pytest.mark.usefixtures("remotews", "rest_api_failing")
  async def test_ssdp_legacy_missing_auth(hass: HomeAssistant) -> None:
      """Test starting a flow from discovery with authentication."""
      with patch(
          "homeassistant.components.samsungtv.bridge.Remote",
          side_effect=AccessDenied("Boom"),
      ):
          # confirm to add the entry
          result = await hass.config_entries.flow.async_init(
              DOMAIN, context={"source": config_entries.SOURCE_SSDP}, data=MOCK_SSDP_DATA
          )
          assert result["type"] == "form"
          assert result["step_id"] == "confirm"
  
          # missing authentication
          result = await hass.config_entries.flow.async_configure(
              result["flow_id"], user_input={}
          )
          assert result["type"] == RESULT_TYPE_FORM
          assert result["step_id"] == "pairing"
          assert result["errors"] == {"base": "auth_missing"}
  
      with patch("homeassistant.components.samsungtv.bridge.Remote"):
          result = await hass.config_entries.flow.async_configure(
              result["flow_id"], user_input={}
          )
  
      assert result["type"] == RESULT_TYPE_CREATE_ENTRY
      assert result["title"] == "fake_model"
      assert result["data"][CONF_HOST] == "fake_host"
      assert result["data"][CONF_NAME] == "fake_model"
      assert result["data"][CONF_MANUFACTURER] == "Samsung fake_manufacturer"
      assert result["data"][CONF_MODEL] == "fake_model"
      assert result["result"].unique_id == "0d1cef00-00dc-1000-9c80-4844f7b172de"
  
  
  @pytest.mark.usefixtures("remotews", "rest_api_failing")
  async def test_ssdp_legacy_not_supported(hass: HomeAssistant) -> None:
      """Test starting a flow from discovery for not supported device."""
      with patch(
          "homeassistant.components.samsungtv.bridge.SamsungTVLegacyBridge.async_try_connect",
          return_value=RESULT_NOT_SUPPORTED,
      ):
          # confirm to add the entry
          result = await hass.config_entries.flow.async_init(
              DOMAIN, context={"source": config_entries.SOURCE_SSDP}, data=MOCK_SSDP_DATA
          )
          assert result["type"] == RESULT_TYPE_ABORT
          assert result["reason"] == RESULT_NOT_SUPPORTED
  
  
  @pytest.mark.usefixtures("remotews", "rest_api", "remoteencws_failing")
  async def test_ssdp_websocket_success_populates_mac_address_and_ssdp_location(
      hass: HomeAssistant,
  ) -> None:
      """Test starting a flow from ssdp for a supported device populates the mac."""
      result = await hass.config_entries.flow.async_init(
          DOMAIN,
          context={"source": config_entries.SOURCE_SSDP},
          data=MOCK_SSDP_DATA_RENDERING_CONTROL_ST,
      )
      assert result["type"] == "form"
      assert result["step_id"] == "confirm"
  
      result = await hass.config_entries.flow.async_configure(
          result["flow_id"], user_input="whatever"
      )
      assert result["type"] == "create_entry"
      assert result["title"] == "Living Room (82GXARRS)"
      assert result["data"][CONF_HOST] == "fake_host"
      assert result["data"][CONF_NAME] == "Living Room"
      assert result["data"][CONF_MAC] == "aa:bb:ww:ii:ff:ii"
      assert result["data"][CONF_MANUFACTURER] == "Samsung fake_manufacturer"
      assert result["data"][CONF_MODEL] == "82GXARRS"
      assert (
          result["data"][CONF_SSDP_RENDERING_CONTROL_LOCATION]
          == "https://fake_host:12345/test"
      )
      assert result["result"].unique_id == "be9554b9-c9fb-41f4-8920-22da015376a4"
  
  
  @pytest.mark.usefixtures("remotews", "rest_api", "remoteencws_failing")
  async def test_ssdp_websocket_success_populates_mac_address_and_main_tv_ssdp_location(
      hass: HomeAssistant,
  ) -> None:
      """Test starting a flow from ssdp for a supported device populates the mac."""
      result = await hass.config_entries.flow.async_init(
          DOMAIN,
          context={"source": config_entries.SOURCE_SSDP},
          data=MOCK_SSDP_DATA_MAIN_TV_AGENT_ST,
      )
      assert result["type"] == "form"
      assert result["step_id"] == "confirm"
  
      result = await hass.config_entries.flow.async_configure(
          result["flow_id"], user_input="whatever"
      )
      assert result["type"] == "create_entry"
      assert result["title"] == "Living Room (82GXARRS)"
      assert result["data"][CONF_HOST] == "fake_host"
      assert result["data"][CONF_NAME] == "Living Room"
      assert result["data"][CONF_MAC] == "aa:bb:ww:ii:ff:ii"
      assert result["data"][CONF_MANUFACTURER] == "Samsung fake_manufacturer"
      assert result["data"][CONF_MODEL] == "82GXARRS"
      assert (
          result["data"][CONF_SSDP_MAIN_TV_AGENT_LOCATION]
          == "https://fake_host:12345/tv_agent"
      )
      assert result["result"].unique_id == "be9554b9-c9fb-41f4-8920-22da015376a4"
  
  
  @pytest.mark.usefixtures("remoteencws", "rest_api_non_ssl_only")
  async def test_ssdp_encrypted_websocket_success_populates_mac_address_and_ssdp_location(
      hass: HomeAssistant,
  ) -> None:
      """Test starting a flow from ssdp for a supported device populates the mac."""
      result = await hass.config_entries.flow.async_init(
          DOMAIN,
          context={"source": config_entries.SOURCE_SSDP},
          data=MOCK_SSDP_DATA_RENDERING_CONTROL_ST,
      )
      assert result["type"] == "form"
      assert result["step_id"] == "confirm"
  
      with patch(
          "homeassistant.components.samsungtv.config_flow.SamsungTVEncryptedWSAsyncAuthenticator",
          autospec=True,
      ) as authenticator_mock:
          authenticator_mock.return_value.try_pin.side_effect = [
              None,
              "037739871315caef138547b03e348b72",
          ]
          authenticator_mock.return_value.get_session_id_and_close.return_value = "1"
  
          result2 = await hass.config_entries.flow.async_configure(
              result["flow_id"], user_input={}
          )
          assert result2["step_id"] == "encrypted_pairing"
  
          result3 = await hass.config_entries.flow.async_configure(
              result2["flow_id"], user_input={"pin": "invalid"}
          )
          assert result3["step_id"] == "encrypted_pairing"
          assert result3["errors"] == {"base": "invalid_pin"}
  
          result4 = await hass.config_entries.flow.async_configure(
              result3["flow_id"], user_input={"pin": "1234"}
          )
  
      assert result4["type"] == "create_entry"
      assert result4["title"] == "TV-UE48JU6470 (UE48JU6400)"
      assert result4["data"][CONF_HOST] == "fake_host"
      assert result4["data"][CONF_NAME] == "TV-UE48JU6470"
      assert result4["data"][CONF_MAC] == "aa:bb:ww:ii:ff:ii"
      assert result4["data"][CONF_MANUFACTURER] == "Samsung fake_manufacturer"
      assert result4["data"][CONF_MODEL] == "UE48JU6400"
      assert (
          result4["data"][CONF_SSDP_RENDERING_CONTROL_LOCATION]
          == "https://fake_host:12345/test"
      )
      assert result4["data"][CONF_TOKEN] == "037739871315caef138547b03e348b72"
      assert result4["data"][CONF_SESSION_ID] == "1"
      assert result4["result"].unique_id == "223da676-497a-4e06-9507-5e27ec4f0fb3"
  
  
  @pytest.mark.usefixtures("rest_api_non_ssl_only")
  async def test_ssdp_encrypted_websocket_not_supported(
      hass: HomeAssistant,
  ) -> None:
      """Test starting a flow from ssdp for an unsupported device populates the mac."""
      with patch(
          "homeassistant.components.samsungtv.bridge.SamsungTVEncryptedWSAsyncRemote.start_listening",
          side_effect=WebSocketException,
      ):
          result = await hass.config_entries.flow.async_init(
              DOMAIN,
              context={"source": config_entries.SOURCE_SSDP},
              data=MOCK_SSDP_DATA_RENDERING_CONTROL_ST,
          )
          assert result["type"] == RESULT_TYPE_ABORT
          assert result["reason"] == RESULT_NOT_SUPPORTED
  
  
  @pytest.mark.usefixtures("rest_api_failing")
  async def test_ssdp_websocket_cannot_connect(hass: HomeAssistant) -> None:
      """Test starting a flow from discovery and we cannot connect."""
      with patch(
          "homeassistant.components.samsungtv.bridge.Remote",
          side_effect=OSError("Boom"),
      ), patch(
          "homeassistant.components.samsungtv.bridge.SamsungTVEncryptedWSAsyncRemote.start_listening",
          side_effect=WebSocketProtocolError("Boom"),
      ), patch(
          "homeassistant.components.samsungtv.bridge.SamsungTVWSAsyncRemote",
      ) as remotews, patch.object(
          remotews, "open", side_effect=WebSocketProtocolError("Boom")
      ):
          # device not supported
          result = await hass.config_entries.flow.async_init(
              DOMAIN, context={"source": config_entries.SOURCE_SSDP}, data=MOCK_SSDP_DATA
          )
          assert result["type"] == "abort"
          assert result["reason"] == RESULT_CANNOT_CONNECT
  
  
  @pytest.mark.usefixtures("remote")
  async def test_ssdp_model_not_supported(hass: HomeAssistant) -> None:
      """Test starting a flow from discovery."""
  
      # confirm to add the entry
      result = await hass.config_entries.flow.async_init(
          DOMAIN,
          context={"source": config_entries.SOURCE_SSDP},
          data=MOCK_SSDP_DATA_WRONGMODEL,
      )
      assert result["type"] == "abort"
      assert result["reason"] == RESULT_NOT_SUPPORTED
  
  
  @pytest.mark.usefixtures("remoteencws_failing")
  async def test_ssdp_not_successful(hass: HomeAssistant) -> None:
      """Test starting a flow from discovery but no device found."""
      with patch(
          "homeassistant.components.samsungtv.bridge.Remote",
          side_effect=OSError("Boom"),
      ), patch(
          "homeassistant.components.samsungtv.bridge.SamsungTVWSAsyncRemote.open",
          side_effect=OSError("Boom"),
      ), patch(
          "homeassistant.components.samsungtv.bridge.SamsungTVWSBridge.async_device_info",
          return_value=MOCK_DEVICE_INFO,
      ):
  
          # confirm to add the entry
          result = await hass.config_entries.flow.async_init(
              DOMAIN, context={"source": config_entries.SOURCE_SSDP}, data=MOCK_SSDP_DATA
          )
          assert result["type"] == "form"
          assert result["step_id"] == "confirm"
  
          # device not found
          result = await hass.config_entries.flow.async_configure(
              result["flow_id"], user_input="whatever"
          )
          assert result["type"] == "abort"
          assert result["reason"] == RESULT_CANNOT_CONNECT
  
  
  @pytest.mark.usefixtures("remoteencws_failing")
  async def test_ssdp_not_successful_2(hass: HomeAssistant) -> None:
      """Test starting a flow from discovery but no device found."""
      with patch(
          "homeassistant.components.samsungtv.bridge.Remote",
          side_effect=OSError("Boom"),
      ), patch(
          "homeassistant.components.samsungtv.bridge.SamsungTVWSAsyncRemote.open",
          side_effect=ConnectionFailure("Boom"),
      ), patch(
          "homeassistant.components.samsungtv.bridge.SamsungTVWSBridge.async_device_info",
          return_value=MOCK_DEVICE_INFO,
      ):
  
          # confirm to add the entry
          result = await hass.config_entries.flow.async_init(
              DOMAIN, context={"source": config_entries.SOURCE_SSDP}, data=MOCK_SSDP_DATA
          )
          assert result["type"] == "form"
          assert result["step_id"] == "confirm"
  
          # device not found
          result = await hass.config_entries.flow.async_configure(
              result["flow_id"], user_input="whatever"
          )
          assert result["type"] == "abort"
          assert result["reason"] == RESULT_CANNOT_CONNECT
  
  
  @pytest.mark.usefixtures("remote", "remoteencws_failing")
  async def test_ssdp_already_in_progress(hass: HomeAssistant) -> None:
      """Test starting a flow from discovery twice."""
      with patch(
          "homeassistant.components.samsungtv.bridge.SamsungTVWSBridge.async_device_info",
          return_value=MOCK_DEVICE_INFO,
      ):
  
          # confirm to add the entry
          result = await hass.config_entries.flow.async_init(
              DOMAIN, context={"source": config_entries.SOURCE_SSDP}, data=MOCK_SSDP_DATA
          )
          assert result["type"] == "form"
          assert result["step_id"] == "confirm"
  
          # failed as already in progress
          result = await hass.config_entries.flow.async_init(
              DOMAIN, context={"source": config_entries.SOURCE_SSDP}, data=MOCK_SSDP_DATA
          )
          assert result["type"] == "abort"
          assert result["reason"] == RESULT_ALREADY_IN_PROGRESS
  
  
  @pytest.mark.usefixtures("remotews", "remoteencws_failing")
  async def test_ssdp_already_configured(hass: HomeAssistant) -> None:
      """Test starting a flow from discovery when already configured."""
      with patch(
          "homeassistant.components.samsungtv.bridge.SamsungTVWSBridge.async_device_info",
          return_value=MOCK_DEVICE_INFO,
      ):
  
          # entry was added
          result = await hass.config_entries.flow.async_init(
              DOMAIN, context={"source": config_entries.SOURCE_USER}, data=MOCK_USER_DATA
          )
          assert result["type"] == "create_entry"
          entry = result["result"]
          assert entry.data[CONF_MANUFACTURER] == DEFAULT_MANUFACTURER
          assert entry.data[CONF_MODEL] == "fake_model"
          assert entry.unique_id == "123"
  
          # failed as already configured
          result2 = await hass.config_entries.flow.async_init(
              DOMAIN, context={"source": config_entries.SOURCE_SSDP}, data=MOCK_SSDP_DATA
          )
          assert result2["type"] == "abort"
          assert result2["reason"] == RESULT_ALREADY_CONFIGURED
  
          # check updated device info
          assert entry.unique_id == "123"
  
  
  @pytest.mark.usefixtures("remote")
  async def test_import_legacy(hass: HomeAssistant) -> None:
      """Test importing from yaml with hostname."""
      result = await hass.config_entries.flow.async_init(
          DOMAIN,
          context={"source": config_entries.SOURCE_IMPORT},
          data=MOCK_IMPORT_DATA,
      )
      await hass.async_block_till_done()
      assert result["type"] == "create_entry"
      assert result["title"] == "fake"
      assert result["data"][CONF_HOST] == "fake_host"
      assert result["data"][CONF_NAME] == "fake"
      assert result["data"][CONF_MANUFACTURER] == "Samsung"
      assert result["result"].unique_id is None
  
      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
  
  
  @pytest.mark.usefixtures("remote", "remotews", "rest_api_failing")
  async def test_import_legacy_without_name(hass: HomeAssistant) -> None:
      """Test importing from yaml without a name."""
      with patch(
          "homeassistant.components.samsungtv.bridge.SamsungTVEncryptedWSAsyncRemote.start_listening",
          side_effect=WebSocketProtocolError("Boom"),
      ):
          result = await hass.config_entries.flow.async_init(
              DOMAIN,
              context={"source": config_entries.SOURCE_IMPORT},
              data=MOCK_IMPORT_DATA_WITHOUT_NAME,
          )
          await hass.async_block_till_done()
      assert result["type"] == "create_entry"
      assert result["title"] == "fake_host"
      assert result["data"][CONF_HOST] == "fake_host"
      assert result["data"][CONF_MANUFACTURER] == "Samsung"
      assert result["result"].unique_id is None
  
      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
  
  
  @pytest.mark.usefixtures("remotews", "rest_api")
  async def test_import_websocket(hass: HomeAssistant):
      """Test importing from yaml with hostname."""
      result = await hass.config_entries.flow.async_init(
          DOMAIN,
          context={"source": config_entries.SOURCE_IMPORT},
          data=MOCK_IMPORT_WSDATA,
      )
      await hass.async_block_till_done()
      assert result["type"] == "create_entry"
      assert result["title"] == "fake"
      assert result["data"][CONF_METHOD] == METHOD_WEBSOCKET
      assert result["data"][CONF_PORT] == 8002
      assert result["data"][CONF_HOST] == "fake_host"
      assert result["data"][CONF_NAME] == "fake"
      assert result["data"][CONF_MANUFACTURER] == "Samsung"
      assert result["result"].unique_id is None
  
  
  @pytest.mark.usefixtures("remoteencws")
  async def test_import_websocket_encrypted(hass: HomeAssistant):
      """Test importing from yaml with hostname."""
      result = await hass.config_entries.flow.async_init(
          DOMAIN,
          context={"source": config_entries.SOURCE_IMPORT},
          data=MOCK_CONFIG_ENCRYPTED_WS,
      )
      await hass.async_block_till_done()
  
      assert result["type"] == "create_entry"
      assert result["title"] == "fake"
      assert result["data"][CONF_METHOD] == METHOD_ENCRYPTED_WEBSOCKET
      assert result["data"][CONF_PORT] == 8000
      assert result["data"][CONF_HOST] == "fake_host"
      assert result["data"][CONF_NAME] == "fake"
      assert result["data"][CONF_MANUFACTURER] == "Samsung"
      assert result["result"].unique_id is None
  
  
  @pytest.mark.usefixtures("remotews", "rest_api")
  async def test_import_websocket_without_port(hass: HomeAssistant):
      """Test importing from yaml with hostname by no port."""
      result = await hass.config_entries.flow.async_init(
          DOMAIN,
          context={"source": config_entries.SOURCE_IMPORT},
          data=MOCK_IMPORT_WSDATA,
      )
      await hass.async_block_till_done()
      assert result["type"] == "create_entry"
      assert result["title"] == "fake"
      assert result["data"][CONF_HOST] == "fake_host"
      assert result["data"][CONF_NAME] == "fake"
      assert result["data"][CONF_MANUFACTURER] == "Samsung"
      assert result["result"].unique_id is None
  
      entries = hass.config_entries.async_entries(DOMAIN)
      assert len(entries) == 1
      assert entries[0].data[CONF_METHOD] == METHOD_WEBSOCKET
      assert entries[0].data[CONF_PORT] == 8002
  
  
  @pytest.mark.usefixtures("remotews")
  async def test_import_unknown_host(hass: HomeAssistant):
      """Test importing from yaml with hostname that does not resolve."""
      with patch(
          "homeassistant.components.samsungtv.config_flow.socket.gethostbyname",
          side_effect=socket.gaierror,
      ):
          result = await hass.config_entries.flow.async_init(
              DOMAIN,
              context={"source": config_entries.SOURCE_IMPORT},
              data=MOCK_IMPORT_DATA,
          )
      await hass.async_block_till_done()
      assert result["type"] == "abort"
      assert result["reason"] == RESULT_UNKNOWN_HOST
  
  
  @pytest.mark.usefixtures("remotews", "rest_api_non_ssl_only", "remoteencws_failing")
  async def test_dhcp_wireless(hass: HomeAssistant) -> None:
      """Test starting a flow from dhcp."""
      # confirm to add the entry
      result = await hass.config_entries.flow.async_init(
          DOMAIN,
          context={"source": config_entries.SOURCE_DHCP},
          data=MOCK_DHCP_DATA,
      )
      await hass.async_block_till_done()
      assert result["type"] == "form"
      assert result["step_id"] == "confirm"
  
      # entry was added
      result = await hass.config_entries.flow.async_configure(
          result["flow_id"], user_input="whatever"
      )
      assert result["type"] == "create_entry"
      assert result["title"] == "TV-UE48JU6470 (UE48JU6400)"
      assert result["data"][CONF_HOST] == "fake_host"
      assert result["data"][CONF_NAME] == "TV-UE48JU6470"
      assert result["data"][CONF_MAC] == "aa:bb:ww:ii:ff:ii"
      assert result["data"][CONF_MANUFACTURER] == "Samsung"
      assert result["data"][CONF_MODEL] == "UE48JU6400"
      assert result["result"].unique_id == "223da676-497a-4e06-9507-5e27ec4f0fb3"
  
  
  @pytest.mark.usefixtures("remotews", "rest_api", "remoteencws_failing")
  async def test_dhcp_wired(hass: HomeAssistant, rest_api: Mock) -> None:
      """Test starting a flow from dhcp."""
      # Even though it is named "wifiMac", it matches the mac of the wired connection
      rest_api.rest_device_info.return_value = SAMPLE_DEVICE_INFO_FRAME
      # confirm to add the entry
      result = await hass.config_entries.flow.async_init(
          DOMAIN,
          context={"source": config_entries.SOURCE_DHCP},
          data=MOCK_DHCP_DATA,
      )
      await hass.async_block_till_done()
      assert result["type"] == "form"
      assert result["step_id"] == "confirm"
  
      # entry was added
      result = await hass.config_entries.flow.async_configure(
          result["flow_id"], user_input="whatever"
      )
      assert result["type"] == "create_entry"
      assert result["title"] == "Samsung Frame (43) (UE43LS003)"
      assert result["data"][CONF_HOST] == "fake_host"
      assert result["data"][CONF_NAME] == "Samsung Frame (43)"
      assert result["data"][CONF_MAC] == "aa:ee:tt:hh:ee:rr"
      assert result["data"][CONF_MANUFACTURER] == "Samsung"
      assert result["data"][CONF_MODEL] == "UE43LS003"
      assert result["result"].unique_id == "be9554b9-c9fb-41f4-8920-22da015376a4"
  
  
  @pytest.mark.usefixtures("remotews", "rest_api", "remoteencws_failing")
  async def test_zeroconf(hass: HomeAssistant) -> None:
      """Test starting a flow from zeroconf."""
      result = await hass.config_entries.flow.async_init(
          DOMAIN,
          context={"source": config_entries.SOURCE_ZEROCONF},
          data=MOCK_ZEROCONF_DATA,
      )
      await hass.async_block_till_done()
      assert result["type"] == "form"
      assert result["step_id"] == "confirm"
  
      # entry was added
      result = await hass.config_entries.flow.async_configure(
          result["flow_id"], user_input="whatever"
      )
      assert result["type"] == "create_entry"
      assert result["title"] == "Living Room (82GXARRS)"
      assert result["data"][CONF_HOST] == "fake_host"
      assert result["data"][CONF_NAME] == "Living Room"
      assert result["data"][CONF_MAC] == "aa:bb:ww:ii:ff:ii"
      assert result["data"][CONF_MANUFACTURER] == "Samsung"
      assert result["data"][CONF_MODEL] == "82GXARRS"
      assert result["result"].unique_id == "be9554b9-c9fb-41f4-8920-22da015376a4"
  
  
  @pytest.mark.usefixtures("remotews", "remoteencws_failing")
  async def test_zeroconf_ignores_soundbar(hass: HomeAssistant, rest_api: Mock) -> None:
      """Test starting a flow from zeroconf where the device is actually a soundbar."""
      rest_api.rest_device_info.return_value = {
          "id": "uuid:be9554b9-c9fb-41f4-8920-22da015376a4",
          "device": {
              "modelName": "82GXARRS",
              "wifiMac": "aa:bb:cc:dd:ee:ff",
              "mac": "aa:bb:cc:dd:ee:ff",
              "name": "[TV] Living Room",
              "type": "Samsung SoundBar",
          },
      }
      result = await hass.config_entries.flow.async_init(
          DOMAIN,
          context={"source": config_entries.SOURCE_ZEROCONF},
          data=MOCK_ZEROCONF_DATA,
      )
      await hass.async_block_till_done()
      assert result["type"] == "abort"
      assert result["reason"] == "not_supported"
  
  
  @pytest.mark.usefixtures("remote", "remotews", "remoteencws", "rest_api_failing")
  async def test_zeroconf_no_device_info(hass: HomeAssistant) -> None:
      """Test starting a flow from zeroconf where device_info returns None."""
      result = await hass.config_entries.flow.async_init(
          DOMAIN,
          context={"source": config_entries.SOURCE_ZEROCONF},
          data=MOCK_ZEROCONF_DATA,
      )
      await hass.async_block_till_done()
      assert result["type"] == "abort"
      assert result["reason"] == "not_supported"
  
  
  @pytest.mark.usefixtures("remotews", "rest_api", "remoteencws_failing")
  async def test_zeroconf_and_dhcp_same_time(hass: HomeAssistant) -> None:
      """Test starting a flow from zeroconf and dhcp."""
      result = await hass.config_entries.flow.async_init(
          DOMAIN,
          context={"source": config_entries.SOURCE_DHCP},
          data=MOCK_DHCP_DATA,
      )
      await hass.async_block_till_done()
      assert result["type"] == "form"
      assert result["step_id"] == "confirm"
  
      result2 = await hass.config_entries.flow.async_init(
          DOMAIN,
          context={"source": config_entries.SOURCE_ZEROCONF},
          data=MOCK_ZEROCONF_DATA,
      )
      await hass.async_block_till_done()
      assert result2["type"] == "abort"
      assert result2["reason"] == "already_in_progress"
  
  
  @pytest.mark.usefixtures("remoteencws_failing")
  async def test_autodetect_websocket(hass: HomeAssistant) -> None:
      """Test for send key with autodetection of protocol."""
      with patch(
          "homeassistant.components.samsungtv.bridge.Remote",
          side_effect=OSError("Boom"),
      ), patch(
          "homeassistant.components.samsungtv.bridge.SamsungTVWSAsyncRemote"
      ) as remotews, patch(
          "homeassistant.components.samsungtv.bridge.SamsungTVAsyncRest",
      ) as rest_api_class:
          remote = Mock(SamsungTVWSAsyncRemote)
          remote.__aenter__ = AsyncMock(return_value=remote)
          remote.__aexit__ = AsyncMock(return_value=False)
          rest_api_class.return_value.rest_device_info = AsyncMock(
              return_value={
                  "id": "uuid:be9554b9-c9fb-41f4-8920-22da015376a4",
                  "device": {
                      "modelName": "82GXARRS",
                      "networkType": "wireless",
                      "wifiMac": "aa:bb:cc:dd:ee:ff",
                      "udn": "uuid:be9554b9-c9fb-41f4-8920-22da015376a4",
                      "mac": "aa:bb:cc:dd:ee:ff",
                      "name": "[TV] Living Room",
                      "type": "Samsung SmartTV",
                  },
              }
          )
          remote.token = "123456789"
          remotews.return_value = remote
  
          result = await hass.config_entries.flow.async_init(
              DOMAIN, context={"source": config_entries.SOURCE_USER}, data=MOCK_USER_DATA
          )
          assert result["type"] == "create_entry"
          assert result["data"][CONF_METHOD] == "websocket"
          assert result["data"][CONF_TOKEN] == "123456789"
          remotews.assert_called_once_with(**AUTODETECT_WEBSOCKET_SSL)
          rest_api_class.assert_called_once_with(**DEVICEINFO_WEBSOCKET_SSL)
          await hass.async_block_till_done()
  
      entries = hass.config_entries.async_entries(DOMAIN)
      assert len(entries) == 1
      assert entries[0].data[CONF_MAC] == "aa:bb:cc:dd:ee:ff"
  
  
  @pytest.mark.usefixtures("remoteencws_failing")
  async def test_websocket_no_mac(hass: HomeAssistant, mac_address: Mock) -> None:
      """Test for send key with autodetection of protocol."""
      mac_address.return_value = "gg:ee:tt:mm:aa:cc"
      with patch(
          "homeassistant.components.samsungtv.bridge.Remote",
          side_effect=OSError("Boom"),
      ), patch(
          "homeassistant.components.samsungtv.bridge.SamsungTVWSAsyncRemote"
      ) as remotews, patch(
          "homeassistant.components.samsungtv.bridge.SamsungTVAsyncRest",
      ) as rest_api_class:
          remote = Mock(SamsungTVWSAsyncRemote)
          remote.__aenter__ = AsyncMock(return_value=remote)
          remote.__aexit__ = AsyncMock(return_value=False)
          rest_api_class.return_value.rest_device_info = AsyncMock(
              return_value={
                  "id": "uuid:be9554b9-c9fb-41f4-8920-22da015376a4",
                  "device": {
                      "modelName": "82GXARRS",
                      "networkType": "lan",
                      "udn": "uuid:be9554b9-c9fb-41f4-8920-22da015376a4",
                      "name": "[TV] Living Room",
                      "type": "Samsung SmartTV",
                  },
              }
          )
  
          remote.token = "123456789"
          remotews.return_value = remote
  
          result = await hass.config_entries.flow.async_init(
              DOMAIN, context={"source": config_entries.SOURCE_USER}, data=MOCK_USER_DATA
          )
          assert result["type"] == "create_entry"
          assert result["data"][CONF_METHOD] == "websocket"
          assert result["data"][CONF_TOKEN] == "123456789"
          assert result["data"][CONF_MAC] == "gg:ee:tt:mm:aa:cc"
          remotews.assert_called_once_with(**AUTODETECT_WEBSOCKET_SSL)
          rest_api_class.assert_called_once_with(**DEVICEINFO_WEBSOCKET_SSL)
          await hass.async_block_till_done()
  
      entries = hass.config_entries.async_entries(DOMAIN)
      assert len(entries) == 1
      assert entries[0].data[CONF_MAC] == "gg:ee:tt:mm:aa:cc"
  
  
  @pytest.mark.usefixtures("rest_api_failing")
  async def test_autodetect_auth_missing(hass: HomeAssistant) -> None:
      """Test for send key with autodetection of protocol."""
      with patch(
          "homeassistant.components.samsungtv.bridge.Remote",
          side_effect=AccessDenied("Boom"),
      ) as remote:
          result = await hass.config_entries.flow.async_init(
              DOMAIN, context={"source": config_entries.SOURCE_USER}, data=MOCK_USER_DATA
          )
          assert result["type"] == RESULT_TYPE_FORM
          assert result["step_id"] == "pairing"
          assert result["errors"] == {"base": "auth_missing"}
  
          assert remote.call_count == 2
          assert remote.call_args_list == [
              call(AUTODETECT_LEGACY),
              call(AUTODETECT_LEGACY),
          ]
      with patch("homeassistant.components.samsungtv.bridge.Remote", side_effect=OSError):
          result2 = await hass.config_entries.flow.async_configure(
              result["flow_id"],
              {},
          )
          await hass.async_block_till_done()
          assert result2["type"] == RESULT_TYPE_ABORT
          assert result2["reason"] == RESULT_CANNOT_CONNECT
  
  
  @pytest.mark.usefixtures("rest_api_failing")
  async def test_autodetect_not_supported(hass: HomeAssistant) -> None:
      """Test for send key with autodetection of protocol."""
      with patch(
          "homeassistant.components.samsungtv.bridge.Remote",
          side_effect=[UnhandledResponse("Boom")],
      ) as remote:
          result = await hass.config_entries.flow.async_init(
              DOMAIN, context={"source": config_entries.SOURCE_USER}, data=MOCK_USER_DATA
          )
          assert result["type"] == "abort"
          assert result["reason"] == RESULT_NOT_SUPPORTED
          assert remote.call_count == 1
          assert remote.call_args_list == [call(AUTODETECT_LEGACY)]
  
  
  @pytest.mark.usefixtures("remote", "rest_api_failing")
  async def test_autodetect_legacy(hass: HomeAssistant) -> None:
      """Test for send key with autodetection of protocol."""
      result = await hass.config_entries.flow.async_init(
          DOMAIN, context={"source": config_entries.SOURCE_USER}, data=MOCK_USER_DATA
      )
      assert result["type"] == "create_entry"
      assert result["data"][CONF_METHOD] == "legacy"
      assert result["data"][CONF_NAME] == "fake_name"
      assert result["data"][CONF_MAC] is None
      assert result["data"][CONF_PORT] == LEGACY_PORT
  
  
  async def test_autodetect_none(hass: HomeAssistant) -> None:
      """Test for send key with autodetection of protocol."""
      with patch(
          "homeassistant.components.samsungtv.bridge.Remote",
          side_effect=OSError("Boom"),
      ) as remote, patch(
          "homeassistant.components.samsungtv.bridge.SamsungTVAsyncRest.rest_device_info",
          side_effect=ResponseError,
      ) as rest_device_info:
          result = await hass.config_entries.flow.async_init(
              DOMAIN, context={"source": config_entries.SOURCE_USER}, data=MOCK_USER_DATA
          )
          assert result["type"] == "abort"
          assert result["reason"] == RESULT_CANNOT_CONNECT
          assert remote.call_count == 1
          assert remote.call_args_list == [
              call(AUTODETECT_LEGACY),
          ]
          assert rest_device_info.call_count == 2
  
  
  @pytest.mark.usefixtures("remotews", "rest_api", "remoteencws_failing")
  async def test_update_old_entry(hass: HomeAssistant) -> None:
      """Test update of old entry."""
      entry = MockConfigEntry(domain=DOMAIN, data=MOCK_OLD_ENTRY)
      entry.add_to_hass(hass)
  
      config_entries_domain = hass.config_entries.async_entries(DOMAIN)
      assert len(config_entries_domain) == 1
      assert entry is config_entries_domain[0]
      assert entry.data[CONF_ID] == "0d1cef00-00dc-1000-9c80-4844f7b172de_old"
      assert entry.data[CONF_IP_ADDRESS] == EXISTING_IP
      assert not entry.unique_id
  
      assert await async_setup_component(hass, DOMAIN, {}) is True
      await hass.async_block_till_done()
  
      # failed as already configured
      result = await hass.config_entries.flow.async_init(
          DOMAIN, context={"source": config_entries.SOURCE_SSDP}, data=MOCK_SSDP_DATA
      )
      assert result["type"] == "abort"
      assert result["reason"] == RESULT_ALREADY_CONFIGURED
  
      config_entries_domain = hass.config_entries.async_entries(DOMAIN)
      assert len(config_entries_domain) == 1
      entry2 = config_entries_domain[0]
  
      # check updated device info
      assert entry2.data.get(CONF_ID) is not None
      assert entry2.data.get(CONF_IP_ADDRESS) is not None
      assert entry2.unique_id == "be9554b9-c9fb-41f4-8920-22da015376a4"
  
  
  @pytest.mark.usefixtures("remotews", "rest_api", "remoteencws_failing")
  async def test_update_missing_mac_unique_id_added_from_dhcp(
      hass: HomeAssistant,
  ) -> None:
      """Test missing mac and unique id added."""
      entry = MockConfigEntry(domain=DOMAIN, data=MOCK_OLD_ENTRY, unique_id=None)
      entry.add_to_hass(hass)
      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:
          result = await hass.config_entries.flow.async_init(
              DOMAIN,
              context={"source": config_entries.SOURCE_DHCP},
              data=MOCK_DHCP_DATA,
          )
          await hass.async_block_till_done()
          assert len(mock_setup.mock_calls) == 1
          assert len(mock_setup_entry.mock_calls) == 1
  
      assert result["type"] == "abort"
      assert result["reason"] == "already_configured"
      assert entry.data[CONF_MAC] == "aa:bb:dd:hh:cc:pp"
      assert entry.unique_id == "be9554b9-c9fb-41f4-8920-22da015376a4"
  
  
  @pytest.mark.usefixtures("remotews", "rest_api", "remoteencws_failing")
  async def test_update_missing_mac_unique_id_added_from_zeroconf(
      hass: HomeAssistant,
  ) -> None:
      """Test missing mac and unique id added."""
      entry = MockConfigEntry(domain=DOMAIN, data=MOCK_OLD_ENTRY, unique_id=None)
      entry.add_to_hass(hass)
      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:
          result = await hass.config_entries.flow.async_init(
              DOMAIN,
              context={"source": config_entries.SOURCE_ZEROCONF},
              data=MOCK_ZEROCONF_DATA,
          )
          await hass.async_block_till_done()
          assert len(mock_setup.mock_calls) == 1
          assert len(mock_setup_entry.mock_calls) == 1
      assert result["type"] == "abort"
      assert result["reason"] == "already_configured"
      assert entry.data[CONF_MAC] == "aa:bb:zz:ee:rr:oo"
      assert entry.unique_id == "be9554b9-c9fb-41f4-8920-22da015376a4"
  
  
  @pytest.mark.usefixtures("remotews", "rest_api", "remoteencws_failing")
  async def test_update_missing_mac_unique_id_ssdp_location_added_from_ssdp(
      hass: HomeAssistant,
  ) -> None:
      """Test missing mac, ssdp_location, and unique id added via ssdp."""
      entry = MockConfigEntry(domain=DOMAIN, data=MOCK_OLD_ENTRY, unique_id=None)
      entry.add_to_hass(hass)
      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:
          result = await hass.config_entries.flow.async_init(
              DOMAIN,
              context={"source": config_entries.SOURCE_SSDP},
              data=MOCK_SSDP_DATA,
          )
          await hass.async_block_till_done()
          assert len(mock_setup.mock_calls) == 1
          assert len(mock_setup_entry.mock_calls) == 1
  
      assert result["type"] == "abort"
      assert result["reason"] == "already_configured"
      assert entry.data[CONF_MAC] == "aa:bb:ww:ii:ff:ii"
      # Wrong st
      assert CONF_SSDP_RENDERING_CONTROL_LOCATION not in entry.data
      assert entry.unique_id == "be9554b9-c9fb-41f4-8920-22da015376a4"
  
  
  @pytest.mark.usefixtures(
      "remote", "remotews", "remoteencws_failing", "rest_api_failing"
  )
  async def test_update_zeroconf_discovery_preserved_unique_id(
      hass: HomeAssistant,
  ) -> None:
      """Test zeroconf discovery preserves unique id."""
      entry = MockConfigEntry(
          domain=DOMAIN,
          data={**MOCK_OLD_ENTRY, CONF_MAC: "aa:bb:zz:ee:rr:oo"},
          unique_id="original",
      )
      entry.add_to_hass(hass)
      result = await hass.config_entries.flow.async_init(
          DOMAIN,
          context={"source": config_entries.SOURCE_ZEROCONF},
          data=MOCK_ZEROCONF_DATA,
      )
      await hass.async_block_till_done()
      assert result["type"] == "abort"
      assert result["reason"] == "not_supported"
      assert entry.data[CONF_MAC] == "aa:bb:zz:ee:rr:oo"
      assert entry.unique_id == "original"
  
  
  @pytest.mark.usefixtures("remotews", "rest_api", "remoteencws_failing")
  async def test_update_missing_mac_unique_id_added_ssdp_location_updated_from_ssdp(
      hass: HomeAssistant,
  ) -> None:
      """Test missing mac and unique id with outdated ssdp_location with the wrong st added via ssdp."""
      entry = MockConfigEntry(
          domain=DOMAIN,
          data={
              **MOCK_OLD_ENTRY,
              CONF_SSDP_RENDERING_CONTROL_LOCATION: "https://1.2.3.4:555/test",
          },
          unique_id=None,
      )
      entry.add_to_hass(hass)
      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:
          result = await hass.config_entries.flow.async_init(
              DOMAIN,
              context={"source": config_entries.SOURCE_SSDP},
              data=MOCK_SSDP_DATA,
          )
          await hass.async_block_till_done()
          assert len(mock_setup.mock_calls) == 1
          assert len(mock_setup_entry.mock_calls) == 1
  
      assert result["type"] == "abort"
      assert result["reason"] == "already_configured"
      assert entry.data[CONF_MAC] == "aa:bb:ww:ii:ff:ii"
      # Wrong ST, ssdp location should not change
      assert (
          entry.data[CONF_SSDP_RENDERING_CONTROL_LOCATION] == "https://1.2.3.4:555/test"
      )
      assert entry.unique_id == "be9554b9-c9fb-41f4-8920-22da015376a4"
  
  
  @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,
  ) -> None:
      """Test missing mac and unique id with outdated ssdp_location with the correct st added via ssdp."""
      entry = MockConfigEntry(
          domain=DOMAIN,
          data={
              **MOCK_OLD_ENTRY,
              CONF_SSDP_RENDERING_CONTROL_LOCATION: "https://1.2.3.4:555/test",
          },
          unique_id=None,
      )
      entry.add_to_hass(hass)
      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:
          result = await hass.config_entries.flow.async_init(
              DOMAIN,
              context={"source": config_entries.SOURCE_SSDP},
              data=MOCK_SSDP_DATA_RENDERING_CONTROL_ST,
          )
          await hass.async_block_till_done()
          assert len(mock_setup.mock_calls) == 1
          assert len(mock_setup_entry.mock_calls) == 1
  
      assert result["type"] == "abort"
      assert result["reason"] == "already_configured"
      assert entry.data[CONF_MAC] == "aa:bb:ww:ii:ff:ii"
      # Correct ST, ssdp location should change
      assert (
          entry.data[CONF_SSDP_RENDERING_CONTROL_LOCATION]
          == "https://fake_host:12345/test"
      )
      assert entry.unique_id == "be9554b9-c9fb-41f4-8920-22da015376a4"
  
  
  @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,
  ) -> None:
      """Test missing mac and unique id with outdated ssdp_location with the correct st added via ssdp."""
      entry = MockConfigEntry(
          domain=DOMAIN,
          data={
              **MOCK_OLD_ENTRY,
              CONF_SSDP_RENDERING_CONTROL_LOCATION: "https://1.2.3.4:555/test",
              CONF_SSDP_MAIN_TV_AGENT_LOCATION: "https://1.2.3.4:555/test",
          },
          unique_id=None,
      )
      entry.add_to_hass(hass)
      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:
          result = await hass.config_entries.flow.async_init(
              DOMAIN,
              context={"source": config_entries.SOURCE_SSDP},
              data=MOCK_SSDP_DATA_MAIN_TV_AGENT_ST,
          )
          await hass.async_block_till_done()
          assert len(mock_setup.mock_calls) == 1
          assert len(mock_setup_entry.mock_calls) == 1
  
      assert result["type"] == "abort"
      assert result["reason"] == "already_configured"
      assert entry.data[CONF_MAC] == "aa:bb:ww:ii:ff:ii"
      # Main TV Agent ST, ssdp location should change
      assert (
          entry.data[CONF_SSDP_MAIN_TV_AGENT_LOCATION]
          == "https://fake_host:12345/tv_agent"
      )
      # Rendering control should not be affected
      assert (
          entry.data[CONF_SSDP_RENDERING_CONTROL_LOCATION] == "https://1.2.3.4:555/test"
      )
      assert entry.unique_id == "be9554b9-c9fb-41f4-8920-22da015376a4"
  
  
  @pytest.mark.usefixtures("remotews", "rest_api", "remoteencws_failing")
  async def test_update_ssdp_location_rendering_st_updated_from_ssdp(
      hass: HomeAssistant,
  ) -> None:
      """Test with outdated ssdp_location with the correct st added via ssdp."""
      entry = MockConfigEntry(
          domain=DOMAIN,
          data={**MOCK_OLD_ENTRY, CONF_MAC: "aa:bb:ww:ii:ff:ii"},
          unique_id="be9554b9-c9fb-41f4-8920-22da015376a4",
      )
      entry.add_to_hass(hass)
      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:
          result = await hass.config_entries.flow.async_init(
              DOMAIN,
              context={"source": config_entries.SOURCE_SSDP},
              data=MOCK_SSDP_DATA_RENDERING_CONTROL_ST,
          )
          await hass.async_block_till_done()
          assert len(mock_setup.mock_calls) == 1
          assert len(mock_setup_entry.mock_calls) == 1
  
      assert result["type"] == "abort"
      assert result["reason"] == "already_configured"
      assert entry.data[CONF_MAC] == "aa:bb:ww:ii:ff:ii"
      # Correct ST, ssdp location should be added
      assert (
          entry.data[CONF_SSDP_RENDERING_CONTROL_LOCATION]
          == "https://fake_host:12345/test"
      )
      assert entry.unique_id == "be9554b9-c9fb-41f4-8920-22da015376a4"
  
  
  @pytest.mark.usefixtures("remotews", "rest_api", "remoteencws_failing")
  async def test_update_main_tv_ssdp_location_rendering_st_updated_from_ssdp(
      hass: HomeAssistant,
  ) -> None:
      """Test with outdated ssdp_location with the correct st added via ssdp."""
      entry = MockConfigEntry(
          domain=DOMAIN,
          data={**MOCK_OLD_ENTRY, CONF_MAC: "aa:bb:ww:ii:ff:ii"},
          unique_id="be9554b9-c9fb-41f4-8920-22da015376a4",
      )
      entry.add_to_hass(hass)
      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:
          result = await hass.config_entries.flow.async_init(
              DOMAIN,
              context={"source": config_entries.SOURCE_SSDP},
              data=MOCK_SSDP_DATA_MAIN_TV_AGENT_ST,
          )
          await hass.async_block_till_done()
          assert len(mock_setup.mock_calls) == 1
          assert len(mock_setup_entry.mock_calls) == 1
  
      assert result["type"] == "abort"
      assert result["reason"] == "already_configured"
      assert entry.data[CONF_MAC] == "aa:bb:ww:ii:ff:ii"
      # Correct ST for MainTV, ssdp location should be added
      assert (
          entry.data[CONF_SSDP_MAIN_TV_AGENT_LOCATION]
          == "https://fake_host:12345/tv_agent"
      )
      assert entry.unique_id == "be9554b9-c9fb-41f4-8920-22da015376a4"
  
  
  @pytest.mark.usefixtures("remotews", "rest_api")
  async def test_update_missing_mac_added_unique_id_preserved_from_zeroconf(
      hass: HomeAssistant,
  ) -> None:
      """Test missing mac and unique id added."""
      entry = MockConfigEntry(
          domain=DOMAIN,
          data=MOCK_OLD_ENTRY,
          unique_id="0d1cef00-00dc-1000-9c80-4844f7b172de",
      )
      entry.add_to_hass(hass)
      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:
          result = await hass.config_entries.flow.async_init(
              DOMAIN,
              context={"source": config_entries.SOURCE_ZEROCONF},
              data=MOCK_ZEROCONF_DATA,
          )
          await hass.async_block_till_done()
          assert len(mock_setup.mock_calls) == 1
          assert len(mock_setup_entry.mock_calls) == 1
      assert result["type"] == "abort"
      assert result["reason"] == "already_configured"
      assert entry.data[CONF_MAC] == "aa:bb:zz:ee:rr:oo"
      assert entry.unique_id == "0d1cef00-00dc-1000-9c80-4844f7b172de"
  
  
  @pytest.mark.usefixtures("remote")
  async def test_update_legacy_missing_mac_from_dhcp(hass: HomeAssistant) -> None:
      """Test missing mac added."""
      entry = MockConfigEntry(
          domain=DOMAIN,
          data=MOCK_LEGACY_ENTRY,
          unique_id="0d1cef00-00dc-1000-9c80-4844f7b172de",
      )
      entry.add_to_hass(hass)
      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:
          result = await hass.config_entries.flow.async_init(
              DOMAIN,
              context={"source": config_entries.SOURCE_DHCP},
              data=dhcp.DhcpServiceInfo(
                  ip=EXISTING_IP, macaddress="aa:bb:cc:dd:ee:ff", hostname="fake_hostname"
              ),
          )
          await hass.async_block_till_done()
          assert len(mock_setup.mock_calls) == 1
          assert len(mock_setup_entry.mock_calls) == 1
      assert result["type"] == "abort"
      assert result["reason"] == "already_configured"
      assert entry.data[CONF_MAC] == "aa:bb:cc:dd:ee:ff"
      assert entry.unique_id == "0d1cef00-00dc-1000-9c80-4844f7b172de"
  
  
  @pytest.mark.usefixtures("remote")
  async def test_update_legacy_missing_mac_from_dhcp_no_unique_id(
      hass: HomeAssistant, rest_api: Mock
  ) -> None:
      """Test missing mac added when there is no unique id."""
      rest_api.rest_device_info.side_effect = HttpApiError
      entry = MockConfigEntry(
          domain=DOMAIN,
          data=MOCK_LEGACY_ENTRY,
      )
      entry.add_to_hass(hass)
      with patch(
          "homeassistant.components.samsungtv.bridge.Remote.__enter__",
          return_value=True,
      ), patch(
          "homeassistant.components.samsungtv.bridge.SamsungTVEncryptedWSAsyncRemote.start_listening",
          side_effect=WebSocketProtocolError("Boom"),
      ), 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:
          result = await hass.config_entries.flow.async_init(
              DOMAIN,
              context={"source": config_entries.SOURCE_DHCP},
              data=dhcp.DhcpServiceInfo(
                  ip=EXISTING_IP, macaddress="aa:bb:cc:dd:ee:ff", hostname="fake_hostname"
              ),
          )
          await hass.async_block_till_done()
          assert len(mock_setup.mock_calls) == 1
          assert len(mock_setup_entry.mock_calls) == 1
      assert result["type"] == "abort"
      assert result["reason"] == "not_supported"
      assert entry.data[CONF_MAC] == "aa:bb:cc:dd:ee:ff"
      assert entry.unique_id is None
  
  
  @pytest.mark.usefixtures("remotews", "rest_api", "remoteencws_failing")
  async def test_update_ssdp_location_unique_id_added_from_ssdp(
      hass: HomeAssistant,
  ) -> None:
      """Test missing ssdp_location, and unique id added via ssdp."""
      entry = MockConfigEntry(
          domain=DOMAIN,
          data={**MOCK_OLD_ENTRY, CONF_MAC: "aa:bb:ww:ii:ff:ii"},
          unique_id=None,
      )
      entry.add_to_hass(hass)
      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:
          result = await hass.config_entries.flow.async_init(
              DOMAIN,
              context={"source": config_entries.SOURCE_SSDP},
              data=MOCK_SSDP_DATA,
          )
          await hass.async_block_till_done()
          assert len(mock_setup.mock_calls) == 1
          assert len(mock_setup_entry.mock_calls) == 1
  
      assert result["type"] == "abort"
      assert result["reason"] == "already_configured"
      assert entry.data[CONF_MAC] == "aa:bb:ww:ii:ff:ii"
      # Wrong st
      assert CONF_SSDP_RENDERING_CONTROL_LOCATION not in entry.data
      assert entry.unique_id == "be9554b9-c9fb-41f4-8920-22da015376a4"
  
  
  @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,
  ) -> None:
      """Test missing ssdp_location, and unique id added via ssdp with rendering control st."""
      entry = MockConfigEntry(
          domain=DOMAIN,
          data={**MOCK_OLD_ENTRY, CONF_MAC: "aa:bb:ww:ii:ff:ii"},
          unique_id=None,
      )
      entry.add_to_hass(hass)
      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:
          result = await hass.config_entries.flow.async_init(
              DOMAIN,
              context={"source": config_entries.SOURCE_SSDP},
              data=MOCK_SSDP_DATA_RENDERING_CONTROL_ST,
          )
          await hass.async_block_till_done()
          assert len(mock_setup.mock_calls) == 1
          assert len(mock_setup_entry.mock_calls) == 1
  
      assert result["type"] == "abort"
      assert result["reason"] == "already_configured"
      assert entry.data[CONF_MAC] == "aa:bb:ww:ii:ff:ii"
      # Correct st
      assert (
          entry.data[CONF_SSDP_RENDERING_CONTROL_LOCATION]
          == "https://fake_host:12345/test"
      )
      assert entry.unique_id == "be9554b9-c9fb-41f4-8920-22da015376a4"
  
  
  @pytest.mark.usefixtures("remote")
  async def test_form_reauth_legacy(hass: HomeAssistant) -> None:
      """Test reauthenticate legacy."""
      entry = MockConfigEntry(domain=DOMAIN, data=MOCK_OLD_ENTRY)
      entry.add_to_hass(hass)
      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"] == {}
  
      result2 = await hass.config_entries.flow.async_configure(
          result["flow_id"],
          {},
      )
      await hass.async_block_till_done()
      assert result2["type"] == "abort"
      assert result2["reason"] == "reauth_successful"
  
  
  @pytest.mark.usefixtures("remotews", "rest_api")
  async def test_form_reauth_websocket(hass: HomeAssistant) -> None:
      """Test reauthenticate websocket."""
      entry = MockConfigEntry(domain=DOMAIN, data=MOCK_ENTRYDATA_WS)
      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"] == {}
  
      result2 = await hass.config_entries.flow.async_configure(
          result["flow_id"],
          {},
      )
      await hass.async_block_till_done()
      assert result2["type"] == "abort"
      assert result2["reason"] == "reauth_successful"
      assert entry.state == config_entries.ConfigEntryState.LOADED
  
  
  @pytest.mark.usefixtures("rest_api")
  async def test_form_reauth_websocket_cannot_connect(
      hass: HomeAssistant, remotews: Mock
  ) -> None:
      """Test reauthenticate websocket when we cannot connect on the first attempt."""
      entry = MockConfigEntry(domain=DOMAIN, data=MOCK_ENTRYDATA_WS)
      entry.add_to_hass(hass)
      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.object(remotews, "open", side_effect=ConnectionFailure):
          result2 = await hass.config_entries.flow.async_configure(
              result["flow_id"],
              {},
          )
          await hass.async_block_till_done()
  
      assert result2["type"] == "form"
      assert result2["errors"] == {"base": RESULT_AUTH_MISSING}
  
      result3 = await hass.config_entries.flow.async_configure(
          result["flow_id"],
          {},
      )
      await hass.async_block_till_done()
  
      assert result3["type"] == "abort"
      assert result3["reason"] == "reauth_successful"
  
  
  async def test_form_reauth_websocket_not_supported(hass: HomeAssistant) -> None:
      """Test reauthenticate websocket when the device is not supported."""
      entry = MockConfigEntry(domain=DOMAIN, data=MOCK_ENTRYDATA_WS)
      entry.add_to_hass(hass)
      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.bridge.SamsungTVWSAsyncRemote.open",
          side_effect=WebSocketException,
      ):
          result2 = await hass.config_entries.flow.async_configure(
              result["flow_id"],
              {},
          )
          await hass.async_block_till_done()
  
      assert result2["type"] == "abort"
      assert result2["reason"] == "not_supported"
  
  
  @pytest.mark.usefixtures("remoteencws", "rest_api")
  async def test_form_reauth_encrypted(hass: HomeAssistant) -> None:
      """Test reauth flow 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 == 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]
  
      with patch(
          "homeassistant.components.samsungtv.config_flow.SamsungTVEncryptedWSAsyncAuthenticator",
          autospec=True,
      ) as authenticator_mock:
          authenticator_mock.return_value.try_pin.side_effect = [
              None,
              "037739871315caef138547b03e348b72",
          ]
          authenticator_mock.return_value.get_session_id_and_close.return_value = "1"
  
          result = await hass.config_entries.flow.async_configure(result["flow_id"])
  
          assert result["type"] == "form"
          assert result["step_id"] == "reauth_confirm"
          assert result["errors"] == {}
  
          # First time on reauth_confirm_encrypted
          # creates the authenticator, start pairing and requests PIN
          result = await hass.config_entries.flow.async_configure(
              result["flow_id"], user_input={}
          )
          assert result["type"] == "form"
          assert result["step_id"] == "reauth_confirm_encrypted"
  
          # Invalid PIN
          result = await hass.config_entries.flow.async_configure(
              result["flow_id"], user_input={"pin": "invalid"}
          )
          assert result["type"] == "form"
          assert result["step_id"] == "reauth_confirm_encrypted"
  
          # Valid PIN
          result = await hass.config_entries.flow.async_configure(
              result["flow_id"], user_input={"pin": "1234"}
          )
          await hass.async_block_till_done()
          assert result["type"] == "abort"
          assert result["reason"] == "reauth_successful"
          assert entry.state == config_entries.ConfigEntryState.LOADED
  
      authenticator_mock.assert_called_once()
      assert authenticator_mock.call_args[0] == ("fake_host",)
  
      authenticator_mock.return_value.start_pairing.assert_called_once()
      assert authenticator_mock.return_value.try_pin.call_count == 2
      assert authenticator_mock.return_value.try_pin.call_args_list == [
          call("invalid"),
          call("1234"),
      ]
      authenticator_mock.return_value.get_session_id_and_close.assert_called_once()
  
      assert entry.data[CONF_TOKEN] == "037739871315caef138547b03e348b72"
      assert entry.data[CONF_SESSION_ID] == "1"
  
  
  @pytest.mark.usefixtures("remotews", "rest_api", "remoteencws_failing")
  async def test_update_incorrect_udn_matching_upnp_udn_unique_id_added_from_ssdp(
      hass: HomeAssistant,
  ) -> None:
      """Test updating the wrong udn from ssdp via upnp udn match."""
      entry = MockConfigEntry(
          domain=DOMAIN,
          data=MOCK_OLD_ENTRY,
          unique_id="0d1cef00-00dc-1000-9c80-4844f7b172de",
      )
      entry.add_to_hass(hass)
      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:
          result = await hass.config_entries.flow.async_init(
              DOMAIN,
              context={"source": config_entries.SOURCE_SSDP},
              data=MOCK_SSDP_DATA,
          )
          await hass.async_block_till_done()
          assert len(mock_setup.mock_calls) == 1
          assert len(mock_setup_entry.mock_calls) == 1
  
      assert result["type"] == "abort"
      assert result["reason"] == "already_configured"
      assert entry.data[CONF_MAC] == "aa:bb:ww:ii:ff:ii"
      assert entry.unique_id == "be9554b9-c9fb-41f4-8920-22da015376a4"
  
  
  @pytest.mark.usefixtures("remotews", "rest_api", "remoteencws_failing")
  async def test_update_incorrect_udn_matching_mac_unique_id_added_from_ssdp(
      hass: HomeAssistant,
  ) -> None:
      """Test updating the wrong udn from ssdp via mac match."""
      entry = MockConfigEntry(
          domain=DOMAIN,
          data={**MOCK_OLD_ENTRY, CONF_MAC: "aa:bb:ww:ii:ff:ii"},
          unique_id=None,
      )
      entry.add_to_hass(hass)
      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:
          result = await hass.config_entries.flow.async_init(
              DOMAIN,
              context={"source": config_entries.SOURCE_SSDP},
              data=MOCK_SSDP_DATA,
          )
          await hass.async_block_till_done()
          assert len(mock_setup.mock_calls) == 1
          assert len(mock_setup_entry.mock_calls) == 1
  
      assert result["type"] == "abort"
      assert result["reason"] == "already_configured"
      assert entry.data[CONF_MAC] == "aa:bb:ww:ii:ff:ii"
      assert entry.unique_id == "be9554b9-c9fb-41f4-8920-22da015376a4"
  
  
  @pytest.mark.usefixtures("remotews", "rest_api", "remoteencws_failing")
  async def test_update_incorrect_udn_matching_mac_from_dhcp(
      hass: HomeAssistant,
  ) -> None:
      """Test that DHCP updates the wrong udn from ssdp via mac match."""
      entry = MockConfigEntry(
          domain=DOMAIN,
          data={**MOCK_ENTRYDATA_WS, CONF_MAC: "aa:bb:ww:ii:ff:ii"},
          source=config_entries.SOURCE_SSDP,
          unique_id="0d1cef00-00dc-1000-9c80-4844f7b172de",
      )
      entry.add_to_hass(hass)
      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:
          result = await hass.config_entries.flow.async_init(
              DOMAIN,
              context={"source": config_entries.SOURCE_DHCP},
              data=MOCK_DHCP_DATA,
          )
          await hass.async_block_till_done()
          assert len(mock_setup.mock_calls) == 1
          assert len(mock_setup_entry.mock_calls) == 1
  
      assert result["type"] == "abort"
      assert result["reason"] == "already_configured"
      assert entry.data[CONF_MAC] == "aa:bb:ww:ii:ff:ii"
      assert entry.unique_id == "be9554b9-c9fb-41f4-8920-22da015376a4"
  
  
  @pytest.mark.usefixtures("remotews", "rest_api", "remoteencws_failing")
  async def test_no_update_incorrect_udn_not_matching_mac_from_dhcp(
      hass: HomeAssistant,
  ) -> None:
      """Test that DHCP does not update the wrong udn from ssdp via host match."""
      entry = MockConfigEntry(
          domain=DOMAIN,
          data={**MOCK_ENTRYDATA_WS, CONF_MAC: "aa:bb:ss:ss:dd:pp"},
          source=config_entries.SOURCE_SSDP,
          unique_id="0d1cef00-00dc-1000-9c80-4844f7b172de",
      )
      entry.add_to_hass(hass)
      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:
          result = await hass.config_entries.flow.async_init(
              DOMAIN,
              context={"source": config_entries.SOURCE_DHCP},
              data=MOCK_DHCP_DATA,
          )
          await hass.async_block_till_done()
          assert len(mock_setup.mock_calls) == 0
          assert len(mock_setup_entry.mock_calls) == 0
  
      assert result["type"] == "form"
      assert result["step_id"] == "confirm"
      assert entry.data[CONF_MAC] == "aa:bb:ss:ss:dd:pp"
      assert entry.unique_id == "0d1cef00-00dc-1000-9c80-4844f7b172de"
  