Skip to content

Commit

Permalink
Initial WIP commit
Browse files Browse the repository at this point in the history
  • Loading branch information
watkins-matt committed Aug 25, 2024
1 parent 65a1f61 commit 05a4848
Show file tree
Hide file tree
Showing 3 changed files with 116 additions and 6 deletions.
51 changes: 51 additions & 0 deletions custom_components/google_keep_sync/coordinator.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ def __init__(
)
self.api = api
self.config_entry = entry
self._user_named_entities = set()
_LOGGER.debug("GoogleKeepSyncCoordinator initialized")

async def _async_update_data(self) -> list[GKeepList]:
Expand Down Expand Up @@ -72,6 +73,9 @@ async def _async_update_data(self) -> list[GKeepList]:
)
_LOGGER.debug("Data sync completed. Received %d lists", len(synced_lists))

# Update entity names if list titles have changed
await self._update_entity_names(synced_lists)

if deleted_list_ids:
_LOGGER.warning(f"The following lists were deleted: {deleted_list_ids}")
# Remove entities for deleted lists
Expand Down Expand Up @@ -239,3 +243,50 @@ async def _remove_deleted_entities(self, deleted_list_ids: list[str]):
"Deleted entity removal process completed. Removed "
f"{removed_entities} entities."
)

async def _update_entity_names(self, synced_lists: list[GKeepList]):
"""Update entity names if list titles have changed."""
entity_registry = async_get_entity_registry(self.hass)
list_prefix = self.config_entry.data.get("list_prefix", "")

_LOGGER.debug(
"Starting entity name update process for %d lists", len(synced_lists)
)

for gkeep_list in synced_lists:
entity_unique_id = f"{DOMAIN}.list.{gkeep_list.id}"
entity_id = entity_registry.async_get_entity_id(
Platform.TODO, DOMAIN, entity_unique_id
)

if not entity_id:
_LOGGER.warning(
"No entity_id found for unique_id: %s", entity_unique_id
)
continue

entity = entity_registry.async_get(entity_id)
if not entity:
_LOGGER.warning("Entity not found in registry for ID: %s", entity_id)
continue

new_name = f"{list_prefix} {gkeep_list.title}".strip()

if entity.name:
if entity_id not in self._user_named_entities:
_LOGGER.info(
"Entity %s has a user-defined name. It will not be automatically updated.",
entity_id,
)
self._user_named_entities.add(entity_id)
continue

current_name = entity.original_name

if current_name != new_name:
_LOGGER.info(
"Updating entity name from '%s' to '%s'", current_name, new_name
)
entity_registry.async_update_entity(entity_id, original_name=new_name)

_LOGGER.debug("Completed entity name update process")
12 changes: 12 additions & 0 deletions custom_components/google_keep_sync/todo.py
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,18 @@ async def async_create_todo_item(self, item: TodoItem) -> None:
await self.coordinator.async_refresh()
_LOGGER.debug("Requested data refresh after item creation.")

def _handle_coordinator_update(self) -> None:
"""Handle updated data from the coordinator."""
for gkeep_list in self.coordinator.data:
if gkeep_list.id == self._gkeep_list_id:
self._gkeep_list = gkeep_list
list_prefix = self.coordinator.config_entry.data.get("list_prefix", "")
new_name = f"{list_prefix} {gkeep_list.title}".strip()
if self._attr_name != new_name:
self._attr_name = new_name
break
super()._handle_coordinator_update()

@property
def todo_items(self) -> list[TodoItem]:
"""Get the current set of To-do items, filtering out empty entries."""
Expand Down
59 changes: 53 additions & 6 deletions tests/test_coordinator.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
"""Unit tests for the todo component."""

import logging
from unittest.mock import AsyncMock, MagicMock, patch

import pytest
Expand Down Expand Up @@ -37,16 +38,62 @@ def mock_api():
async def test_async_update_data(
mock_api: MagicMock, mock_hass: MagicMock, mock_config_entry: MockConfigEntry
):
"""Test update_data method."""
"""Test update_data method with debugging."""
with patch.object(mock_api, "async_sync_data", AsyncMock()):
mock_api.async_sync_data.return_value = ["list1", "list2"], []
# Create MagicMock objects for the lists
mock_list1 = MagicMock()
mock_list1.id = "1"
mock_list1.title = "list1"
mock_list2 = MagicMock()
mock_list2.id = "2"
mock_list2.title = "list2"

mock_lists = [mock_list1, mock_list2]
mock_api.async_sync_data.return_value = (mock_lists, [])

coordinator = GoogleKeepSyncCoordinator(mock_hass, mock_api, mock_config_entry)
coordinator.config_entry = mock_config_entry

result = await coordinator._async_update_data()

assert result == ["list1", "list2"], []
coordinator.config_entry.data = {
"list_prefix": "Test",
"lists_to_sync": ["1", "2"],
}

# Mock the entity registry
mock_entity_registry = MagicMock()
mock_entity_registry.async_get_entity_id.return_value = "todo.test_entity"

# Use spec_set to define allowed attributes
mock_entity = MagicMock(spec_set=["entity_id", "name", "original_name"])
mock_entity.entity_id = "todo.test_entity"
mock_entity.name = None # Explicitly set to None
mock_entity.original_name = "Old Name"
mock_entity_registry.async_get.return_value = mock_entity

# Add debug logging
logging.getLogger().setLevel(logging.DEBUG)

with patch(
"homeassistant.helpers.entity_registry.async_get",
return_value=mock_entity_registry,
), patch.object(
coordinator, "_update_entity_names", wraps=coordinator._update_entity_names
) as mock_update_names:
result = await coordinator._async_update_data()

assert result == mock_lists
mock_api.async_sync_data.assert_called_once()

# Debug output
print(f"mock_entity.name: {mock_entity.name}")
print(f"mock_entity.original_name: {mock_entity.original_name}")
print(f"_update_entity_names called: {mock_update_names.called}")
if mock_update_names.called:
print(f"_update_entity_names args: {mock_update_names.call_args}")

# Check if async_update_entity was called
mock_entity_registry.async_update_entity.assert_called_once_with(

Check failure on line 94 in tests/test_coordinator.py

View workflow job for this annotation

GitHub Actions / Run Tests

test_async_update_data AssertionError: Expected 'async_update_entity' to be called once. Called 0 times.
"todo.test_entity", original_name="Test list1"
)


async def test_parse_gkeep_data_dict_empty(
Expand Down

0 comments on commit 05a4848

Please sign in to comment.