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
parent
3920844dca
commit
fb4aff25a2
|
@ -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
|
||||
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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()
|
|
@ -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": {
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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,
|
||||
),
|
||||
},
|
||||
),
|
||||
)
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
|
|
|
@ -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,
|
||||
},
|
||||
]
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue