From ddbf85fc38b40ef2bec2d0310356c9d2a17f1bf0 Mon Sep 17 00:00:00 2001 From: Joost Lekkerkerker Date: Tue, 29 Aug 2023 09:36:27 +0200 Subject: [PATCH] Abort YouTube configuration if user doesn't have subscriptions (#99140) --- .../components/youtube/config_flow.py | 2 + homeassistant/components/youtube/strings.json | 1 + .../fixtures/get_no_subscriptions.json | 10 +++++ tests/components/youtube/test_config_flow.py | 40 +++++++++++++++++++ 4 files changed, 53 insertions(+) create mode 100644 tests/components/youtube/fixtures/get_no_subscriptions.json diff --git a/homeassistant/components/youtube/config_flow.py b/homeassistant/components/youtube/config_flow.py index 50dee14d61a..cf0d61b5d38 100644 --- a/homeassistant/components/youtube/config_flow.py +++ b/homeassistant/components/youtube/config_flow.py @@ -145,6 +145,8 @@ class OAuth2FlowHandler( ) async for subscription in youtube.get_user_subscriptions() ] + if not selectable_channels: + return self.async_abort(reason="no_subscriptions") return self.async_show_form( step_id="channels", data_schema=vol.Schema( diff --git a/homeassistant/components/youtube/strings.json b/homeassistant/components/youtube/strings.json index ccb7e9c506e..1b9ecbc1cb3 100644 --- a/homeassistant/components/youtube/strings.json +++ b/homeassistant/components/youtube/strings.json @@ -5,6 +5,7 @@ "no_channel": "Please create a YouTube channel to be able to use the integration. Instructions can be found at {support_url}.", "already_configured": "[%key:common::config_flow::abort::already_configured_account%]", "reauth_successful": "[%key:common::config_flow::abort::reauth_successful%]", + "no_subscriptions": "You need to be subscribed to YouTube channels in order to add them.", "unknown": "[%key:common::config_flow::error::unknown%]" }, "error": { diff --git a/tests/components/youtube/fixtures/get_no_subscriptions.json b/tests/components/youtube/fixtures/get_no_subscriptions.json new file mode 100644 index 00000000000..77a64503fc0 --- /dev/null +++ b/tests/components/youtube/fixtures/get_no_subscriptions.json @@ -0,0 +1,10 @@ +{ + "kind": "youtube#SubscriptionListResponse", + "etag": "6C9iFE7CzKQqPrEoJlE0H2U27xI", + "nextPageToken": "CAEQAA", + "pageInfo": { + "totalResults": 0, + "resultsPerPage": 1 + }, + "items": [] +} diff --git a/tests/components/youtube/test_config_flow.py b/tests/components/youtube/test_config_flow.py index 97875004d11..c4aacc9603d 100644 --- a/tests/components/youtube/test_config_flow.py +++ b/tests/components/youtube/test_config_flow.py @@ -121,6 +121,46 @@ async def test_flow_abort_without_channel( assert result["reason"] == "no_channel" +async def test_flow_abort_without_subscriptions( + hass: HomeAssistant, + hass_client_no_auth: ClientSessionGenerator, + current_request_with_host: None, +) -> None: + """Check abort flow if user has no subscriptions.""" + result = await hass.config_entries.flow.async_init( + "youtube", context={"source": config_entries.SOURCE_USER} + ) + state = config_entry_oauth2_flow._encode_jwt( + hass, + { + "flow_id": result["flow_id"], + "redirect_uri": "https://example.com/auth/external/callback", + }, + ) + + assert result["url"] == ( + f"{GOOGLE_AUTH_URI}?response_type=code&client_id={CLIENT_ID}" + "&redirect_uri=https://example.com/auth/external/callback" + f"&state={state}&scope={'+'.join(SCOPES)}" + "&access_type=offline&prompt=consent" + ) + + client = await hass_client_no_auth() + resp = await client.get(f"/auth/external/callback?code=abcd&state={state}") + assert resp.status == 200 + assert resp.headers["content-type"] == "text/html; charset=utf-8" + + service = MockYouTube(subscriptions_fixture="youtube/get_no_subscriptions.json") + with patch( + "homeassistant.components.youtube.async_setup_entry", return_value=True + ), patch( + "homeassistant.components.youtube.config_flow.YouTube", return_value=service + ): + result = await hass.config_entries.flow.async_configure(result["flow_id"]) + assert result["type"] == FlowResultType.ABORT + assert result["reason"] == "no_subscriptions" + + async def test_flow_http_error( hass: HomeAssistant, hass_client_no_auth: ClientSessionGenerator,