mirror of
https://github.com/home-assistant/core.git
synced 2025-07-18 10:47:10 +00:00
Use GraphQL for GitHub integration (#66928)
This commit is contained in:
parent
4ca339c5b1
commit
9f57ce504b
@ -17,7 +17,7 @@ repos:
|
|||||||
hooks:
|
hooks:
|
||||||
- id: codespell
|
- id: codespell
|
||||||
args:
|
args:
|
||||||
- --ignore-words-list=hass,alot,datas,dof,dur,ether,farenheit,hist,iff,iif,ines,ist,lightsensor,mut,nd,pres,referer,rime,ser,serie,te,technik,ue,uint,visability,wan,wanna,withing,iam,incomfort,ba,haa
|
- --ignore-words-list=hass,alot,datas,dof,dur,ether,farenheit,hist,iff,iif,ines,ist,lightsensor,mut,nd,pres,referer,rime,ser,serie,te,technik,ue,uint,visability,wan,wanna,withing,iam,incomfort,ba,haa,pullrequests
|
||||||
- --skip="./.*,*.csv,*.json"
|
- --skip="./.*,*.csv,*.json"
|
||||||
- --quiet-level=2
|
- --quiet-level=2
|
||||||
exclude_types: [csv, json]
|
exclude_types: [csv, json]
|
||||||
|
@ -13,13 +13,7 @@ from homeassistant.helpers.aiohttp_client import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
from .const import CONF_REPOSITORIES, DOMAIN, LOGGER
|
from .const import CONF_REPOSITORIES, DOMAIN, LOGGER
|
||||||
from .coordinator import (
|
from .coordinator import GitHubDataUpdateCoordinator
|
||||||
DataUpdateCoordinators,
|
|
||||||
RepositoryCommitDataUpdateCoordinator,
|
|
||||||
RepositoryInformationDataUpdateCoordinator,
|
|
||||||
RepositoryIssueDataUpdateCoordinator,
|
|
||||||
RepositoryReleaseDataUpdateCoordinator,
|
|
||||||
)
|
|
||||||
|
|
||||||
PLATFORMS: list[Platform] = [Platform.SENSOR]
|
PLATFORMS: list[Platform] = [Platform.SENSOR]
|
||||||
|
|
||||||
@ -37,24 +31,15 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
|||||||
repositories: list[str] = entry.options[CONF_REPOSITORIES]
|
repositories: list[str] = entry.options[CONF_REPOSITORIES]
|
||||||
|
|
||||||
for repository in repositories:
|
for repository in repositories:
|
||||||
coordinators: DataUpdateCoordinators = {
|
coordinator = GitHubDataUpdateCoordinator(
|
||||||
"information": RepositoryInformationDataUpdateCoordinator(
|
hass=hass,
|
||||||
hass=hass, entry=entry, client=client, repository=repository
|
client=client,
|
||||||
),
|
repository=repository,
|
||||||
"release": RepositoryReleaseDataUpdateCoordinator(
|
)
|
||||||
hass=hass, entry=entry, client=client, repository=repository
|
|
||||||
),
|
|
||||||
"issue": RepositoryIssueDataUpdateCoordinator(
|
|
||||||
hass=hass, entry=entry, client=client, repository=repository
|
|
||||||
),
|
|
||||||
"commit": RepositoryCommitDataUpdateCoordinator(
|
|
||||||
hass=hass, entry=entry, client=client, repository=repository
|
|
||||||
),
|
|
||||||
}
|
|
||||||
|
|
||||||
await coordinators["information"].async_config_entry_first_refresh()
|
await coordinator.async_config_entry_first_refresh()
|
||||||
|
|
||||||
hass.data[DOMAIN][repository] = coordinators
|
hass.data[DOMAIN][repository] = coordinator
|
||||||
|
|
||||||
async_cleanup_device_registry(hass=hass, entry=entry)
|
async_cleanup_device_registry(hass=hass, entry=entry)
|
||||||
|
|
||||||
|
@ -3,9 +3,6 @@ from __future__ import annotations
|
|||||||
|
|
||||||
from datetime import timedelta
|
from datetime import timedelta
|
||||||
from logging import Logger, getLogger
|
from logging import Logger, getLogger
|
||||||
from typing import NamedTuple
|
|
||||||
|
|
||||||
from aiogithubapi import GitHubIssueModel
|
|
||||||
|
|
||||||
LOGGER: Logger = getLogger(__package__)
|
LOGGER: Logger = getLogger(__package__)
|
||||||
|
|
||||||
@ -18,12 +15,3 @@ DEFAULT_UPDATE_INTERVAL = timedelta(seconds=300)
|
|||||||
|
|
||||||
CONF_ACCESS_TOKEN = "access_token"
|
CONF_ACCESS_TOKEN = "access_token"
|
||||||
CONF_REPOSITORIES = "repositories"
|
CONF_REPOSITORIES = "repositories"
|
||||||
|
|
||||||
|
|
||||||
class IssuesPulls(NamedTuple):
|
|
||||||
"""Issues and pull requests."""
|
|
||||||
|
|
||||||
issues_count: int
|
|
||||||
issue_last: GitHubIssueModel | None
|
|
||||||
pulls_count: int
|
|
||||||
pull_last: GitHubIssueModel | None
|
|
||||||
|
@ -1,44 +1,92 @@
|
|||||||
"""Custom data update coordinators for the GitHub integration."""
|
"""Custom data update coordinator for the GitHub integration."""
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from typing import Literal, TypedDict
|
from typing import Any
|
||||||
|
|
||||||
from aiogithubapi import (
|
from aiogithubapi import (
|
||||||
GitHubAPI,
|
GitHubAPI,
|
||||||
GitHubCommitModel,
|
|
||||||
GitHubConnectionException,
|
GitHubConnectionException,
|
||||||
GitHubException,
|
GitHubException,
|
||||||
GitHubNotModifiedException,
|
|
||||||
GitHubRatelimitException,
|
GitHubRatelimitException,
|
||||||
GitHubReleaseModel,
|
|
||||||
GitHubRepositoryModel,
|
|
||||||
GitHubResponseModel,
|
GitHubResponseModel,
|
||||||
)
|
)
|
||||||
|
|
||||||
from homeassistant.config_entries import ConfigEntry
|
from homeassistant.core import HomeAssistant
|
||||||
from homeassistant.core import HomeAssistant, T
|
|
||||||
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
|
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
|
||||||
|
|
||||||
from .const import DEFAULT_UPDATE_INTERVAL, DOMAIN, LOGGER, IssuesPulls
|
from .const import DEFAULT_UPDATE_INTERVAL, DOMAIN, LOGGER
|
||||||
|
|
||||||
CoordinatorKeyType = Literal["information", "release", "issue", "commit"]
|
GRAPHQL_REPOSITORY_QUERY = """
|
||||||
|
query ($owner: String!, $repository: String!) {
|
||||||
|
rateLimit {
|
||||||
|
cost
|
||||||
|
remaining
|
||||||
|
}
|
||||||
|
repository(owner: $owner, name: $repository) {
|
||||||
|
default_branch_ref: defaultBranchRef {
|
||||||
|
commit: target {
|
||||||
|
... on Commit {
|
||||||
|
message: messageHeadline
|
||||||
|
url
|
||||||
|
sha: oid
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
stargazers_count: stargazerCount
|
||||||
|
forks_count: forkCount
|
||||||
|
full_name: nameWithOwner
|
||||||
|
id: databaseId
|
||||||
|
watchers(first: 1) {
|
||||||
|
total: totalCount
|
||||||
|
}
|
||||||
|
issue: issues(
|
||||||
|
first: 1
|
||||||
|
states: OPEN
|
||||||
|
orderBy: {field: CREATED_AT, direction: DESC}
|
||||||
|
) {
|
||||||
|
total: totalCount
|
||||||
|
issues: nodes {
|
||||||
|
title
|
||||||
|
url
|
||||||
|
number
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pull_request: pullRequests(
|
||||||
|
first: 1
|
||||||
|
states: OPEN
|
||||||
|
orderBy: {field: CREATED_AT, direction: DESC}
|
||||||
|
) {
|
||||||
|
total: totalCount
|
||||||
|
pull_requests: nodes {
|
||||||
|
title
|
||||||
|
url
|
||||||
|
number
|
||||||
|
}
|
||||||
|
}
|
||||||
|
release: latestRelease {
|
||||||
|
name
|
||||||
|
url
|
||||||
|
tag: tagName
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
class GitHubBaseDataUpdateCoordinator(DataUpdateCoordinator[T]):
|
class GitHubDataUpdateCoordinator(DataUpdateCoordinator[dict[str, Any]]):
|
||||||
"""Base class for GitHub data update coordinators."""
|
"""Data update coordinator for the GitHub integration."""
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
entry: ConfigEntry,
|
|
||||||
client: GitHubAPI,
|
client: GitHubAPI,
|
||||||
repository: str,
|
repository: str,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Initialize GitHub data update coordinator base class."""
|
"""Initialize GitHub data update coordinator base class."""
|
||||||
self.config_entry = entry
|
|
||||||
self.repository = repository
|
self.repository = repository
|
||||||
self._client = client
|
self._client = client
|
||||||
self._last_response: GitHubResponseModel[T] | None = None
|
self._last_response: GitHubResponseModel[dict[str, Any]] | None = None
|
||||||
|
self.data = {}
|
||||||
|
|
||||||
super().__init__(
|
super().__init__(
|
||||||
hass,
|
hass,
|
||||||
@ -47,30 +95,14 @@ class GitHubBaseDataUpdateCoordinator(DataUpdateCoordinator[T]):
|
|||||||
update_interval=DEFAULT_UPDATE_INTERVAL,
|
update_interval=DEFAULT_UPDATE_INTERVAL,
|
||||||
)
|
)
|
||||||
|
|
||||||
@property
|
async def _async_update_data(self) -> GitHubResponseModel[dict[str, Any]]:
|
||||||
def _etag(self) -> str:
|
"""Update data."""
|
||||||
"""Return the ETag of the last response."""
|
owner, repository = self.repository.split("/")
|
||||||
return self._last_response.etag if self._last_response is not None else None
|
|
||||||
|
|
||||||
async def fetch_data(self) -> GitHubResponseModel[T]:
|
|
||||||
"""Fetch data from GitHub API."""
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def _parse_response(response: GitHubResponseModel[T]) -> T:
|
|
||||||
"""Parse the response from GitHub API."""
|
|
||||||
return response.data
|
|
||||||
|
|
||||||
async def _async_update_data(self) -> T:
|
|
||||||
try:
|
try:
|
||||||
response = await self.fetch_data()
|
response = await self._client.graphql(
|
||||||
except GitHubNotModifiedException:
|
query=GRAPHQL_REPOSITORY_QUERY,
|
||||||
LOGGER.debug(
|
variables={"owner": owner, "repository": repository},
|
||||||
"Content for %s with %s not modified",
|
|
||||||
self.repository,
|
|
||||||
self.__class__.__name__,
|
|
||||||
)
|
)
|
||||||
# Return the last known data if the request result was not modified
|
|
||||||
return self.data
|
|
||||||
except (GitHubConnectionException, GitHubRatelimitException) as exception:
|
except (GitHubConnectionException, GitHubRatelimitException) as exception:
|
||||||
# These are expected and we dont log anything extra
|
# These are expected and we dont log anything extra
|
||||||
raise UpdateFailed(exception) from exception
|
raise UpdateFailed(exception) from exception
|
||||||
@ -80,133 +112,4 @@ class GitHubBaseDataUpdateCoordinator(DataUpdateCoordinator[T]):
|
|||||||
raise UpdateFailed(exception) from exception
|
raise UpdateFailed(exception) from exception
|
||||||
else:
|
else:
|
||||||
self._last_response = response
|
self._last_response = response
|
||||||
return self._parse_response(response)
|
return response.data["data"]["repository"]
|
||||||
|
|
||||||
|
|
||||||
class RepositoryInformationDataUpdateCoordinator(
|
|
||||||
GitHubBaseDataUpdateCoordinator[GitHubRepositoryModel]
|
|
||||||
):
|
|
||||||
"""Data update coordinator for repository information."""
|
|
||||||
|
|
||||||
async def fetch_data(self) -> GitHubResponseModel[GitHubRepositoryModel]:
|
|
||||||
"""Get the latest data from GitHub."""
|
|
||||||
return await self._client.repos.get(self.repository, **{"etag": self._etag})
|
|
||||||
|
|
||||||
|
|
||||||
class RepositoryReleaseDataUpdateCoordinator(
|
|
||||||
GitHubBaseDataUpdateCoordinator[GitHubReleaseModel]
|
|
||||||
):
|
|
||||||
"""Data update coordinator for repository release."""
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def _parse_response(
|
|
||||||
response: GitHubResponseModel[GitHubReleaseModel | None],
|
|
||||||
) -> GitHubReleaseModel | None:
|
|
||||||
"""Parse the response from GitHub API."""
|
|
||||||
if not response.data:
|
|
||||||
return None
|
|
||||||
|
|
||||||
for release in response.data:
|
|
||||||
if not release.prerelease and not release.draft:
|
|
||||||
return release
|
|
||||||
|
|
||||||
# Fall back to the latest release if no non-prerelease release is found
|
|
||||||
return response.data[0]
|
|
||||||
|
|
||||||
async def fetch_data(self) -> GitHubReleaseModel | None:
|
|
||||||
"""Get the latest data from GitHub."""
|
|
||||||
return await self._client.repos.releases.list(
|
|
||||||
self.repository, **{"etag": self._etag}
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class RepositoryIssueDataUpdateCoordinator(
|
|
||||||
GitHubBaseDataUpdateCoordinator[IssuesPulls]
|
|
||||||
):
|
|
||||||
"""Data update coordinator for repository issues."""
|
|
||||||
|
|
||||||
_issue_etag: str | None = None
|
|
||||||
_pull_etag: str | None = None
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def _parse_response(response: IssuesPulls) -> IssuesPulls:
|
|
||||||
"""Parse the response from GitHub API."""
|
|
||||||
return response
|
|
||||||
|
|
||||||
async def fetch_data(self) -> IssuesPulls:
|
|
||||||
"""Get the latest data from GitHub."""
|
|
||||||
pulls_count = 0
|
|
||||||
pull_last = None
|
|
||||||
issues_count = 0
|
|
||||||
issue_last = None
|
|
||||||
try:
|
|
||||||
pull_response = await self._client.repos.pulls.list(
|
|
||||||
self.repository,
|
|
||||||
**{"params": {"per_page": 1}, "etag": self._pull_etag},
|
|
||||||
)
|
|
||||||
except GitHubNotModifiedException:
|
|
||||||
# Return the last known data if the request result was not modified
|
|
||||||
pulls_count = self.data.pulls_count
|
|
||||||
pull_last = self.data.pull_last
|
|
||||||
else:
|
|
||||||
self._pull_etag = pull_response.etag
|
|
||||||
pulls_count = pull_response.last_page_number or len(pull_response.data)
|
|
||||||
pull_last = pull_response.data[0] if pull_response.data else None
|
|
||||||
|
|
||||||
try:
|
|
||||||
issue_response = await self._client.repos.issues.list(
|
|
||||||
self.repository,
|
|
||||||
**{"params": {"per_page": 1}, "etag": self._issue_etag},
|
|
||||||
)
|
|
||||||
except GitHubNotModifiedException:
|
|
||||||
# Return the last known data if the request result was not modified
|
|
||||||
issues_count = self.data.issues_count
|
|
||||||
issue_last = self.data.issue_last
|
|
||||||
else:
|
|
||||||
self._issue_etag = issue_response.etag
|
|
||||||
issues_count = (
|
|
||||||
issue_response.last_page_number or len(issue_response.data)
|
|
||||||
) - pulls_count
|
|
||||||
issue_last = issue_response.data[0] if issue_response.data else None
|
|
||||||
|
|
||||||
if issue_last is not None and issue_last.pull_request:
|
|
||||||
issue_response = await self._client.repos.issues.list(self.repository)
|
|
||||||
for issue in issue_response.data:
|
|
||||||
if not issue.pull_request:
|
|
||||||
issue_last = issue
|
|
||||||
break
|
|
||||||
|
|
||||||
return IssuesPulls(
|
|
||||||
issues_count=issues_count,
|
|
||||||
issue_last=issue_last,
|
|
||||||
pulls_count=pulls_count,
|
|
||||||
pull_last=pull_last,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class RepositoryCommitDataUpdateCoordinator(
|
|
||||||
GitHubBaseDataUpdateCoordinator[GitHubCommitModel]
|
|
||||||
):
|
|
||||||
"""Data update coordinator for repository commit."""
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def _parse_response(
|
|
||||||
response: GitHubResponseModel[GitHubCommitModel | None],
|
|
||||||
) -> GitHubCommitModel | None:
|
|
||||||
"""Parse the response from GitHub API."""
|
|
||||||
return response.data[0] if response.data else None
|
|
||||||
|
|
||||||
async def fetch_data(self) -> GitHubCommitModel | None:
|
|
||||||
"""Get the latest data from GitHub."""
|
|
||||||
return await self._client.repos.list_commits(
|
|
||||||
self.repository, **{"params": {"per_page": 1}, "etag": self._etag}
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class DataUpdateCoordinators(TypedDict):
|
|
||||||
"""Custom data update coordinators for the GitHub integration."""
|
|
||||||
|
|
||||||
information: RepositoryInformationDataUpdateCoordinator
|
|
||||||
release: RepositoryReleaseDataUpdateCoordinator
|
|
||||||
issue: RepositoryIssueDataUpdateCoordinator
|
|
||||||
commit: RepositoryCommitDataUpdateCoordinator
|
|
||||||
|
@ -13,7 +13,7 @@ from homeassistant.helpers.aiohttp_client import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
from .const import CONF_ACCESS_TOKEN, DOMAIN
|
from .const import CONF_ACCESS_TOKEN, DOMAIN
|
||||||
from .coordinator import DataUpdateCoordinators
|
from .coordinator import GitHubDataUpdateCoordinator
|
||||||
|
|
||||||
|
|
||||||
async def async_get_config_entry_diagnostics(
|
async def async_get_config_entry_diagnostics(
|
||||||
@ -35,11 +35,10 @@ async def async_get_config_entry_diagnostics(
|
|||||||
else:
|
else:
|
||||||
data["rate_limit"] = rate_limit_response.data.as_dict
|
data["rate_limit"] = rate_limit_response.data.as_dict
|
||||||
|
|
||||||
repositories: dict[str, DataUpdateCoordinators] = hass.data[DOMAIN]
|
repositories: dict[str, GitHubDataUpdateCoordinator] = hass.data[DOMAIN]
|
||||||
data["repositories"] = {}
|
data["repositories"] = {}
|
||||||
|
|
||||||
for repository, coordinators in repositories.items():
|
for repository, coordinator in repositories.items():
|
||||||
info = coordinators["information"].data
|
data["repositories"][repository] = coordinator.data
|
||||||
data["repositories"][repository] = info.as_dict if info else None
|
|
||||||
|
|
||||||
return data
|
return data
|
||||||
|
@ -19,19 +19,14 @@ from homeassistant.helpers.typing import StateType
|
|||||||
from homeassistant.helpers.update_coordinator import CoordinatorEntity
|
from homeassistant.helpers.update_coordinator import CoordinatorEntity
|
||||||
|
|
||||||
from .const import DOMAIN
|
from .const import DOMAIN
|
||||||
from .coordinator import (
|
from .coordinator import GitHubDataUpdateCoordinator
|
||||||
CoordinatorKeyType,
|
|
||||||
DataUpdateCoordinators,
|
|
||||||
GitHubBaseDataUpdateCoordinator,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class BaseEntityDescriptionMixin:
|
class BaseEntityDescriptionMixin:
|
||||||
"""Mixin for required GitHub base description keys."""
|
"""Mixin for required GitHub base description keys."""
|
||||||
|
|
||||||
coordinator_key: CoordinatorKeyType
|
value_fn: Callable[[dict[str, Any]], StateType]
|
||||||
value_fn: Callable[[Any], StateType]
|
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
@ -40,8 +35,8 @@ class BaseEntityDescription(SensorEntityDescription):
|
|||||||
|
|
||||||
icon: str = "mdi:github"
|
icon: str = "mdi:github"
|
||||||
entity_registry_enabled_default: bool = False
|
entity_registry_enabled_default: bool = False
|
||||||
attr_fn: Callable[[Any], Mapping[str, Any] | None] = lambda data: None
|
attr_fn: Callable[[dict[str, Any]], Mapping[str, Any] | None] = lambda data: None
|
||||||
avabl_fn: Callable[[Any], bool] = lambda data: True
|
avabl_fn: Callable[[dict[str, Any]], bool] = lambda data: True
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
@ -57,8 +52,7 @@ SENSOR_DESCRIPTIONS: tuple[GitHubSensorEntityDescription, ...] = (
|
|||||||
native_unit_of_measurement="Stars",
|
native_unit_of_measurement="Stars",
|
||||||
entity_category=EntityCategory.DIAGNOSTIC,
|
entity_category=EntityCategory.DIAGNOSTIC,
|
||||||
state_class=SensorStateClass.MEASUREMENT,
|
state_class=SensorStateClass.MEASUREMENT,
|
||||||
value_fn=lambda data: data.stargazers_count,
|
value_fn=lambda data: data["stargazers_count"],
|
||||||
coordinator_key="information",
|
|
||||||
),
|
),
|
||||||
GitHubSensorEntityDescription(
|
GitHubSensorEntityDescription(
|
||||||
key="subscribers_count",
|
key="subscribers_count",
|
||||||
@ -67,9 +61,7 @@ SENSOR_DESCRIPTIONS: tuple[GitHubSensorEntityDescription, ...] = (
|
|||||||
native_unit_of_measurement="Watchers",
|
native_unit_of_measurement="Watchers",
|
||||||
entity_category=EntityCategory.DIAGNOSTIC,
|
entity_category=EntityCategory.DIAGNOSTIC,
|
||||||
state_class=SensorStateClass.MEASUREMENT,
|
state_class=SensorStateClass.MEASUREMENT,
|
||||||
# The API returns a watcher_count, but subscribers_count is more accurate
|
value_fn=lambda data: data["watchers"]["total"],
|
||||||
value_fn=lambda data: data.subscribers_count,
|
|
||||||
coordinator_key="information",
|
|
||||||
),
|
),
|
||||||
GitHubSensorEntityDescription(
|
GitHubSensorEntityDescription(
|
||||||
key="forks_count",
|
key="forks_count",
|
||||||
@ -78,8 +70,7 @@ SENSOR_DESCRIPTIONS: tuple[GitHubSensorEntityDescription, ...] = (
|
|||||||
native_unit_of_measurement="Forks",
|
native_unit_of_measurement="Forks",
|
||||||
entity_category=EntityCategory.DIAGNOSTIC,
|
entity_category=EntityCategory.DIAGNOSTIC,
|
||||||
state_class=SensorStateClass.MEASUREMENT,
|
state_class=SensorStateClass.MEASUREMENT,
|
||||||
value_fn=lambda data: data.forks_count,
|
value_fn=lambda data: data["forks_count"],
|
||||||
coordinator_key="information",
|
|
||||||
),
|
),
|
||||||
GitHubSensorEntityDescription(
|
GitHubSensorEntityDescription(
|
||||||
key="issues_count",
|
key="issues_count",
|
||||||
@ -87,8 +78,7 @@ SENSOR_DESCRIPTIONS: tuple[GitHubSensorEntityDescription, ...] = (
|
|||||||
native_unit_of_measurement="Issues",
|
native_unit_of_measurement="Issues",
|
||||||
entity_category=EntityCategory.DIAGNOSTIC,
|
entity_category=EntityCategory.DIAGNOSTIC,
|
||||||
state_class=SensorStateClass.MEASUREMENT,
|
state_class=SensorStateClass.MEASUREMENT,
|
||||||
value_fn=lambda data: data.issues_count,
|
value_fn=lambda data: data["issue"]["total"],
|
||||||
coordinator_key="issue",
|
|
||||||
),
|
),
|
||||||
GitHubSensorEntityDescription(
|
GitHubSensorEntityDescription(
|
||||||
key="pulls_count",
|
key="pulls_count",
|
||||||
@ -96,50 +86,46 @@ SENSOR_DESCRIPTIONS: tuple[GitHubSensorEntityDescription, ...] = (
|
|||||||
native_unit_of_measurement="Pull Requests",
|
native_unit_of_measurement="Pull Requests",
|
||||||
entity_category=EntityCategory.DIAGNOSTIC,
|
entity_category=EntityCategory.DIAGNOSTIC,
|
||||||
state_class=SensorStateClass.MEASUREMENT,
|
state_class=SensorStateClass.MEASUREMENT,
|
||||||
value_fn=lambda data: data.pulls_count,
|
value_fn=lambda data: data["pull_request"]["total"],
|
||||||
coordinator_key="issue",
|
|
||||||
),
|
),
|
||||||
GitHubSensorEntityDescription(
|
GitHubSensorEntityDescription(
|
||||||
coordinator_key="commit",
|
|
||||||
key="latest_commit",
|
key="latest_commit",
|
||||||
name="Latest Commit",
|
name="Latest Commit",
|
||||||
value_fn=lambda data: data.commit.message.splitlines()[0][:255],
|
value_fn=lambda data: data["default_branch_ref"]["commit"]["message"][:255],
|
||||||
attr_fn=lambda data: {
|
attr_fn=lambda data: {
|
||||||
"sha": data.sha,
|
"sha": data["default_branch_ref"]["commit"]["sha"],
|
||||||
"url": data.html_url,
|
"url": data["default_branch_ref"]["commit"]["url"],
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
GitHubSensorEntityDescription(
|
GitHubSensorEntityDescription(
|
||||||
coordinator_key="release",
|
|
||||||
key="latest_release",
|
key="latest_release",
|
||||||
name="Latest Release",
|
name="Latest Release",
|
||||||
entity_registry_enabled_default=True,
|
entity_registry_enabled_default=True,
|
||||||
value_fn=lambda data: data.name[:255],
|
avabl_fn=lambda data: data["release"] is not None,
|
||||||
|
value_fn=lambda data: data["release"]["name"][:255],
|
||||||
attr_fn=lambda data: {
|
attr_fn=lambda data: {
|
||||||
"url": data.html_url,
|
"url": data["release"]["url"],
|
||||||
"tag": data.tag_name,
|
"tag": data["release"]["tag"],
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
GitHubSensorEntityDescription(
|
GitHubSensorEntityDescription(
|
||||||
coordinator_key="issue",
|
|
||||||
key="latest_issue",
|
key="latest_issue",
|
||||||
name="Latest Issue",
|
name="Latest Issue",
|
||||||
value_fn=lambda data: data.issue_last.title[:255],
|
avabl_fn=lambda data: data["issue"]["issues"],
|
||||||
avabl_fn=lambda data: data.issue_last is not None,
|
value_fn=lambda data: data["issue"]["issues"][0]["title"][:255],
|
||||||
attr_fn=lambda data: {
|
attr_fn=lambda data: {
|
||||||
"url": data.issue_last.html_url,
|
"url": data["issue"]["issues"][0]["url"],
|
||||||
"number": data.issue_last.number,
|
"number": data["issue"]["issues"][0]["number"],
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
GitHubSensorEntityDescription(
|
GitHubSensorEntityDescription(
|
||||||
coordinator_key="issue",
|
|
||||||
key="latest_pull_request",
|
key="latest_pull_request",
|
||||||
name="Latest Pull Request",
|
name="Latest Pull Request",
|
||||||
value_fn=lambda data: data.pull_last.title[:255],
|
avabl_fn=lambda data: data["pull_request"]["pull_requests"],
|
||||||
avabl_fn=lambda data: data.pull_last is not None,
|
value_fn=lambda data: data["pull_request"]["pull_requests"][0]["title"][:255],
|
||||||
attr_fn=lambda data: {
|
attr_fn=lambda data: {
|
||||||
"url": data.pull_last.html_url,
|
"url": data["pull_request"]["pull_requests"][0]["url"],
|
||||||
"number": data.pull_last.number,
|
"number": data["pull_request"]["pull_requests"][0]["number"],
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
@ -151,43 +137,41 @@ async def async_setup_entry(
|
|||||||
async_add_entities: AddEntitiesCallback,
|
async_add_entities: AddEntitiesCallback,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Set up GitHub sensor based on a config entry."""
|
"""Set up GitHub sensor based on a config entry."""
|
||||||
repositories: dict[str, DataUpdateCoordinators] = hass.data[DOMAIN]
|
repositories: dict[str, GitHubDataUpdateCoordinator] = hass.data[DOMAIN]
|
||||||
async_add_entities(
|
async_add_entities(
|
||||||
(
|
(
|
||||||
GitHubSensorEntity(coordinators, description)
|
GitHubSensorEntity(coordinator, description)
|
||||||
for description in SENSOR_DESCRIPTIONS
|
for description in SENSOR_DESCRIPTIONS
|
||||||
for coordinators in repositories.values()
|
for coordinator in repositories.values()
|
||||||
),
|
),
|
||||||
update_before_add=True,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class GitHubSensorEntity(CoordinatorEntity, SensorEntity):
|
class GitHubSensorEntity(CoordinatorEntity[dict[str, Any]], SensorEntity):
|
||||||
"""Defines a GitHub sensor entity."""
|
"""Defines a GitHub sensor entity."""
|
||||||
|
|
||||||
_attr_attribution = "Data provided by the GitHub API"
|
_attr_attribution = "Data provided by the GitHub API"
|
||||||
|
|
||||||
coordinator: GitHubBaseDataUpdateCoordinator
|
coordinator: GitHubDataUpdateCoordinator
|
||||||
entity_description: GitHubSensorEntityDescription
|
entity_description: GitHubSensorEntityDescription
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
coordinators: DataUpdateCoordinators,
|
coordinator: GitHubDataUpdateCoordinator,
|
||||||
entity_description: GitHubSensorEntityDescription,
|
entity_description: GitHubSensorEntityDescription,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Initialize the sensor."""
|
"""Initialize the sensor."""
|
||||||
coordinator = coordinators[entity_description.coordinator_key]
|
|
||||||
_information = coordinators["information"].data
|
|
||||||
|
|
||||||
super().__init__(coordinator=coordinator)
|
super().__init__(coordinator=coordinator)
|
||||||
|
|
||||||
self.entity_description = entity_description
|
self.entity_description = entity_description
|
||||||
self._attr_name = f"{_information.full_name} {entity_description.name}"
|
self._attr_name = (
|
||||||
self._attr_unique_id = f"{_information.id}_{entity_description.key}"
|
f"{coordinator.data.get('full_name')} {entity_description.name}"
|
||||||
|
)
|
||||||
|
self._attr_unique_id = f"{coordinator.data.get('id')}_{entity_description.key}"
|
||||||
|
|
||||||
self._attr_device_info = DeviceInfo(
|
self._attr_device_info = DeviceInfo(
|
||||||
identifiers={(DOMAIN, coordinator.repository)},
|
identifiers={(DOMAIN, coordinator.repository)},
|
||||||
name=_information.full_name,
|
name=coordinator.data.get("full_name"),
|
||||||
manufacturer="GitHub",
|
manufacturer="GitHub",
|
||||||
configuration_url=f"https://github.com/{coordinator.repository}",
|
configuration_url=f"https://github.com/{coordinator.repository}",
|
||||||
entry_type=DeviceEntryType.SERVICE,
|
entry_type=DeviceEntryType.SERVICE,
|
||||||
|
@ -31,12 +31,11 @@ async def setup_github_integration(
|
|||||||
},
|
},
|
||||||
headers=headers,
|
headers=headers,
|
||||||
)
|
)
|
||||||
for endpoint in ("issues", "pulls", "releases", "commits"):
|
aioclient_mock.post(
|
||||||
aioclient_mock.get(
|
"https://api.github.com/graphql",
|
||||||
f"https://api.github.com/repos/{repository}/{endpoint}",
|
json=json.loads(load_fixture("graphql.json", DOMAIN)),
|
||||||
json=json.loads(load_fixture(f"{endpoint}.json", DOMAIN)),
|
headers=headers,
|
||||||
headers=headers,
|
)
|
||||||
)
|
|
||||||
mock_config_entry.add_to_hass(hass)
|
mock_config_entry.add_to_hass(hass)
|
||||||
|
|
||||||
setup_result = await hass.config_entries.async_setup(mock_config_entry.entry_id)
|
setup_result = await hass.config_entries.async_setup(mock_config_entry.entry_id)
|
||||||
|
@ -1,80 +0,0 @@
|
|||||||
[
|
|
||||||
{
|
|
||||||
"url": "https://api.github.com/repos/octocat/Hello-World/commits/6dcb09b5b57875f334f61aebed695e2e4193db5e",
|
|
||||||
"sha": "6dcb09b5b57875f334f61aebed695e2e4193db5e",
|
|
||||||
"node_id": "MDY6Q29tbWl0NmRjYjA5YjViNTc4NzVmMzM0ZjYxYWViZWQ2OTVlMmU0MTkzZGI1ZQ==",
|
|
||||||
"html_url": "https://github.com/octocat/Hello-World/commit/6dcb09b5b57875f334f61aebed695e2e4193db5e",
|
|
||||||
"comments_url": "https://api.github.com/repos/octocat/Hello-World/commits/6dcb09b5b57875f334f61aebed695e2e4193db5e/comments",
|
|
||||||
"commit": {
|
|
||||||
"url": "https://api.github.com/repos/octocat/Hello-World/git/commits/6dcb09b5b57875f334f61aebed695e2e4193db5e",
|
|
||||||
"author": {
|
|
||||||
"name": "Monalisa Octocat",
|
|
||||||
"email": "support@github.com",
|
|
||||||
"date": "2011-04-14T16:00:49Z"
|
|
||||||
},
|
|
||||||
"committer": {
|
|
||||||
"name": "Monalisa Octocat",
|
|
||||||
"email": "support@github.com",
|
|
||||||
"date": "2011-04-14T16:00:49Z"
|
|
||||||
},
|
|
||||||
"message": "Fix all the bugs",
|
|
||||||
"tree": {
|
|
||||||
"url": "https://api.github.com/repos/octocat/Hello-World/tree/6dcb09b5b57875f334f61aebed695e2e4193db5e",
|
|
||||||
"sha": "6dcb09b5b57875f334f61aebed695e2e4193db5e"
|
|
||||||
},
|
|
||||||
"comment_count": 0,
|
|
||||||
"verification": {
|
|
||||||
"verified": false,
|
|
||||||
"reason": "unsigned",
|
|
||||||
"signature": null,
|
|
||||||
"payload": null
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"author": {
|
|
||||||
"login": "octocat",
|
|
||||||
"id": 1,
|
|
||||||
"node_id": "MDQ6VXNlcjE=",
|
|
||||||
"avatar_url": "https://github.com/images/error/octocat_happy.gif",
|
|
||||||
"gravatar_id": "",
|
|
||||||
"url": "https://api.github.com/users/octocat",
|
|
||||||
"html_url": "https://github.com/octocat",
|
|
||||||
"followers_url": "https://api.github.com/users/octocat/followers",
|
|
||||||
"following_url": "https://api.github.com/users/octocat/following{/other_user}",
|
|
||||||
"gists_url": "https://api.github.com/users/octocat/gists{/gist_id}",
|
|
||||||
"starred_url": "https://api.github.com/users/octocat/starred{/owner}{/repo}",
|
|
||||||
"subscriptions_url": "https://api.github.com/users/octocat/subscriptions",
|
|
||||||
"organizations_url": "https://api.github.com/users/octocat/orgs",
|
|
||||||
"repos_url": "https://api.github.com/users/octocat/repos",
|
|
||||||
"events_url": "https://api.github.com/users/octocat/events{/privacy}",
|
|
||||||
"received_events_url": "https://api.github.com/users/octocat/received_events",
|
|
||||||
"type": "User",
|
|
||||||
"site_admin": false
|
|
||||||
},
|
|
||||||
"committer": {
|
|
||||||
"login": "octocat",
|
|
||||||
"id": 1,
|
|
||||||
"node_id": "MDQ6VXNlcjE=",
|
|
||||||
"avatar_url": "https://github.com/images/error/octocat_happy.gif",
|
|
||||||
"gravatar_id": "",
|
|
||||||
"url": "https://api.github.com/users/octocat",
|
|
||||||
"html_url": "https://github.com/octocat",
|
|
||||||
"followers_url": "https://api.github.com/users/octocat/followers",
|
|
||||||
"following_url": "https://api.github.com/users/octocat/following{/other_user}",
|
|
||||||
"gists_url": "https://api.github.com/users/octocat/gists{/gist_id}",
|
|
||||||
"starred_url": "https://api.github.com/users/octocat/starred{/owner}{/repo}",
|
|
||||||
"subscriptions_url": "https://api.github.com/users/octocat/subscriptions",
|
|
||||||
"organizations_url": "https://api.github.com/users/octocat/orgs",
|
|
||||||
"repos_url": "https://api.github.com/users/octocat/repos",
|
|
||||||
"events_url": "https://api.github.com/users/octocat/events{/privacy}",
|
|
||||||
"received_events_url": "https://api.github.com/users/octocat/received_events",
|
|
||||||
"type": "User",
|
|
||||||
"site_admin": false
|
|
||||||
},
|
|
||||||
"parents": [
|
|
||||||
{
|
|
||||||
"url": "https://api.github.com/repos/octocat/Hello-World/commits/6dcb09b5b57875f334f61aebed695e2e4193db5e",
|
|
||||||
"sha": "6dcb09b5b57875f334f61aebed695e2e4193db5e"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
49
tests/components/github/fixtures/graphql.json
Normal file
49
tests/components/github/fixtures/graphql.json
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
{
|
||||||
|
"data": {
|
||||||
|
"rateLimit": {
|
||||||
|
"cost": 1,
|
||||||
|
"remaining": 4999
|
||||||
|
},
|
||||||
|
"repository": {
|
||||||
|
"default_branch_ref": {
|
||||||
|
"commit": {
|
||||||
|
"message": "Fix all the bugs",
|
||||||
|
"url": "https://github.com/octocat/Hello-World/commit/6dcb09b5b57875f334f61aebed695e2e4193db5e",
|
||||||
|
"sha": "6dcb09b5b57875f334f61aebed695e2e4193db5e"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"stargazers_count": 9,
|
||||||
|
"forks_count": 9,
|
||||||
|
"full_name": "octocat/Hello-World",
|
||||||
|
"id": 1296269,
|
||||||
|
"watchers": {
|
||||||
|
"total": 9
|
||||||
|
},
|
||||||
|
"issue": {
|
||||||
|
"total": 1,
|
||||||
|
"issues": [
|
||||||
|
{
|
||||||
|
"title": "Found a bug",
|
||||||
|
"url": "https://github.com/octocat/Hello-World/issues/1347",
|
||||||
|
"number": 1347
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"pull_request": {
|
||||||
|
"total": 1,
|
||||||
|
"pull_requests": [
|
||||||
|
{
|
||||||
|
"title": "Amazing new feature",
|
||||||
|
"url": "https://github.com/octocat/Hello-World/pull/1347",
|
||||||
|
"number": 1347
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"release": {
|
||||||
|
"name": "v1.0.0",
|
||||||
|
"url": "https://github.com/octocat/Hello-World/releases/v1.0.0",
|
||||||
|
"tag": "v1.0.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,159 +0,0 @@
|
|||||||
[
|
|
||||||
{
|
|
||||||
"id": 1,
|
|
||||||
"node_id": "MDU6SXNzdWUx",
|
|
||||||
"url": "https://api.github.com/repos/octocat/Hello-World/issues/1347",
|
|
||||||
"repository_url": "https://api.github.com/repos/octocat/Hello-World",
|
|
||||||
"labels_url": "https://api.github.com/repos/octocat/Hello-World/issues/1347/labels{/name}",
|
|
||||||
"comments_url": "https://api.github.com/repos/octocat/Hello-World/issues/1347/comments",
|
|
||||||
"events_url": "https://api.github.com/repos/octocat/Hello-World/issues/1347/events",
|
|
||||||
"html_url": "https://github.com/octocat/Hello-World/issues/1347",
|
|
||||||
"number": 1347,
|
|
||||||
"state": "open",
|
|
||||||
"title": "Found a bug",
|
|
||||||
"body": "I'm having a problem with this.",
|
|
||||||
"user": {
|
|
||||||
"login": "octocat",
|
|
||||||
"id": 1,
|
|
||||||
"node_id": "MDQ6VXNlcjE=",
|
|
||||||
"avatar_url": "https://github.com/images/error/octocat_happy.gif",
|
|
||||||
"gravatar_id": "",
|
|
||||||
"url": "https://api.github.com/users/octocat",
|
|
||||||
"html_url": "https://github.com/octocat",
|
|
||||||
"followers_url": "https://api.github.com/users/octocat/followers",
|
|
||||||
"following_url": "https://api.github.com/users/octocat/following{/other_user}",
|
|
||||||
"gists_url": "https://api.github.com/users/octocat/gists{/gist_id}",
|
|
||||||
"starred_url": "https://api.github.com/users/octocat/starred{/owner}{/repo}",
|
|
||||||
"subscriptions_url": "https://api.github.com/users/octocat/subscriptions",
|
|
||||||
"organizations_url": "https://api.github.com/users/octocat/orgs",
|
|
||||||
"repos_url": "https://api.github.com/users/octocat/repos",
|
|
||||||
"events_url": "https://api.github.com/users/octocat/events{/privacy}",
|
|
||||||
"received_events_url": "https://api.github.com/users/octocat/received_events",
|
|
||||||
"type": "User",
|
|
||||||
"site_admin": false
|
|
||||||
},
|
|
||||||
"labels": [
|
|
||||||
{
|
|
||||||
"id": 208045946,
|
|
||||||
"node_id": "MDU6TGFiZWwyMDgwNDU5NDY=",
|
|
||||||
"url": "https://api.github.com/repos/octocat/Hello-World/labels/bug",
|
|
||||||
"name": "bug",
|
|
||||||
"description": "Something isn't working",
|
|
||||||
"color": "f29513",
|
|
||||||
"default": true
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"assignee": {
|
|
||||||
"login": "octocat",
|
|
||||||
"id": 1,
|
|
||||||
"node_id": "MDQ6VXNlcjE=",
|
|
||||||
"avatar_url": "https://github.com/images/error/octocat_happy.gif",
|
|
||||||
"gravatar_id": "",
|
|
||||||
"url": "https://api.github.com/users/octocat",
|
|
||||||
"html_url": "https://github.com/octocat",
|
|
||||||
"followers_url": "https://api.github.com/users/octocat/followers",
|
|
||||||
"following_url": "https://api.github.com/users/octocat/following{/other_user}",
|
|
||||||
"gists_url": "https://api.github.com/users/octocat/gists{/gist_id}",
|
|
||||||
"starred_url": "https://api.github.com/users/octocat/starred{/owner}{/repo}",
|
|
||||||
"subscriptions_url": "https://api.github.com/users/octocat/subscriptions",
|
|
||||||
"organizations_url": "https://api.github.com/users/octocat/orgs",
|
|
||||||
"repos_url": "https://api.github.com/users/octocat/repos",
|
|
||||||
"events_url": "https://api.github.com/users/octocat/events{/privacy}",
|
|
||||||
"received_events_url": "https://api.github.com/users/octocat/received_events",
|
|
||||||
"type": "User",
|
|
||||||
"site_admin": false
|
|
||||||
},
|
|
||||||
"assignees": [
|
|
||||||
{
|
|
||||||
"login": "octocat",
|
|
||||||
"id": 1,
|
|
||||||
"node_id": "MDQ6VXNlcjE=",
|
|
||||||
"avatar_url": "https://github.com/images/error/octocat_happy.gif",
|
|
||||||
"gravatar_id": "",
|
|
||||||
"url": "https://api.github.com/users/octocat",
|
|
||||||
"html_url": "https://github.com/octocat",
|
|
||||||
"followers_url": "https://api.github.com/users/octocat/followers",
|
|
||||||
"following_url": "https://api.github.com/users/octocat/following{/other_user}",
|
|
||||||
"gists_url": "https://api.github.com/users/octocat/gists{/gist_id}",
|
|
||||||
"starred_url": "https://api.github.com/users/octocat/starred{/owner}{/repo}",
|
|
||||||
"subscriptions_url": "https://api.github.com/users/octocat/subscriptions",
|
|
||||||
"organizations_url": "https://api.github.com/users/octocat/orgs",
|
|
||||||
"repos_url": "https://api.github.com/users/octocat/repos",
|
|
||||||
"events_url": "https://api.github.com/users/octocat/events{/privacy}",
|
|
||||||
"received_events_url": "https://api.github.com/users/octocat/received_events",
|
|
||||||
"type": "User",
|
|
||||||
"site_admin": false
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"milestone": {
|
|
||||||
"url": "https://api.github.com/repos/octocat/Hello-World/milestones/1",
|
|
||||||
"html_url": "https://github.com/octocat/Hello-World/milestones/v1.0",
|
|
||||||
"labels_url": "https://api.github.com/repos/octocat/Hello-World/milestones/1/labels",
|
|
||||||
"id": 1002604,
|
|
||||||
"node_id": "MDk6TWlsZXN0b25lMTAwMjYwNA==",
|
|
||||||
"number": 1,
|
|
||||||
"state": "open",
|
|
||||||
"title": "v1.0",
|
|
||||||
"description": "Tracking milestone for version 1.0",
|
|
||||||
"creator": {
|
|
||||||
"login": "octocat",
|
|
||||||
"id": 1,
|
|
||||||
"node_id": "MDQ6VXNlcjE=",
|
|
||||||
"avatar_url": "https://github.com/images/error/octocat_happy.gif",
|
|
||||||
"gravatar_id": "",
|
|
||||||
"url": "https://api.github.com/users/octocat",
|
|
||||||
"html_url": "https://github.com/octocat",
|
|
||||||
"followers_url": "https://api.github.com/users/octocat/followers",
|
|
||||||
"following_url": "https://api.github.com/users/octocat/following{/other_user}",
|
|
||||||
"gists_url": "https://api.github.com/users/octocat/gists{/gist_id}",
|
|
||||||
"starred_url": "https://api.github.com/users/octocat/starred{/owner}{/repo}",
|
|
||||||
"subscriptions_url": "https://api.github.com/users/octocat/subscriptions",
|
|
||||||
"organizations_url": "https://api.github.com/users/octocat/orgs",
|
|
||||||
"repos_url": "https://api.github.com/users/octocat/repos",
|
|
||||||
"events_url": "https://api.github.com/users/octocat/events{/privacy}",
|
|
||||||
"received_events_url": "https://api.github.com/users/octocat/received_events",
|
|
||||||
"type": "User",
|
|
||||||
"site_admin": false
|
|
||||||
},
|
|
||||||
"open_issues": 4,
|
|
||||||
"closed_issues": 8,
|
|
||||||
"created_at": "2011-04-10T20:09:31Z",
|
|
||||||
"updated_at": "2014-03-03T18:58:10Z",
|
|
||||||
"closed_at": "2013-02-12T13:22:01Z",
|
|
||||||
"due_on": "2012-10-09T23:39:01Z"
|
|
||||||
},
|
|
||||||
"locked": true,
|
|
||||||
"active_lock_reason": "too heated",
|
|
||||||
"comments": 0,
|
|
||||||
"pull_request": {
|
|
||||||
"url": "https://api.github.com/repos/octocat/Hello-World/pulls/1347",
|
|
||||||
"html_url": "https://github.com/octocat/Hello-World/pull/1347",
|
|
||||||
"diff_url": "https://github.com/octocat/Hello-World/pull/1347.diff",
|
|
||||||
"patch_url": "https://github.com/octocat/Hello-World/pull/1347.patch"
|
|
||||||
},
|
|
||||||
"closed_at": null,
|
|
||||||
"created_at": "2011-04-22T13:33:48Z",
|
|
||||||
"updated_at": "2011-04-22T13:33:48Z",
|
|
||||||
"closed_by": {
|
|
||||||
"login": "octocat",
|
|
||||||
"id": 1,
|
|
||||||
"node_id": "MDQ6VXNlcjE=",
|
|
||||||
"avatar_url": "https://github.com/images/error/octocat_happy.gif",
|
|
||||||
"gravatar_id": "",
|
|
||||||
"url": "https://api.github.com/users/octocat",
|
|
||||||
"html_url": "https://github.com/octocat",
|
|
||||||
"followers_url": "https://api.github.com/users/octocat/followers",
|
|
||||||
"following_url": "https://api.github.com/users/octocat/following{/other_user}",
|
|
||||||
"gists_url": "https://api.github.com/users/octocat/gists{/gist_id}",
|
|
||||||
"starred_url": "https://api.github.com/users/octocat/starred{/owner}{/repo}",
|
|
||||||
"subscriptions_url": "https://api.github.com/users/octocat/subscriptions",
|
|
||||||
"organizations_url": "https://api.github.com/users/octocat/orgs",
|
|
||||||
"repos_url": "https://api.github.com/users/octocat/repos",
|
|
||||||
"events_url": "https://api.github.com/users/octocat/events{/privacy}",
|
|
||||||
"received_events_url": "https://api.github.com/users/octocat/received_events",
|
|
||||||
"type": "User",
|
|
||||||
"site_admin": false
|
|
||||||
},
|
|
||||||
"author_association": "COLLABORATOR"
|
|
||||||
}
|
|
||||||
]
|
|
@ -1,520 +0,0 @@
|
|||||||
[
|
|
||||||
{
|
|
||||||
"url": "https://api.github.com/repos/octocat/Hello-World/pulls/1347",
|
|
||||||
"id": 1,
|
|
||||||
"node_id": "MDExOlB1bGxSZXF1ZXN0MQ==",
|
|
||||||
"html_url": "https://github.com/octocat/Hello-World/pull/1347",
|
|
||||||
"diff_url": "https://github.com/octocat/Hello-World/pull/1347.diff",
|
|
||||||
"patch_url": "https://github.com/octocat/Hello-World/pull/1347.patch",
|
|
||||||
"issue_url": "https://api.github.com/repos/octocat/Hello-World/issues/1347",
|
|
||||||
"commits_url": "https://api.github.com/repos/octocat/Hello-World/pulls/1347/commits",
|
|
||||||
"review_comments_url": "https://api.github.com/repos/octocat/Hello-World/pulls/1347/comments",
|
|
||||||
"review_comment_url": "https://api.github.com/repos/octocat/Hello-World/pulls/comments{/number}",
|
|
||||||
"comments_url": "https://api.github.com/repos/octocat/Hello-World/issues/1347/comments",
|
|
||||||
"statuses_url": "https://api.github.com/repos/octocat/Hello-World/statuses/6dcb09b5b57875f334f61aebed695e2e4193db5e",
|
|
||||||
"number": 1347,
|
|
||||||
"state": "open",
|
|
||||||
"locked": true,
|
|
||||||
"title": "Amazing new feature",
|
|
||||||
"user": {
|
|
||||||
"login": "octocat",
|
|
||||||
"id": 1,
|
|
||||||
"node_id": "MDQ6VXNlcjE=",
|
|
||||||
"avatar_url": "https://github.com/images/error/octocat_happy.gif",
|
|
||||||
"gravatar_id": "",
|
|
||||||
"url": "https://api.github.com/users/octocat",
|
|
||||||
"html_url": "https://github.com/octocat",
|
|
||||||
"followers_url": "https://api.github.com/users/octocat/followers",
|
|
||||||
"following_url": "https://api.github.com/users/octocat/following{/other_user}",
|
|
||||||
"gists_url": "https://api.github.com/users/octocat/gists{/gist_id}",
|
|
||||||
"starred_url": "https://api.github.com/users/octocat/starred{/owner}{/repo}",
|
|
||||||
"subscriptions_url": "https://api.github.com/users/octocat/subscriptions",
|
|
||||||
"organizations_url": "https://api.github.com/users/octocat/orgs",
|
|
||||||
"repos_url": "https://api.github.com/users/octocat/repos",
|
|
||||||
"events_url": "https://api.github.com/users/octocat/events{/privacy}",
|
|
||||||
"received_events_url": "https://api.github.com/users/octocat/received_events",
|
|
||||||
"type": "User",
|
|
||||||
"site_admin": false
|
|
||||||
},
|
|
||||||
"body": "Please pull these awesome changes in!",
|
|
||||||
"labels": [
|
|
||||||
{
|
|
||||||
"id": 208045946,
|
|
||||||
"node_id": "MDU6TGFiZWwyMDgwNDU5NDY=",
|
|
||||||
"url": "https://api.github.com/repos/octocat/Hello-World/labels/bug",
|
|
||||||
"name": "bug",
|
|
||||||
"description": "Something isn't working",
|
|
||||||
"color": "f29513",
|
|
||||||
"default": true
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"milestone": {
|
|
||||||
"url": "https://api.github.com/repos/octocat/Hello-World/milestones/1",
|
|
||||||
"html_url": "https://github.com/octocat/Hello-World/milestones/v1.0",
|
|
||||||
"labels_url": "https://api.github.com/repos/octocat/Hello-World/milestones/1/labels",
|
|
||||||
"id": 1002604,
|
|
||||||
"node_id": "MDk6TWlsZXN0b25lMTAwMjYwNA==",
|
|
||||||
"number": 1,
|
|
||||||
"state": "open",
|
|
||||||
"title": "v1.0",
|
|
||||||
"description": "Tracking milestone for version 1.0",
|
|
||||||
"creator": {
|
|
||||||
"login": "octocat",
|
|
||||||
"id": 1,
|
|
||||||
"node_id": "MDQ6VXNlcjE=",
|
|
||||||
"avatar_url": "https://github.com/images/error/octocat_happy.gif",
|
|
||||||
"gravatar_id": "",
|
|
||||||
"url": "https://api.github.com/users/octocat",
|
|
||||||
"html_url": "https://github.com/octocat",
|
|
||||||
"followers_url": "https://api.github.com/users/octocat/followers",
|
|
||||||
"following_url": "https://api.github.com/users/octocat/following{/other_user}",
|
|
||||||
"gists_url": "https://api.github.com/users/octocat/gists{/gist_id}",
|
|
||||||
"starred_url": "https://api.github.com/users/octocat/starred{/owner}{/repo}",
|
|
||||||
"subscriptions_url": "https://api.github.com/users/octocat/subscriptions",
|
|
||||||
"organizations_url": "https://api.github.com/users/octocat/orgs",
|
|
||||||
"repos_url": "https://api.github.com/users/octocat/repos",
|
|
||||||
"events_url": "https://api.github.com/users/octocat/events{/privacy}",
|
|
||||||
"received_events_url": "https://api.github.com/users/octocat/received_events",
|
|
||||||
"type": "User",
|
|
||||||
"site_admin": false
|
|
||||||
},
|
|
||||||
"open_issues": 4,
|
|
||||||
"closed_issues": 8,
|
|
||||||
"created_at": "2011-04-10T20:09:31Z",
|
|
||||||
"updated_at": "2014-03-03T18:58:10Z",
|
|
||||||
"closed_at": "2013-02-12T13:22:01Z",
|
|
||||||
"due_on": "2012-10-09T23:39:01Z"
|
|
||||||
},
|
|
||||||
"active_lock_reason": "too heated",
|
|
||||||
"created_at": "2011-01-26T19:01:12Z",
|
|
||||||
"updated_at": "2011-01-26T19:01:12Z",
|
|
||||||
"closed_at": "2011-01-26T19:01:12Z",
|
|
||||||
"merged_at": "2011-01-26T19:01:12Z",
|
|
||||||
"merge_commit_sha": "e5bd3914e2e596debea16f433f57875b5b90bcd6",
|
|
||||||
"assignee": {
|
|
||||||
"login": "octocat",
|
|
||||||
"id": 1,
|
|
||||||
"node_id": "MDQ6VXNlcjE=",
|
|
||||||
"avatar_url": "https://github.com/images/error/octocat_happy.gif",
|
|
||||||
"gravatar_id": "",
|
|
||||||
"url": "https://api.github.com/users/octocat",
|
|
||||||
"html_url": "https://github.com/octocat",
|
|
||||||
"followers_url": "https://api.github.com/users/octocat/followers",
|
|
||||||
"following_url": "https://api.github.com/users/octocat/following{/other_user}",
|
|
||||||
"gists_url": "https://api.github.com/users/octocat/gists{/gist_id}",
|
|
||||||
"starred_url": "https://api.github.com/users/octocat/starred{/owner}{/repo}",
|
|
||||||
"subscriptions_url": "https://api.github.com/users/octocat/subscriptions",
|
|
||||||
"organizations_url": "https://api.github.com/users/octocat/orgs",
|
|
||||||
"repos_url": "https://api.github.com/users/octocat/repos",
|
|
||||||
"events_url": "https://api.github.com/users/octocat/events{/privacy}",
|
|
||||||
"received_events_url": "https://api.github.com/users/octocat/received_events",
|
|
||||||
"type": "User",
|
|
||||||
"site_admin": false
|
|
||||||
},
|
|
||||||
"assignees": [
|
|
||||||
{
|
|
||||||
"login": "octocat",
|
|
||||||
"id": 1,
|
|
||||||
"node_id": "MDQ6VXNlcjE=",
|
|
||||||
"avatar_url": "https://github.com/images/error/octocat_happy.gif",
|
|
||||||
"gravatar_id": "",
|
|
||||||
"url": "https://api.github.com/users/octocat",
|
|
||||||
"html_url": "https://github.com/octocat",
|
|
||||||
"followers_url": "https://api.github.com/users/octocat/followers",
|
|
||||||
"following_url": "https://api.github.com/users/octocat/following{/other_user}",
|
|
||||||
"gists_url": "https://api.github.com/users/octocat/gists{/gist_id}",
|
|
||||||
"starred_url": "https://api.github.com/users/octocat/starred{/owner}{/repo}",
|
|
||||||
"subscriptions_url": "https://api.github.com/users/octocat/subscriptions",
|
|
||||||
"organizations_url": "https://api.github.com/users/octocat/orgs",
|
|
||||||
"repos_url": "https://api.github.com/users/octocat/repos",
|
|
||||||
"events_url": "https://api.github.com/users/octocat/events{/privacy}",
|
|
||||||
"received_events_url": "https://api.github.com/users/octocat/received_events",
|
|
||||||
"type": "User",
|
|
||||||
"site_admin": false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"login": "hubot",
|
|
||||||
"id": 1,
|
|
||||||
"node_id": "MDQ6VXNlcjE=",
|
|
||||||
"avatar_url": "https://github.com/images/error/hubot_happy.gif",
|
|
||||||
"gravatar_id": "",
|
|
||||||
"url": "https://api.github.com/users/hubot",
|
|
||||||
"html_url": "https://github.com/hubot",
|
|
||||||
"followers_url": "https://api.github.com/users/hubot/followers",
|
|
||||||
"following_url": "https://api.github.com/users/hubot/following{/other_user}",
|
|
||||||
"gists_url": "https://api.github.com/users/hubot/gists{/gist_id}",
|
|
||||||
"starred_url": "https://api.github.com/users/hubot/starred{/owner}{/repo}",
|
|
||||||
"subscriptions_url": "https://api.github.com/users/hubot/subscriptions",
|
|
||||||
"organizations_url": "https://api.github.com/users/hubot/orgs",
|
|
||||||
"repos_url": "https://api.github.com/users/hubot/repos",
|
|
||||||
"events_url": "https://api.github.com/users/hubot/events{/privacy}",
|
|
||||||
"received_events_url": "https://api.github.com/users/hubot/received_events",
|
|
||||||
"type": "User",
|
|
||||||
"site_admin": true
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"requested_reviewers": [
|
|
||||||
{
|
|
||||||
"login": "other_user",
|
|
||||||
"id": 1,
|
|
||||||
"node_id": "MDQ6VXNlcjE=",
|
|
||||||
"avatar_url": "https://github.com/images/error/other_user_happy.gif",
|
|
||||||
"gravatar_id": "",
|
|
||||||
"url": "https://api.github.com/users/other_user",
|
|
||||||
"html_url": "https://github.com/other_user",
|
|
||||||
"followers_url": "https://api.github.com/users/other_user/followers",
|
|
||||||
"following_url": "https://api.github.com/users/other_user/following{/other_user}",
|
|
||||||
"gists_url": "https://api.github.com/users/other_user/gists{/gist_id}",
|
|
||||||
"starred_url": "https://api.github.com/users/other_user/starred{/owner}{/repo}",
|
|
||||||
"subscriptions_url": "https://api.github.com/users/other_user/subscriptions",
|
|
||||||
"organizations_url": "https://api.github.com/users/other_user/orgs",
|
|
||||||
"repos_url": "https://api.github.com/users/other_user/repos",
|
|
||||||
"events_url": "https://api.github.com/users/other_user/events{/privacy}",
|
|
||||||
"received_events_url": "https://api.github.com/users/other_user/received_events",
|
|
||||||
"type": "User",
|
|
||||||
"site_admin": false
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"requested_teams": [
|
|
||||||
{
|
|
||||||
"id": 1,
|
|
||||||
"node_id": "MDQ6VGVhbTE=",
|
|
||||||
"url": "https://api.github.com/teams/1",
|
|
||||||
"html_url": "https://github.com/orgs/github/teams/justice-league",
|
|
||||||
"name": "Justice League",
|
|
||||||
"slug": "justice-league",
|
|
||||||
"description": "A great team.",
|
|
||||||
"privacy": "closed",
|
|
||||||
"permission": "admin",
|
|
||||||
"members_url": "https://api.github.com/teams/1/members{/member}",
|
|
||||||
"repositories_url": "https://api.github.com/teams/1/repos",
|
|
||||||
"parent": null
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"head": {
|
|
||||||
"label": "octocat:new-topic",
|
|
||||||
"ref": "new-topic",
|
|
||||||
"sha": "6dcb09b5b57875f334f61aebed695e2e4193db5e",
|
|
||||||
"user": {
|
|
||||||
"login": "octocat",
|
|
||||||
"id": 1,
|
|
||||||
"node_id": "MDQ6VXNlcjE=",
|
|
||||||
"avatar_url": "https://github.com/images/error/octocat_happy.gif",
|
|
||||||
"gravatar_id": "",
|
|
||||||
"url": "https://api.github.com/users/octocat",
|
|
||||||
"html_url": "https://github.com/octocat",
|
|
||||||
"followers_url": "https://api.github.com/users/octocat/followers",
|
|
||||||
"following_url": "https://api.github.com/users/octocat/following{/other_user}",
|
|
||||||
"gists_url": "https://api.github.com/users/octocat/gists{/gist_id}",
|
|
||||||
"starred_url": "https://api.github.com/users/octocat/starred{/owner}{/repo}",
|
|
||||||
"subscriptions_url": "https://api.github.com/users/octocat/subscriptions",
|
|
||||||
"organizations_url": "https://api.github.com/users/octocat/orgs",
|
|
||||||
"repos_url": "https://api.github.com/users/octocat/repos",
|
|
||||||
"events_url": "https://api.github.com/users/octocat/events{/privacy}",
|
|
||||||
"received_events_url": "https://api.github.com/users/octocat/received_events",
|
|
||||||
"type": "User",
|
|
||||||
"site_admin": false
|
|
||||||
},
|
|
||||||
"repo": {
|
|
||||||
"id": 1296269,
|
|
||||||
"node_id": "MDEwOlJlcG9zaXRvcnkxMjk2MjY5",
|
|
||||||
"name": "Hello-World",
|
|
||||||
"full_name": "octocat/Hello-World",
|
|
||||||
"owner": {
|
|
||||||
"login": "octocat",
|
|
||||||
"id": 1,
|
|
||||||
"node_id": "MDQ6VXNlcjE=",
|
|
||||||
"avatar_url": "https://github.com/images/error/octocat_happy.gif",
|
|
||||||
"gravatar_id": "",
|
|
||||||
"url": "https://api.github.com/users/octocat",
|
|
||||||
"html_url": "https://github.com/octocat",
|
|
||||||
"followers_url": "https://api.github.com/users/octocat/followers",
|
|
||||||
"following_url": "https://api.github.com/users/octocat/following{/other_user}",
|
|
||||||
"gists_url": "https://api.github.com/users/octocat/gists{/gist_id}",
|
|
||||||
"starred_url": "https://api.github.com/users/octocat/starred{/owner}{/repo}",
|
|
||||||
"subscriptions_url": "https://api.github.com/users/octocat/subscriptions",
|
|
||||||
"organizations_url": "https://api.github.com/users/octocat/orgs",
|
|
||||||
"repos_url": "https://api.github.com/users/octocat/repos",
|
|
||||||
"events_url": "https://api.github.com/users/octocat/events{/privacy}",
|
|
||||||
"received_events_url": "https://api.github.com/users/octocat/received_events",
|
|
||||||
"type": "User",
|
|
||||||
"site_admin": false
|
|
||||||
},
|
|
||||||
"private": false,
|
|
||||||
"html_url": "https://github.com/octocat/Hello-World",
|
|
||||||
"description": "This your first repo!",
|
|
||||||
"fork": false,
|
|
||||||
"url": "https://api.github.com/repos/octocat/Hello-World",
|
|
||||||
"archive_url": "https://api.github.com/repos/octocat/Hello-World/{archive_format}{/ref}",
|
|
||||||
"assignees_url": "https://api.github.com/repos/octocat/Hello-World/assignees{/user}",
|
|
||||||
"blobs_url": "https://api.github.com/repos/octocat/Hello-World/git/blobs{/sha}",
|
|
||||||
"branches_url": "https://api.github.com/repos/octocat/Hello-World/branches{/branch}",
|
|
||||||
"collaborators_url": "https://api.github.com/repos/octocat/Hello-World/collaborators{/collaborator}",
|
|
||||||
"comments_url": "https://api.github.com/repos/octocat/Hello-World/comments{/number}",
|
|
||||||
"commits_url": "https://api.github.com/repos/octocat/Hello-World/commits{/sha}",
|
|
||||||
"compare_url": "https://api.github.com/repos/octocat/Hello-World/compare/{base}...{head}",
|
|
||||||
"contents_url": "https://api.github.com/repos/octocat/Hello-World/contents/{+path}",
|
|
||||||
"contributors_url": "https://api.github.com/repos/octocat/Hello-World/contributors",
|
|
||||||
"deployments_url": "https://api.github.com/repos/octocat/Hello-World/deployments",
|
|
||||||
"downloads_url": "https://api.github.com/repos/octocat/Hello-World/downloads",
|
|
||||||
"events_url": "https://api.github.com/repos/octocat/Hello-World/events",
|
|
||||||
"forks_url": "https://api.github.com/repos/octocat/Hello-World/forks",
|
|
||||||
"git_commits_url": "https://api.github.com/repos/octocat/Hello-World/git/commits{/sha}",
|
|
||||||
"git_refs_url": "https://api.github.com/repos/octocat/Hello-World/git/refs{/sha}",
|
|
||||||
"git_tags_url": "https://api.github.com/repos/octocat/Hello-World/git/tags{/sha}",
|
|
||||||
"git_url": "git:github.com/octocat/Hello-World.git",
|
|
||||||
"issue_comment_url": "https://api.github.com/repos/octocat/Hello-World/issues/comments{/number}",
|
|
||||||
"issue_events_url": "https://api.github.com/repos/octocat/Hello-World/issues/events{/number}",
|
|
||||||
"issues_url": "https://api.github.com/repos/octocat/Hello-World/issues{/number}",
|
|
||||||
"keys_url": "https://api.github.com/repos/octocat/Hello-World/keys{/key_id}",
|
|
||||||
"labels_url": "https://api.github.com/repos/octocat/Hello-World/labels{/name}",
|
|
||||||
"languages_url": "https://api.github.com/repos/octocat/Hello-World/languages",
|
|
||||||
"merges_url": "https://api.github.com/repos/octocat/Hello-World/merges",
|
|
||||||
"milestones_url": "https://api.github.com/repos/octocat/Hello-World/milestones{/number}",
|
|
||||||
"notifications_url": "https://api.github.com/repos/octocat/Hello-World/notifications{?since,all,participating}",
|
|
||||||
"pulls_url": "https://api.github.com/repos/octocat/Hello-World/pulls{/number}",
|
|
||||||
"releases_url": "https://api.github.com/repos/octocat/Hello-World/releases{/id}",
|
|
||||||
"ssh_url": "git@github.com:octocat/Hello-World.git",
|
|
||||||
"stargazers_url": "https://api.github.com/repos/octocat/Hello-World/stargazers",
|
|
||||||
"statuses_url": "https://api.github.com/repos/octocat/Hello-World/statuses/{sha}",
|
|
||||||
"subscribers_url": "https://api.github.com/repos/octocat/Hello-World/subscribers",
|
|
||||||
"subscription_url": "https://api.github.com/repos/octocat/Hello-World/subscription",
|
|
||||||
"tags_url": "https://api.github.com/repos/octocat/Hello-World/tags",
|
|
||||||
"teams_url": "https://api.github.com/repos/octocat/Hello-World/teams",
|
|
||||||
"trees_url": "https://api.github.com/repos/octocat/Hello-World/git/trees{/sha}",
|
|
||||||
"clone_url": "https://github.com/octocat/Hello-World.git",
|
|
||||||
"mirror_url": "git:git.example.com/octocat/Hello-World",
|
|
||||||
"hooks_url": "https://api.github.com/repos/octocat/Hello-World/hooks",
|
|
||||||
"svn_url": "https://svn.github.com/octocat/Hello-World",
|
|
||||||
"homepage": "https://github.com",
|
|
||||||
"language": null,
|
|
||||||
"forks_count": 9,
|
|
||||||
"stargazers_count": 80,
|
|
||||||
"watchers_count": 80,
|
|
||||||
"size": 108,
|
|
||||||
"default_branch": "master",
|
|
||||||
"open_issues_count": 0,
|
|
||||||
"is_template": true,
|
|
||||||
"topics": [
|
|
||||||
"octocat",
|
|
||||||
"atom",
|
|
||||||
"electron",
|
|
||||||
"api"
|
|
||||||
],
|
|
||||||
"has_issues": true,
|
|
||||||
"has_projects": true,
|
|
||||||
"has_wiki": true,
|
|
||||||
"has_pages": false,
|
|
||||||
"has_downloads": true,
|
|
||||||
"archived": false,
|
|
||||||
"disabled": false,
|
|
||||||
"visibility": "public",
|
|
||||||
"pushed_at": "2011-01-26T19:06:43Z",
|
|
||||||
"created_at": "2011-01-26T19:01:12Z",
|
|
||||||
"updated_at": "2011-01-26T19:14:43Z",
|
|
||||||
"permissions": {
|
|
||||||
"admin": false,
|
|
||||||
"push": false,
|
|
||||||
"pull": true
|
|
||||||
},
|
|
||||||
"allow_rebase_merge": true,
|
|
||||||
"template_repository": null,
|
|
||||||
"temp_clone_token": "ABTLWHOULUVAXGTRYU7OC2876QJ2O",
|
|
||||||
"allow_squash_merge": true,
|
|
||||||
"allow_auto_merge": false,
|
|
||||||
"delete_branch_on_merge": true,
|
|
||||||
"allow_merge_commit": true,
|
|
||||||
"subscribers_count": 42,
|
|
||||||
"network_count": 0,
|
|
||||||
"license": {
|
|
||||||
"key": "mit",
|
|
||||||
"name": "MIT License",
|
|
||||||
"url": "https://api.github.com/licenses/mit",
|
|
||||||
"spdx_id": "MIT",
|
|
||||||
"node_id": "MDc6TGljZW5zZW1pdA==",
|
|
||||||
"html_url": "https://github.com/licenses/mit"
|
|
||||||
},
|
|
||||||
"forks": 1,
|
|
||||||
"open_issues": 1,
|
|
||||||
"watchers": 1
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"base": {
|
|
||||||
"label": "octocat:master",
|
|
||||||
"ref": "master",
|
|
||||||
"sha": "6dcb09b5b57875f334f61aebed695e2e4193db5e",
|
|
||||||
"user": {
|
|
||||||
"login": "octocat",
|
|
||||||
"id": 1,
|
|
||||||
"node_id": "MDQ6VXNlcjE=",
|
|
||||||
"avatar_url": "https://github.com/images/error/octocat_happy.gif",
|
|
||||||
"gravatar_id": "",
|
|
||||||
"url": "https://api.github.com/users/octocat",
|
|
||||||
"html_url": "https://github.com/octocat",
|
|
||||||
"followers_url": "https://api.github.com/users/octocat/followers",
|
|
||||||
"following_url": "https://api.github.com/users/octocat/following{/other_user}",
|
|
||||||
"gists_url": "https://api.github.com/users/octocat/gists{/gist_id}",
|
|
||||||
"starred_url": "https://api.github.com/users/octocat/starred{/owner}{/repo}",
|
|
||||||
"subscriptions_url": "https://api.github.com/users/octocat/subscriptions",
|
|
||||||
"organizations_url": "https://api.github.com/users/octocat/orgs",
|
|
||||||
"repos_url": "https://api.github.com/users/octocat/repos",
|
|
||||||
"events_url": "https://api.github.com/users/octocat/events{/privacy}",
|
|
||||||
"received_events_url": "https://api.github.com/users/octocat/received_events",
|
|
||||||
"type": "User",
|
|
||||||
"site_admin": false
|
|
||||||
},
|
|
||||||
"repo": {
|
|
||||||
"id": 1296269,
|
|
||||||
"node_id": "MDEwOlJlcG9zaXRvcnkxMjk2MjY5",
|
|
||||||
"name": "Hello-World",
|
|
||||||
"full_name": "octocat/Hello-World",
|
|
||||||
"owner": {
|
|
||||||
"login": "octocat",
|
|
||||||
"id": 1,
|
|
||||||
"node_id": "MDQ6VXNlcjE=",
|
|
||||||
"avatar_url": "https://github.com/images/error/octocat_happy.gif",
|
|
||||||
"gravatar_id": "",
|
|
||||||
"url": "https://api.github.com/users/octocat",
|
|
||||||
"html_url": "https://github.com/octocat",
|
|
||||||
"followers_url": "https://api.github.com/users/octocat/followers",
|
|
||||||
"following_url": "https://api.github.com/users/octocat/following{/other_user}",
|
|
||||||
"gists_url": "https://api.github.com/users/octocat/gists{/gist_id}",
|
|
||||||
"starred_url": "https://api.github.com/users/octocat/starred{/owner}{/repo}",
|
|
||||||
"subscriptions_url": "https://api.github.com/users/octocat/subscriptions",
|
|
||||||
"organizations_url": "https://api.github.com/users/octocat/orgs",
|
|
||||||
"repos_url": "https://api.github.com/users/octocat/repos",
|
|
||||||
"events_url": "https://api.github.com/users/octocat/events{/privacy}",
|
|
||||||
"received_events_url": "https://api.github.com/users/octocat/received_events",
|
|
||||||
"type": "User",
|
|
||||||
"site_admin": false
|
|
||||||
},
|
|
||||||
"private": false,
|
|
||||||
"html_url": "https://github.com/octocat/Hello-World",
|
|
||||||
"description": "This your first repo!",
|
|
||||||
"fork": false,
|
|
||||||
"url": "https://api.github.com/repos/octocat/Hello-World",
|
|
||||||
"archive_url": "https://api.github.com/repos/octocat/Hello-World/{archive_format}{/ref}",
|
|
||||||
"assignees_url": "https://api.github.com/repos/octocat/Hello-World/assignees{/user}",
|
|
||||||
"blobs_url": "https://api.github.com/repos/octocat/Hello-World/git/blobs{/sha}",
|
|
||||||
"branches_url": "https://api.github.com/repos/octocat/Hello-World/branches{/branch}",
|
|
||||||
"collaborators_url": "https://api.github.com/repos/octocat/Hello-World/collaborators{/collaborator}",
|
|
||||||
"comments_url": "https://api.github.com/repos/octocat/Hello-World/comments{/number}",
|
|
||||||
"commits_url": "https://api.github.com/repos/octocat/Hello-World/commits{/sha}",
|
|
||||||
"compare_url": "https://api.github.com/repos/octocat/Hello-World/compare/{base}...{head}",
|
|
||||||
"contents_url": "https://api.github.com/repos/octocat/Hello-World/contents/{+path}",
|
|
||||||
"contributors_url": "https://api.github.com/repos/octocat/Hello-World/contributors",
|
|
||||||
"deployments_url": "https://api.github.com/repos/octocat/Hello-World/deployments",
|
|
||||||
"downloads_url": "https://api.github.com/repos/octocat/Hello-World/downloads",
|
|
||||||
"events_url": "https://api.github.com/repos/octocat/Hello-World/events",
|
|
||||||
"forks_url": "https://api.github.com/repos/octocat/Hello-World/forks",
|
|
||||||
"git_commits_url": "https://api.github.com/repos/octocat/Hello-World/git/commits{/sha}",
|
|
||||||
"git_refs_url": "https://api.github.com/repos/octocat/Hello-World/git/refs{/sha}",
|
|
||||||
"git_tags_url": "https://api.github.com/repos/octocat/Hello-World/git/tags{/sha}",
|
|
||||||
"git_url": "git:github.com/octocat/Hello-World.git",
|
|
||||||
"issue_comment_url": "https://api.github.com/repos/octocat/Hello-World/issues/comments{/number}",
|
|
||||||
"issue_events_url": "https://api.github.com/repos/octocat/Hello-World/issues/events{/number}",
|
|
||||||
"issues_url": "https://api.github.com/repos/octocat/Hello-World/issues{/number}",
|
|
||||||
"keys_url": "https://api.github.com/repos/octocat/Hello-World/keys{/key_id}",
|
|
||||||
"labels_url": "https://api.github.com/repos/octocat/Hello-World/labels{/name}",
|
|
||||||
"languages_url": "https://api.github.com/repos/octocat/Hello-World/languages",
|
|
||||||
"merges_url": "https://api.github.com/repos/octocat/Hello-World/merges",
|
|
||||||
"milestones_url": "https://api.github.com/repos/octocat/Hello-World/milestones{/number}",
|
|
||||||
"notifications_url": "https://api.github.com/repos/octocat/Hello-World/notifications{?since,all,participating}",
|
|
||||||
"pulls_url": "https://api.github.com/repos/octocat/Hello-World/pulls{/number}",
|
|
||||||
"releases_url": "https://api.github.com/repos/octocat/Hello-World/releases{/id}",
|
|
||||||
"ssh_url": "git@github.com:octocat/Hello-World.git",
|
|
||||||
"stargazers_url": "https://api.github.com/repos/octocat/Hello-World/stargazers",
|
|
||||||
"statuses_url": "https://api.github.com/repos/octocat/Hello-World/statuses/{sha}",
|
|
||||||
"subscribers_url": "https://api.github.com/repos/octocat/Hello-World/subscribers",
|
|
||||||
"subscription_url": "https://api.github.com/repos/octocat/Hello-World/subscription",
|
|
||||||
"tags_url": "https://api.github.com/repos/octocat/Hello-World/tags",
|
|
||||||
"teams_url": "https://api.github.com/repos/octocat/Hello-World/teams",
|
|
||||||
"trees_url": "https://api.github.com/repos/octocat/Hello-World/git/trees{/sha}",
|
|
||||||
"clone_url": "https://github.com/octocat/Hello-World.git",
|
|
||||||
"mirror_url": "git:git.example.com/octocat/Hello-World",
|
|
||||||
"hooks_url": "https://api.github.com/repos/octocat/Hello-World/hooks",
|
|
||||||
"svn_url": "https://svn.github.com/octocat/Hello-World",
|
|
||||||
"homepage": "https://github.com",
|
|
||||||
"language": null,
|
|
||||||
"forks_count": 9,
|
|
||||||
"stargazers_count": 80,
|
|
||||||
"watchers_count": 80,
|
|
||||||
"size": 108,
|
|
||||||
"default_branch": "master",
|
|
||||||
"open_issues_count": 0,
|
|
||||||
"is_template": true,
|
|
||||||
"topics": [
|
|
||||||
"octocat",
|
|
||||||
"atom",
|
|
||||||
"electron",
|
|
||||||
"api"
|
|
||||||
],
|
|
||||||
"has_issues": true,
|
|
||||||
"has_projects": true,
|
|
||||||
"has_wiki": true,
|
|
||||||
"has_pages": false,
|
|
||||||
"has_downloads": true,
|
|
||||||
"archived": false,
|
|
||||||
"disabled": false,
|
|
||||||
"visibility": "public",
|
|
||||||
"pushed_at": "2011-01-26T19:06:43Z",
|
|
||||||
"created_at": "2011-01-26T19:01:12Z",
|
|
||||||
"updated_at": "2011-01-26T19:14:43Z",
|
|
||||||
"permissions": {
|
|
||||||
"admin": false,
|
|
||||||
"push": false,
|
|
||||||
"pull": true
|
|
||||||
},
|
|
||||||
"allow_rebase_merge": true,
|
|
||||||
"template_repository": null,
|
|
||||||
"temp_clone_token": "ABTLWHOULUVAXGTRYU7OC2876QJ2O",
|
|
||||||
"allow_squash_merge": true,
|
|
||||||
"allow_auto_merge": false,
|
|
||||||
"delete_branch_on_merge": true,
|
|
||||||
"allow_merge_commit": true,
|
|
||||||
"subscribers_count": 42,
|
|
||||||
"network_count": 0,
|
|
||||||
"license": {
|
|
||||||
"key": "mit",
|
|
||||||
"name": "MIT License",
|
|
||||||
"url": "https://api.github.com/licenses/mit",
|
|
||||||
"spdx_id": "MIT",
|
|
||||||
"node_id": "MDc6TGljZW5zZW1pdA==",
|
|
||||||
"html_url": "https://github.com/licenses/mit"
|
|
||||||
},
|
|
||||||
"forks": 1,
|
|
||||||
"open_issues": 1,
|
|
||||||
"watchers": 1
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"_links": {
|
|
||||||
"self": {
|
|
||||||
"href": "https://api.github.com/repos/octocat/Hello-World/pulls/1347"
|
|
||||||
},
|
|
||||||
"html": {
|
|
||||||
"href": "https://github.com/octocat/Hello-World/pull/1347"
|
|
||||||
},
|
|
||||||
"issue": {
|
|
||||||
"href": "https://api.github.com/repos/octocat/Hello-World/issues/1347"
|
|
||||||
},
|
|
||||||
"comments": {
|
|
||||||
"href": "https://api.github.com/repos/octocat/Hello-World/issues/1347/comments"
|
|
||||||
},
|
|
||||||
"review_comments": {
|
|
||||||
"href": "https://api.github.com/repos/octocat/Hello-World/pulls/1347/comments"
|
|
||||||
},
|
|
||||||
"review_comment": {
|
|
||||||
"href": "https://api.github.com/repos/octocat/Hello-World/pulls/comments{/number}"
|
|
||||||
},
|
|
||||||
"commits": {
|
|
||||||
"href": "https://api.github.com/repos/octocat/Hello-World/pulls/1347/commits"
|
|
||||||
},
|
|
||||||
"statuses": {
|
|
||||||
"href": "https://api.github.com/repos/octocat/Hello-World/statuses/6dcb09b5b57875f334f61aebed695e2e4193db5e"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"author_association": "OWNER",
|
|
||||||
"auto_merge": null,
|
|
||||||
"draft": false
|
|
||||||
}
|
|
||||||
]
|
|
@ -1,76 +0,0 @@
|
|||||||
[
|
|
||||||
{
|
|
||||||
"url": "https://api.github.com/repos/octocat/Hello-World/releases/1",
|
|
||||||
"html_url": "https://github.com/octocat/Hello-World/releases/v1.0.0",
|
|
||||||
"assets_url": "https://api.github.com/repos/octocat/Hello-World/releases/1/assets",
|
|
||||||
"upload_url": "https://uploads.github.com/repos/octocat/Hello-World/releases/1/assets{?name,label}",
|
|
||||||
"tarball_url": "https://api.github.com/repos/octocat/Hello-World/tarball/v1.0.0",
|
|
||||||
"zipball_url": "https://api.github.com/repos/octocat/Hello-World/zipball/v1.0.0",
|
|
||||||
"id": 1,
|
|
||||||
"node_id": "MDc6UmVsZWFzZTE=",
|
|
||||||
"tag_name": "v1.0.0",
|
|
||||||
"target_commitish": "master",
|
|
||||||
"name": "v1.0.0",
|
|
||||||
"body": "Description of the release",
|
|
||||||
"draft": false,
|
|
||||||
"prerelease": false,
|
|
||||||
"created_at": "2013-02-27T19:35:32Z",
|
|
||||||
"published_at": "2013-02-27T19:35:32Z",
|
|
||||||
"author": {
|
|
||||||
"login": "octocat",
|
|
||||||
"id": 1,
|
|
||||||
"node_id": "MDQ6VXNlcjE=",
|
|
||||||
"avatar_url": "https://github.com/images/error/octocat_happy.gif",
|
|
||||||
"gravatar_id": "",
|
|
||||||
"url": "https://api.github.com/users/octocat",
|
|
||||||
"html_url": "https://github.com/octocat",
|
|
||||||
"followers_url": "https://api.github.com/users/octocat/followers",
|
|
||||||
"following_url": "https://api.github.com/users/octocat/following{/other_user}",
|
|
||||||
"gists_url": "https://api.github.com/users/octocat/gists{/gist_id}",
|
|
||||||
"starred_url": "https://api.github.com/users/octocat/starred{/owner}{/repo}",
|
|
||||||
"subscriptions_url": "https://api.github.com/users/octocat/subscriptions",
|
|
||||||
"organizations_url": "https://api.github.com/users/octocat/orgs",
|
|
||||||
"repos_url": "https://api.github.com/users/octocat/repos",
|
|
||||||
"events_url": "https://api.github.com/users/octocat/events{/privacy}",
|
|
||||||
"received_events_url": "https://api.github.com/users/octocat/received_events",
|
|
||||||
"type": "User",
|
|
||||||
"site_admin": false
|
|
||||||
},
|
|
||||||
"assets": [
|
|
||||||
{
|
|
||||||
"url": "https://api.github.com/repos/octocat/Hello-World/releases/assets/1",
|
|
||||||
"browser_download_url": "https://github.com/octocat/Hello-World/releases/download/v1.0.0/example.zip",
|
|
||||||
"id": 1,
|
|
||||||
"node_id": "MDEyOlJlbGVhc2VBc3NldDE=",
|
|
||||||
"name": "example.zip",
|
|
||||||
"label": "short description",
|
|
||||||
"state": "uploaded",
|
|
||||||
"content_type": "application/zip",
|
|
||||||
"size": 1024,
|
|
||||||
"download_count": 42,
|
|
||||||
"created_at": "2013-02-27T19:35:32Z",
|
|
||||||
"updated_at": "2013-02-27T19:35:32Z",
|
|
||||||
"uploader": {
|
|
||||||
"login": "octocat",
|
|
||||||
"id": 1,
|
|
||||||
"node_id": "MDQ6VXNlcjE=",
|
|
||||||
"avatar_url": "https://github.com/images/error/octocat_happy.gif",
|
|
||||||
"gravatar_id": "",
|
|
||||||
"url": "https://api.github.com/users/octocat",
|
|
||||||
"html_url": "https://github.com/octocat",
|
|
||||||
"followers_url": "https://api.github.com/users/octocat/followers",
|
|
||||||
"following_url": "https://api.github.com/users/octocat/following{/other_user}",
|
|
||||||
"gists_url": "https://api.github.com/users/octocat/gists{/gist_id}",
|
|
||||||
"starred_url": "https://api.github.com/users/octocat/starred{/owner}{/repo}",
|
|
||||||
"subscriptions_url": "https://api.github.com/users/octocat/subscriptions",
|
|
||||||
"organizations_url": "https://api.github.com/users/octocat/orgs",
|
|
||||||
"repos_url": "https://api.github.com/users/octocat/repos",
|
|
||||||
"events_url": "https://api.github.com/users/octocat/events{/privacy}",
|
|
||||||
"received_events_url": "https://api.github.com/users/octocat/received_events",
|
|
||||||
"type": "User",
|
|
||||||
"site_admin": false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
@ -1,14 +1,16 @@
|
|||||||
"""Test GitHub diagnostics."""
|
"""Test GitHub diagnostics."""
|
||||||
|
|
||||||
|
import json
|
||||||
|
|
||||||
from aiogithubapi import GitHubException
|
from aiogithubapi import GitHubException
|
||||||
from aiohttp import ClientSession
|
from aiohttp import ClientSession
|
||||||
|
|
||||||
from homeassistant.components.github.const import CONF_REPOSITORIES
|
from homeassistant.components.github.const import CONF_REPOSITORIES, DOMAIN
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
|
|
||||||
from .common import setup_github_integration
|
from .common import setup_github_integration
|
||||||
|
|
||||||
from tests.common import MockConfigEntry
|
from tests.common import MockConfigEntry, load_fixture
|
||||||
from tests.components.diagnostics import get_diagnostics_for_config_entry
|
from tests.components.diagnostics import get_diagnostics_for_config_entry
|
||||||
from tests.test_util.aiohttp import AiohttpClientMocker
|
from tests.test_util.aiohttp import AiohttpClientMocker
|
||||||
|
|
||||||
@ -21,13 +23,21 @@ async def test_entry_diagnostics(
|
|||||||
) -> None:
|
) -> None:
|
||||||
"""Test config entry diagnostics."""
|
"""Test config entry diagnostics."""
|
||||||
mock_config_entry.options = {CONF_REPOSITORIES: ["home-assistant/core"]}
|
mock_config_entry.options = {CONF_REPOSITORIES: ["home-assistant/core"]}
|
||||||
await setup_github_integration(hass, mock_config_entry, aioclient_mock)
|
response_json = json.loads(load_fixture("graphql.json", DOMAIN))
|
||||||
|
response_json["data"]["repository"]["full_name"] = "home-assistant/core"
|
||||||
|
|
||||||
|
aioclient_mock.post(
|
||||||
|
"https://api.github.com/graphql",
|
||||||
|
json=response_json,
|
||||||
|
headers=json.loads(load_fixture("base_headers.json", DOMAIN)),
|
||||||
|
)
|
||||||
aioclient_mock.get(
|
aioclient_mock.get(
|
||||||
"https://api.github.com/rate_limit",
|
"https://api.github.com/rate_limit",
|
||||||
json={"resources": {"core": {"remaining": 100, "limit": 100}}},
|
json={"resources": {"core": {"remaining": 100, "limit": 100}}},
|
||||||
headers={"Content-Type": "application/json"},
|
headers={"Content-Type": "application/json"},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
await setup_github_integration(hass, mock_config_entry, aioclient_mock)
|
||||||
result = await get_diagnostics_for_config_entry(
|
result = await get_diagnostics_for_config_entry(
|
||||||
hass,
|
hass,
|
||||||
hass_client,
|
hass_client,
|
||||||
|
@ -1,62 +1,37 @@
|
|||||||
"""Test GitHub sensor."""
|
"""Test GitHub sensor."""
|
||||||
from unittest.mock import MagicMock, patch
|
import json
|
||||||
|
|
||||||
from aiogithubapi import GitHubNotModifiedException
|
from homeassistant.components.github.const import DEFAULT_UPDATE_INTERVAL, DOMAIN
|
||||||
import pytest
|
|
||||||
|
|
||||||
from homeassistant.components.github.const import DEFAULT_UPDATE_INTERVAL
|
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
from homeassistant.util import dt
|
from homeassistant.util import dt
|
||||||
|
|
||||||
from tests.common import MockConfigEntry, async_fire_time_changed
|
from tests.common import MockConfigEntry, async_fire_time_changed, load_fixture
|
||||||
|
from tests.test_util.aiohttp import AiohttpClientMocker
|
||||||
|
|
||||||
TEST_SENSOR_ENTITY = "sensor.octocat_hello_world_latest_release"
|
TEST_SENSOR_ENTITY = "sensor.octocat_hello_world_latest_release"
|
||||||
|
|
||||||
|
|
||||||
async def test_sensor_updates_with_not_modified_content(
|
|
||||||
hass: HomeAssistant,
|
|
||||||
init_integration: MockConfigEntry,
|
|
||||||
caplog: pytest.LogCaptureFixture,
|
|
||||||
) -> None:
|
|
||||||
"""Test the sensor updates by default GitHub sensors."""
|
|
||||||
state = hass.states.get(TEST_SENSOR_ENTITY)
|
|
||||||
assert state.state == "v1.0.0"
|
|
||||||
assert (
|
|
||||||
"Content for octocat/Hello-World with RepositoryReleaseDataUpdateCoordinator not modified"
|
|
||||||
not in caplog.text
|
|
||||||
)
|
|
||||||
|
|
||||||
with patch(
|
|
||||||
"aiogithubapi.namespaces.releases.GitHubReleasesNamespace.list",
|
|
||||||
side_effect=GitHubNotModifiedException,
|
|
||||||
):
|
|
||||||
|
|
||||||
async_fire_time_changed(hass, dt.utcnow() + DEFAULT_UPDATE_INTERVAL)
|
|
||||||
await hass.async_block_till_done()
|
|
||||||
|
|
||||||
assert (
|
|
||||||
"Content for octocat/Hello-World with RepositoryReleaseDataUpdateCoordinator not modified"
|
|
||||||
in caplog.text
|
|
||||||
)
|
|
||||||
new_state = hass.states.get(TEST_SENSOR_ENTITY)
|
|
||||||
assert state.state == new_state.state
|
|
||||||
|
|
||||||
|
|
||||||
async def test_sensor_updates_with_empty_release_array(
|
async def test_sensor_updates_with_empty_release_array(
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
init_integration: MockConfigEntry,
|
init_integration: MockConfigEntry,
|
||||||
|
aioclient_mock: AiohttpClientMocker,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Test the sensor updates by default GitHub sensors."""
|
"""Test the sensor updates by default GitHub sensors."""
|
||||||
state = hass.states.get(TEST_SENSOR_ENTITY)
|
state = hass.states.get(TEST_SENSOR_ENTITY)
|
||||||
assert state.state == "v1.0.0"
|
assert state.state == "v1.0.0"
|
||||||
|
|
||||||
with patch(
|
response_json = json.loads(load_fixture("graphql.json", DOMAIN))
|
||||||
"aiogithubapi.namespaces.releases.GitHubReleasesNamespace.list",
|
response_json["data"]["repository"]["release"] = None
|
||||||
return_value=MagicMock(data=[]),
|
|
||||||
):
|
|
||||||
|
|
||||||
async_fire_time_changed(hass, dt.utcnow() + DEFAULT_UPDATE_INTERVAL)
|
aioclient_mock.clear_requests()
|
||||||
await hass.async_block_till_done()
|
aioclient_mock.post(
|
||||||
|
"https://api.github.com/graphql",
|
||||||
|
json=response_json,
|
||||||
|
headers=json.loads(load_fixture("base_headers.json", DOMAIN)),
|
||||||
|
)
|
||||||
|
|
||||||
|
async_fire_time_changed(hass, dt.utcnow() + DEFAULT_UPDATE_INTERVAL)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
new_state = hass.states.get(TEST_SENSOR_ENTITY)
|
new_state = hass.states.get(TEST_SENSOR_ENTITY)
|
||||||
assert new_state.state == "unavailable"
|
assert new_state.state == "unavailable"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user