Add diagnostics to GitHub integration (#64385)
This commit is contained in:
parent
edaf75321e
commit
b46b32bafa
4 changed files with 137 additions and 2 deletions
45
homeassistant/components/github/diagnostics.py
Normal file
45
homeassistant/components/github/diagnostics.py
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
"""Diagnostics support for the GitHub integration."""
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
|
from aiogithubapi import GitHubAPI, GitHubException
|
||||||
|
|
||||||
|
from homeassistant.config_entries import ConfigEntry
|
||||||
|
from homeassistant.core import HomeAssistant
|
||||||
|
from homeassistant.helpers.aiohttp_client import (
|
||||||
|
SERVER_SOFTWARE,
|
||||||
|
async_get_clientsession,
|
||||||
|
)
|
||||||
|
|
||||||
|
from .const import CONF_ACCESS_TOKEN, DOMAIN
|
||||||
|
from .coordinator import DataUpdateCoordinators
|
||||||
|
|
||||||
|
|
||||||
|
async def async_get_config_entry_diagnostics(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
config_entry: ConfigEntry,
|
||||||
|
) -> dict[str, Any]:
|
||||||
|
"""Return diagnostics for a config entry."""
|
||||||
|
data = {"options": {**config_entry.options}}
|
||||||
|
client = GitHubAPI(
|
||||||
|
token=config_entry.data[CONF_ACCESS_TOKEN],
|
||||||
|
session=async_get_clientsession(hass),
|
||||||
|
**{"client_name": SERVER_SOFTWARE},
|
||||||
|
)
|
||||||
|
|
||||||
|
try:
|
||||||
|
rate_limit_response = await client.rate_limit()
|
||||||
|
except GitHubException as err:
|
||||||
|
data["rate_limit"] = {"error": str(err)}
|
||||||
|
else:
|
||||||
|
data["rate_limit"] = rate_limit_response.data.as_dict
|
||||||
|
|
||||||
|
repositories: dict[str, DataUpdateCoordinators] = hass.data[DOMAIN]
|
||||||
|
data["repositories"] = {}
|
||||||
|
|
||||||
|
for repository, coordinators in repositories.items():
|
||||||
|
info = coordinators["information"].data
|
||||||
|
data["repositories"][repository] = info.as_dict if info else None
|
||||||
|
|
||||||
|
return data
|
|
@ -10,10 +10,12 @@ from homeassistant.components.github.const import (
|
||||||
DEFAULT_REPOSITORIES,
|
DEFAULT_REPOSITORIES,
|
||||||
DOMAIN,
|
DOMAIN,
|
||||||
)
|
)
|
||||||
|
from homeassistant.core import HomeAssistant
|
||||||
|
|
||||||
from .common import MOCK_ACCESS_TOKEN
|
from .common import MOCK_ACCESS_TOKEN
|
||||||
|
|
||||||
from tests.common import MockConfigEntry
|
from tests.common import MockConfigEntry
|
||||||
|
from tests.test_util.aiohttp import AiohttpClientMocker
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
|
@ -32,3 +34,28 @@ def mock_setup_entry() -> Generator[None, None, None]:
|
||||||
"""Mock setting up a config entry."""
|
"""Mock setting up a config entry."""
|
||||||
with patch("homeassistant.components.github.async_setup_entry", return_value=True):
|
with patch("homeassistant.components.github.async_setup_entry", return_value=True):
|
||||||
yield
|
yield
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
async def setup_github_integration(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
mock_config_entry: MockConfigEntry,
|
||||||
|
aioclient_mock: AiohttpClientMocker,
|
||||||
|
) -> Generator[None, None, None]:
|
||||||
|
"""Mock setting up the integration."""
|
||||||
|
aioclient_mock.get(
|
||||||
|
"https://api.github.com/repos/home-assistant/core",
|
||||||
|
json={},
|
||||||
|
headers={"Content-Type": "application/json"},
|
||||||
|
)
|
||||||
|
for endpoint in ("issues", "pulls", "releases", "commits"):
|
||||||
|
aioclient_mock.get(
|
||||||
|
f"https://api.github.com/repos/home-assistant/core/{endpoint}",
|
||||||
|
json=[],
|
||||||
|
headers={"Content-Type": "application/json"},
|
||||||
|
)
|
||||||
|
mock_config_entry.options = {CONF_REPOSITORIES: ["home-assistant/core"]}
|
||||||
|
mock_config_entry.add_to_hass(hass)
|
||||||
|
|
||||||
|
await hass.config_entries.async_setup(mock_config_entry.entry_id)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
|
@ -90,7 +90,7 @@ async def test_flow_with_registration_failure(
|
||||||
"""Test flow with registration failure of the device."""
|
"""Test flow with registration failure of the device."""
|
||||||
aioclient_mock.post(
|
aioclient_mock.post(
|
||||||
"https://github.com/login/device/code",
|
"https://github.com/login/device/code",
|
||||||
side_effect=GitHubException("Registration failed"),
|
exc=GitHubException("Registration failed"),
|
||||||
)
|
)
|
||||||
result = await hass.config_entries.flow.async_init(
|
result = await hass.config_entries.flow.async_init(
|
||||||
DOMAIN,
|
DOMAIN,
|
||||||
|
@ -118,7 +118,7 @@ async def test_flow_with_activation_failure(
|
||||||
)
|
)
|
||||||
aioclient_mock.post(
|
aioclient_mock.post(
|
||||||
"https://github.com/login/oauth/access_token",
|
"https://github.com/login/oauth/access_token",
|
||||||
side_effect=GitHubException("Activation failed"),
|
exc=GitHubException("Activation failed"),
|
||||||
)
|
)
|
||||||
result = await hass.config_entries.flow.async_init(
|
result = await hass.config_entries.flow.async_init(
|
||||||
DOMAIN,
|
DOMAIN,
|
||||||
|
|
63
tests/components/github/test_diagnostics.py
Normal file
63
tests/components/github/test_diagnostics.py
Normal file
|
@ -0,0 +1,63 @@
|
||||||
|
"""Test GitHub diagnostics."""
|
||||||
|
from collections.abc import Generator
|
||||||
|
|
||||||
|
from aiogithubapi import GitHubException
|
||||||
|
from aiohttp import ClientSession
|
||||||
|
|
||||||
|
from homeassistant.core import HomeAssistant
|
||||||
|
|
||||||
|
from tests.common import MockConfigEntry
|
||||||
|
from tests.components.diagnostics import get_diagnostics_for_config_entry
|
||||||
|
from tests.test_util.aiohttp import AiohttpClientMocker
|
||||||
|
|
||||||
|
|
||||||
|
async def test_entry_diagnostics(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
hass_client: ClientSession,
|
||||||
|
mock_config_entry: MockConfigEntry,
|
||||||
|
aioclient_mock: AiohttpClientMocker,
|
||||||
|
setup_github_integration: Generator[None, None, None],
|
||||||
|
) -> None:
|
||||||
|
"""Test config entry diagnostics."""
|
||||||
|
aioclient_mock.get(
|
||||||
|
"https://api.github.com/rate_limit",
|
||||||
|
json={"resources": {"core": {"remaining": 100, "limit": 100}}},
|
||||||
|
headers={"Content-Type": "application/json"},
|
||||||
|
)
|
||||||
|
|
||||||
|
result = await get_diagnostics_for_config_entry(
|
||||||
|
hass,
|
||||||
|
hass_client,
|
||||||
|
mock_config_entry,
|
||||||
|
)
|
||||||
|
|
||||||
|
assert result["options"]["repositories"] == ["home-assistant/core"]
|
||||||
|
assert result["rate_limit"] == {
|
||||||
|
"resources": {"core": {"remaining": 100, "limit": 100}}
|
||||||
|
}
|
||||||
|
assert result["repositories"]["home-assistant/core"] == {}
|
||||||
|
|
||||||
|
|
||||||
|
async def test_entry_diagnostics_exception(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
hass_client: ClientSession,
|
||||||
|
mock_config_entry: MockConfigEntry,
|
||||||
|
aioclient_mock: AiohttpClientMocker,
|
||||||
|
setup_github_integration: Generator[None, None, None],
|
||||||
|
) -> None:
|
||||||
|
"""Test config entry diagnostics with exception for ratelimit."""
|
||||||
|
aioclient_mock.get(
|
||||||
|
"https://api.github.com/rate_limit",
|
||||||
|
exc=GitHubException("error"),
|
||||||
|
)
|
||||||
|
|
||||||
|
result = await get_diagnostics_for_config_entry(
|
||||||
|
hass,
|
||||||
|
hass_client,
|
||||||
|
mock_config_entry,
|
||||||
|
)
|
||||||
|
|
||||||
|
assert (
|
||||||
|
result["rate_limit"]["error"]
|
||||||
|
== "Unexpected exception for 'https://api.github.com/rate_limit' with - error"
|
||||||
|
)
|
Loading…
Add table
Add a link
Reference in a new issue