From 9f57ce504bc1299d34a2149b2e8a5c4ef2c93ea0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joakim=20S=C3=B8rensen?= Date: Sun, 20 Feb 2022 11:59:11 +0100 Subject: [PATCH] Use GraphQL for GitHub integration (#66928) --- .pre-commit-config.yaml | 2 +- homeassistant/components/github/__init__.py | 31 +- homeassistant/components/github/const.py | 12 - .../components/github/coordinator.py | 237 +++----- .../components/github/diagnostics.py | 9 +- homeassistant/components/github/sensor.py | 86 ++- tests/components/github/common.py | 11 +- tests/components/github/fixtures/commits.json | 80 --- tests/components/github/fixtures/graphql.json | 49 ++ tests/components/github/fixtures/issues.json | 159 ------ tests/components/github/fixtures/pulls.json | 520 ------------------ .../components/github/fixtures/releases.json | 76 --- tests/components/github/test_diagnostics.py | 16 +- tests/components/github/test_sensor.py | 57 +- 14 files changed, 201 insertions(+), 1144 deletions(-) delete mode 100644 tests/components/github/fixtures/commits.json create mode 100644 tests/components/github/fixtures/graphql.json delete mode 100644 tests/components/github/fixtures/issues.json delete mode 100644 tests/components/github/fixtures/pulls.json delete mode 100644 tests/components/github/fixtures/releases.json diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index f16a65fb4c07..7cdd28cd6e97 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -17,7 +17,7 @@ repos: hooks: - id: codespell 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" - --quiet-level=2 exclude_types: [csv, json] diff --git a/homeassistant/components/github/__init__.py b/homeassistant/components/github/__init__.py index ae13e8df9590..4ecff6e9648b 100644 --- a/homeassistant/components/github/__init__.py +++ b/homeassistant/components/github/__init__.py @@ -13,13 +13,7 @@ from homeassistant.helpers.aiohttp_client import ( ) from .const import CONF_REPOSITORIES, DOMAIN, LOGGER -from .coordinator import ( - DataUpdateCoordinators, - RepositoryCommitDataUpdateCoordinator, - RepositoryInformationDataUpdateCoordinator, - RepositoryIssueDataUpdateCoordinator, - RepositoryReleaseDataUpdateCoordinator, -) +from .coordinator import GitHubDataUpdateCoordinator 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] for repository in repositories: - coordinators: DataUpdateCoordinators = { - "information": RepositoryInformationDataUpdateCoordinator( - hass=hass, entry=entry, 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 - ), - } + coordinator = GitHubDataUpdateCoordinator( + hass=hass, + 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) diff --git a/homeassistant/components/github/const.py b/homeassistant/components/github/const.py index 7a0c471ab036..efe9d7baa5e6 100644 --- a/homeassistant/components/github/const.py +++ b/homeassistant/components/github/const.py @@ -3,9 +3,6 @@ from __future__ import annotations from datetime import timedelta from logging import Logger, getLogger -from typing import NamedTuple - -from aiogithubapi import GitHubIssueModel LOGGER: Logger = getLogger(__package__) @@ -18,12 +15,3 @@ DEFAULT_UPDATE_INTERVAL = timedelta(seconds=300) CONF_ACCESS_TOKEN = "access_token" CONF_REPOSITORIES = "repositories" - - -class IssuesPulls(NamedTuple): - """Issues and pull requests.""" - - issues_count: int - issue_last: GitHubIssueModel | None - pulls_count: int - pull_last: GitHubIssueModel | None diff --git a/homeassistant/components/github/coordinator.py b/homeassistant/components/github/coordinator.py index 32f0df98e1f4..9769c944f162 100644 --- a/homeassistant/components/github/coordinator.py +++ b/homeassistant/components/github/coordinator.py @@ -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 typing import Literal, TypedDict +from typing import Any from aiogithubapi import ( GitHubAPI, - GitHubCommitModel, GitHubConnectionException, GitHubException, - GitHubNotModifiedException, GitHubRatelimitException, - GitHubReleaseModel, - GitHubRepositoryModel, GitHubResponseModel, ) -from homeassistant.config_entries import ConfigEntry -from homeassistant.core import HomeAssistant, T +from homeassistant.core import HomeAssistant 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]): - """Base class for GitHub data update coordinators.""" +class GitHubDataUpdateCoordinator(DataUpdateCoordinator[dict[str, Any]]): + """Data update coordinator for the GitHub integration.""" def __init__( self, hass: HomeAssistant, - entry: ConfigEntry, client: GitHubAPI, repository: str, ) -> None: """Initialize GitHub data update coordinator base class.""" - self.config_entry = entry self.repository = repository self._client = client - self._last_response: GitHubResponseModel[T] | None = None + self._last_response: GitHubResponseModel[dict[str, Any]] | None = None + self.data = {} super().__init__( hass, @@ -47,30 +95,14 @@ class GitHubBaseDataUpdateCoordinator(DataUpdateCoordinator[T]): update_interval=DEFAULT_UPDATE_INTERVAL, ) - @property - def _etag(self) -> str: - """Return the ETag of the last response.""" - 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: + async def _async_update_data(self) -> GitHubResponseModel[dict[str, Any]]: + """Update data.""" + owner, repository = self.repository.split("/") try: - response = await self.fetch_data() - except GitHubNotModifiedException: - LOGGER.debug( - "Content for %s with %s not modified", - self.repository, - self.__class__.__name__, + response = await self._client.graphql( + query=GRAPHQL_REPOSITORY_QUERY, + variables={"owner": owner, "repository": repository}, ) - # Return the last known data if the request result was not modified - return self.data except (GitHubConnectionException, GitHubRatelimitException) as exception: # These are expected and we dont log anything extra raise UpdateFailed(exception) from exception @@ -80,133 +112,4 @@ class GitHubBaseDataUpdateCoordinator(DataUpdateCoordinator[T]): raise UpdateFailed(exception) from exception else: self._last_response = response - return self._parse_response(response) - - -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 + return response.data["data"]["repository"] diff --git a/homeassistant/components/github/diagnostics.py b/homeassistant/components/github/diagnostics.py index 101bf642c91b..c2546d636b82 100644 --- a/homeassistant/components/github/diagnostics.py +++ b/homeassistant/components/github/diagnostics.py @@ -13,7 +13,7 @@ from homeassistant.helpers.aiohttp_client import ( ) from .const import CONF_ACCESS_TOKEN, DOMAIN -from .coordinator import DataUpdateCoordinators +from .coordinator import GitHubDataUpdateCoordinator async def async_get_config_entry_diagnostics( @@ -35,11 +35,10 @@ async def async_get_config_entry_diagnostics( else: 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"] = {} - for repository, coordinators in repositories.items(): - info = coordinators["information"].data - data["repositories"][repository] = info.as_dict if info else None + for repository, coordinator in repositories.items(): + data["repositories"][repository] = coordinator.data return data diff --git a/homeassistant/components/github/sensor.py b/homeassistant/components/github/sensor.py index 18aaa43d18d5..7fad114a2ae6 100644 --- a/homeassistant/components/github/sensor.py +++ b/homeassistant/components/github/sensor.py @@ -19,19 +19,14 @@ from homeassistant.helpers.typing import StateType from homeassistant.helpers.update_coordinator import CoordinatorEntity from .const import DOMAIN -from .coordinator import ( - CoordinatorKeyType, - DataUpdateCoordinators, - GitHubBaseDataUpdateCoordinator, -) +from .coordinator import GitHubDataUpdateCoordinator @dataclass class BaseEntityDescriptionMixin: """Mixin for required GitHub base description keys.""" - coordinator_key: CoordinatorKeyType - value_fn: Callable[[Any], StateType] + value_fn: Callable[[dict[str, Any]], StateType] @dataclass @@ -40,8 +35,8 @@ class BaseEntityDescription(SensorEntityDescription): icon: str = "mdi:github" entity_registry_enabled_default: bool = False - attr_fn: Callable[[Any], Mapping[str, Any] | None] = lambda data: None - avabl_fn: Callable[[Any], bool] = lambda data: True + attr_fn: Callable[[dict[str, Any]], Mapping[str, Any] | None] = lambda data: None + avabl_fn: Callable[[dict[str, Any]], bool] = lambda data: True @dataclass @@ -57,8 +52,7 @@ SENSOR_DESCRIPTIONS: tuple[GitHubSensorEntityDescription, ...] = ( native_unit_of_measurement="Stars", entity_category=EntityCategory.DIAGNOSTIC, state_class=SensorStateClass.MEASUREMENT, - value_fn=lambda data: data.stargazers_count, - coordinator_key="information", + value_fn=lambda data: data["stargazers_count"], ), GitHubSensorEntityDescription( key="subscribers_count", @@ -67,9 +61,7 @@ SENSOR_DESCRIPTIONS: tuple[GitHubSensorEntityDescription, ...] = ( native_unit_of_measurement="Watchers", entity_category=EntityCategory.DIAGNOSTIC, state_class=SensorStateClass.MEASUREMENT, - # The API returns a watcher_count, but subscribers_count is more accurate - value_fn=lambda data: data.subscribers_count, - coordinator_key="information", + value_fn=lambda data: data["watchers"]["total"], ), GitHubSensorEntityDescription( key="forks_count", @@ -78,8 +70,7 @@ SENSOR_DESCRIPTIONS: tuple[GitHubSensorEntityDescription, ...] = ( native_unit_of_measurement="Forks", entity_category=EntityCategory.DIAGNOSTIC, state_class=SensorStateClass.MEASUREMENT, - value_fn=lambda data: data.forks_count, - coordinator_key="information", + value_fn=lambda data: data["forks_count"], ), GitHubSensorEntityDescription( key="issues_count", @@ -87,8 +78,7 @@ SENSOR_DESCRIPTIONS: tuple[GitHubSensorEntityDescription, ...] = ( native_unit_of_measurement="Issues", entity_category=EntityCategory.DIAGNOSTIC, state_class=SensorStateClass.MEASUREMENT, - value_fn=lambda data: data.issues_count, - coordinator_key="issue", + value_fn=lambda data: data["issue"]["total"], ), GitHubSensorEntityDescription( key="pulls_count", @@ -96,50 +86,46 @@ SENSOR_DESCRIPTIONS: tuple[GitHubSensorEntityDescription, ...] = ( native_unit_of_measurement="Pull Requests", entity_category=EntityCategory.DIAGNOSTIC, state_class=SensorStateClass.MEASUREMENT, - value_fn=lambda data: data.pulls_count, - coordinator_key="issue", + value_fn=lambda data: data["pull_request"]["total"], ), GitHubSensorEntityDescription( - coordinator_key="commit", key="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: { - "sha": data.sha, - "url": data.html_url, + "sha": data["default_branch_ref"]["commit"]["sha"], + "url": data["default_branch_ref"]["commit"]["url"], }, ), GitHubSensorEntityDescription( - coordinator_key="release", key="latest_release", name="Latest Release", 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: { - "url": data.html_url, - "tag": data.tag_name, + "url": data["release"]["url"], + "tag": data["release"]["tag"], }, ), GitHubSensorEntityDescription( - coordinator_key="issue", key="latest_issue", name="Latest Issue", - value_fn=lambda data: data.issue_last.title[:255], - avabl_fn=lambda data: data.issue_last is not None, + avabl_fn=lambda data: data["issue"]["issues"], + value_fn=lambda data: data["issue"]["issues"][0]["title"][:255], attr_fn=lambda data: { - "url": data.issue_last.html_url, - "number": data.issue_last.number, + "url": data["issue"]["issues"][0]["url"], + "number": data["issue"]["issues"][0]["number"], }, ), GitHubSensorEntityDescription( - coordinator_key="issue", key="latest_pull_request", name="Latest Pull Request", - value_fn=lambda data: data.pull_last.title[:255], - avabl_fn=lambda data: data.pull_last is not None, + avabl_fn=lambda data: data["pull_request"]["pull_requests"], + value_fn=lambda data: data["pull_request"]["pull_requests"][0]["title"][:255], attr_fn=lambda data: { - "url": data.pull_last.html_url, - "number": data.pull_last.number, + "url": data["pull_request"]["pull_requests"][0]["url"], + "number": data["pull_request"]["pull_requests"][0]["number"], }, ), ) @@ -151,43 +137,41 @@ async def async_setup_entry( async_add_entities: AddEntitiesCallback, ) -> None: """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( ( - GitHubSensorEntity(coordinators, description) + GitHubSensorEntity(coordinator, description) 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.""" _attr_attribution = "Data provided by the GitHub API" - coordinator: GitHubBaseDataUpdateCoordinator + coordinator: GitHubDataUpdateCoordinator entity_description: GitHubSensorEntityDescription def __init__( self, - coordinators: DataUpdateCoordinators, + coordinator: GitHubDataUpdateCoordinator, entity_description: GitHubSensorEntityDescription, ) -> None: """Initialize the sensor.""" - coordinator = coordinators[entity_description.coordinator_key] - _information = coordinators["information"].data - super().__init__(coordinator=coordinator) self.entity_description = entity_description - self._attr_name = f"{_information.full_name} {entity_description.name}" - self._attr_unique_id = f"{_information.id}_{entity_description.key}" + self._attr_name = ( + 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( identifiers={(DOMAIN, coordinator.repository)}, - name=_information.full_name, + name=coordinator.data.get("full_name"), manufacturer="GitHub", configuration_url=f"https://github.com/{coordinator.repository}", entry_type=DeviceEntryType.SERVICE, diff --git a/tests/components/github/common.py b/tests/components/github/common.py index a99834f0cbdf..a75a8cfaa785 100644 --- a/tests/components/github/common.py +++ b/tests/components/github/common.py @@ -31,12 +31,11 @@ async def setup_github_integration( }, headers=headers, ) - for endpoint in ("issues", "pulls", "releases", "commits"): - aioclient_mock.get( - f"https://api.github.com/repos/{repository}/{endpoint}", - json=json.loads(load_fixture(f"{endpoint}.json", DOMAIN)), - headers=headers, - ) + aioclient_mock.post( + "https://api.github.com/graphql", + json=json.loads(load_fixture("graphql.json", DOMAIN)), + headers=headers, + ) mock_config_entry.add_to_hass(hass) setup_result = await hass.config_entries.async_setup(mock_config_entry.entry_id) diff --git a/tests/components/github/fixtures/commits.json b/tests/components/github/fixtures/commits.json deleted file mode 100644 index c0deeaf51eaf..000000000000 --- a/tests/components/github/fixtures/commits.json +++ /dev/null @@ -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" - } - ] - } -] \ No newline at end of file diff --git a/tests/components/github/fixtures/graphql.json b/tests/components/github/fixtures/graphql.json new file mode 100644 index 000000000000..d8fe86f6c955 --- /dev/null +++ b/tests/components/github/fixtures/graphql.json @@ -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" + } + } + } +} \ No newline at end of file diff --git a/tests/components/github/fixtures/issues.json b/tests/components/github/fixtures/issues.json deleted file mode 100644 index d59f1f5c7967..000000000000 --- a/tests/components/github/fixtures/issues.json +++ /dev/null @@ -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" - } -] \ No newline at end of file diff --git a/tests/components/github/fixtures/pulls.json b/tests/components/github/fixtures/pulls.json deleted file mode 100644 index a42763b18d8a..000000000000 --- a/tests/components/github/fixtures/pulls.json +++ /dev/null @@ -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 - } -] \ No newline at end of file diff --git a/tests/components/github/fixtures/releases.json b/tests/components/github/fixtures/releases.json deleted file mode 100644 index e69206ae7840..000000000000 --- a/tests/components/github/fixtures/releases.json +++ /dev/null @@ -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 - } - } - ] - } -] \ No newline at end of file diff --git a/tests/components/github/test_diagnostics.py b/tests/components/github/test_diagnostics.py index 6e5e6e13fa44..80dfaec24459 100644 --- a/tests/components/github/test_diagnostics.py +++ b/tests/components/github/test_diagnostics.py @@ -1,14 +1,16 @@ """Test GitHub diagnostics.""" +import json + from aiogithubapi import GitHubException 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 .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.test_util.aiohttp import AiohttpClientMocker @@ -21,13 +23,21 @@ async def test_entry_diagnostics( ) -> None: """Test config entry diagnostics.""" 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( "https://api.github.com/rate_limit", json={"resources": {"core": {"remaining": 100, "limit": 100}}}, headers={"Content-Type": "application/json"}, ) + await setup_github_integration(hass, mock_config_entry, aioclient_mock) result = await get_diagnostics_for_config_entry( hass, hass_client, diff --git a/tests/components/github/test_sensor.py b/tests/components/github/test_sensor.py index cea3edc6b47b..cba787cbc287 100644 --- a/tests/components/github/test_sensor.py +++ b/tests/components/github/test_sensor.py @@ -1,62 +1,37 @@ """Test GitHub sensor.""" -from unittest.mock import MagicMock, patch +import json -from aiogithubapi import GitHubNotModifiedException -import pytest - -from homeassistant.components.github.const import DEFAULT_UPDATE_INTERVAL +from homeassistant.components.github.const import DEFAULT_UPDATE_INTERVAL, DOMAIN from homeassistant.core import HomeAssistant 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" -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( hass: HomeAssistant, init_integration: MockConfigEntry, + aioclient_mock: AiohttpClientMocker, ) -> None: """Test the sensor updates by default GitHub sensors.""" state = hass.states.get(TEST_SENSOR_ENTITY) assert state.state == "v1.0.0" - with patch( - "aiogithubapi.namespaces.releases.GitHubReleasesNamespace.list", - return_value=MagicMock(data=[]), - ): + response_json = json.loads(load_fixture("graphql.json", DOMAIN)) + response_json["data"]["repository"]["release"] = None - async_fire_time_changed(hass, dt.utcnow() + DEFAULT_UPDATE_INTERVAL) - await hass.async_block_till_done() + aioclient_mock.clear_requests() + 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) assert new_state.state == "unavailable"