diff --git a/homeassistant/components/radarr/config_flow.py b/homeassistant/components/radarr/config_flow.py index e44bbdd0fb02..a94aa6111746 100644 --- a/homeassistant/components/radarr/config_flow.py +++ b/homeassistant/components/radarr/config_flow.py @@ -47,11 +47,13 @@ class RadarrConfigFlow(ConfigFlow, domain=DOMAIN): errors = {} if user_input is not None: - # aiopyarr defaults to the service port if one isn't given - # this is counter to standard practice where http = 80 - # and https = 443. + # Ensure an explicit port is present in the URL so that + # aiopyarr does not fall back to its own service-port default + # (which differs from the standard HTTP/HTTPS ports). url = URL(user_input[CONF_URL]) - user_input[CONF_URL] = f"{url.scheme}://{url.host}:{url.port}{url.path}" + if url.explicit_port is None: + url = url.with_port(url.port) + user_input[CONF_URL] = url.human_repr() try: if result := await validate_input(self.hass, user_input): diff --git a/homeassistant/components/sonarr/config_flow.py b/homeassistant/components/sonarr/config_flow.py index f27ef17af606..24779c5aa810 100644 --- a/homeassistant/components/sonarr/config_flow.py +++ b/homeassistant/components/sonarr/config_flow.py @@ -100,12 +100,14 @@ class SonarrConfigFlow(ConfigFlow, domain=DOMAIN): CONF_VERIFY_SSL, DEFAULT_VERIFY_SSL ) - # aiopyarr defaults to the service port if one isn't given - # this is counter to standard practice where http = 80 - # and https = 443. + # Ensure an explicit port is present in the URL so that + # aiopyarr does not fall back to its own service-port default + # (which differs from the standard HTTP/HTTPS ports). if CONF_URL in user_input: url = yarl.URL(user_input[CONF_URL]) - user_input[CONF_URL] = f"{url.scheme}://{url.host}:{url.port}{url.path}" + if url.explicit_port is None: + url = url.with_port(url.port) + user_input[CONF_URL] = url.human_repr() if self.source == SOURCE_REAUTH: user_input = {**self._get_reauth_entry().data, **user_input} diff --git a/tests/components/radarr/test_config_flow.py b/tests/components/radarr/test_config_flow.py index 02f9493a32c7..37ea415be8bd 100644 --- a/tests/components/radarr/test_config_flow.py +++ b/tests/components/radarr/test_config_flow.py @@ -140,24 +140,41 @@ async def test_zero_conf(hass: HomeAssistant) -> None: assert result["data"] == CONF_DATA -async def test_url_rewrite(hass: HomeAssistant) -> None: +@pytest.mark.parametrize( + ("input_url", "expected_url"), + [ + pytest.param( + "https://192.168.1.100/", + "https://192.168.1.100:443/", + id="ip_without_port", + ), + pytest.param( + "https://radarr-anime.example.com/", + "https://radarr-anime.example.com:443/", + id="hyphenated_hostname", + ), + ], +) +async def test_url_rewrite( + hass: HomeAssistant, input_url: str, expected_url: str +) -> None: """Test auth flow url rewrite.""" with ( patch( "homeassistant.components.radarr.config_flow.RadarrClient.async_try_zeroconf", - return_value=("v3", API_KEY, "/test"), + return_value=("v3", API_KEY, "/"), ), patch_async_setup_entry(), ): result = await hass.config_entries.flow.async_init( DOMAIN, context={CONF_SOURCE: SOURCE_USER}, - data={CONF_URL: "https://192.168.1.100/test", CONF_VERIFY_SSL: False}, + data={CONF_URL: input_url, CONF_VERIFY_SSL: False}, ) assert result["type"] is FlowResultType.CREATE_ENTRY assert result["title"] == DEFAULT_NAME - assert result["data"][CONF_URL] == "https://192.168.1.100:443/test" + assert result["data"][CONF_URL] == expected_url @pytest.mark.freeze_time("2021-12-03 00:00:00+00:00") diff --git a/tests/components/sonarr/test_config_flow.py b/tests/components/sonarr/test_config_flow.py index f5628dd5f125..61abae00750c 100644 --- a/tests/components/sonarr/test_config_flow.py +++ b/tests/components/sonarr/test_config_flow.py @@ -52,11 +52,32 @@ async def test_cannot_connect( assert result["errors"] == {"base": "cannot_connect"} +@pytest.mark.parametrize( + ("input_url", "expected_url", "expected_title"), + [ + pytest.param( + "https://192.168.1.189", + "https://192.168.1.189:443/", + "192.168.1.189", + id="ip_without_port", + ), + pytest.param( + "https://sonarr-anime.example.com/", + "https://sonarr-anime.example.com:443/", + "sonarr-anime.example.com", + id="hyphenated_hostname", + ), + ], +) @pytest.mark.usefixtures("mock_setup_entry") async def test_url_rewrite( - hass: HomeAssistant, mock_sonarr_config_flow: MagicMock + hass: HomeAssistant, + mock_sonarr_config_flow: MagicMock, + input_url: str, + expected_url: str, + expected_title: str, ) -> None: - """Test the full manual user flow from start to finish.""" + """Test auth flow url rewrite.""" result = await hass.config_entries.flow.async_init( DOMAIN, context={CONF_SOURCE: SOURCE_USER}, @@ -66,17 +87,17 @@ async def test_url_rewrite( assert result["step_id"] == "user" user_input = MOCK_USER_INPUT.copy() - user_input[CONF_URL] = "https://192.168.1.189" + user_input[CONF_URL] = input_url result = await hass.config_entries.flow.async_configure( result["flow_id"], user_input=user_input, ) assert result["type"] is FlowResultType.CREATE_ENTRY - assert result["title"] == "192.168.1.189" + assert result["title"] == expected_title assert result["data"] - assert result["data"][CONF_URL] == "https://192.168.1.189:443/" + assert result["data"][CONF_URL] == expected_url async def test_invalid_auth(