text: """Tests for the Nest config flow."""
  import asyncio
  from unittest.mock import Mock, patch
  
  from homeassistant import data_entry_flow
  from homeassistant.setup import async_setup_component
  from homeassistant.components.nest import config_flow, DOMAIN
  
  from tests.common import mock_coro
  
  
  async def test_abort_if_no_implementation_registered(hass):
      """Test we abort if no implementation is registered."""
      flow = config_flow.NestFlowHandler()
      flow.hass = hass
      result = await flow.async_step_init()
  
      assert result["type"] == data_entry_flow.RESULT_TYPE_ABORT
      assert result["reason"] == "no_flows"
  
  
  async def test_abort_if_already_setup(hass):
      """Test we abort if Nest is already setup."""
      flow = config_flow.NestFlowHandler()
      flow.hass = hass
  
      with patch.object(hass.config_entries, "async_entries", return_value=[{}]):
          result = await flow.async_step_init()
  
      assert result["type"] == data_entry_flow.RESULT_TYPE_ABORT
      assert result["reason"] == "already_setup"
  
  
  async def test_full_flow_implementation(hass):
      """Test registering an implementation and finishing flow works."""
      gen_authorize_url = Mock(return_value=mock_coro("https://example.com"))
      convert_code = Mock(return_value=mock_coro({"access_token": "yoo"}))
      config_flow.register_flow_implementation(
          hass, "test", "Test", gen_authorize_url, convert_code
      )
      config_flow.register_flow_implementation(
          hass, "test-other", "Test Other", None, None
      )
  
      flow = config_flow.NestFlowHandler()
      flow.hass = hass
      result = await flow.async_step_init()
      assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
      assert result["step_id"] == "init"
  
      result = await flow.async_step_init({"flow_impl": "test"})
      assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
      assert result["step_id"] == "link"
      assert result["description_placeholders"] == {"url": "https://example.com"}
  
      result = await flow.async_step_link({"code": "123ABC"})
      assert result["type"] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY
      assert result["data"]["tokens"] == {"access_token": "yoo"}
      assert result["data"]["impl_domain"] == "test"
      assert result["title"] == "Nest (via Test)"
  
  
  async def test_not_pick_implementation_if_only_one(hass):
      """Test we allow picking implementation if we have two."""
      gen_authorize_url = Mock(return_value=mock_coro("https://example.com"))
      config_flow.register_flow_implementation(
          hass, "test", "Test", gen_authorize_url, None
      )
  
      flow = config_flow.NestFlowHandler()
      flow.hass = hass
      result = await flow.async_step_init()
      assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
      assert result["step_id"] == "link"
  
  
  async def test_abort_if_timeout_generating_auth_url(hass):
      """Test we abort if generating authorize url fails."""
      gen_authorize_url = Mock(side_effect=asyncio.TimeoutError)
      config_flow.register_flow_implementation(
          hass, "test", "Test", gen_authorize_url, None
      )
  
      flow = config_flow.NestFlowHandler()
      flow.hass = hass
      result = await flow.async_step_init()
      assert result["type"] == data_entry_flow.RESULT_TYPE_ABORT
      assert result["reason"] == "authorize_url_timeout"
  
  
  async def test_abort_if_exception_generating_auth_url(hass):
      """Test we abort if generating authorize url blows up."""
      gen_authorize_url = Mock(side_effect=ValueError)
      config_flow.register_flow_implementation(
          hass, "test", "Test", gen_authorize_url, None
      )
  
      flow = config_flow.NestFlowHandler()
      flow.hass = hass
      result = await flow.async_step_init()
      assert result["type"] == data_entry_flow.RESULT_TYPE_ABORT
      assert result["reason"] == "authorize_url_fail"
  
  
  async def test_verify_code_timeout(hass):
      """Test verify code timing out."""
      gen_authorize_url = Mock(return_value=mock_coro("https://example.com"))
      convert_code = Mock(side_effect=asyncio.TimeoutError)
      config_flow.register_flow_implementation(
          hass, "test", "Test", gen_authorize_url, convert_code
      )
  
      flow = config_flow.NestFlowHandler()
      flow.hass = hass
      result = await flow.async_step_init()
      assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
      assert result["step_id"] == "link"
  
      result = await flow.async_step_link({"code": "123ABC"})
      assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
      assert result["step_id"] == "link"
      assert result["errors"] == {"code": "timeout"}
  
  
  async def test_verify_code_invalid(hass):
      """Test verify code invalid."""
      gen_authorize_url = Mock(return_value=mock_coro("https://example.com"))
      convert_code = Mock(side_effect=config_flow.CodeInvalid)
      config_flow.register_flow_implementation(
          hass, "test", "Test", gen_authorize_url, convert_code
      )
  
      flow = config_flow.NestFlowHandler()
      flow.hass = hass
      result = await flow.async_step_init()
      assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
      assert result["step_id"] == "link"
  
      result = await flow.async_step_link({"code": "123ABC"})
      assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
      assert result["step_id"] == "link"
      assert result["errors"] == {"code": "invalid_code"}
  
  
  async def test_verify_code_unknown_error(hass):
      """Test verify code unknown error."""
      gen_authorize_url = Mock(return_value=mock_coro("https://example.com"))
      convert_code = Mock(side_effect=config_flow.NestAuthError)
      config_flow.register_flow_implementation(
          hass, "test", "Test", gen_authorize_url, convert_code
      )
  
      flow = config_flow.NestFlowHandler()
      flow.hass = hass
      result = await flow.async_step_init()
      assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
      assert result["step_id"] == "link"
  
      result = await flow.async_step_link({"code": "123ABC"})
      assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
      assert result["step_id"] == "link"
      assert result["errors"] == {"code": "unknown"}
  
  
  async def test_verify_code_exception(hass):
      """Test verify code blows up."""
      gen_authorize_url = Mock(return_value=mock_coro("https://example.com"))
      convert_code = Mock(side_effect=ValueError)
      config_flow.register_flow_implementation(
          hass, "test", "Test", gen_authorize_url, convert_code
      )
  
      flow = config_flow.NestFlowHandler()
      flow.hass = hass
      result = await flow.async_step_init()
      assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
      assert result["step_id"] == "link"
  
      result = await flow.async_step_link({"code": "123ABC"})
      assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
      assert result["step_id"] == "link"
      assert result["errors"] == {"code": "internal_error"}
  
  
  async def test_step_import(hass):
      """Test that we trigger import when configuring with client."""
      with patch("os.path.isfile", return_value=False):
          assert await async_setup_component(
              hass, DOMAIN, {DOMAIN: {"client_id": "bla", "client_secret": "bla"}}
          )
          await hass.async_block_till_done()
  
      flow = hass.config_entries.flow.async_progress()[0]
      result = await hass.config_entries.flow.async_configure(flow["flow_id"])
  
      assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
      assert result["step_id"] == "link"
  
  
  async def test_step_import_with_token_cache(hass):
      """Test that we import existing token cache."""
      with patch("os.path.isfile", return_value=True), patch(
          "homeassistant.components.nest.config_flow.load_json",
          return_value={"access_token": "yo"},
      ), patch(
          "homeassistant.components.nest.async_setup_entry", return_value=mock_coro(True)
      ):
          assert await async_setup_component(
              hass, DOMAIN, {DOMAIN: {"client_id": "bla", "client_secret": "bla"}}
          )
          await hass.async_block_till_done()
  
      entry = hass.config_entries.async_entries(DOMAIN)[0]
  
      assert entry.data == {"impl_domain": "nest", "tokens": {"access_token": "yo"}}
  