Remove Twitch YAML import (#115278)

This commit is contained in:
Joost Lekkerkerker 2024-04-09 18:34:29 +02:00 committed by GitHub
parent d2dcf04946
commit e7c247f1f0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 7 additions and 300 deletions

View File

@ -8,17 +8,13 @@ from typing import Any, cast
from twitchAPI.helper import first
from twitchAPI.twitch import Twitch
from twitchAPI.type import AuthScope, InvalidTokenException
from homeassistant.config_entries import ConfigEntry, ConfigFlowResult
from homeassistant.const import CONF_ACCESS_TOKEN, CONF_CLIENT_ID, CONF_TOKEN
from homeassistant.core import DOMAIN as HOMEASSISTANT_DOMAIN
from homeassistant.data_entry_flow import AbortFlow
from homeassistant.const import CONF_ACCESS_TOKEN, CONF_TOKEN
from homeassistant.helpers import config_entry_oauth2_flow
from homeassistant.helpers.config_entry_oauth2_flow import LocalOAuth2Implementation
from homeassistant.helpers.issue_registry import IssueSeverity, async_create_issue
from .const import CONF_CHANNELS, CONF_REFRESH_TOKEN, DOMAIN, LOGGER, OAUTH_SCOPES
from .const import CONF_CHANNELS, DOMAIN, LOGGER, OAUTH_SCOPES
class OAuth2FlowHandler(
@ -121,77 +117,3 @@ class OAuth2FlowHandler(
if user_input is None:
return self.async_show_form(step_id="reauth_confirm")
return await self.async_step_user()
async def async_step_import(self, config: dict[str, Any]) -> ConfigFlowResult:
"""Import from yaml."""
client = await Twitch(
app_id=config[CONF_CLIENT_ID],
authenticate_app=False,
)
client.auto_refresh_auth = False
token = config[CONF_TOKEN]
try:
await client.set_user_authentication(
token, validate=True, scope=[AuthScope.USER_READ_SUBSCRIPTIONS]
)
except InvalidTokenException:
async_create_issue(
self.hass,
DOMAIN,
"deprecated_yaml_invalid_token",
breaks_in_ha_version="2024.4.0",
is_fixable=False,
severity=IssueSeverity.WARNING,
translation_key="deprecated_yaml_invalid_token",
translation_placeholders={
"domain": DOMAIN,
"integration_title": "Twitch",
},
)
return self.async_abort(reason="invalid_token")
user = await first(client.get_users())
assert user
await self.async_set_unique_id(user.id)
try:
self._abort_if_unique_id_configured()
except AbortFlow:
async_create_issue(
self.hass,
DOMAIN,
"deprecated_yaml_already_imported",
breaks_in_ha_version="2024.4.0",
is_fixable=False,
severity=IssueSeverity.WARNING,
translation_key="deprecated_yaml_already_imported",
translation_placeholders={
"domain": DOMAIN,
"integration_title": "Twitch",
},
)
raise
async_create_issue(
self.hass,
HOMEASSISTANT_DOMAIN,
"deprecated_yaml",
breaks_in_ha_version="2024.4.0",
is_fixable=False,
severity=IssueSeverity.WARNING,
translation_key="deprecated_yaml",
translation_placeholders={
"domain": DOMAIN,
"integration_title": "Twitch",
},
)
return self.async_create_entry(
title=user.display_name,
data={
"auth_implementation": DOMAIN,
CONF_TOKEN: {
CONF_ACCESS_TOKEN: token,
CONF_REFRESH_TOKEN: "",
"expires_at": 0,
},
"imported": True,
},
options={CONF_CHANNELS: config[CONF_CHANNELS]},
)

View File

@ -10,34 +10,15 @@ from twitchAPI.twitch import (
TwitchResourceNotFound,
TwitchUser,
)
import voluptuous as vol
from homeassistant.components.application_credentials import (
ClientCredential,
async_import_client_credential,
)
from homeassistant.components.sensor import PLATFORM_SCHEMA, SensorEntity
from homeassistant.config_entries import SOURCE_IMPORT, ConfigEntry
from homeassistant.const import CONF_CLIENT_ID, CONF_CLIENT_SECRET, CONF_TOKEN
from homeassistant.components.sensor import SensorEntity
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant
from homeassistant.helpers.config_entry_oauth2_flow import OAuth2Session
import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.issue_registry import IssueSeverity, async_create_issue
from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
from .const import CLIENT, CONF_CHANNELS, DOMAIN, LOGGER, OAUTH_SCOPES, SESSION
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
{
vol.Required(CONF_CLIENT_ID): cv.string,
vol.Required(CONF_CLIENT_SECRET): cv.string,
vol.Required(CONF_CHANNELS): vol.All(cv.ensure_list, [cv.string]),
vol.Optional(CONF_TOKEN): cv.string,
}
)
ATTR_GAME = "game"
ATTR_TITLE = "title"
ATTR_SUBSCRIPTION = "subscribed"
@ -59,40 +40,6 @@ def chunk_list(lst: list, chunk_size: int) -> list[list]:
return [lst[i : i + chunk_size] for i in range(0, len(lst), chunk_size)]
async def async_setup_platform(
hass: HomeAssistant,
config: ConfigType,
async_add_entities: AddEntitiesCallback,
discovery_info: DiscoveryInfoType | None = None,
) -> None:
"""Set up the Twitch platform."""
await async_import_client_credential(
hass,
DOMAIN,
ClientCredential(config[CONF_CLIENT_ID], config[CONF_CLIENT_SECRET]),
)
if CONF_TOKEN in config:
hass.async_create_task(
hass.config_entries.flow.async_init(
DOMAIN, context={"source": SOURCE_IMPORT}, data=config
)
)
else:
async_create_issue(
hass,
DOMAIN,
"deprecated_yaml_credentials_imported",
breaks_in_ha_version="2024.4.0",
is_fixable=False,
severity=IssueSeverity.WARNING,
translation_key="deprecated_yaml_credentials_imported",
translation_placeholders={
"domain": DOMAIN,
"integration_title": "Twitch",
},
)
async def async_setup_entry(
hass: HomeAssistant,
entry: ConfigEntry,

View File

@ -16,19 +16,5 @@
"oauth_unauthorized": "[%key:common::config_flow::abort::oauth2_unauthorized%]",
"oauth_failed": "[%key:common::config_flow::abort::oauth2_failed%]"
}
},
"issues": {
"deprecated_yaml_invalid_token": {
"title": "The {integration_title} YAML configuration is being removed",
"description": "Configuring {integration_title} using YAML is being removed.\n\nYour configuration couldn't be imported because the token in the configuration.yaml was invalid.\n\nPlease add Twitch again via the UI.\n\nRemove the `{domain}` configuration from your configuration.yaml file and restart Home Assistant to fix this issue."
},
"deprecated_yaml_credentials_imported": {
"title": "The {integration_title} YAML configuration is being removed",
"description": "Configuring {integration_title} using YAML is being removed.\n\nYour application credentials are imported, but a config entry could not be created because there was no access token.\n\nPlease add Twitch again via the UI.\n\nRemove the `{domain}` configuration from your configuration.yaml file and restart Home Assistant to fix this issue."
},
"deprecated_yaml_already_imported": {
"title": "The {integration_title} YAML configuration is being removed",
"description": "Configuring {integration_title} using YAML is being removed.\n\nYour application credentials are already imported.\n\nRemove the `{domain}` configuration from your configuration.yaml file and restart Home Assistant to fix this issue."
}
}
}

