Create issues in demo integration (#75081)

* Create issues in demo integration

* Add unfixable non-expiring issue

* Update test

* Adjust tests

* update translations

* add hassfest translation schema

* Update homeassistant/components/demo/translations/en.json

Co-authored-by: Zack Barett <zackbarett@hey.com>

* Rename Resolution Center -> Repairs

* Update homeassistant/components/demo/strings.json

Co-authored-by: Zack Barett <zackbarett@hey.com>

* Adjust hassfest to require description or fix_flow

* Update homeassistant/components/demo/repairs.py

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>

* Update tests/components/demo/test_init.py

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>

* Add missing translation strings

* black

* Adjust repairs imports

Co-authored-by: Bram Kragten <mail@bramkragten.nl>
Co-authored-by: Franck Nijhof <git@frenck.dev>
Co-authored-by: Zack Barett <zackbarett@hey.com>
Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
pull/75501/head
Erik Montnemery 2022-07-20 14:46:06 +02:00 committed by GitHub
parent 3920844dca
commit fb4aff25a2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 266 additions and 4 deletions

View File

@ -10,6 +10,7 @@ from homeassistant.components.recorder.statistics import (
async_add_external_statistics,
get_last_statistics,
)
from homeassistant.components.repairs import IssueSeverity, async_create_issue
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import (
ATTR_ENTITY_ID,
@ -177,6 +178,39 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
hass.bus.async_listen(EVENT_HOMEASSISTANT_START, demo_start_listener)
# Create issues
async_create_issue(
hass,
DOMAIN,
"transmogrifier_deprecated",
breaks_in_ha_version="2023.1.1",
is_fixable=False,
learn_more_url="https://en.wiktionary.org/wiki/transmogrifier",
severity=IssueSeverity.WARNING,
translation_key="transmogrifier_deprecated",
)
async_create_issue(
hass,
DOMAIN,
"out_of_blinker_fluid",
breaks_in_ha_version="2023.1.1",
is_fixable=True,
learn_more_url="https://www.youtube.com/watch?v=b9rntRxLlbU",
severity=IssueSeverity.CRITICAL,
translation_key="out_of_blinker_fluid",
)
async_create_issue(
hass,
DOMAIN,
"unfixable_problem",
is_fixable=False,
learn_more_url="https://www.youtube.com/watch?v=dQw4w9WgXcQ",
severity=IssueSeverity.WARNING,
translation_key="unfixable_problem",
)
return True

View File

@ -3,7 +3,7 @@
"name": "Demo",
"documentation": "https://www.home-assistant.io/integrations/demo",
"after_dependencies": ["recorder"],
"dependencies": ["conversation", "group", "zone"],
"dependencies": ["conversation", "group", "repairs", "zone"],
"codeowners": ["@home-assistant/core"],
"quality_scale": "internal",
"iot_class": "calculated"

View File

@ -0,0 +1,33 @@
"""Repairs platform for the demo integration."""
from __future__ import annotations
import voluptuous as vol
from homeassistant import data_entry_flow
from homeassistant.components.repairs import RepairsFlow
class DemoFixFlow(RepairsFlow):
"""Handler for an issue fixing flow."""
async def async_step_init(
self, user_input: dict[str, str] | None = None
) -> data_entry_flow.FlowResult:
"""Handle the first step of a fix flow."""
return await (self.async_step_confirm())
async def async_step_confirm(
self, user_input: dict[str, str] | None = None
) -> data_entry_flow.FlowResult:
"""Handle the confirm step of a fix flow."""
if user_input is not None:
return self.async_create_entry(title="Fixed issue", data={})
return self.async_show_form(step_id="confirm", data_schema=vol.Schema({}))
async def async_create_fix_flow(hass, issue_id):
"""Create flow."""
return DemoFixFlow()

View File

@ -1,5 +1,26 @@
{
"title": "Demo",
"issues": {
"out_of_blinker_fluid": {
"title": "The blinker fluid is empty and needs to be refilled",
"fix_flow": {
"step": {
"confirm": {
"title": "Blinker fluid needs to be refilled",
"description": "Press OK when blinker fluid has been refilled"
}
}
}
},
"transmogrifier_deprecated": {
"title": "The transmogrifier component is deprecated",
"description": "The transmogrifier component is now deprecated due to the lack of local control available in the new API"
},
"unfixable_problem": {
"title": "This is not a fixable problem",
"description": "This issue is never going to give up."
}
},
"options": {
"step": {
"init": {

View File

@ -1,6 +1,30 @@
{
"issues": {
"out_of_blinker_fluid": {
"fix_flow": {
"step": {
"confirm": {
"description": "Press OK when blinker fluid has been refilled",
"title": "Blinker fluid needs to be refilled"
}
}
},
"title": "The blinker fluid is empty and needs to be refilled"
},
"transmogrifier_deprecated": {
"description": "The transmogrifier component is now deprecated due to the lack of local control available in the new API",
"title": "The transmogrifier component is deprecated"
},
"unfixable_problem": {
"description": "This issue is never going to give up.",
"title": "This is not a fixable problem"
}
},
"options": {
"step": {
"init": {
"data": {}
},
"options_1": {
"data": {
"bool": "Optional boolean",

View File

@ -21,7 +21,7 @@ REMOVED = 2
RE_REFERENCE = r"\[\%key:(.+)\%\]"
# Only allow translatino of integration names if they contain non-brand names
# Only allow translation of integration names if they contain non-brand names
ALLOW_NAME_TRANSLATION = {
"cert_expiry",
"cpuspeed",
@ -185,7 +185,7 @@ def gen_data_entry_schema(
return vol.All(*validators)
def gen_strings_schema(config: Config, integration: Integration):
def gen_strings_schema(config: Config, integration: Integration) -> vol.Schema:
"""Generate a strings schema."""
return vol.Schema(
{
@ -227,6 +227,25 @@ def gen_strings_schema(config: Config, integration: Integration):
vol.Optional("application_credentials"): {
vol.Optional("description"): cv.string_with_no_html,
},
vol.Optional("issues"): {
str: vol.All(
cv.has_at_least_one_key("description", "fix_flow"),
vol.Schema(
{
vol.Required("title"): cv.string_with_no_html,
vol.Exclusive(
"description", "fixable"
): cv.string_with_no_html,
vol.Exclusive("fix_flow", "fixable"): gen_data_entry_schema(
config=config,
integration=integration,
flow_title=UNDEFINED,
require_step_title=False,
),
},
),
)
},
}
)

View File

@ -1,6 +1,7 @@
"""The tests for the Demo component."""
from http import HTTPStatus
import json
from unittest.mock import patch
from unittest.mock import ANY, patch
import pytest
@ -69,3 +70,133 @@ async def test_demo_statistics(hass, recorder_mock):
"statistic_id": "demo:energy_consumption",
"unit_of_measurement": "kWh",
} in statistic_ids
async def test_issues_created(hass, hass_client, hass_ws_client):
"""Test issues are created and can be fixed."""
assert await async_setup_component(hass, DOMAIN, {DOMAIN: {}})
await hass.async_block_till_done()
await hass.async_start()
ws_client = await hass_ws_client(hass)
client = await hass_client()
await ws_client.send_json({"id": 1, "type": "repairs/list_issues"})
msg = await ws_client.receive_json()
assert msg["success"]
assert msg["result"] == {
"issues": [
{
"breaks_in_ha_version": "2023.1.1",
"created": ANY,
"dismissed_version": None,
"domain": "demo",
"ignored": False,
"is_fixable": False,
"issue_id": "transmogrifier_deprecated",
"learn_more_url": "https://en.wiktionary.org/wiki/transmogrifier",
"severity": "warning",
"translation_key": "transmogrifier_deprecated",
"translation_placeholders": None,
},
{
"breaks_in_ha_version": "2023.1.1",
"created": ANY,
"dismissed_version": None,
"domain": "demo",
"ignored": False,
"is_fixable": True,
"issue_id": "out_of_blinker_fluid",
"learn_more_url": "https://www.youtube.com/watch?v=b9rntRxLlbU",
"severity": "critical",
"translation_key": "out_of_blinker_fluid",
"translation_placeholders": None,
},
{
"breaks_in_ha_version": None,
"created": ANY,
"dismissed_version": None,
"domain": "demo",
"ignored": False,
"is_fixable": False,
"issue_id": "unfixable_problem",
"learn_more_url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
"severity": "warning",
"translation_key": "unfixable_problem",
"translation_placeholders": None,
},
]
}
url = "/api/repairs/issues/fix"
resp = await client.post(
url, json={"handler": "demo", "issue_id": "out_of_blinker_fluid"}
)
assert resp.status == HTTPStatus.OK
data = await resp.json()
flow_id = data["flow_id"]
assert data == {
"data_schema": [],
"description_placeholders": None,
"errors": None,
"flow_id": ANY,
"handler": "demo",
"last_step": None,
"step_id": "confirm",
"type": "form",
}
url = f"/api/repairs/issues/fix/{flow_id}"
resp = await client.post(url)
assert resp.status == HTTPStatus.OK
data = await resp.json()
flow_id = data["flow_id"]
assert data == {
"description": None,
"description_placeholders": None,
"flow_id": flow_id,
"handler": "demo",
"title": "Fixed issue",
"type": "create_entry",
"version": 1,
}
await ws_client.send_json({"id": 4, "type": "repairs/list_issues"})
msg = await ws_client.receive_json()
assert msg["success"]
assert msg["result"] == {
"issues": [
{
"breaks_in_ha_version": "2023.1.1",
"created": ANY,
"dismissed_version": None,
"domain": "demo",
"ignored": False,
"is_fixable": False,
"issue_id": "transmogrifier_deprecated",
"learn_more_url": "https://en.wiktionary.org/wiki/transmogrifier",
"severity": "warning",
"translation_key": "transmogrifier_deprecated",
"translation_placeholders": None,
},
{
"breaks_in_ha_version": None,
"created": ANY,
"dismissed_version": None,
"domain": "demo",
"ignored": False,
"is_fixable": False,
"issue_id": "unfixable_problem",
"learn_more_url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
"severity": "warning",
"translation_key": "unfixable_problem",
"translation_placeholders": None,
},
]
}