Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 21 additions & 1 deletion homeassistant/components/logi_circle/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
Platform,
)
from homeassistant.core import HomeAssistant, ServiceCall
from homeassistant.helpers import config_validation as cv
from homeassistant.helpers import config_validation as cv, issue_registry as ir
from homeassistant.helpers.dispatcher import async_dispatcher_send
from homeassistant.helpers.typing import ConfigType

Expand Down Expand Up @@ -131,6 +131,19 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:

async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
"""Set up Logi Circle from a config entry."""
ir.async_create_issue(
hass,
DOMAIN,
DOMAIN,
breaks_in_ha_version="2024.9.0",
is_fixable=False,
severity=ir.IssueSeverity.ERROR,
Comment thread
emontnemery marked this conversation as resolved.
Outdated
translation_key="integration_removed",
translation_placeholders={
"entries": "/config/integrations/integration/logi_circle",
},
)

logi_circle = LogiCircle(
client_id=entry.data[CONF_CLIENT_ID],
client_secret=entry.data[CONF_CLIENT_SECRET],
Expand Down Expand Up @@ -239,6 +252,13 @@ async def shut_down(event=None):

async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
"""Unload a config entry."""
if all(
config_entry.state is config_entries.ConfigEntryState.NOT_LOADED
for config_entry in hass.config_entries.async_entries(DOMAIN)
if config_entry.entry_id != entry.entry_id
):
ir.async_delete_issue(hass, DOMAIN, DOMAIN)

unload_ok = await hass.config_entries.async_unload_platforms(entry, PLATFORMS)

logi_circle = hass.data.pop(DATA_LOGI)
Expand Down
6 changes: 6 additions & 0 deletions homeassistant/components/logi_circle/strings.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,12 @@
}
}
},
"issues": {
"integration_removed": {
"title": "The Logi Circle integration has been deprecated and will be removed",
"description": "Logitech stopped accepting applications for access to the Logi Circle API in May 2022, and the Logi Circle integration will be removed from Home Assistant.\n\nTo resolve this issue, please remove the integration entries from your Home Assistant setup. [Click here to see your existing Logi Circle integration entries]({entries})."
}
},
"services": {
"set_config": {
"name": "Set config",
Expand Down
68 changes: 68 additions & 0 deletions tests/components/logi_circle/test_init.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
"""Tests for the Logi Circle integration."""

import asyncio
from unittest.mock import AsyncMock, Mock, patch

import pytest

from homeassistant.components.logi_circle import DOMAIN
from homeassistant.config_entries import ConfigEntryState
from homeassistant.core import HomeAssistant
from homeassistant.helpers import issue_registry as ir

from tests.common import MockConfigEntry


@pytest.fixture(name="disable_platforms")
async def disable_platforms_fixture(hass):
"""Disable logi_circle platforms."""
with patch("homeassistant.components.logi_circle.PLATFORMS", []):
yield


@pytest.fixture
def mock_logi_circle():
"""Mock logi_circle."""

auth_provider_mock = Mock()
auth_provider_mock.close = AsyncMock()
auth_provider_mock.clear_authorization = AsyncMock()

with patch("homeassistant.components.logi_circle.LogiCircle") as logi_circle:
future = asyncio.Future()
future.set_result({"accountId": "testId"})
LogiCircle = logi_circle()
LogiCircle.auth_provider = auth_provider_mock
LogiCircle.synchronize_cameras = AsyncMock()
yield LogiCircle


async def test_repair_issue(
hass: HomeAssistant,
issue_registry: ir.IssueRegistry,
disable_platforms,
mock_logi_circle,
) -> None:
"""Test the LogiCircle configuration entry loading/unloading handles the repair."""
config_entry = MockConfigEntry(
title="Example 1",
domain=DOMAIN,
data={
"api_key": "blah",
"client_id": "blah",
"client_secret": "blah",
"redirect_uri": "blah",
},
)
config_entry.add_to_hass(hass)
await hass.config_entries.async_setup(config_entry.entry_id)
await hass.async_block_till_done()
assert config_entry.state is ConfigEntryState.LOADED
assert issue_registry.async_get_issue(DOMAIN, DOMAIN)

# Remove the entry
await hass.config_entries.async_remove(config_entry.entry_id)
await hass.async_block_till_done()

assert config_entry.state is ConfigEntryState.NOT_LOADED
assert issue_registry.async_get_issue(DOMAIN, DOMAIN) is None