mirror of
https://github.com/home-assistant/core
synced 2024-07-12 07:21:24 +02:00
Typing improvements for Sentry (#50787)
* Typing improvements for Sentry * Fix event tags access * Fix tests
This commit is contained in:
parent
cad4ec867b
commit
e64b5afa58
@ -2,6 +2,8 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import re
|
||||
from types import MappingProxyType
|
||||
from typing import Any
|
||||
|
||||
import sentry_sdk
|
||||
from sentry_sdk.integrations.aiohttp import AioHttpIntegration
|
||||
@ -120,19 +122,19 @@ def get_channel(version: str) -> str:
|
||||
|
||||
def process_before_send(
|
||||
hass: HomeAssistant,
|
||||
options,
|
||||
options: MappingProxyType[str, Any],
|
||||
channel: str,
|
||||
huuid: str,
|
||||
system_info: dict[str, bool | str],
|
||||
custom_components: dict[str, Integration],
|
||||
event,
|
||||
hint,
|
||||
event: dict[str, Any],
|
||||
hint: dict[str, Any],
|
||||
):
|
||||
"""Process a Sentry event before sending it to Sentry."""
|
||||
# Filter out handled events by default
|
||||
if (
|
||||
"tags" in event
|
||||
and event.tags.get("handled", "no") == "yes"
|
||||
and event["tags"].get("handled", "no") == "yes"
|
||||
and not options.get(CONF_EVENT_HANDLED)
|
||||
):
|
||||
return None
|
||||
@ -204,7 +206,7 @@ def process_before_send(
|
||||
"channel": channel,
|
||||
"custom_components": "\n".join(sorted(custom_components)),
|
||||
"integrations": "\n".join(sorted(integrations)),
|
||||
**system_info,
|
||||
**system_info, # type: ignore[arg-type]
|
||||
},
|
||||
}
|
||||
)
|
||||
|
3
mypy.ini
3
mypy.ini
@ -1267,9 +1267,6 @@ ignore_errors = true
|
||||
[mypy-homeassistant.components.sense.*]
|
||||
ignore_errors = true
|
||||
|
||||
[mypy-homeassistant.components.sentry.*]
|
||||
ignore_errors = true
|
||||
|
||||
[mypy-homeassistant.components.sesame.*]
|
||||
ignore_errors = true
|
||||
|
||||
|
@ -176,7 +176,6 @@ IGNORED_MODULES: Final[list[str]] = [
|
||||
"homeassistant.components.script.*",
|
||||
"homeassistant.components.search.*",
|
||||
"homeassistant.components.sense.*",
|
||||
"homeassistant.components.sentry.*",
|
||||
"homeassistant.components.sesame.*",
|
||||
"homeassistant.components.sharkiq.*",
|
||||
"homeassistant.components.sma.*",
|
||||
|
@ -1,4 +1,8 @@
|
||||
"""Configuration for Sonos tests."""
|
||||
"""Configuration for Sentry tests."""
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Any
|
||||
|
||||
import pytest
|
||||
|
||||
from homeassistant.components.sentry import DOMAIN
|
||||
@ -7,12 +11,12 @@ from tests.common import MockConfigEntry
|
||||
|
||||
|
||||
@pytest.fixture(name="config_entry")
|
||||
def config_entry_fixture():
|
||||
def config_entry_fixture() -> MockConfigEntry:
|
||||
"""Create a mock config entry."""
|
||||
return MockConfigEntry(domain=DOMAIN, title="Sentry")
|
||||
|
||||
|
||||
@pytest.fixture(name="config")
|
||||
def config_fixture():
|
||||
def config_fixture() -> dict[str, Any]:
|
||||
"""Create hass config fixture."""
|
||||
return {DOMAIN: {"dsn": "http://public@sentry.local/1"}}
|
||||
|
@ -16,20 +16,26 @@ from homeassistant.components.sentry.const import (
|
||||
DOMAIN,
|
||||
)
|
||||
from homeassistant.config_entries import SOURCE_USER
|
||||
from homeassistant.data_entry_flow import RESULT_TYPE_ABORT, RESULT_TYPE_FORM
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.data_entry_flow import (
|
||||
RESULT_TYPE_ABORT,
|
||||
RESULT_TYPE_CREATE_ENTRY,
|
||||
RESULT_TYPE_FORM,
|
||||
)
|
||||
from homeassistant.setup import async_setup_component
|
||||
|
||||
from tests.common import MockConfigEntry
|
||||
|
||||
|
||||
async def test_full_user_flow_implementation(hass):
|
||||
async def test_full_user_flow_implementation(hass: HomeAssistant) -> None:
|
||||
"""Test we get the form."""
|
||||
await async_setup_component(hass, "persistent_notification", {})
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
DOMAIN, context={"source": SOURCE_USER}
|
||||
)
|
||||
assert result["type"] == RESULT_TYPE_FORM
|
||||
assert result["errors"] == {}
|
||||
assert result.get("type") == RESULT_TYPE_FORM
|
||||
assert result.get("errors") == {}
|
||||
assert "flow_id" in result
|
||||
|
||||
with patch("homeassistant.components.sentry.config_flow.Dsn"), patch(
|
||||
"homeassistant.components.sentry.async_setup_entry",
|
||||
@ -40,9 +46,9 @@ async def test_full_user_flow_implementation(hass):
|
||||
{"dsn": "http://public@sentry.local/1"},
|
||||
)
|
||||
|
||||
assert result2["type"] == "create_entry"
|
||||
assert result2["title"] == "Sentry"
|
||||
assert result2["data"] == {
|
||||
assert result2.get("type") == "create_entry"
|
||||
assert result2.get("title") == "Sentry"
|
||||
assert result2.get("data") == {
|
||||
"dsn": "http://public@sentry.local/1",
|
||||
}
|
||||
await hass.async_block_till_done()
|
||||
@ -50,22 +56,23 @@ async def test_full_user_flow_implementation(hass):
|
||||
assert len(mock_setup_entry.mock_calls) == 1
|
||||
|
||||
|
||||
async def test_integration_already_exists(hass):
|
||||
async def test_integration_already_exists(hass: HomeAssistant) -> None:
|
||||
"""Test we only allow a single config flow."""
|
||||
MockConfigEntry(domain=DOMAIN).add_to_hass(hass)
|
||||
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
DOMAIN, context={"source": SOURCE_USER}
|
||||
)
|
||||
assert result["type"] == RESULT_TYPE_ABORT
|
||||
assert result["reason"] == "single_instance_allowed"
|
||||
assert result.get("type") == RESULT_TYPE_ABORT
|
||||
assert result.get("reason") == "single_instance_allowed"
|
||||
|
||||
|
||||
async def test_user_flow_bad_dsn(hass):
|
||||
async def test_user_flow_bad_dsn(hass: HomeAssistant) -> None:
|
||||
"""Test we handle bad dsn error."""
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
DOMAIN, context={"source": SOURCE_USER}
|
||||
)
|
||||
assert "flow_id" in result
|
||||
|
||||
with patch(
|
||||
"homeassistant.components.sentry.config_flow.Dsn",
|
||||
@ -76,15 +83,16 @@ async def test_user_flow_bad_dsn(hass):
|
||||
{"dsn": "foo"},
|
||||
)
|
||||
|
||||
assert result2["type"] == RESULT_TYPE_FORM
|
||||
assert result2["errors"] == {"base": "bad_dsn"}
|
||||
assert result2.get("type") == RESULT_TYPE_FORM
|
||||
assert result2.get("errors") == {"base": "bad_dsn"}
|
||||
|
||||
|
||||
async def test_user_flow_unkown_exception(hass):
|
||||
async def test_user_flow_unkown_exception(hass: HomeAssistant) -> None:
|
||||
"""Test we handle any unknown exception error."""
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
DOMAIN, context={"source": SOURCE_USER}
|
||||
)
|
||||
assert "flow_id" in result
|
||||
|
||||
with patch(
|
||||
"homeassistant.components.sentry.config_flow.Dsn",
|
||||
@ -95,11 +103,11 @@ async def test_user_flow_unkown_exception(hass):
|
||||
{"dsn": "foo"},
|
||||
)
|
||||
|
||||
assert result2["type"] == RESULT_TYPE_FORM
|
||||
assert result2["errors"] == {"base": "unknown"}
|
||||
assert result2.get("type") == RESULT_TYPE_FORM
|
||||
assert result2.get("errors") == {"base": "unknown"}
|
||||
|
||||
|
||||
async def test_options_flow(hass):
|
||||
async def test_options_flow(hass: HomeAssistant) -> None:
|
||||
"""Test options config flow."""
|
||||
entry = MockConfigEntry(
|
||||
domain=DOMAIN,
|
||||
@ -113,8 +121,9 @@ async def test_options_flow(hass):
|
||||
|
||||
result = await hass.config_entries.options.async_init(entry.entry_id)
|
||||
|
||||
assert result["type"] == RESULT_TYPE_FORM
|
||||
assert result["step_id"] == "init"
|
||||
assert result.get("type") == RESULT_TYPE_FORM
|
||||
assert result.get("step_id") == "init"
|
||||
assert "flow_id" in result
|
||||
|
||||
result = await hass.config_entries.options.async_configure(
|
||||
result["flow_id"],
|
||||
@ -130,8 +139,8 @@ async def test_options_flow(hass):
|
||||
},
|
||||
)
|
||||
|
||||
assert result["type"] == "create_entry"
|
||||
assert result["data"] == {
|
||||
assert result.get("type") == RESULT_TYPE_CREATE_ENTRY
|
||||
assert result.get("data") == {
|
||||
CONF_ENVIRONMENT: "Test",
|
||||
CONF_EVENT_CUSTOM_COMPONENTS: True,
|
||||
CONF_EVENT_HANDLED: True,
|
||||
|
@ -1,6 +1,6 @@
|
||||
"""Tests for Sentry integration."""
|
||||
import logging
|
||||
from unittest.mock import MagicMock, Mock, patch
|
||||
from unittest.mock import Mock, patch
|
||||
|
||||
import pytest
|
||||
|
||||
@ -112,12 +112,12 @@ async def test_setup_entry_with_tracing(hass: HomeAssistant) -> None:
|
||||
("0.115.0dev0", "dev"),
|
||||
],
|
||||
)
|
||||
async def test_get_channel(version, channel) -> None:
|
||||
async def test_get_channel(version: str, channel: str) -> None:
|
||||
"""Test if channel detection works from Home Assistant version number."""
|
||||
assert get_channel(version) == channel
|
||||
|
||||
|
||||
async def test_process_before_send(hass: HomeAssistant):
|
||||
async def test_process_before_send(hass: HomeAssistant) -> None:
|
||||
"""Test regular use of the Sentry process before sending function."""
|
||||
hass.config.components.add("puppies")
|
||||
hass.config.components.add("a_integration")
|
||||
@ -308,12 +308,6 @@ async def test_filter_log_events(hass: HomeAssistant, logger, options, event):
|
||||
)
|
||||
async def test_filter_handled_events(hass: HomeAssistant, handled, options, event):
|
||||
"""Tests filtering of handled events based on configuration options."""
|
||||
|
||||
event_mock = MagicMock()
|
||||
event_mock.__iter__ = ["tags"]
|
||||
event_mock.__contains__ = lambda _, val: val == "tags"
|
||||
event_mock.tags = {"handled": handled}
|
||||
|
||||
result = process_before_send(
|
||||
hass,
|
||||
options=options,
|
||||
@ -321,7 +315,7 @@ async def test_filter_handled_events(hass: HomeAssistant, handled, options, even
|
||||
huuid="12345",
|
||||
system_info={"installation_type": "pytest"},
|
||||
custom_components=[],
|
||||
event=event_mock,
|
||||
event={"tags": {"handled": handled}},
|
||||
hint={},
|
||||
)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user