Files
haos-hacs-immich-album-watcher/packages/core/tests/test_notification_queue.py
alexei.dolgolyov d0783d0b6a
Some checks failed
Validate / Hassfest (push) Has been cancelled
Add shared core library and architecture plans (Phase 1)
Extract HA-independent logic from the integration into packages/core/
as a standalone Python library (immich-watcher-core). This is the first
phase of restructuring the project to support a standalone web app
alongside the existing HAOS integration.

Core library modules:
- models: SharedLinkInfo, AssetInfo, AlbumData, AlbumChange dataclasses
- immich_client: Async Immich API client (aiohttp, session-injected)
- change_detector: Pure function for album change detection
- asset_utils: Filtering, sorting, URL building utilities
- telegram/client: Full Telegram Bot API (text, photo, video, media groups)
- telegram/cache: File ID cache with pluggable storage backend
- telegram/media: Media size checks, URL extraction, group splitting
- notifications/queue: Persistent notification queue
- storage: StorageBackend protocol + JSON file implementation

All modules have zero Home Assistant imports. 50 unit tests passing.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 12:40:08 +03:00

84 lines
2.5 KiB
Python

"""Tests for notification queue."""
import pytest
from typing import Any
from immich_watcher_core.notifications.queue import NotificationQueue
class InMemoryBackend:
"""In-memory storage backend for testing."""
def __init__(self, initial_data: dict[str, Any] | None = None):
self._data = initial_data
async def load(self) -> dict[str, Any] | None:
return self._data
async def save(self, data: dict[str, Any]) -> None:
self._data = data
async def remove(self) -> None:
self._data = None
@pytest.fixture
def backend():
return InMemoryBackend()
class TestNotificationQueue:
@pytest.mark.asyncio
async def test_empty_queue(self, backend):
queue = NotificationQueue(backend)
await queue.async_load()
assert not queue.has_pending()
assert queue.get_all() == []
@pytest.mark.asyncio
async def test_enqueue_and_get(self, backend):
queue = NotificationQueue(backend)
await queue.async_load()
await queue.async_enqueue({"chat_id": "123", "text": "Hello"})
assert queue.has_pending()
items = queue.get_all()
assert len(items) == 1
assert items[0]["params"]["chat_id"] == "123"
@pytest.mark.asyncio
async def test_multiple_enqueue(self, backend):
queue = NotificationQueue(backend)
await queue.async_load()
await queue.async_enqueue({"msg": "first"})
await queue.async_enqueue({"msg": "second"})
assert len(queue.get_all()) == 2
@pytest.mark.asyncio
async def test_clear(self, backend):
queue = NotificationQueue(backend)
await queue.async_load()
await queue.async_enqueue({"msg": "test"})
await queue.async_clear()
assert not queue.has_pending()
@pytest.mark.asyncio
async def test_remove_indices(self, backend):
queue = NotificationQueue(backend)
await queue.async_load()
await queue.async_enqueue({"msg": "first"})
await queue.async_enqueue({"msg": "second"})
await queue.async_enqueue({"msg": "third"})
# Remove indices in descending order
await queue.async_remove_indices([2, 0])
items = queue.get_all()
assert len(items) == 1
assert items[0]["params"]["msg"] == "second"
@pytest.mark.asyncio
async def test_remove_all(self, backend):
queue = NotificationQueue(backend)
await queue.async_load()
await queue.async_enqueue({"msg": "test"})
await queue.async_remove()
assert backend._data is None