Implement YouTube async library (#97072)

This commit is contained in:
Joost Lekkerkerker 2023-07-25 10:18:20 +02:00 committed by GitHub
parent 714a04d603
commit 04f6d1848b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
21 changed files with 270 additions and 587 deletions

View file

@ -1,9 +1,8 @@
"""Test the YouTube config flow."""
from unittest.mock import patch
from googleapiclient.errors import HttpError
from httplib2 import Response
import pytest
from youtubeaio.types import ForbiddenError
from homeassistant import config_entries
from homeassistant.components.youtube.const import CONF_CHANNELS, DOMAIN
@ -11,7 +10,7 @@ from homeassistant.core import HomeAssistant
from homeassistant.data_entry_flow import FlowResultType
from homeassistant.helpers import config_entry_oauth2_flow
from . import MockService
from . import MockYouTube
from .conftest import (
CLIENT_ID,
GOOGLE_AUTH_URI,
@ -21,7 +20,7 @@ from .conftest import (
ComponentSetup,
)
from tests.common import MockConfigEntry, load_fixture
from tests.common import MockConfigEntry
from tests.test_util.aiohttp import AiohttpClientMocker
from tests.typing import ClientSessionGenerator
@ -58,9 +57,8 @@ async def test_full_flow(
with patch(
"homeassistant.components.youtube.async_setup_entry", return_value=True
) as mock_setup, patch(
"homeassistant.components.youtube.api.build", return_value=MockService()
), patch(
"homeassistant.components.youtube.config_flow.build", return_value=MockService()
"homeassistant.components.youtube.config_flow.YouTube",
return_value=MockYouTube(),
):
result = await hass.config_entries.flow.async_configure(result["flow_id"])
assert result["type"] == FlowResultType.FORM
@ -112,11 +110,11 @@ async def test_flow_abort_without_channel(
assert resp.status == 200
assert resp.headers["content-type"] == "text/html; charset=utf-8"
service = MockService(channel_fixture="youtube/get_no_channel.json")
service = MockYouTube(channel_fixture="youtube/get_no_channel.json")
with patch(
"homeassistant.components.youtube.async_setup_entry", return_value=True
), patch("homeassistant.components.youtube.api.build", return_value=service), patch(
"homeassistant.components.youtube.config_flow.build", return_value=service
), 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
@ -153,41 +151,29 @@ async def test_flow_http_error(
assert resp.headers["content-type"] == "text/html; charset=utf-8"
with patch(
"homeassistant.components.youtube.config_flow.build",
side_effect=HttpError(
Response(
{
"vary": "Origin, X-Origin, Referer",
"content-type": "application/json; charset=UTF-8",
"date": "Mon, 15 May 2023 21:25:42 GMT",
"server": "scaffolding on HTTPServer2",
"cache-control": "private",
"x-xss-protection": "0",
"x-frame-options": "SAMEORIGIN",
"x-content-type-options": "nosniff",
"alt-svc": 'h3=":443"; ma=2592000,h3-29=":443"; ma=2592000',
"transfer-encoding": "chunked",
"status": "403",
"content-length": "947",
"-content-encoding": "gzip",
}
),
b'{"error": {"code": 403,"message": "YouTube Data API v3 has not been used in project 0 before or it is disabled. Enable it by visiting https://console.developers.google.com/apis/api/youtube.googleapis.com/overview?project=0 then retry. If you enabled this API recently, wait a few minutes for the action to propagate to our systems and retry.","errors": [ { "message": "YouTube Data API v3 has not been used in project 0 before or it is disabled. Enable it by visiting https://console.developers.google.com/apis/api/youtube.googleapis.com/overview?project=0 then retry. If you enabled this API recently, wait a few minutes for the action to propagate to our systems and retry.", "domain": "usageLimits", "reason": "accessNotConfigured", "extendedHelp": "https://console.developers.google.com" }],"status": "PERMISSION_DENIED"\n }\n}\n',
"homeassistant.components.youtube.config_flow.YouTube.get_user_channels",
side_effect=ForbiddenError(
"YouTube Data API v3 has not been used in project 0 before or it is disabled. Enable it by visiting https://console.developers.google.com/apis/api/youtube.googleapis.com/overview?project=0 then retry. If you enabled this API recently, wait a few minutes for the action to propagate to our systems and retry."
),
):
result = await hass.config_entries.flow.async_configure(result["flow_id"])
assert result["type"] == FlowResultType.ABORT
assert result["reason"] == "access_not_configured"
assert (
result["description_placeholders"]["message"]
== "YouTube Data API v3 has not been used in project 0 before or it is disabled. Enable it by visiting https://console.developers.google.com/apis/api/youtube.googleapis.com/overview?project=0 then retry. If you enabled this API recently, wait a few minutes for the action to propagate to our systems and retry."
assert result["description_placeholders"]["message"] == (
"YouTube Data API v3 has not been used in project 0 before or it is disabled. Enable it by visiting https://console.developers.google.com/apis/api/youtube.googleapis.com/overview?project=0 then retry. If you enabled this API recently, wait a few minutes for the action to propagate to our systems and retry."
)
@pytest.mark.parametrize(
("fixture", "abort_reason", "placeholders", "calls", "access_token"),
[
("get_channel", "reauth_successful", None, 1, "updated-access-token"),
(
"get_channel",
"reauth_successful",
None,
1,
"updated-access-token",
),
(
"get_channel_2",
"wrong_account",
@ -254,14 +240,12 @@ async def test_reauth(
},
)
youtube = MockYouTube(channel_fixture=f"youtube/{fixture}.json")
with patch(
"homeassistant.components.youtube.async_setup_entry", return_value=True
) as mock_setup, patch(
"httplib2.Http.request",
return_value=(
Response({}),
bytes(load_fixture(f"youtube/{fixture}.json"), encoding="UTF-8"),
),
"homeassistant.components.youtube.config_flow.YouTube",
return_value=youtube,
):
result = await hass.config_entries.flow.async_configure(result["flow_id"])
@ -309,7 +293,7 @@ async def test_flow_exception(
assert resp.headers["content-type"] == "text/html; charset=utf-8"
with patch(
"homeassistant.components.youtube.config_flow.build", side_effect=Exception
"homeassistant.components.youtube.config_flow.YouTube", side_effect=Exception
):
result = await hass.config_entries.flow.async_configure(result["flow_id"])
assert result["type"] == FlowResultType.ABORT
@ -322,7 +306,8 @@ async def test_options_flow(
"""Test the full options flow."""
await setup_integration()
with patch(
"homeassistant.components.youtube.config_flow.build", return_value=MockService()
"homeassistant.components.youtube.config_flow.YouTube",
return_value=MockYouTube(),
):
entry = hass.config_entries.async_entries(DOMAIN)[0]
result = await hass.config_entries.options.async_init(entry.entry_id)