152 lines
5.2 KiB
Python
152 lines
5.2 KiB
Python
"""Tests for NotificationsRepository."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import pytest
|
|
import pytest_asyncio
|
|
|
|
from app.features.notifications.repository import NotificationsRepository
|
|
from app.library.sqlite_store import SqliteStore
|
|
from app.tests.helpers import make_in_memory_db_path
|
|
|
|
|
|
@pytest_asyncio.fixture
|
|
async def repo():
|
|
"""Provide a fresh repository instance with initialized database for each test."""
|
|
NotificationsRepository._reset_singleton()
|
|
SqliteStore._reset_singleton()
|
|
|
|
store = SqliteStore(db_path=make_in_memory_db_path("notifications-repository"))
|
|
await store.get_connection()
|
|
|
|
repository = NotificationsRepository.get_instance()
|
|
|
|
yield repository
|
|
|
|
await store.close()
|
|
|
|
NotificationsRepository._reset_singleton()
|
|
SqliteStore._reset_singleton()
|
|
|
|
|
|
class TestNotificationsRepository:
|
|
"""Test suite for NotificationsRepository database operations."""
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_list_empty(self, repo):
|
|
"""List returns empty when no notifications exist."""
|
|
notifications = await repo.all()
|
|
assert notifications == [], "Should return empty list when no notifications exist"
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_create_notification(self, repo):
|
|
"""Create notification with valid data."""
|
|
payload = {
|
|
"name": "Webhook",
|
|
"on": ["item_completed"],
|
|
"presets": [],
|
|
"enabled": True,
|
|
"request_url": "https://example.com/webhook",
|
|
"request_method": "POST",
|
|
"request_type": "json",
|
|
"request_data_key": "data",
|
|
"request_headers": [{"key": "Authorization", "value": "Bearer token"}],
|
|
}
|
|
|
|
model = await repo.create(payload)
|
|
|
|
assert model.id is not None, "Should generate ID for new notification"
|
|
assert model.name == "Webhook", "Should store name correctly"
|
|
assert model.request_url == "https://example.com/webhook", "Should store request url"
|
|
assert model.request_method == "POST", "Should store request method"
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_get_by_id(self, repo):
|
|
"""Get notification by integer ID."""
|
|
created = await repo.create(
|
|
{
|
|
"name": "Get Test",
|
|
"on": [],
|
|
"presets": [],
|
|
"enabled": True,
|
|
"request_url": "https://example.com",
|
|
"request_method": "POST",
|
|
"request_type": "json",
|
|
"request_data_key": "data",
|
|
"request_headers": [],
|
|
}
|
|
)
|
|
|
|
retrieved = await repo.get(created.id)
|
|
|
|
assert retrieved is not None, "Should retrieve created notification"
|
|
assert retrieved.id == created.id, "Should match created notification id"
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_update_notification(self, repo):
|
|
"""Update existing notification."""
|
|
created = await repo.create(
|
|
{
|
|
"name": "Update Test",
|
|
"on": [],
|
|
"presets": [],
|
|
"enabled": True,
|
|
"request_url": "https://example.com",
|
|
"request_method": "POST",
|
|
"request_type": "json",
|
|
"request_data_key": "data",
|
|
"request_headers": [],
|
|
}
|
|
)
|
|
|
|
updated = await repo.update(created.id, {"name": "Updated Name", "enabled": False})
|
|
|
|
assert updated.name == "Updated Name", "Should update name"
|
|
assert updated.enabled is False, "Should update enabled flag"
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_delete_notification(self, repo):
|
|
"""Delete existing notification."""
|
|
created = await repo.create(
|
|
{
|
|
"name": "Delete Test",
|
|
"on": [],
|
|
"presets": [],
|
|
"enabled": True,
|
|
"request_url": "https://example.com",
|
|
"request_method": "POST",
|
|
"request_type": "json",
|
|
"request_data_key": "data",
|
|
"request_headers": [],
|
|
}
|
|
)
|
|
|
|
deleted = await repo.delete(created.id)
|
|
|
|
assert deleted.id == created.id, "Should return deleted notification"
|
|
assert await repo.get(created.id) is None, "Deleted notification should not be retrievable"
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_list_paginated(self, repo):
|
|
"""List paginated returns correct subset."""
|
|
for i in range(4):
|
|
await repo.create(
|
|
{
|
|
"name": f"Item {i}",
|
|
"on": [],
|
|
"presets": [],
|
|
"enabled": True,
|
|
"request_url": "https://example.com",
|
|
"request_method": "POST",
|
|
"request_type": "json",
|
|
"request_data_key": "data",
|
|
"request_headers": [],
|
|
}
|
|
)
|
|
|
|
items, total, page, total_pages = await repo.list_paginated(page=1, per_page=2)
|
|
|
|
assert len(items) == 2, "Should return 2 items per page"
|
|
assert total == 4, "Should report total count of 4"
|
|
assert page == 1, "Should be on page 1"
|
|
assert total_pages == 2, "Should have 2 pages total"
|