7a0da7932b
OSV-Scanner (Scheduled) / scan-scheduled (push) Failing after 0s
Create Release / test-gate (push) Has been cancelled
Create Release / release-gate (push) Has been cancelled
Create Release / ci-gate (push) Has been cancelled
Create Release / version-check (push) Has been cancelled
Create Release / e2e-test-gate (push) Has been cancelled
Create Release / responsive-test-gate (push) Has been cancelled
Create Release / compat-test-gate (push) Has been cancelled
Create Release / compose-integration-gate (push) Has been cancelled
Create Release / vulture-gate (push) Has been cancelled
Create Release / build (push) Has been cancelled
Create Release / provenance (push) Has been cancelled
Create Release / prerelease-docker (push) Has been cancelled
Create Release / publish-docker (push) Has been cancelled
Create Release / create-release (push) Has been cancelled
Create Release / cleanup-changelog (push) Has been cancelled
Create Release / trigger-pypi (push) Has been cancelled
Create Release / monitor-pypi (push) Has been cancelled
Create Release / Clean up orphan prerelease tags and signatures (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [research-form] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [research-metrics] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [research-workflow] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [settings-core] (push) Has been cancelled
CodeQL Advanced / Analyze (javascript-typescript) (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [history-news] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [library] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [link-analytics] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [chat-core] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [chat-lifecycle] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [error-benchmark] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [settings-pages] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) (push) Has been cancelled
Docker Tests (Consolidated) / Accessibility Tests (push) Has been cancelled
Docker Tests (Consolidated) / LLM Unit Tests (push) Has been cancelled
Docker Tests (Consolidated) / LLM Example Tests (push) Has been cancelled
Docker Tests (Consolidated) / Production Image Smoke Test (push) Has been cancelled
Docker Tests (Consolidated) / Infrastructure Tests (push) Has been cancelled
OSSF Scorecard / OSSF Security Scorecard Analysis (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [mobile] (push) Has been cancelled
Backwards Compatibility / Verify Encryption Constants (push) Has been cancelled
Backwards Compatibility / PyPI Version Compatibility (push) Has been cancelled
Backwards Compatibility / Database Migration Tests (push) Has been cancelled
CodeQL Advanced / Analyze (python) (push) Has been cancelled
Docker Tests (Consolidated) / detect-changes (push) Has been cancelled
Docker Tests (Consolidated) / Build Test Image (push) Has been cancelled
Docker Tests (Consolidated) / All Pytest Tests + Coverage (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [accessibility] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [api-crud] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [auth-login] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [auth-pages] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [auth-register] (push) Has been cancelled
592 lines
21 KiB
Python
592 lines
21 KiB
Python
"""
|
|
Tests for news/folder_manager.py
|
|
|
|
Tests cover:
|
|
- FolderManager initialization
|
|
- _sub_to_dict - subscription to dictionary conversion
|
|
- update_subscription - update logic with refresh interval recalculation
|
|
- get_subscription_stats - statistics calculation
|
|
- Folder CRUD operations
|
|
"""
|
|
|
|
from datetime import datetime, timezone, timedelta
|
|
from unittest.mock import MagicMock, patch
|
|
|
|
|
|
class TestFolderManagerInit:
|
|
"""Tests for FolderManager initialization."""
|
|
|
|
def test_init_stores_session(self):
|
|
"""Test that initialization stores the session."""
|
|
from local_deep_research.news.folder_manager import FolderManager
|
|
|
|
mock_session = MagicMock()
|
|
manager = FolderManager(mock_session)
|
|
|
|
assert manager.session == mock_session
|
|
|
|
|
|
class TestSubToDict:
|
|
"""Tests for _sub_to_dict method."""
|
|
|
|
def test_sub_to_dict_includes_id(self):
|
|
"""Test that _sub_to_dict includes the subscription id."""
|
|
from local_deep_research.news.folder_manager import FolderManager
|
|
|
|
mock_session = MagicMock()
|
|
manager = FolderManager(mock_session)
|
|
|
|
mock_sub = MagicMock()
|
|
mock_sub.id = "sub-123"
|
|
mock_sub.subscription_type = "search"
|
|
mock_sub.query_or_topic = "test query"
|
|
mock_sub.created_at = datetime.now(timezone.utc)
|
|
mock_sub.last_refresh = None
|
|
mock_sub.next_refresh = None
|
|
mock_sub.refresh_interval_minutes = 60
|
|
mock_sub.status = "active"
|
|
|
|
result = manager._sub_to_dict(mock_sub)
|
|
|
|
assert result["id"] == "sub-123"
|
|
|
|
def test_sub_to_dict_includes_type(self):
|
|
"""Test that _sub_to_dict includes subscription type."""
|
|
from local_deep_research.news.folder_manager import FolderManager
|
|
|
|
mock_session = MagicMock()
|
|
manager = FolderManager(mock_session)
|
|
|
|
mock_sub = MagicMock()
|
|
mock_sub.id = "sub-123"
|
|
mock_sub.subscription_type = "topic"
|
|
mock_sub.query_or_topic = "AI News"
|
|
mock_sub.created_at = datetime.now(timezone.utc)
|
|
mock_sub.last_refresh = None
|
|
mock_sub.next_refresh = None
|
|
mock_sub.refresh_interval_minutes = 60
|
|
mock_sub.status = "active"
|
|
|
|
result = manager._sub_to_dict(mock_sub)
|
|
|
|
assert result["type"] == "topic"
|
|
|
|
def test_sub_to_dict_includes_query_or_topic(self):
|
|
"""Test that _sub_to_dict includes query_or_topic."""
|
|
from local_deep_research.news.folder_manager import FolderManager
|
|
|
|
mock_session = MagicMock()
|
|
manager = FolderManager(mock_session)
|
|
|
|
mock_sub = MagicMock()
|
|
mock_sub.id = "sub-123"
|
|
mock_sub.subscription_type = "search"
|
|
mock_sub.query_or_topic = "machine learning news"
|
|
mock_sub.created_at = datetime.now(timezone.utc)
|
|
mock_sub.last_refresh = None
|
|
mock_sub.next_refresh = None
|
|
mock_sub.refresh_interval_minutes = 60
|
|
mock_sub.status = "active"
|
|
|
|
result = manager._sub_to_dict(mock_sub)
|
|
|
|
assert result["query_or_topic"] == "machine learning news"
|
|
|
|
def test_sub_to_dict_formats_created_at_iso(self):
|
|
"""Test that _sub_to_dict formats created_at as ISO string."""
|
|
from local_deep_research.news.folder_manager import FolderManager
|
|
|
|
mock_session = MagicMock()
|
|
manager = FolderManager(mock_session)
|
|
|
|
created = datetime(2024, 1, 15, 10, 30, 0, tzinfo=timezone.utc)
|
|
mock_sub = MagicMock()
|
|
mock_sub.id = "sub-123"
|
|
mock_sub.subscription_type = "search"
|
|
mock_sub.query_or_topic = "test"
|
|
mock_sub.created_at = created
|
|
mock_sub.last_refresh = None
|
|
mock_sub.next_refresh = None
|
|
mock_sub.refresh_interval_minutes = 60
|
|
mock_sub.status = "active"
|
|
|
|
result = manager._sub_to_dict(mock_sub)
|
|
|
|
assert result["created_at"] == "2024-01-15T10:30:00+00:00"
|
|
|
|
def test_sub_to_dict_handles_none_created_at(self):
|
|
"""Test that _sub_to_dict handles None created_at."""
|
|
from local_deep_research.news.folder_manager import FolderManager
|
|
|
|
mock_session = MagicMock()
|
|
manager = FolderManager(mock_session)
|
|
|
|
mock_sub = MagicMock()
|
|
mock_sub.id = "sub-123"
|
|
mock_sub.subscription_type = "search"
|
|
mock_sub.query_or_topic = "test"
|
|
mock_sub.created_at = None
|
|
mock_sub.last_refresh = None
|
|
mock_sub.next_refresh = None
|
|
mock_sub.refresh_interval_minutes = 60
|
|
mock_sub.status = "active"
|
|
|
|
result = manager._sub_to_dict(mock_sub)
|
|
|
|
assert result["created_at"] is None
|
|
|
|
def test_sub_to_dict_handles_none_last_refresh(self):
|
|
"""Test that _sub_to_dict handles None last_refresh."""
|
|
from local_deep_research.news.folder_manager import FolderManager
|
|
|
|
mock_session = MagicMock()
|
|
manager = FolderManager(mock_session)
|
|
|
|
mock_sub = MagicMock()
|
|
mock_sub.id = "sub-123"
|
|
mock_sub.subscription_type = "search"
|
|
mock_sub.query_or_topic = "test"
|
|
mock_sub.created_at = datetime.now(timezone.utc)
|
|
mock_sub.last_refresh = None
|
|
mock_sub.next_refresh = None
|
|
mock_sub.refresh_interval_minutes = 60
|
|
mock_sub.status = "active"
|
|
|
|
result = manager._sub_to_dict(mock_sub)
|
|
|
|
assert result["last_refresh"] is None
|
|
|
|
def test_sub_to_dict_formats_last_refresh_iso(self):
|
|
"""Test that _sub_to_dict formats last_refresh as ISO string."""
|
|
from local_deep_research.news.folder_manager import FolderManager
|
|
|
|
mock_session = MagicMock()
|
|
manager = FolderManager(mock_session)
|
|
|
|
last_refresh = datetime(2024, 1, 15, 12, 0, 0, tzinfo=timezone.utc)
|
|
mock_sub = MagicMock()
|
|
mock_sub.id = "sub-123"
|
|
mock_sub.subscription_type = "search"
|
|
mock_sub.query_or_topic = "test"
|
|
mock_sub.created_at = datetime.now(timezone.utc)
|
|
mock_sub.last_refresh = last_refresh
|
|
mock_sub.next_refresh = None
|
|
mock_sub.refresh_interval_minutes = 60
|
|
mock_sub.status = "active"
|
|
|
|
result = manager._sub_to_dict(mock_sub)
|
|
|
|
assert result["last_refresh"] == "2024-01-15T12:00:00+00:00"
|
|
|
|
def test_sub_to_dict_formats_next_refresh_iso(self):
|
|
"""Test that _sub_to_dict formats next_refresh as ISO string."""
|
|
from local_deep_research.news.folder_manager import FolderManager
|
|
|
|
mock_session = MagicMock()
|
|
manager = FolderManager(mock_session)
|
|
|
|
next_refresh = datetime(2024, 1, 15, 13, 0, 0, tzinfo=timezone.utc)
|
|
mock_sub = MagicMock()
|
|
mock_sub.id = "sub-123"
|
|
mock_sub.subscription_type = "search"
|
|
mock_sub.query_or_topic = "test"
|
|
mock_sub.created_at = datetime.now(timezone.utc)
|
|
mock_sub.last_refresh = None
|
|
mock_sub.next_refresh = next_refresh
|
|
mock_sub.refresh_interval_minutes = 60
|
|
mock_sub.status = "active"
|
|
|
|
result = manager._sub_to_dict(mock_sub)
|
|
|
|
assert result["next_refresh"] == "2024-01-15T13:00:00+00:00"
|
|
|
|
def test_sub_to_dict_includes_refresh_interval_minutes(self):
|
|
"""Test that _sub_to_dict includes refresh_interval_minutes."""
|
|
from local_deep_research.news.folder_manager import FolderManager
|
|
|
|
mock_session = MagicMock()
|
|
manager = FolderManager(mock_session)
|
|
|
|
mock_sub = MagicMock()
|
|
mock_sub.id = "sub-123"
|
|
mock_sub.subscription_type = "search"
|
|
mock_sub.query_or_topic = "test"
|
|
mock_sub.created_at = datetime.now(timezone.utc)
|
|
mock_sub.last_refresh = None
|
|
mock_sub.next_refresh = None
|
|
mock_sub.refresh_interval_minutes = 120
|
|
mock_sub.status = "active"
|
|
|
|
result = manager._sub_to_dict(mock_sub)
|
|
|
|
assert result["refresh_interval_minutes"] == 120
|
|
|
|
def test_sub_to_dict_includes_status(self):
|
|
"""Test that _sub_to_dict includes status."""
|
|
from local_deep_research.news.folder_manager import FolderManager
|
|
|
|
mock_session = MagicMock()
|
|
manager = FolderManager(mock_session)
|
|
|
|
mock_sub = MagicMock()
|
|
mock_sub.id = "sub-123"
|
|
mock_sub.subscription_type = "search"
|
|
mock_sub.query_or_topic = "test"
|
|
mock_sub.created_at = datetime.now(timezone.utc)
|
|
mock_sub.last_refresh = None
|
|
mock_sub.next_refresh = None
|
|
mock_sub.refresh_interval_minutes = 60
|
|
mock_sub.status = "paused"
|
|
|
|
result = manager._sub_to_dict(mock_sub)
|
|
|
|
assert result["status"] == "paused"
|
|
|
|
|
|
class TestUpdateSubscription:
|
|
"""Tests for update_subscription method."""
|
|
|
|
def test_update_returns_none_for_nonexistent(self):
|
|
"""Test that update_subscription returns None for nonexistent subscription."""
|
|
from local_deep_research.news.folder_manager import FolderManager
|
|
|
|
mock_session = MagicMock()
|
|
mock_query = MagicMock()
|
|
mock_query.filter_by.return_value.first.return_value = None
|
|
mock_session.query.return_value = mock_query
|
|
|
|
manager = FolderManager(mock_session)
|
|
|
|
result = manager.update_subscription("nonexistent-id", status="paused")
|
|
|
|
assert result is None
|
|
|
|
def test_update_changes_status(self):
|
|
"""Test that update_subscription changes status."""
|
|
from local_deep_research.news.folder_manager import FolderManager
|
|
|
|
mock_session = MagicMock()
|
|
mock_sub = MagicMock()
|
|
mock_sub.id = "sub-123"
|
|
mock_sub.status = "active"
|
|
mock_sub.updated_at = None
|
|
|
|
mock_query = MagicMock()
|
|
mock_query.filter_by.return_value.first.return_value = mock_sub
|
|
mock_session.query.return_value = mock_query
|
|
|
|
manager = FolderManager(mock_session)
|
|
|
|
result = manager.update_subscription("sub-123", status="paused")
|
|
|
|
assert mock_sub.status == "paused"
|
|
assert result == mock_sub
|
|
|
|
def test_update_recalculates_next_refresh_with_last_refresh(self):
|
|
"""Test that updating refresh_interval_minutes recalculates next_refresh based on last_refresh."""
|
|
from local_deep_research.news.folder_manager import FolderManager
|
|
|
|
mock_session = MagicMock()
|
|
mock_sub = MagicMock()
|
|
mock_sub.id = "sub-123"
|
|
mock_sub.last_refresh = datetime(
|
|
2024, 1, 15, 10, 0, 0, tzinfo=timezone.utc
|
|
)
|
|
mock_sub.next_refresh = datetime(
|
|
2024, 1, 15, 11, 0, 0, tzinfo=timezone.utc
|
|
) # Old: 60 min
|
|
mock_sub.updated_at = None
|
|
|
|
mock_query = MagicMock()
|
|
mock_query.filter_by.return_value.first.return_value = mock_sub
|
|
mock_session.query.return_value = mock_query
|
|
|
|
manager = FolderManager(mock_session)
|
|
|
|
# Change to 120 minutes
|
|
manager.update_subscription("sub-123", refresh_interval_minutes=120)
|
|
|
|
# next_refresh should be last_refresh + 120 minutes
|
|
expected_next = datetime(2024, 1, 15, 12, 0, 0, tzinfo=timezone.utc)
|
|
assert mock_sub.next_refresh == expected_next
|
|
|
|
def test_update_recalculates_next_refresh_without_last_refresh(self):
|
|
"""Test that updating refresh_interval_minutes calculates from now when no last_refresh."""
|
|
from local_deep_research.news.folder_manager import FolderManager
|
|
|
|
mock_session = MagicMock()
|
|
mock_sub = MagicMock()
|
|
mock_sub.id = "sub-123"
|
|
mock_sub.last_refresh = None
|
|
mock_sub.next_refresh = None
|
|
mock_sub.updated_at = None
|
|
|
|
mock_query = MagicMock()
|
|
mock_query.filter_by.return_value.first.return_value = mock_sub
|
|
mock_session.query.return_value = mock_query
|
|
|
|
manager = FolderManager(mock_session)
|
|
|
|
before = datetime.now(timezone.utc)
|
|
manager.update_subscription("sub-123", refresh_interval_minutes=60)
|
|
after = datetime.now(timezone.utc)
|
|
|
|
# next_refresh should be approximately now + 60 minutes
|
|
expected_min = before + timedelta(minutes=60)
|
|
expected_max = after + timedelta(minutes=60)
|
|
assert expected_min <= mock_sub.next_refresh <= expected_max
|
|
|
|
def test_update_sets_updated_at(self):
|
|
"""Test that update_subscription sets updated_at."""
|
|
from local_deep_research.news.folder_manager import FolderManager
|
|
|
|
mock_session = MagicMock()
|
|
mock_sub = MagicMock()
|
|
mock_sub.id = "sub-123"
|
|
mock_sub.updated_at = None
|
|
|
|
mock_query = MagicMock()
|
|
mock_query.filter_by.return_value.first.return_value = mock_sub
|
|
mock_session.query.return_value = mock_query
|
|
|
|
manager = FolderManager(mock_session)
|
|
|
|
before = datetime.now(timezone.utc)
|
|
manager.update_subscription("sub-123", status="paused")
|
|
after = datetime.now(timezone.utc)
|
|
|
|
assert mock_sub.updated_at is not None
|
|
assert before <= mock_sub.updated_at <= after
|
|
|
|
def test_update_does_not_modify_id(self):
|
|
"""Test that update_subscription does not modify id."""
|
|
from local_deep_research.news.folder_manager import FolderManager
|
|
|
|
mock_session = MagicMock()
|
|
mock_sub = MagicMock()
|
|
mock_sub.id = "sub-123"
|
|
mock_sub.updated_at = None
|
|
|
|
mock_query = MagicMock()
|
|
mock_query.filter_by.return_value.first.return_value = mock_sub
|
|
mock_session.query.return_value = mock_query
|
|
|
|
manager = FolderManager(mock_session)
|
|
|
|
# Try to update id (should be ignored)
|
|
manager.update_subscription("sub-123", id="new-id")
|
|
|
|
assert mock_sub.id == "sub-123"
|
|
|
|
def test_update_does_not_modify_created_at(self):
|
|
"""Test that update_subscription does not modify created_at."""
|
|
from local_deep_research.news.folder_manager import FolderManager
|
|
|
|
mock_session = MagicMock()
|
|
original_created = datetime(2024, 1, 1, 0, 0, 0, tzinfo=timezone.utc)
|
|
mock_sub = MagicMock()
|
|
mock_sub.id = "sub-123"
|
|
mock_sub.created_at = original_created
|
|
mock_sub.updated_at = None
|
|
|
|
mock_query = MagicMock()
|
|
mock_query.filter_by.return_value.first.return_value = mock_sub
|
|
mock_session.query.return_value = mock_query
|
|
|
|
manager = FolderManager(mock_session)
|
|
|
|
# Try to update created_at (should be ignored)
|
|
new_created = datetime(2024, 6, 1, 0, 0, 0, tzinfo=timezone.utc)
|
|
manager.update_subscription("sub-123", created_at=new_created)
|
|
|
|
assert mock_sub.created_at == original_created
|
|
|
|
|
|
class TestGetSubscriptionStats:
|
|
"""Tests for get_subscription_stats method."""
|
|
|
|
def test_stats_includes_total_count(self):
|
|
"""Test that stats includes total count."""
|
|
from local_deep_research.news.folder_manager import FolderManager
|
|
|
|
mock_session = MagicMock()
|
|
mock_session.query.return_value.count.return_value = 10
|
|
mock_session.query.return_value.filter_by.return_value.count.return_value = 5
|
|
mock_session.query.return_value.order_by.return_value.all.return_value = []
|
|
|
|
manager = FolderManager(mock_session)
|
|
|
|
result = manager.get_subscription_stats("user-123")
|
|
|
|
assert result["total"] == 10
|
|
|
|
def test_stats_includes_active_count(self):
|
|
"""Test that stats includes active count."""
|
|
from local_deep_research.news.folder_manager import FolderManager
|
|
|
|
mock_session = MagicMock()
|
|
|
|
def mock_filter_by(**kwargs):
|
|
mock_result = MagicMock()
|
|
if kwargs.get("status") == "active":
|
|
mock_result.count.return_value = 8
|
|
elif kwargs.get("subscription_type") == "search":
|
|
mock_result.count.return_value = 5
|
|
elif kwargs.get("subscription_type") == "topic":
|
|
mock_result.count.return_value = 3
|
|
else:
|
|
mock_result.count.return_value = 0
|
|
return mock_result
|
|
|
|
mock_session.query.return_value.count.return_value = 10
|
|
mock_session.query.return_value.filter_by = mock_filter_by
|
|
mock_session.query.return_value.order_by.return_value.all.return_value = []
|
|
|
|
manager = FolderManager(mock_session)
|
|
|
|
result = manager.get_subscription_stats("user-123")
|
|
|
|
assert result["active"] == 8
|
|
|
|
def test_stats_includes_by_type(self):
|
|
"""Test that stats includes counts by type."""
|
|
from local_deep_research.news.folder_manager import FolderManager
|
|
|
|
mock_session = MagicMock()
|
|
|
|
type_counts = {"search": 5, "topic": 3}
|
|
|
|
def mock_filter_by(**kwargs):
|
|
mock_result = MagicMock()
|
|
sub_type = kwargs.get("subscription_type")
|
|
status = kwargs.get("status")
|
|
if sub_type and status == "active":
|
|
mock_result.count.return_value = type_counts.get(sub_type, 0)
|
|
elif status == "active":
|
|
mock_result.count.return_value = 8
|
|
else:
|
|
mock_result.count.return_value = 0
|
|
return mock_result
|
|
|
|
mock_session.query.return_value.count.return_value = 10
|
|
mock_session.query.return_value.filter_by = mock_filter_by
|
|
mock_session.query.return_value.order_by.return_value.all.return_value = []
|
|
|
|
manager = FolderManager(mock_session)
|
|
|
|
result = manager.get_subscription_stats("user-123")
|
|
|
|
assert "by_type" in result
|
|
assert result["by_type"]["search"] == 5
|
|
assert result["by_type"]["topic"] == 3
|
|
|
|
def test_stats_includes_folder_count(self):
|
|
"""Test that stats includes folder count."""
|
|
from local_deep_research.news.folder_manager import FolderManager
|
|
|
|
mock_session = MagicMock()
|
|
mock_session.query.return_value.count.return_value = 10
|
|
mock_session.query.return_value.filter_by.return_value.count.return_value = 5
|
|
mock_session.query.return_value.order_by.return_value.all.return_value = [
|
|
MagicMock(),
|
|
MagicMock(),
|
|
MagicMock(), # 3 folders
|
|
]
|
|
|
|
manager = FolderManager(mock_session)
|
|
|
|
result = manager.get_subscription_stats("user-123")
|
|
|
|
assert result["folders"] == 3
|
|
|
|
|
|
class TestDeleteSubscription:
|
|
"""Tests for delete_subscription method."""
|
|
|
|
def test_delete_returns_false_for_nonexistent(self):
|
|
"""Test that delete_subscription returns False for nonexistent subscription."""
|
|
from local_deep_research.news.folder_manager import FolderManager
|
|
|
|
mock_session = MagicMock()
|
|
mock_query = MagicMock()
|
|
mock_query.filter_by.return_value.first.return_value = None
|
|
mock_session.query.return_value = mock_query
|
|
|
|
manager = FolderManager(mock_session)
|
|
|
|
result = manager.delete_subscription("nonexistent-id")
|
|
|
|
assert result is False
|
|
|
|
def test_delete_returns_true_for_success(self):
|
|
"""Test that delete_subscription returns True on success."""
|
|
from local_deep_research.news.folder_manager import FolderManager
|
|
|
|
mock_session = MagicMock()
|
|
mock_sub = MagicMock()
|
|
mock_query = MagicMock()
|
|
mock_query.filter_by.return_value.first.return_value = mock_sub
|
|
mock_session.query.return_value = mock_query
|
|
|
|
manager = FolderManager(mock_session)
|
|
|
|
result = manager.delete_subscription("sub-123")
|
|
|
|
assert result is True
|
|
mock_session.delete.assert_called_once_with(mock_sub)
|
|
mock_session.commit.assert_called_once()
|
|
|
|
|
|
class TestGetUserFolders:
|
|
"""Tests for get_user_folders method."""
|
|
|
|
def test_returns_all_folders_ordered_by_name(self):
|
|
"""Test that get_user_folders returns folders ordered by name."""
|
|
from local_deep_research.news.folder_manager import FolderManager
|
|
|
|
mock_session = MagicMock()
|
|
mock_folders = [MagicMock(name="Alpha"), MagicMock(name="Beta")]
|
|
|
|
mock_query = MagicMock()
|
|
mock_query.order_by.return_value.all.return_value = mock_folders
|
|
mock_session.query.return_value = mock_query
|
|
|
|
manager = FolderManager(mock_session)
|
|
|
|
result = manager.get_user_folders("user-123")
|
|
|
|
assert result == mock_folders
|
|
|
|
|
|
class TestCreateFolder:
|
|
"""Tests for create_folder method."""
|
|
|
|
def test_create_folder_with_name_only(self):
|
|
"""Test creating folder with name only."""
|
|
from local_deep_research.news.folder_manager import FolderManager
|
|
|
|
mock_session = MagicMock()
|
|
manager = FolderManager(mock_session)
|
|
|
|
with patch("uuid.uuid4") as mock_uuid:
|
|
mock_uuid.return_value = MagicMock(__str__=lambda x: "test-uuid")
|
|
manager.create_folder("My Folder")
|
|
|
|
mock_session.add.assert_called_once()
|
|
mock_session.commit.assert_called_once()
|
|
|
|
def test_create_folder_with_description(self):
|
|
"""Test creating folder with description."""
|
|
from local_deep_research.news.folder_manager import FolderManager
|
|
|
|
mock_session = MagicMock()
|
|
manager = FolderManager(mock_session)
|
|
|
|
with patch("uuid.uuid4") as mock_uuid:
|
|
mock_uuid.return_value = MagicMock(__str__=lambda x: "test-uuid")
|
|
manager.create_folder("My Folder", description="A test folder")
|
|
|
|
mock_session.add.assert_called_once()
|
|
added_folder = mock_session.add.call_args[0][0]
|
|
assert added_folder.description == "A test folder"
|