test_config_flow.py 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702
  1. """Tests for the config flow."""
  2. from unittest.mock import ANY, AsyncMock, MagicMock, patch
  3. import pytest
  4. import voluptuous as vol
  5. from homeassistant.const import CONF_HOST, CONF_NAME
  6. from homeassistant.data_entry_flow import FlowResultType
  7. from pytest_homeassistant_custom_component.common import MockConfigEntry
  8. from custom_components.tuya_local import (
  9. async_migrate_entry,
  10. async_setup_entry,
  11. config_flow,
  12. )
  13. from custom_components.tuya_local.const import (
  14. CONF_DEVICE_CID,
  15. CONF_DEVICE_ID,
  16. CONF_LOCAL_KEY,
  17. CONF_POLL_ONLY,
  18. CONF_PROTOCOL_VERSION,
  19. CONF_TYPE,
  20. DOMAIN,
  21. )
  22. @pytest.fixture(autouse=True)
  23. def auto_enable_custom_integrations(enable_custom_integrations):
  24. yield
  25. @pytest.fixture(autouse=True)
  26. def prevent_task_creation():
  27. with patch(
  28. "custom_components.tuya_local.device.TuyaLocalDevice.register_entity",
  29. ):
  30. yield
  31. @pytest.fixture
  32. def bypass_setup():
  33. """Prevent actual setup of the integration after config flow."""
  34. with patch(
  35. "custom_components.tuya_local.async_setup_entry",
  36. return_value=True,
  37. ):
  38. yield
  39. @pytest.mark.asyncio
  40. async def test_init_entry(hass):
  41. """Test initialisation of the config flow."""
  42. entry = MockConfigEntry(
  43. domain=DOMAIN,
  44. version=11,
  45. title="test",
  46. data={
  47. CONF_DEVICE_ID: "deviceid",
  48. CONF_HOST: "hostname",
  49. CONF_LOCAL_KEY: "localkey",
  50. CONF_POLL_ONLY: False,
  51. CONF_PROTOCOL_VERSION: "auto",
  52. CONF_TYPE: "kogan_kahtp_heater",
  53. CONF_DEVICE_CID: None,
  54. },
  55. options={},
  56. )
  57. entry.add_to_hass(hass)
  58. await hass.config_entries.async_setup(entry.entry_id)
  59. await hass.async_block_till_done()
  60. assert hass.states.get("climate.test")
  61. assert hass.states.get("lock.test_child_lock")
  62. @pytest.mark.asyncio
  63. @patch("custom_components.tuya_local.setup_device")
  64. async def test_migrate_entry(mock_setup, hass):
  65. """Test migration from old entry format."""
  66. mock_device = MagicMock()
  67. mock_device.async_inferred_type = AsyncMock(return_value="goldair_gpph_heater")
  68. mock_setup.return_value = mock_device
  69. entry = MockConfigEntry(
  70. domain=DOMAIN,
  71. version=1,
  72. title="test",
  73. data={
  74. CONF_DEVICE_ID: "deviceid",
  75. CONF_HOST: "hostname",
  76. CONF_LOCAL_KEY: "localkey",
  77. CONF_TYPE: "auto",
  78. "climate": True,
  79. "child_lock": True,
  80. "display_light": True,
  81. },
  82. )
  83. entry.add_to_hass(hass)
  84. assert await async_migrate_entry(hass, entry)
  85. mock_device.async_inferred_type = AsyncMock(return_value=None)
  86. mock_device.reset_mock()
  87. entry = MockConfigEntry(
  88. domain=DOMAIN,
  89. version=1,
  90. title="test2",
  91. data={
  92. CONF_DEVICE_ID: "deviceid",
  93. CONF_HOST: "hostname",
  94. CONF_LOCAL_KEY: "localkey",
  95. CONF_TYPE: "unknown",
  96. "climate": False,
  97. },
  98. )
  99. entry.add_to_hass(hass)
  100. assert not await async_migrate_entry(hass, entry)
  101. mock_device.reset_mock()
  102. entry = MockConfigEntry(
  103. domain=DOMAIN,
  104. version=2,
  105. title="test3",
  106. data={
  107. CONF_DEVICE_ID: "deviceid",
  108. CONF_HOST: "hostname",
  109. CONF_LOCAL_KEY: "localkey",
  110. CONF_TYPE: "auto",
  111. },
  112. options={
  113. "climate": False,
  114. },
  115. )
  116. entry.add_to_hass(hass)
  117. assert not await async_migrate_entry(hass, entry)
  118. mock_device.async_inferred_type = AsyncMock(return_value="smartplugv1")
  119. mock_device.reset_mock()
  120. entry = MockConfigEntry(
  121. domain=DOMAIN,
  122. version=3,
  123. title="test4",
  124. data={
  125. CONF_DEVICE_ID: "deviceid",
  126. CONF_HOST: "hostname",
  127. CONF_LOCAL_KEY: "localkey",
  128. CONF_TYPE: "smartplugv1",
  129. },
  130. options={
  131. "switch": True,
  132. },
  133. )
  134. entry.add_to_hass(hass)
  135. assert await async_migrate_entry(hass, entry)
  136. mock_device.async_inferred_type = AsyncMock(return_value="smartplugv2")
  137. mock_device.reset_mock()
  138. entry = MockConfigEntry(
  139. domain=DOMAIN,
  140. version=3,
  141. title="test5",
  142. data={
  143. CONF_DEVICE_ID: "deviceid",
  144. CONF_HOST: "hostname",
  145. CONF_LOCAL_KEY: "localkey",
  146. CONF_TYPE: "smartplugv1",
  147. },
  148. options={
  149. "switch": True,
  150. },
  151. )
  152. entry.add_to_hass(hass)
  153. assert await async_migrate_entry(hass, entry)
  154. mock_device.async_inferred_type = AsyncMock(return_value="goldair_dehumidifier")
  155. mock_device.reset_mock()
  156. entry = MockConfigEntry(
  157. domain=DOMAIN,
  158. version=4,
  159. title="test6",
  160. data={
  161. CONF_DEVICE_ID: "deviceid",
  162. CONF_HOST: "hostname",
  163. CONF_LOCAL_KEY: "localkey",
  164. CONF_TYPE: "goldair_dehumidifier",
  165. },
  166. options={
  167. "humidifier": True,
  168. "fan": True,
  169. "light": True,
  170. "lock": False,
  171. "switch": True,
  172. },
  173. )
  174. entry.add_to_hass(hass)
  175. assert await async_migrate_entry(hass, entry)
  176. mock_device.async_inferred_type = AsyncMock(
  177. return_value="grid_connect_usb_double_power_point"
  178. )
  179. mock_device.reset_mock()
  180. entry = MockConfigEntry(
  181. domain=DOMAIN,
  182. version=6,
  183. title="test7",
  184. data={
  185. CONF_DEVICE_ID: "deviceid",
  186. CONF_HOST: "hostname",
  187. CONF_LOCAL_KEY: "localkey",
  188. CONF_TYPE: "grid_connect_usb_double_power_point",
  189. },
  190. options={
  191. "switch_main_switch": True,
  192. "switch_left_outlet": True,
  193. "switch_right_outlet": True,
  194. },
  195. )
  196. entry.add_to_hass(hass)
  197. assert await async_migrate_entry(hass, entry)
  198. @pytest.mark.asyncio
  199. async def test_flow_user_init(hass):
  200. """Test the initialisation of the form in the first step of the config flow."""
  201. result = await hass.config_entries.flow.async_init(
  202. DOMAIN, context={"source": "user"}
  203. )
  204. expected = {
  205. "data_schema": ANY,
  206. "description_placeholders": None,
  207. "errors": {},
  208. "flow_id": ANY,
  209. "handler": DOMAIN,
  210. "step_id": "user",
  211. "type": "form",
  212. "last_step": ANY,
  213. "preview": ANY,
  214. }
  215. assert expected == result
  216. # Check the schema. Simple comparison does not work since they are not
  217. # the same object
  218. try:
  219. result["data_schema"](
  220. {CONF_DEVICE_ID: "test", CONF_LOCAL_KEY: "test", CONF_HOST: "test"}
  221. )
  222. except vol.MultipleInvalid:
  223. assert False
  224. try:
  225. result["data_schema"]({CONF_DEVICE_ID: "missing_some"})
  226. assert False
  227. except vol.MultipleInvalid:
  228. pass
  229. @pytest.mark.asyncio
  230. @patch("custom_components.tuya_local.config_flow.TuyaLocalDevice")
  231. async def test_async_test_connection_valid(mock_device, hass):
  232. """Test that device is returned when connection is valid."""
  233. mock_instance = AsyncMock()
  234. mock_instance.has_returned_state = True
  235. mock_instance.pause = MagicMock()
  236. mock_instance.resume = MagicMock()
  237. mock_device.return_value = mock_instance
  238. hass.data[DOMAIN] = {"deviceid": {"device": mock_instance}}
  239. device = await config_flow.async_test_connection(
  240. {
  241. CONF_DEVICE_ID: "deviceid",
  242. CONF_LOCAL_KEY: "localkey",
  243. CONF_HOST: "hostname",
  244. CONF_PROTOCOL_VERSION: "auto",
  245. },
  246. hass,
  247. )
  248. assert device == mock_instance
  249. mock_instance.pause.assert_called_once()
  250. mock_instance.resume.assert_called_once()
  251. @pytest.mark.asyncio
  252. @patch("custom_components.tuya_local.config_flow.TuyaLocalDevice")
  253. async def test_async_test_connection_for_subdevice_valid(mock_device, hass):
  254. """Test that subdevice is returned when connection is valid."""
  255. mock_instance = AsyncMock()
  256. mock_instance.has_returned_state = True
  257. mock_instance.pause = MagicMock()
  258. mock_instance.resume = MagicMock()
  259. mock_device.return_value = mock_instance
  260. hass.data[DOMAIN] = {"subdeviceid": {"device": mock_instance}}
  261. device = await config_flow.async_test_connection(
  262. {
  263. CONF_DEVICE_ID: "deviceid",
  264. CONF_LOCAL_KEY: "localkey",
  265. CONF_HOST: "hostname",
  266. CONF_PROTOCOL_VERSION: "auto",
  267. CONF_DEVICE_CID: "subdeviceid",
  268. },
  269. hass,
  270. )
  271. assert device == mock_instance
  272. mock_instance.pause.assert_called_once()
  273. mock_instance.resume.assert_called_once()
  274. @pytest.mark.asyncio
  275. @patch("custom_components.tuya_local.config_flow.TuyaLocalDevice")
  276. async def test_async_test_connection_invalid(mock_device, hass):
  277. """Test that None is returned when connection is invalid."""
  278. mock_instance = AsyncMock()
  279. mock_instance.has_returned_state = False
  280. mock_device.return_value = mock_instance
  281. device = await config_flow.async_test_connection(
  282. {
  283. CONF_DEVICE_ID: "deviceid",
  284. CONF_LOCAL_KEY: "localkey",
  285. CONF_HOST: "hostname",
  286. CONF_PROTOCOL_VERSION: "auto",
  287. },
  288. hass,
  289. )
  290. assert device is None
  291. @pytest.mark.asyncio
  292. @patch("custom_components.tuya_local.config_flow.async_test_connection")
  293. async def test_flow_user_init_invalid_config(mock_test, hass):
  294. """Test errors populated when config is invalid."""
  295. mock_test.return_value = None
  296. flow = await hass.config_entries.flow.async_init(DOMAIN, context={"source": "user"})
  297. result = await hass.config_entries.flow.async_configure(
  298. flow["flow_id"],
  299. user_input={
  300. CONF_DEVICE_ID: "deviceid",
  301. CONF_HOST: "hostname",
  302. CONF_LOCAL_KEY: "badkey",
  303. CONF_PROTOCOL_VERSION: "auto",
  304. CONF_POLL_ONLY: False,
  305. },
  306. )
  307. assert {"base": "connection"} == result["errors"]
  308. def setup_device_mock(mock, failure=False, type="test"):
  309. mock_type = MagicMock()
  310. mock_type.legacy_type = type
  311. mock_type.config_type = type
  312. mock_type.match_quality.return_value = 100
  313. mock_iter = MagicMock()
  314. mock_iter.__aiter__.return_value = [mock_type] if not failure else []
  315. mock.async_possible_types = MagicMock(return_value=mock_iter)
  316. @pytest.mark.asyncio
  317. @patch("custom_components.tuya_local.config_flow.async_test_connection")
  318. async def test_flow_user_init_data_valid(mock_test, hass):
  319. """Test we advance to the next step when connection config is valid."""
  320. mock_device = MagicMock()
  321. setup_device_mock(mock_device)
  322. mock_test.return_value = mock_device
  323. flow = await hass.config_entries.flow.async_init(DOMAIN, context={"source": "user"})
  324. result = await hass.config_entries.flow.async_configure(
  325. flow["flow_id"],
  326. user_input={
  327. CONF_DEVICE_ID: "deviceid",
  328. CONF_HOST: "hostname",
  329. CONF_LOCAL_KEY: "localkey",
  330. },
  331. )
  332. assert "form" == result["type"]
  333. assert "select_type" == result["step_id"]
  334. @pytest.mark.asyncio
  335. @patch.object(config_flow.ConfigFlowHandler, "device")
  336. async def test_flow_select_type_init(mock_device, hass):
  337. """Test the initialisation of the form in the 2nd step of the config flow."""
  338. setup_device_mock(mock_device)
  339. result = await hass.config_entries.flow.async_init(
  340. DOMAIN, context={"source": "select_type"}
  341. )
  342. expected = {
  343. "data_schema": ANY,
  344. "description_placeholders": None,
  345. "errors": None,
  346. "flow_id": ANY,
  347. "handler": DOMAIN,
  348. "step_id": "select_type",
  349. "type": "form",
  350. "last_step": ANY,
  351. "preview": ANY,
  352. }
  353. assert expected == result
  354. # Check the schema. Simple comparison does not work since they are not
  355. # the same object
  356. try:
  357. result["data_schema"]({CONF_TYPE: "test"})
  358. except vol.MultipleInvalid:
  359. assert False
  360. try:
  361. result["data_schema"]({CONF_TYPE: "not_test"})
  362. assert False
  363. except vol.MultipleInvalid:
  364. pass
  365. @pytest.mark.asyncio
  366. @patch.object(config_flow.ConfigFlowHandler, "device")
  367. async def test_flow_select_type_aborts_when_no_match(mock_device, hass):
  368. """Test the flow aborts when an unsupported device is used."""
  369. setup_device_mock(mock_device, failure=True)
  370. result = await hass.config_entries.flow.async_init(
  371. DOMAIN, context={"source": "select_type"}
  372. )
  373. assert result["type"] == "abort"
  374. assert result["reason"] == "not_supported"
  375. @pytest.mark.asyncio
  376. @patch.object(config_flow.ConfigFlowHandler, "device")
  377. async def test_flow_select_type_data_valid(mock_device, hass):
  378. """Test the flow continues when valid data is supplied."""
  379. setup_device_mock(mock_device, type="smartplugv1")
  380. flow = await hass.config_entries.flow.async_init(
  381. DOMAIN, context={"source": "select_type"}
  382. )
  383. result = await hass.config_entries.flow.async_configure(
  384. flow["flow_id"],
  385. user_input={CONF_TYPE: "smartplugv1"},
  386. )
  387. assert "form" == result["type"]
  388. assert "choose_entities" == result["step_id"]
  389. @pytest.mark.asyncio
  390. async def test_flow_choose_entities_init(hass):
  391. """Test the initialisation of the form in the 3rd step of the config flow."""
  392. with patch.dict(config_flow.ConfigFlowHandler.data, {CONF_TYPE: "smartplugv1"}):
  393. result = await hass.config_entries.flow.async_init(
  394. DOMAIN, context={"source": "choose_entities"}
  395. )
  396. expected = {
  397. "data_schema": ANY,
  398. "description_placeholders": None,
  399. "errors": None,
  400. "flow_id": ANY,
  401. "handler": DOMAIN,
  402. "step_id": "choose_entities",
  403. "type": "form",
  404. "last_step": ANY,
  405. "preview": ANY,
  406. }
  407. assert expected == result
  408. # Check the schema. Simple comparison does not work since they are not
  409. # the same object
  410. try:
  411. result["data_schema"]({CONF_NAME: "test"})
  412. except vol.MultipleInvalid:
  413. assert False
  414. try:
  415. result["data_schema"]({"climate": True})
  416. assert False
  417. except vol.MultipleInvalid:
  418. pass
  419. @pytest.mark.asyncio
  420. async def test_flow_choose_entities_creates_config_entry(hass, bypass_setup):
  421. """Test the flow ends when data is valid."""
  422. with patch.dict(
  423. config_flow.ConfigFlowHandler.data,
  424. {
  425. CONF_DEVICE_ID: "deviceid",
  426. CONF_LOCAL_KEY: "localkey",
  427. CONF_HOST: "hostname",
  428. CONF_POLL_ONLY: False,
  429. CONF_PROTOCOL_VERSION: "auto",
  430. CONF_TYPE: "kogan_kahtp_heater",
  431. CONF_DEVICE_CID: None,
  432. },
  433. ):
  434. flow = await hass.config_entries.flow.async_init(
  435. DOMAIN, context={"source": "choose_entities"}
  436. )
  437. result = await hass.config_entries.flow.async_configure(
  438. flow["flow_id"],
  439. user_input={
  440. CONF_NAME: "test",
  441. },
  442. )
  443. expected = {
  444. "version": 13,
  445. "minor_version": ANY,
  446. "context": {"source": "choose_entities"},
  447. "type": FlowResultType.CREATE_ENTRY,
  448. "flow_id": ANY,
  449. "handler": DOMAIN,
  450. "title": "test",
  451. "description": None,
  452. "description_placeholders": None,
  453. "result": ANY,
  454. "options": {},
  455. "data": {
  456. CONF_DEVICE_ID: "deviceid",
  457. CONF_HOST: "hostname",
  458. CONF_LOCAL_KEY: "localkey",
  459. CONF_POLL_ONLY: False,
  460. CONF_PROTOCOL_VERSION: "auto",
  461. CONF_TYPE: "kogan_kahtp_heater",
  462. CONF_DEVICE_CID: None,
  463. },
  464. }
  465. assert expected == result
  466. @pytest.mark.asyncio
  467. async def test_options_flow_init(hass):
  468. """Test config flow options."""
  469. config_entry = MockConfigEntry(
  470. domain=DOMAIN,
  471. version=13,
  472. unique_id="uniqueid",
  473. data={
  474. CONF_DEVICE_ID: "deviceid",
  475. CONF_HOST: "hostname",
  476. CONF_LOCAL_KEY: "localkey",
  477. CONF_NAME: "test",
  478. CONF_POLL_ONLY: False,
  479. CONF_PROTOCOL_VERSION: "auto",
  480. CONF_TYPE: "smartplugv1",
  481. CONF_DEVICE_CID: "",
  482. },
  483. )
  484. config_entry.add_to_hass(hass)
  485. assert await hass.config_entries.async_setup(config_entry.entry_id)
  486. await hass.async_block_till_done()
  487. # show initial form
  488. result = await hass.config_entries.options.async_init(config_entry.entry_id)
  489. assert "form" == result["type"]
  490. assert "user" == result["step_id"]
  491. assert {} == result["errors"]
  492. assert result["data_schema"](
  493. {
  494. CONF_HOST: "hostname",
  495. CONF_LOCAL_KEY: "localkey",
  496. }
  497. )
  498. @pytest.mark.asyncio
  499. @patch("custom_components.tuya_local.config_flow.async_test_connection")
  500. async def test_options_flow_modifies_config(mock_test, hass):
  501. mock_device = MagicMock()
  502. mock_test.return_value = mock_device
  503. config_entry = MockConfigEntry(
  504. domain=DOMAIN,
  505. version=13,
  506. unique_id="uniqueid",
  507. data={
  508. CONF_DEVICE_ID: "deviceid",
  509. CONF_HOST: "hostname",
  510. CONF_LOCAL_KEY: "localkey",
  511. CONF_NAME: "test",
  512. CONF_POLL_ONLY: False,
  513. CONF_PROTOCOL_VERSION: "auto",
  514. CONF_TYPE: "ble_pt216_temp_humidity",
  515. CONF_DEVICE_CID: "subdeviceid",
  516. },
  517. )
  518. config_entry.add_to_hass(hass)
  519. assert await hass.config_entries.async_setup(config_entry.entry_id)
  520. await hass.async_block_till_done()
  521. # show initial form
  522. form = await hass.config_entries.options.async_init(config_entry.entry_id)
  523. # submit updated config
  524. result = await hass.config_entries.options.async_configure(
  525. form["flow_id"],
  526. user_input={
  527. CONF_HOST: "new_hostname",
  528. CONF_LOCAL_KEY: "new_key",
  529. CONF_POLL_ONLY: False,
  530. CONF_PROTOCOL_VERSION: 3.3,
  531. CONF_DEVICE_CID: "subdeviceid",
  532. },
  533. )
  534. expected = {
  535. CONF_HOST: "new_hostname",
  536. CONF_LOCAL_KEY: "new_key",
  537. CONF_POLL_ONLY: False,
  538. CONF_PROTOCOL_VERSION: 3.3,
  539. CONF_DEVICE_CID: "subdeviceid",
  540. }
  541. assert "create_entry" == result["type"]
  542. assert "" == result["title"]
  543. assert result["result"] is True
  544. assert expected == result["data"]
  545. @pytest.mark.asyncio
  546. @patch("custom_components.tuya_local.config_flow.async_test_connection")
  547. async def test_options_flow_fails_when_connection_fails(mock_test, hass):
  548. mock_test.return_value = None
  549. config_entry = MockConfigEntry(
  550. domain=DOMAIN,
  551. version=13,
  552. unique_id="uniqueid",
  553. data={
  554. CONF_DEVICE_ID: "deviceid",
  555. CONF_HOST: "hostname",
  556. CONF_LOCAL_KEY: "localkey",
  557. CONF_NAME: "test",
  558. CONF_POLL_ONLY: False,
  559. CONF_PROTOCOL_VERSION: "auto",
  560. CONF_TYPE: "smartplugv1",
  561. CONF_DEVICE_CID: "",
  562. },
  563. )
  564. config_entry.add_to_hass(hass)
  565. assert await hass.config_entries.async_setup(config_entry.entry_id)
  566. await hass.async_block_till_done()
  567. # show initial form
  568. form = await hass.config_entries.options.async_init(config_entry.entry_id)
  569. # submit updated config
  570. result = await hass.config_entries.options.async_configure(
  571. form["flow_id"],
  572. user_input={
  573. CONF_HOST: "new_hostname",
  574. CONF_LOCAL_KEY: "new_key",
  575. },
  576. )
  577. assert "form" == result["type"]
  578. assert "user" == result["step_id"]
  579. assert {"base": "connection"} == result["errors"]
  580. @pytest.mark.asyncio
  581. @patch("custom_components.tuya_local.config_flow.async_test_connection")
  582. async def test_options_flow_fails_when_config_is_missing(mock_test, hass):
  583. mock_device = MagicMock()
  584. mock_test.return_value = mock_device
  585. config_entry = MockConfigEntry(
  586. domain=DOMAIN,
  587. version=13,
  588. unique_id="uniqueid",
  589. data={
  590. CONF_DEVICE_ID: "deviceid",
  591. CONF_HOST: "hostname",
  592. CONF_LOCAL_KEY: "localkey",
  593. CONF_NAME: "test",
  594. CONF_POLL_ONLY: False,
  595. CONF_PROTOCOL_VERSION: "auto",
  596. CONF_TYPE: "non_existing",
  597. },
  598. )
  599. config_entry.add_to_hass(hass)
  600. await hass.config_entries.async_setup(config_entry.entry_id)
  601. await hass.async_block_till_done()
  602. # show initial form
  603. result = await hass.config_entries.options.async_init(config_entry.entry_id)
  604. assert result["type"] == "abort"
  605. assert result["reason"] == "not_supported"
  606. @pytest.mark.asyncio
  607. @patch("custom_components.tuya_local.setup_device")
  608. async def test_async_setup_entry_for_switch(mock_device, hass):
  609. """Test setting up based on a config entry. Repeats test_init_entry."""
  610. config_entry = MockConfigEntry(
  611. domain=DOMAIN,
  612. version=13,
  613. unique_id="uniqueid",
  614. data={
  615. CONF_DEVICE_ID: "deviceid",
  616. CONF_HOST: "hostname",
  617. CONF_LOCAL_KEY: "localkey",
  618. CONF_NAME: "test",
  619. CONF_POLL_ONLY: False,
  620. CONF_PROTOCOL_VERSION: 3.3,
  621. CONF_TYPE: "smartplugv2",
  622. },
  623. )
  624. config_entry.add_to_hass(hass)
  625. assert await async_setup_entry(hass, config_entry)