from __future__ import annotations from pathlib import Path from uuid import uuid4 import pytest from ragcore.application.sources import SourceConnector from ragcore.domain.sources import ( Acquisition, FolderSourceConfig, ScanResult, SourceCursor, SourceFingerprint, SourceItem, SourceValidationError, WebsiteSourceConfig, ) def _item(external_id: str = "item-1") -> SourceItem: return SourceItem( source_id=uuid4(), external_id=external_id, locator="file:///docs/item.txt", name="item.txt" ) def test_connector_contract_has_no_parse_or_publication_responsibility() -> None: assert not hasattr(SourceConnector, "parse") assert not hasattr(SourceConnector, "publish") assert {"scan", "acquire", "fingerprint"} <= set(dir(SourceConnector)) def test_partial_scan_cannot_imply_deletion() -> None: result = ScanResult( items=(_item("still-present"),), next_cursor=SourceCursor("page-2"), complete=False ) assert result.deleted_item_ids({"still-present", "temporarily-missing"}) == frozenset() complete = ScanResult(items=(_item("still-present"),), next_cursor=None, complete=True) assert complete.deleted_item_ids({"still-present", "source-deleted"}) == {"source-deleted"} def test_configs_are_typed_and_secret_safe(tmp_path: Path) -> None: config = FolderSourceConfig(tmp_path.resolve()) assert config.root == tmp_path.resolve() with pytest.raises(SourceValidationError): FolderSourceConfig(Path("relative/root")) with pytest.raises(SourceValidationError): WebsiteSourceConfig(("example.test",), "https://other.test/sitemap.xml") with pytest.raises(SourceValidationError): SourceItem( source_id=uuid4(), external_id="secret-item", locator="https://example.test/item", name="item", metadata={"api_token": "must-not-enter-source-metadata"}, ) @pytest.mark.asyncio async def test_acquisition_is_a_stream_and_does_not_parse_or_publish() -> None: async def stream(): yield b"bytes" item = _item() acquisition = Acquisition(stream(), item, SourceFingerprint("a" * 64)) assert [part async for part in acquisition.stream] == [b"bytes"] assert not hasattr(acquisition, "parsed_document") assert not hasattr(acquisition, "publication")