hass-core/tests/components/twitch/test_config_flow.py

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

206 lines
6.4 KiB
Python
Raw Normal View History

"""Test config flow for Twitch."""
from unittest.mock import AsyncMock
import pytest
from twitchAPI.object.api import TwitchUser
from homeassistant.components.twitch.const import (
CONF_CHANNELS,
DOMAIN,
OAUTH2_AUTHORIZE,
)
2024-04-09 18:34:29 +02:00
from homeassistant.config_entries import SOURCE_REAUTH, SOURCE_USER
from homeassistant.core import HomeAssistant
from homeassistant.data_entry_flow import FlowResult, FlowResultType
2024-04-09 18:34:29 +02:00
from homeassistant.helpers import config_entry_oauth2_flow
from . import get_generator, setup_integration
from .conftest import CLIENT_ID, TITLE
from tests.common import MockConfigEntry
from tests.typing import ClientSessionGenerator
async def _do_get_token(
hass: HomeAssistant,
result: FlowResult,
hass_client_no_auth: ClientSessionGenerator,
scopes: list[str],
) -> None:
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"{OAUTH2_AUTHORIZE}?response_type=code&client_id={CLIENT_ID}"
"&redirect_uri=https://example.com/auth/external/callback"
f"&state={state}&scope={'+'.join(scopes)}"
)
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"
@pytest.mark.usefixtures("current_request_with_host")
async def test_full_flow(
hass: HomeAssistant,
hass_client_no_auth: ClientSessionGenerator,
mock_setup_entry,
twitch_mock: AsyncMock,
scopes: list[str],
) -> None:
"""Check full flow."""
result = await hass.config_entries.flow.async_init(
"twitch", context={"source": SOURCE_USER}
)
await _do_get_token(hass, result, hass_client_no_auth, scopes)
result = await hass.config_entries.flow.async_configure(result["flow_id"])
assert len(hass.config_entries.async_entries(DOMAIN)) == 1
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"] == "mock-access-token"
assert result["result"].data["token"]["refresh_token"] == "mock-refresh-token"
assert result["result"].unique_id == "123"
assert result["options"] == {CONF_CHANNELS: ["internetofthings", "homeassistant"]}
@pytest.mark.usefixtures("current_request_with_host")
async def test_already_configured(
hass: HomeAssistant,
hass_client_no_auth: ClientSessionGenerator,
config_entry: MockConfigEntry,
mock_setup_entry,
twitch_mock: AsyncMock,
scopes: list[str],
) -> None:
"""Check flow aborts when account already configured."""
await setup_integration(hass, config_entry)
result = await hass.config_entries.flow.async_init(
"twitch", context={"source": SOURCE_USER}
)
await _do_get_token(hass, result, hass_client_no_auth, scopes)
result = await hass.config_entries.flow.async_configure(result["flow_id"])
assert result["type"] is FlowResultType.ABORT
assert result["reason"] == "already_configured"
@pytest.mark.usefixtures("current_request_with_host")
async def test_reauth(
hass: HomeAssistant,
hass_client_no_auth: ClientSessionGenerator,
config_entry: MockConfigEntry,
mock_setup_entry,
twitch_mock: AsyncMock,
scopes: list[str],
) -> None:
"""Check reauth flow."""
await setup_integration(hass, config_entry)
result = await hass.config_entries.flow.async_init(
DOMAIN,
context={
"source": SOURCE_REAUTH,
"entry_id": config_entry.entry_id,
},
data=config_entry.data,
)
assert result["type"] is FlowResultType.FORM
assert result["step_id"] == "reauth_confirm"
result = await hass.config_entries.flow.async_configure(result["flow_id"], {})
await _do_get_token(hass, result, hass_client_no_auth, scopes)
result = await hass.config_entries.flow.async_configure(result["flow_id"])
assert result["type"] is FlowResultType.ABORT
assert result["reason"] == "reauth_successful"
@pytest.mark.usefixtures("current_request_with_host")
async def test_reauth_from_import(
hass: HomeAssistant,
hass_client_no_auth: ClientSessionGenerator,
mock_setup_entry,
twitch_mock: AsyncMock,
expires_at,
scopes: list[str],
) -> None:
"""Check reauth flow."""
config_entry = MockConfigEntry(
domain=DOMAIN,
title=TITLE,
unique_id="123",
data={
"auth_implementation": DOMAIN,
"token": {
"access_token": "mock-access-token",
"refresh_token": "mock-refresh-token",
"expires_at": expires_at,
"scope": " ".join(scopes),
},
"imported": True,
},
options={"channels": ["internetofthings"]},
)
await test_reauth(
hass,
hass_client_no_auth,
config_entry,
mock_setup_entry,
twitch_mock,
scopes,
)
entries = hass.config_entries.async_entries(DOMAIN)
entry = entries[0]
assert "imported" not in entry.data
assert entry.options == {CONF_CHANNELS: ["internetofthings", "homeassistant"]}
@pytest.mark.usefixtures("current_request_with_host")
async def test_reauth_wrong_account(
hass: HomeAssistant,
hass_client_no_auth: ClientSessionGenerator,
config_entry: MockConfigEntry,
mock_setup_entry,
twitch_mock: AsyncMock,
scopes: list[str],
) -> None:
"""Check reauth flow."""
await setup_integration(hass, config_entry)
twitch_mock.return_value.get_users = lambda *args, **kwargs: get_generator(
"get_users_2.json", TwitchUser
)
result = await hass.config_entries.flow.async_init(
DOMAIN,
context={
"source": SOURCE_REAUTH,
"entry_id": config_entry.entry_id,
},
data=config_entry.data,
)
assert result["type"] is FlowResultType.FORM
assert result["step_id"] == "reauth_confirm"
result = await hass.config_entries.flow.async_configure(result["flow_id"], {})
await _do_get_token(hass, result, hass_client_no_auth, scopes)
result = await hass.config_entries.flow.async_configure(result["flow_id"])
assert result["type"] is FlowResultType.ABORT
assert result["reason"] == "wrong_account"