mirror of
				https://github.com/home-assistant/core.git
				synced 2025-10-31 06:29:31 +00:00 
			
		
		
		
	Compare commits
	
		
			3 Commits
		
	
	
		
			2024.2.0b1
			...
			otbr_user_
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | 18dae08244 | ||
|   | 5d21b6e7a7 | ||
|   | eea98b22e0 | 
| @@ -1,9 +1,14 @@ | |||||||
| """Config flow for the Open Thread Border Router integration.""" | """Config flow for the Open Thread Border Router integration.""" | ||||||
| from __future__ import annotations | from __future__ import annotations | ||||||
|  |  | ||||||
|  | import python_otbr_api | ||||||
|  | import voluptuous as vol | ||||||
|  |  | ||||||
| from homeassistant.components.hassio import HassioServiceInfo | from homeassistant.components.hassio import HassioServiceInfo | ||||||
| from homeassistant.config_entries import ConfigFlow | from homeassistant.config_entries import ConfigFlow | ||||||
|  | from homeassistant.const import CONF_URL | ||||||
| from homeassistant.data_entry_flow import FlowResult | from homeassistant.data_entry_flow import FlowResult | ||||||
|  | from homeassistant.helpers.aiohttp_client import async_get_clientsession | ||||||
|  |  | ||||||
| from .const import DOMAIN | from .const import DOMAIN | ||||||
|  |  | ||||||
| @@ -13,13 +18,43 @@ class OTBRConfigFlow(ConfigFlow, domain=DOMAIN): | |||||||
|  |  | ||||||
|     VERSION = 1 |     VERSION = 1 | ||||||
|  |  | ||||||
|  |     async def async_step_user( | ||||||
|  |         self, user_input: dict[str, str] | None = None | ||||||
|  |     ) -> FlowResult: | ||||||
|  |         """Set up by user.""" | ||||||
|  |         if self._async_current_entries(): | ||||||
|  |             return self.async_abort(reason="single_instance_allowed") | ||||||
|  |  | ||||||
|  |         errors = {} | ||||||
|  |  | ||||||
|  |         if user_input is not None: | ||||||
|  |             url = user_input[CONF_URL] | ||||||
|  |             api = python_otbr_api.OTBR(url, async_get_clientsession(self.hass), 10) | ||||||
|  |             try: | ||||||
|  |                 await api.get_active_dataset_tlvs() | ||||||
|  |             except python_otbr_api.OTBRError: | ||||||
|  |                 errors["base"] = "cannot_connect" | ||||||
|  |             else: | ||||||
|  |                 await self.async_set_unique_id(DOMAIN) | ||||||
|  |                 return self.async_create_entry( | ||||||
|  |                     title="Thread", | ||||||
|  |                     data={"url": url}, | ||||||
|  |                 ) | ||||||
|  |  | ||||||
|  |         data_schema = vol.Schema({CONF_URL: str}) | ||||||
|  |         return self.async_show_form( | ||||||
|  |             step_id="user", data_schema=data_schema, errors=errors | ||||||
|  |         ) | ||||||
|  |  | ||||||
|     async def async_step_hassio(self, discovery_info: HassioServiceInfo) -> FlowResult: |     async def async_step_hassio(self, discovery_info: HassioServiceInfo) -> FlowResult: | ||||||
|         """Handle hassio discovery.""" |         """Handle hassio discovery.""" | ||||||
|         if self._async_current_entries(): |         if self._async_current_entries(): | ||||||
|             return self.async_abort(reason="single_instance_allowed") |             return self.async_abort(reason="single_instance_allowed") | ||||||
|  |  | ||||||
|         config = discovery_info.config |         config = discovery_info.config | ||||||
|  |         url = f"http://{config['host']}:{config['port']}" | ||||||
|  |         await self.async_set_unique_id(DOMAIN) | ||||||
|         return self.async_create_entry( |         return self.async_create_entry( | ||||||
|             title="Thread", |             title="Thread", | ||||||
|             data={"url": f"http://{config['host']}:{config['port']}"}, |             data={"url": url}, | ||||||
|         ) |         ) | ||||||
|   | |||||||
| @@ -3,7 +3,7 @@ | |||||||
|   "after_dependencies": ["hassio"], |   "after_dependencies": ["hassio"], | ||||||
|   "domain": "otbr", |   "domain": "otbr", | ||||||
|   "iot_class": "local_polling", |   "iot_class": "local_polling", | ||||||
|   "config_flow": false, |   "config_flow": true, | ||||||
|   "documentation": "https://www.home-assistant.io/integrations/otbr", |   "documentation": "https://www.home-assistant.io/integrations/otbr", | ||||||
|   "integration_type": "system", |   "integration_type": "system", | ||||||
|   "name": "Thread", |   "name": "Thread", | ||||||
|   | |||||||
							
								
								
									
										18
									
								
								homeassistant/components/otbr/strings.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								homeassistant/components/otbr/strings.json
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,18 @@ | |||||||
|  | { | ||||||
|  |   "config": { | ||||||
|  |     "step": { | ||||||
|  |       "user": { | ||||||
|  |         "data": { | ||||||
|  |           "url": "[%key:common::config_flow::data::url%]" | ||||||
|  |         }, | ||||||
|  |         "description": "Provide URL for the Open Thread Border Router's REST API" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "error": { | ||||||
|  |       "cannot_connect": "[%key:common::config_flow::error::cannot_connect%]" | ||||||
|  |     }, | ||||||
|  |     "abort": { | ||||||
|  |       "already_configured": "[%key:common::config_flow::abort::already_configured_service%]" | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
							
								
								
									
										18
									
								
								homeassistant/components/otbr/translations/en.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								homeassistant/components/otbr/translations/en.json
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,18 @@ | |||||||
|  | { | ||||||
|  |     "config": { | ||||||
|  |         "abort": { | ||||||
|  |             "already_configured": "Service is already configured" | ||||||
|  |         }, | ||||||
|  |         "error": { | ||||||
|  |             "cannot_connect": "Failed to connect" | ||||||
|  |         }, | ||||||
|  |         "step": { | ||||||
|  |             "user": { | ||||||
|  |                 "data": { | ||||||
|  |                     "url": "URL" | ||||||
|  |                 }, | ||||||
|  |                 "description": "Provide URL for the Open Thread Border Router's REST API" | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -304,6 +304,7 @@ FLOWS = { | |||||||
|         "openuv", |         "openuv", | ||||||
|         "openweathermap", |         "openweathermap", | ||||||
|         "oralb", |         "oralb", | ||||||
|  |         "otbr", | ||||||
|         "overkiz", |         "overkiz", | ||||||
|         "ovo_energy", |         "ovo_energy", | ||||||
|         "owntracks", |         "owntracks", | ||||||
|   | |||||||
| @@ -1,4 +1,5 @@ | |||||||
| """Test the Open Thread Border Router config flow.""" | """Test the Open Thread Border Router config flow.""" | ||||||
|  | from http import HTTPStatus | ||||||
| from unittest.mock import patch | from unittest.mock import patch | ||||||
|  |  | ||||||
| from homeassistant.components import hassio, otbr | from homeassistant.components import hassio, otbr | ||||||
| @@ -6,6 +7,7 @@ from homeassistant.core import HomeAssistant | |||||||
| from homeassistant.data_entry_flow import FlowResultType | from homeassistant.data_entry_flow import FlowResultType | ||||||
|  |  | ||||||
| from tests.common import MockConfigEntry, MockModule, mock_integration | from tests.common import MockConfigEntry, MockModule, mock_integration | ||||||
|  | from tests.test_util.aiohttp import AiohttpClientMocker | ||||||
|  |  | ||||||
| HASSIO_DATA = hassio.HassioServiceInfo( | HASSIO_DATA = hassio.HassioServiceInfo( | ||||||
|     config={"host": "blah", "port": "bluh"}, |     config={"host": "blah", "port": "bluh"}, | ||||||
| @@ -14,6 +16,67 @@ HASSIO_DATA = hassio.HassioServiceInfo( | |||||||
| ) | ) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | async def test_user_flow( | ||||||
|  |     hass: HomeAssistant, aioclient_mock: AiohttpClientMocker | ||||||
|  | ) -> None: | ||||||
|  |     """Test the user flow.""" | ||||||
|  |     url = "http://custom_url:1234" | ||||||
|  |     aioclient_mock.get(f"{url}/node/dataset/active", text="aa") | ||||||
|  |     result = await hass.config_entries.flow.async_init( | ||||||
|  |         otbr.DOMAIN, context={"source": "user"} | ||||||
|  |     ) | ||||||
|  |  | ||||||
|  |     expected_data = {"url": url} | ||||||
|  |  | ||||||
|  |     assert result["type"] == FlowResultType.FORM | ||||||
|  |     assert result["errors"] == {} | ||||||
|  |  | ||||||
|  |     with patch( | ||||||
|  |         "homeassistant.components.otbr.async_setup_entry", | ||||||
|  |         return_value=True, | ||||||
|  |     ) as mock_setup_entry: | ||||||
|  |         result = await hass.config_entries.flow.async_configure( | ||||||
|  |             result["flow_id"], | ||||||
|  |             { | ||||||
|  |                 "url": url, | ||||||
|  |             }, | ||||||
|  |         ) | ||||||
|  |     assert result["type"] == FlowResultType.CREATE_ENTRY | ||||||
|  |     assert result["title"] == "Thread" | ||||||
|  |     assert result["data"] == expected_data | ||||||
|  |     assert result["options"] == {} | ||||||
|  |     assert len(mock_setup_entry.mock_calls) == 1 | ||||||
|  |  | ||||||
|  |     config_entry = hass.config_entries.async_entries(otbr.DOMAIN)[0] | ||||||
|  |     assert config_entry.data == expected_data | ||||||
|  |     assert config_entry.options == {} | ||||||
|  |     assert config_entry.title == "Thread" | ||||||
|  |     assert config_entry.unique_id is None | ||||||
|  |  | ||||||
|  |  | ||||||
|  | async def test_user_flow_404( | ||||||
|  |     hass: HomeAssistant, aioclient_mock: AiohttpClientMocker | ||||||
|  | ) -> None: | ||||||
|  |     """Test the user flow.""" | ||||||
|  |     url = "http://custom_url:1234" | ||||||
|  |     aioclient_mock.get(f"{url}/node/dataset/active", status=HTTPStatus.NOT_FOUND) | ||||||
|  |     result = await hass.config_entries.flow.async_init( | ||||||
|  |         otbr.DOMAIN, context={"source": "user"} | ||||||
|  |     ) | ||||||
|  |  | ||||||
|  |     assert result["type"] == FlowResultType.FORM | ||||||
|  |     assert result["errors"] == {} | ||||||
|  |  | ||||||
|  |     result = await hass.config_entries.flow.async_configure( | ||||||
|  |         result["flow_id"], | ||||||
|  |         { | ||||||
|  |             "url": url, | ||||||
|  |         }, | ||||||
|  |     ) | ||||||
|  |     assert result["type"] == FlowResultType.FORM | ||||||
|  |     assert result["errors"] == {"base": "cannot_connect"} | ||||||
|  |  | ||||||
|  |  | ||||||
| async def test_hassio_discovery_flow(hass: HomeAssistant) -> None: | async def test_hassio_discovery_flow(hass: HomeAssistant) -> None: | ||||||
|     """Test the hassio discovery flow.""" |     """Test the hassio discovery flow.""" | ||||||
|     with patch( |     with patch( | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user