View File

@ -2,23 +2,20 @@
from unittest.mock import patch
import pytest
from homeassistant.components.twitch.const import (
CONF_CHANNELS,
DOMAIN,
OAUTH2_AUTHORIZE,
)
from homeassistant.config_entries import SOURCE_IMPORT, SOURCE_REAUTH, SOURCE_USER
from homeassistant.const import CONF_CLIENT_ID, CONF_CLIENT_SECRET, CONF_TOKEN
from homeassistant.config_entries import SOURCE_REAUTH, SOURCE_USER
from homeassistant.core import HomeAssistant
from homeassistant.data_entry_flow import FlowResult, FlowResultType
from homeassistant.helpers import config_entry_oauth2_flow, issue_registry as ir
from homeassistant.helpers import config_entry_oauth2_flow
from . import setup_integration
from tests.common import MockConfigEntry
from tests.components.twitch import TwitchInvalidTokenMock, TwitchMock
from tests.components.twitch import TwitchMock
from tests.components.twitch.conftest import CLIENT_ID, TITLE
from tests.typing import ClientSessionGenerator
@ -206,91 +203,3 @@ async def test_reauth_wrong_account(
assert result["type"] is FlowResultType.ABORT
assert result["reason"] == "wrong_account"
async def test_import(
hass: HomeAssistant,
hass_client_no_auth: ClientSessionGenerator,
current_request_with_host: None,
mock_setup_entry,
twitch: TwitchMock,
) -> None:
"""Test import flow."""
result = await hass.config_entries.flow.async_init(
DOMAIN,
context={
"source": SOURCE_IMPORT,
},
data={
"platform": "twitch",
CONF_CLIENT_ID: "1234",
CONF_CLIENT_SECRET: "abcd",
CONF_TOKEN: "efgh",
"channels": ["channel123"],
},
)
assert result["type"] is FlowResultType.CREATE_ENTRY
assert result["title"] == "channel123"
assert "result" in result
assert "token" in result["result"].data
assert result["result"].data["token"]["access_token"] == "efgh"
assert result["result"].data["token"]["refresh_token"] == ""
assert result["result"].unique_id == "123"
assert result["options"] == {CONF_CHANNELS: ["channel123"]}
@pytest.mark.parametrize("twitch_mock", [TwitchInvalidTokenMock()])
async def test_import_invalid_token(
hass: HomeAssistant,
hass_client_no_auth: ClientSessionGenerator,
current_request_with_host: None,
mock_setup_entry,
twitch: TwitchMock,
) -> None:
"""Test import flow."""
result = await hass.config_entries.flow.async_init(
DOMAIN,
context={
"source": SOURCE_IMPORT,
},
data={
"platform": "twitch",
CONF_CLIENT_ID: "1234",
CONF_CLIENT_SECRET: "abcd",
CONF_TOKEN: "efgh",
"channels": ["channel123"],
},
)
assert result["type"] is FlowResultType.ABORT
assert result["reason"] == "invalid_token"
issue_registry = ir.async_get(hass)
assert len(issue_registry.issues) == 1
async def test_import_already_imported(
hass: HomeAssistant,
hass_client_no_auth: ClientSessionGenerator,
current_request_with_host: None,
config_entry: MockConfigEntry,
mock_setup_entry,
twitch: TwitchMock,
) -> None:
"""Test import flow where the config is already imported."""
await setup_integration(hass, config_entry)
result = await hass.config_entries.flow.async_init(
DOMAIN,
context={
"source": SOURCE_IMPORT,
},
data={
"platform": "twitch",
CONF_CLIENT_ID: "1234",
CONF_CLIENT_SECRET: "abcd",
CONF_TOKEN: "efgh",
"channels": ["channel123"],
},
)
assert result["type"] is FlowResultType.ABORT
assert result["reason"] == "already_configured"
issue_registry = ir.async_get(hass)
assert len(issue_registry.issues) == 1

View File

@ -4,12 +4,7 @@ from datetime import datetime
import pytest
from homeassistant.components.sensor import DOMAIN as SENSOR_DOMAIN
from homeassistant.components.twitch.const import CONF_CHANNELS, DOMAIN
from homeassistant.const import CONF_CLIENT_ID, CONF_CLIENT_SECRET, CONF_TOKEN, Platform
from homeassistant.core import HomeAssistant
from homeassistant.helpers import issue_registry as ir
from homeassistant.setup import async_setup_component
from ...common import MockConfigEntry
from . import (
@ -23,58 +18,6 @@ from . import (
)
ENTITY_ID = "sensor.channel123"
CONFIG = {
"auth_implementation": "cred",
CONF_CLIENT_ID: "1234",
CONF_CLIENT_SECRET: "abcd",
}
LEGACY_CONFIG_WITHOUT_TOKEN = {
SENSOR_DOMAIN: {
"platform": "twitch",
CONF_CLIENT_ID: "1234",
CONF_CLIENT_SECRET: "abcd",
"channels": ["channel123"],
}
}
LEGACY_CONFIG = {
SENSOR_DOMAIN: {
"platform": "twitch",
CONF_CLIENT_ID: "1234",
CONF_CLIENT_SECRET: "abcd",
CONF_TOKEN: "efgh",
"channels": ["channel123"],
}
}
OPTIONS = {CONF_CHANNELS: ["channel123"]}
async def test_legacy_migration(
hass: HomeAssistant, twitch: TwitchMock, mock_setup_entry
) -> None:
"""Test importing legacy yaml."""
assert await async_setup_component(hass, Platform.SENSOR, LEGACY_CONFIG)
await hass.async_block_till_done()
entries = hass.config_entries.async_entries(DOMAIN)
assert len(entries) == 1
issue_registry = ir.async_get(hass)
assert len(issue_registry.issues) == 1
async def test_legacy_migration_without_token(
hass: HomeAssistant, twitch: TwitchMock
) -> None:
"""Test importing legacy yaml."""
assert await async_setup_component(
hass, Platform.SENSOR, LEGACY_CONFIG_WITHOUT_TOKEN
)
await hass.async_block_till_done()
entries = hass.config_entries.async_entries(DOMAIN)
assert len(entries) == 0
issue_registry = ir.async_get(hass)
assert len(issue_registry.issues) == 1
async def test_offline(