Store creation timestamps for resolution center issues (#75430)

This commit is contained in:
Erik Montnemery 2022-07-19 13:01:39 +02:00 committed by GitHub
parent 8e8c6e2394
commit c3d536b255
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 70 additions and 5 deletions

View File

@ -2,11 +2,13 @@
from __future__ import annotations
import dataclasses
from datetime import datetime
from typing import Optional, cast
from homeassistant.const import __version__ as ha_version
from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers.storage import Store
import homeassistant.util.dt as dt_util
from .models import IssueSeverity
@ -14,7 +16,6 @@ DATA_REGISTRY = "issue_registry"
STORAGE_KEY = "resolution_center.issue_registry"
STORAGE_VERSION = 1
SAVE_DELAY = 10
SAVED_FIELDS = ("dismissed_version", "domain", "issue_id")
@dataclasses.dataclass(frozen=True)
@ -23,6 +24,7 @@ class IssueEntry:
active: bool
breaks_in_ha_version: str | None
created: datetime
dismissed_version: str | None
domain: str
is_fixable: bool | None
@ -68,6 +70,7 @@ class IssueRegistry:
issue = IssueEntry(
active=True,
breaks_in_ha_version=breaks_in_ha_version,
created=dt_util.utcnow(),
dismissed_version=None,
domain=domain,
is_fixable=is_fixable,
@ -125,10 +128,11 @@ class IssueRegistry:
if isinstance(data, dict):
for issue in data["issues"]:
assert issue["domain"] and issue["issue_id"]
assert issue["created"] and issue["domain"] and issue["issue_id"]
issues[(issue["domain"], issue["issue_id"])] = IssueEntry(
active=False,
breaks_in_ha_version=None,
created=cast(datetime, dt_util.parse_datetime(issue["created"])),
dismissed_version=issue["dismissed_version"],
domain=issue["domain"],
is_fixable=None,
@ -152,7 +156,12 @@ class IssueRegistry:
data = {}
data["issues"] = [
{field: getattr(entry, field) for field in SAVED_FIELDS}
{
"created": entry.created.isoformat(),
"dismissed_version": entry.dismissed_version,
"domain": entry.domain,
"issue_id": entry.issue_id,
}
for entry in self.issues.values()
]

View File

@ -67,8 +67,9 @@ def ws_list_issues(
"""Return a list of issues."""
def ws_dict(kv_pairs: list[tuple[Any, Any]]) -> dict[Any, Any]:
result = {k: v for k, v in kv_pairs if k != "active"}
result = {k: v for k, v in kv_pairs if k not in ("active")}
result["dismissed"] = result["dismissed_version"] is not None
result["created"] = result["created"].isoformat()
return result
issue_registry = async_get_issue_registry(hass)

View File

@ -1,6 +1,7 @@
"""Test the resolution center websocket API."""
from unittest.mock import AsyncMock, Mock
from freezegun import freeze_time
import pytest
from homeassistant.components.resolution_center import (
@ -19,6 +20,7 @@ from homeassistant.setup import async_setup_component
from tests.common import mock_platform
@freeze_time("2022-07-19 07:53:05")
async def test_create_update_issue(hass: HomeAssistant, hass_ws_client) -> None:
"""Test creating and updating issues."""
assert await async_setup_component(hass, DOMAIN, {})
@ -75,6 +77,7 @@ async def test_create_update_issue(hass: HomeAssistant, hass_ws_client) -> None:
"issues": [
dict(
issue,
created="2022-07-19T07:53:05+00:00",
dismissed=False,
dismissed_version=None,
)
@ -101,6 +104,7 @@ async def test_create_update_issue(hass: HomeAssistant, hass_ws_client) -> None:
assert msg["success"]
assert msg["result"]["issues"][0] == dict(
issues[0],
created="2022-07-19T07:53:05+00:00",
dismissed=False,
dismissed_version=None,
learn_more_url="blablabla",
@ -147,6 +151,7 @@ async def test_create_issue_invalid_version(
assert msg["result"] == {"issues": []}
@freeze_time("2022-07-19 07:53:05")
async def test_dismiss_issue(hass: HomeAssistant, hass_ws_client) -> None:
"""Test dismissing issues."""
assert await async_setup_component(hass, DOMAIN, {})
@ -193,6 +198,7 @@ async def test_dismiss_issue(hass: HomeAssistant, hass_ws_client) -> None:
"issues": [
dict(
issue,
created="2022-07-19T07:53:05+00:00",
dismissed=False,
dismissed_version=None,
)
@ -212,6 +218,7 @@ async def test_dismiss_issue(hass: HomeAssistant, hass_ws_client) -> None:
"issues": [
dict(
issue,
created="2022-07-19T07:53:05+00:00",
dismissed=False,
dismissed_version=None,
)
@ -230,6 +237,7 @@ async def test_dismiss_issue(hass: HomeAssistant, hass_ws_client) -> None:
"issues": [
dict(
issue,
created="2022-07-19T07:53:05+00:00",
dismissed=True,
dismissed_version=ha_version,
)
@ -248,6 +256,7 @@ async def test_dismiss_issue(hass: HomeAssistant, hass_ws_client) -> None:
"issues": [
dict(
issue,
created="2022-07-19T07:53:05+00:00",
dismissed=True,
dismissed_version=ha_version,
)
@ -274,14 +283,16 @@ async def test_dismiss_issue(hass: HomeAssistant, hass_ws_client) -> None:
assert msg["success"]
assert msg["result"]["issues"][0] == dict(
issues[0],
created="2022-07-19T07:53:05+00:00",
dismissed=True,
dismissed_version=ha_version,
learn_more_url="blablabla",
)
async def test_delete_issue(hass: HomeAssistant, hass_ws_client) -> None:
async def test_delete_issue(hass: HomeAssistant, hass_ws_client, freezer) -> None:
"""Test we can delete an issue."""
freezer.move_to("2022-07-19 07:53:05")
assert await async_setup_component(hass, DOMAIN, {})
client = await hass_ws_client(hass)
@ -320,6 +331,7 @@ async def test_delete_issue(hass: HomeAssistant, hass_ws_client) -> None:
"issues": [
dict(
issue,
created="2022-07-19T07:53:05+00:00",
dismissed=False,
dismissed_version=None,
)
@ -338,6 +350,7 @@ async def test_delete_issue(hass: HomeAssistant, hass_ws_client) -> None:
"issues": [
dict(
issue,
created="2022-07-19T07:53:05+00:00",
dismissed=False,
dismissed_version=None,
)
@ -363,6 +376,38 @@ async def test_delete_issue(hass: HomeAssistant, hass_ws_client) -> None:
assert msg["success"]
assert msg["result"] == {"issues": []}
# Create the same issues again created timestamp should change
freezer.move_to("2022-07-19 08:53:05")
for issue in issues:
async_create_issue(
hass,
issue["domain"],
issue["issue_id"],
breaks_in_ha_version=issue["breaks_in_ha_version"],
is_fixable=issue["is_fixable"],
learn_more_url=issue["learn_more_url"],
severity=issue["severity"],
translation_key=issue["translation_key"],
translation_placeholders=issue["translation_placeholders"],
)
await client.send_json({"id": 5, "type": "resolution_center/list_issues"})
msg = await client.receive_json()
assert msg["success"]
assert msg["result"] == {
"issues": [
dict(
issue,
created="2022-07-19T08:53:05+00:00",
dismissed=False,
dismissed_version=None,
)
for issue in issues
]
}
async def test_non_compliant_platform(hass: HomeAssistant, hass_ws_client) -> None:
"""Test non-compliant platforms are not registered."""

View File

@ -64,8 +64,10 @@ async def test_load_issues(hass: HomeAssistant) -> None:
assert list(registry.issues) == list(registry2.issues)
issue1_registry2 = registry2.async_get_issue("test", "issue_1")
assert issue1_registry2.created == issue1.created
assert issue1_registry2.dismissed_version == issue1.dismissed_version
issue2_registry2 = registry2.async_get_issue("test", "issue_2")
assert issue2_registry2.created == issue2.created
assert issue2_registry2.dismissed_version == issue2.dismissed_version
@ -76,11 +78,13 @@ async def test_loading_issues_from_storage(hass: HomeAssistant, hass_storage) ->
"data": {
"issues": [
{
"created": "2022-07-19T09:41:13.746514+00:00",
"dismissed_version": "2022.7.0.dev0",
"domain": "test",
"issue_id": "issue_1",
},
{
"created": "2022-07-19T19:41:13.746514+00:00",
"dismissed_version": None,
"domain": "test",
"issue_id": "issue_2",

View File

@ -4,6 +4,7 @@ from __future__ import annotations
from http import HTTPStatus
from unittest.mock import ANY, AsyncMock, Mock
from freezegun import freeze_time
import pytest
import voluptuous as vol
@ -56,6 +57,7 @@ async def create_issues(hass, ws_client):
"issues": [
dict(
issue,
created=ANY,
dismissed=False,
dismissed_version=None,
)
@ -146,6 +148,7 @@ async def test_dismiss_issue(hass: HomeAssistant, hass_ws_client) -> None:
"issues": [
dict(
issue,
created=ANY,
dismissed=True,
dismissed_version=ha_version,
)
@ -188,6 +191,7 @@ async def test_fix_non_existing_issue(
"issues": [
dict(
issue,
created=ANY,
dismissed=False,
dismissed_version=None,
)
@ -333,6 +337,7 @@ async def test_step_unauth(
assert resp.status == HTTPStatus.UNAUTHORIZED
@freeze_time("2022-07-19 07:53:05")
async def test_list_issues(hass: HomeAssistant, hass_ws_client) -> None:
"""Test we can list issues."""
assert await async_setup_component(hass, DOMAIN, {})
@ -389,6 +394,7 @@ async def test_list_issues(hass: HomeAssistant, hass_ws_client) -> None:
"issues": [
dict(
issue,
created="2022-07-19T07:53:05+00:00",
dismissed=False,
dismissed_version=None,
)