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
300 lines
8.9 KiB
Python
300 lines
8.9 KiB
Python
"""
|
|
Tests for news/core/base_card.py
|
|
|
|
Tests cover:
|
|
- CardSource dataclass
|
|
- CardVersion dataclass
|
|
- BaseCard abstract class
|
|
- Card initialization and field generation
|
|
"""
|
|
|
|
import pytest
|
|
from unittest.mock import Mock
|
|
from dataclasses import is_dataclass
|
|
from abc import ABC
|
|
|
|
|
|
class TestCardSourceDataclass:
|
|
"""Tests for CardSource dataclass."""
|
|
|
|
def test_card_source_is_dataclass(self):
|
|
"""CardSource is a dataclass."""
|
|
from local_deep_research.news.core.base_card import CardSource
|
|
|
|
assert is_dataclass(CardSource)
|
|
|
|
def test_card_source_required_type_field(self):
|
|
"""CardSource requires type field."""
|
|
from local_deep_research.news.core.base_card import CardSource
|
|
|
|
source = CardSource(type="news_item")
|
|
assert source.type == "news_item"
|
|
|
|
def test_card_source_optional_fields_defaults(self):
|
|
"""CardSource has optional fields with defaults."""
|
|
from local_deep_research.news.core.base_card import CardSource
|
|
|
|
source = CardSource(type="test")
|
|
|
|
assert source.source_id is None
|
|
assert source.created_from == ""
|
|
assert source.metadata == {}
|
|
|
|
def test_card_source_custom_metadata(self):
|
|
"""CardSource accepts custom metadata."""
|
|
from local_deep_research.news.core.base_card import CardSource
|
|
|
|
source = CardSource(
|
|
type="test",
|
|
metadata={"query": "test query", "timestamp": "2024-01-01"},
|
|
)
|
|
|
|
assert source.metadata["query"] == "test query"
|
|
assert source.metadata["timestamp"] == "2024-01-01"
|
|
|
|
|
|
class TestCardVersionDataclass:
|
|
"""Tests for CardVersion dataclass."""
|
|
|
|
def test_card_version_is_dataclass(self):
|
|
"""CardVersion is a dataclass."""
|
|
from local_deep_research.news.core.base_card import CardVersion
|
|
|
|
assert is_dataclass(CardVersion)
|
|
|
|
def test_card_version_initialization(self):
|
|
"""CardVersion initializes with required fields."""
|
|
from local_deep_research.news.core.base_card import CardVersion
|
|
from datetime import datetime
|
|
|
|
version = CardVersion(
|
|
version_id="v1",
|
|
created_at=datetime.now(),
|
|
content={"result": "test"},
|
|
query_used="test query",
|
|
)
|
|
|
|
assert version.version_id == "v1"
|
|
assert version.query_used == "test query"
|
|
assert version.content == {"result": "test"}
|
|
|
|
def test_card_version_optional_search_strategy(self):
|
|
"""CardVersion has optional search_strategy."""
|
|
from local_deep_research.news.core.base_card import CardVersion
|
|
from datetime import datetime
|
|
|
|
version = CardVersion(
|
|
version_id="v1",
|
|
created_at=datetime.now(),
|
|
content={},
|
|
query_used="test",
|
|
)
|
|
|
|
assert version.search_strategy is None
|
|
|
|
def test_card_version_generates_id_if_empty(self):
|
|
"""CardVersion generates ID if provided ID is empty."""
|
|
from local_deep_research.news.core.base_card import CardVersion
|
|
from datetime import datetime
|
|
|
|
version = CardVersion(
|
|
version_id="",
|
|
created_at=datetime.now(),
|
|
content={},
|
|
query_used="test",
|
|
)
|
|
|
|
assert version.version_id != ""
|
|
assert len(version.version_id) > 0
|
|
|
|
|
|
class TestBaseCardClass:
|
|
"""Tests for BaseCard abstract class."""
|
|
|
|
def test_base_card_is_abstract(self):
|
|
"""BaseCard is an abstract class."""
|
|
from local_deep_research.news.core.base_card import BaseCard
|
|
|
|
assert issubclass(BaseCard, ABC)
|
|
|
|
def test_base_card_is_dataclass(self):
|
|
"""BaseCard is a dataclass."""
|
|
from local_deep_research.news.core.base_card import BaseCard
|
|
|
|
assert is_dataclass(BaseCard)
|
|
|
|
|
|
class TestConcreteCard:
|
|
"""Tests using a concrete implementation of BaseCard."""
|
|
|
|
@pytest.fixture
|
|
def card_source(self):
|
|
"""Create a card source."""
|
|
from local_deep_research.news.core.base_card import CardSource
|
|
|
|
return CardSource(type="test")
|
|
|
|
@pytest.fixture
|
|
def concrete_card_class(self):
|
|
"""Create a concrete card class."""
|
|
from local_deep_research.news.core.base_card import BaseCard
|
|
|
|
class TestCard(BaseCard):
|
|
def get_card_type(self):
|
|
return "test"
|
|
|
|
def to_dict(self):
|
|
return {"id": self.id, "topic": self.topic}
|
|
|
|
return TestCard
|
|
|
|
def test_card_initialization(self, concrete_card_class, card_source):
|
|
"""Card initializes with required fields."""
|
|
card = concrete_card_class(
|
|
topic="Test Topic",
|
|
source=card_source,
|
|
user_id="user123",
|
|
)
|
|
|
|
assert card.topic == "Test Topic"
|
|
assert card.source is card_source
|
|
assert card.user_id == "user123"
|
|
|
|
def test_card_generates_id(self, concrete_card_class, card_source):
|
|
"""Card generates ID when not provided."""
|
|
card = concrete_card_class(
|
|
topic="Test Topic",
|
|
source=card_source,
|
|
user_id="user123",
|
|
)
|
|
|
|
assert card.id is not None
|
|
assert len(card.id) > 0
|
|
|
|
def test_card_uses_provided_id(self, concrete_card_class, card_source):
|
|
"""Card uses provided card_id."""
|
|
card = concrete_card_class(
|
|
topic="Test Topic",
|
|
source=card_source,
|
|
user_id="user123",
|
|
card_id="custom-id-123",
|
|
)
|
|
|
|
assert card.id == "custom-id-123"
|
|
|
|
def test_card_timestamps_generated(self, concrete_card_class, card_source):
|
|
"""Card generates timestamps on creation."""
|
|
card = concrete_card_class(
|
|
topic="Test Topic",
|
|
source=card_source,
|
|
user_id="user123",
|
|
)
|
|
|
|
assert card.created_at is not None
|
|
assert card.updated_at is not None
|
|
|
|
def test_card_interaction_defaults(self, concrete_card_class, card_source):
|
|
"""Card has default interaction values."""
|
|
card = concrete_card_class(
|
|
topic="Test Topic",
|
|
source=card_source,
|
|
user_id="user123",
|
|
)
|
|
|
|
assert card.interaction["votes_up"] == 0
|
|
assert card.interaction["votes_down"] == 0
|
|
assert card.interaction["views"] == 0
|
|
assert card.interaction["shares"] == 0
|
|
|
|
def test_card_empty_versions_list(self, concrete_card_class, card_source):
|
|
"""Card has empty versions list initially."""
|
|
card = concrete_card_class(
|
|
topic="Test Topic",
|
|
source=card_source,
|
|
user_id="user123",
|
|
)
|
|
|
|
assert card.versions == []
|
|
|
|
def test_card_optional_parent_id(self, concrete_card_class, card_source):
|
|
"""Card has optional parent_card_id."""
|
|
card = concrete_card_class(
|
|
topic="Test Topic",
|
|
source=card_source,
|
|
user_id="user123",
|
|
parent_card_id="parent-123",
|
|
)
|
|
|
|
assert card.parent_card_id == "parent-123"
|
|
|
|
def test_card_default_metadata(self, concrete_card_class, card_source):
|
|
"""Card has empty default metadata."""
|
|
card = concrete_card_class(
|
|
topic="Test Topic",
|
|
source=card_source,
|
|
user_id="user123",
|
|
)
|
|
|
|
assert card.metadata == {}
|
|
|
|
def test_card_custom_metadata(self, concrete_card_class, card_source):
|
|
"""Card accepts custom metadata."""
|
|
card = concrete_card_class(
|
|
topic="Test Topic",
|
|
source=card_source,
|
|
user_id="user123",
|
|
metadata={"key": "value"},
|
|
)
|
|
|
|
assert card.metadata == {"key": "value"}
|
|
|
|
|
|
class TestCardProgressCallback:
|
|
"""Tests for card progress callback."""
|
|
|
|
@pytest.fixture
|
|
def card_source(self):
|
|
"""Create a card source."""
|
|
from local_deep_research.news.core.base_card import CardSource
|
|
|
|
return CardSource(type="test")
|
|
|
|
@pytest.fixture
|
|
def concrete_card_class(self):
|
|
"""Create a concrete card class."""
|
|
from local_deep_research.news.core.base_card import BaseCard
|
|
|
|
class TestCard(BaseCard):
|
|
def get_card_type(self):
|
|
return "test"
|
|
|
|
def to_dict(self):
|
|
return {"id": self.id, "topic": self.topic}
|
|
|
|
return TestCard
|
|
|
|
def test_card_progress_callback_initially_none(
|
|
self, concrete_card_class, card_source
|
|
):
|
|
"""Card progress_callback is None initially."""
|
|
card = concrete_card_class(
|
|
topic="Test",
|
|
source=card_source,
|
|
user_id="user123",
|
|
)
|
|
|
|
assert card.progress_callback is None
|
|
|
|
def test_card_set_progress_callback(self, concrete_card_class, card_source):
|
|
"""Card can set progress callback."""
|
|
card = concrete_card_class(
|
|
topic="Test",
|
|
source=card_source,
|
|
user_id="user123",
|
|
)
|
|
|
|
callback = Mock()
|
|
card.set_progress_callback(callback)
|
|
|
|
assert card.progress_callback is callback
|