""" Extended tests for model consolidation - Comprehensive model architecture validation. Tests cover: - All model imports from consolidated location - Model relationships and foreign keys - Column definitions and types - Model constraints and indexes - Enum definitions - Cross-model consistency """ from sqlalchemy import inspect class TestModelImports: """Tests for model imports from consolidated location.""" def test_benchmark_models_importable(self): """Benchmark models should be importable.""" from local_deep_research.database.models import ( BenchmarkRun, BenchmarkResult, BenchmarkProgress, ) assert BenchmarkRun is not None assert BenchmarkResult is not None assert BenchmarkProgress is not None def test_library_models_importable(self): """Library models should be importable.""" from local_deep_research.database.models import ( Document, Collection, DocumentChunk, ) assert Document is not None assert Collection is not None assert DocumentChunk is not None class TestModelRelationships: """Tests for model relationships.""" def test_benchmark_run_has_results_relationship(self): """BenchmarkRun should have results relationship.""" from local_deep_research.database.models import BenchmarkRun assert hasattr(BenchmarkRun, "results") def test_benchmark_run_has_progress_relationship(self): """BenchmarkRun should have progress_updates relationship.""" from local_deep_research.database.models import BenchmarkRun assert hasattr(BenchmarkRun, "progress_updates") def test_benchmark_result_has_run_relationship(self): """BenchmarkResult should have benchmark_run relationship.""" from local_deep_research.database.models import BenchmarkResult assert hasattr(BenchmarkResult, "benchmark_run") def test_document_has_collections_relationship(self): """Document should have collections relationship.""" from local_deep_research.database.models import Document assert hasattr(Document, "collections") def test_collection_has_documents_relationship(self): """Collection should have document_links relationship.""" from local_deep_research.database.models import Collection assert hasattr(Collection, "document_links") class TestColumnDefinitions: """Tests for model column definitions.""" def test_research_history_has_query_column(self): """ResearchHistory should have query column.""" from local_deep_research.database.models import ResearchHistory assert hasattr(ResearchHistory, "query") def test_research_history_has_status_column(self): """ResearchHistory should have status column.""" from local_deep_research.database.models import ResearchHistory assert hasattr(ResearchHistory, "status") def test_research_history_has_research_meta_column(self): """ResearchHistory should have research_meta (renamed from metadata).""" from local_deep_research.database.models import ResearchHistory assert hasattr(ResearchHistory, "research_meta") def test_research_resource_has_title_column(self): """ResearchResource should have title column.""" from local_deep_research.database.models import ResearchResource assert hasattr(ResearchResource, "title") def test_research_resource_has_url_column(self): """ResearchResource should have url column.""" from local_deep_research.database.models import ResearchResource assert hasattr(ResearchResource, "url") def test_research_resource_has_resource_metadata_column(self): """ResearchResource should have resource_metadata (renamed from metadata).""" from local_deep_research.database.models import ResearchResource assert hasattr(ResearchResource, "resource_metadata") def test_document_has_required_columns(self): """Document should have all required columns.""" from local_deep_research.database.models import Document required_columns = [ "id", "document_hash", "file_size", "file_type", "status", "created_at", ] for col in required_columns: assert hasattr(Document, col), f"Document missing column: {col}" def test_collection_has_required_columns(self): """Collection should have all required columns.""" from local_deep_research.database.models import Collection required_columns = ["id", "name", "is_default", "created_at"] for col in required_columns: assert hasattr(Collection, col), f"Collection missing column: {col}" class TestEnumDefinitions: """Tests for enum definitions.""" def test_document_status_has_expected_values(self): """DocumentStatus should have expected values.""" from local_deep_research.database.models.library import DocumentStatus assert DocumentStatus.PENDING.value == "pending" assert DocumentStatus.PROCESSING.value == "processing" assert DocumentStatus.COMPLETED.value == "completed" assert DocumentStatus.FAILED.value == "failed" def test_embedding_provider_enum_exists(self): """EmbeddingProvider enum should exist.""" from local_deep_research.database.models.library import ( EmbeddingProvider, ) assert EmbeddingProvider is not None assert ( EmbeddingProvider.SENTENCE_TRANSFORMERS.value == "sentence_transformers" ) assert EmbeddingProvider.OLLAMA.value == "ollama" # Issue #3883 — OPENAI covers the cloud API and any # OpenAI-compatible endpoint (LM Studio, vLLM, llama.cpp). assert EmbeddingProvider.OPENAI.value == "openai" def test_embedding_provider_openai_constructible_from_string(self): """EmbeddingProvider("openai") should resolve to the OPENAI member. The library RAG service stores the provider as a string and later persists it via ``EmbeddingProvider(value)``; the round-trip is the column-write path that issue #3883's acceptance criteria #1 calls out. """ from local_deep_research.database.models.library import ( EmbeddingProvider, ) assert EmbeddingProvider("openai") is EmbeddingProvider.OPENAI class TestTableNames: """Tests for correct table names.""" def test_document_table_name(self): """Document should have correct table name.""" from local_deep_research.database.models import Document assert Document.__tablename__ == "documents" def test_collection_table_name(self): """Collection should have correct table name.""" from local_deep_research.database.models import Collection assert Collection.__tablename__ == "collections" def test_document_chunk_table_name(self): """DocumentChunk should have correct table name.""" from local_deep_research.database.models import DocumentChunk assert DocumentChunk.__tablename__ == "document_chunks" def test_rag_index_table_name(self): """RAGIndex should have correct table name.""" from local_deep_research.database.models import RAGIndex assert RAGIndex.__tablename__ == "rag_indices" class TestModelConstraints: """Tests for model constraints.""" def test_document_has_unique_hash_constraint(self): """Document should have unique document_hash constraint.""" from local_deep_research.database.models import Document mapper = inspect(Document) columns = {c.name: c for c in mapper.columns} assert columns["document_hash"].unique is True def test_collection_document_has_unique_constraint(self): """DocumentCollection should have unique document-collection pair.""" from local_deep_research.database.models import DocumentCollection # Check table args for unique constraint table_args = DocumentCollection.__table_args__ has_unique = any( hasattr(arg, "name") and "uix_document_collection" in str(arg.name) for arg in table_args if hasattr(arg, "name") ) assert has_unique class TestIndexDefinitions: """Tests for index definitions.""" def test_document_has_source_type_index(self): """Document should have source_type index.""" from local_deep_research.database.models import Document table_args = Document.__table_args__ has_index = any( hasattr(arg, "name") and "idx_source_type" in str(arg.name) for arg in table_args if hasattr(arg, "name") ) assert has_index def test_document_chunk_has_collection_index(self): """DocumentChunk should have collection index.""" from local_deep_research.database.models import DocumentChunk table_args = DocumentChunk.__table_args__ has_index = any( hasattr(arg, "name") and "idx_chunk_collection" in str(arg.name) for arg in table_args if hasattr(arg, "name") ) assert has_index class TestCrossModelConsistency: """Tests for cross-model consistency.""" def test_document_references_source_type(self): """Document.source_type_id should reference source_types.""" from local_deep_research.database.models import Document mapper = inspect(Document) columns = {c.name: c for c in mapper.columns} fk = list(columns["source_type_id"].foreign_keys)[0] assert "source_types" in str(fk.target_fullname) def test_document_collection_references_both(self): """DocumentCollection should reference both Document and Collection.""" from local_deep_research.database.models import DocumentCollection mapper = inspect(DocumentCollection) columns = {c.name: c for c in mapper.columns} doc_fk = list(columns["document_id"].foreign_keys)[0] coll_fk = list(columns["collection_id"].foreign_keys)[0] assert "documents" in str(doc_fk.target_fullname) assert "collections" in str(coll_fk.target_fullname) class TestModelRepr: """Tests for model __repr__ methods.""" def test_document_repr_not_error(self): """Document __repr__ should not raise errors.""" from local_deep_research.database.models import Document doc = Document() doc.id = "test-id" doc.title = "Test Document" doc.file_type = "pdf" doc.file_size = 1024 # Should not raise repr_str = repr(doc) assert "Document" in repr_str def test_collection_repr_not_error(self): """Collection __repr__ should not raise errors.""" from local_deep_research.database.models import Collection coll = Collection() coll.id = "test-id" coll.name = "Test Collection" coll.collection_type = "user_collection" repr_str = repr(coll) assert "Collection" in repr_str class TestModelDefaults: """Tests for model default values.""" def test_document_status_default(self): """Document status should default to COMPLETED.""" from local_deep_research.database.models import Document mapper = inspect(Document) columns = {c.name: c for c in mapper.columns} default = columns["status"].default assert default is not None def test_collection_is_default_defaults_to_false(self): """Collection.is_default should default to False.""" from local_deep_research.database.models import Collection mapper = inspect(Collection) columns = {c.name: c for c in mapper.columns} default = columns["is_default"].default assert default is not None assert default.arg is False class TestNullableColumns: """Tests for nullable column settings.""" def test_document_id_not_nullable(self): """Document.id should not be nullable.""" from local_deep_research.database.models import Document mapper = inspect(Document) columns = {c.name: c for c in mapper.columns} assert columns["id"].nullable is False def test_document_hash_not_nullable(self): """Document.document_hash should not be nullable.""" from local_deep_research.database.models import Document mapper = inspect(Document) columns = {c.name: c for c in mapper.columns} assert columns["document_hash"].nullable is False def test_document_original_url_nullable(self): """Document.original_url should be nullable (for uploads).""" from local_deep_research.database.models import Document mapper = inspect(Document) columns = {c.name: c for c in mapper.columns} assert columns["original_url"].nullable is True class TestExtractionEnums: """Tests for extraction-related enums.""" def test_extraction_method_enum(self): """ExtractionMethod enum should have expected values.""" from local_deep_research.database.models.library import ExtractionMethod assert ExtractionMethod.PDF_EXTRACTION.value == "pdf_extraction" assert ExtractionMethod.NATIVE_API.value == "native_api" assert ExtractionMethod.UNKNOWN.value == "unknown" def test_extraction_source_enum(self): """ExtractionSource enum should have expected values.""" from local_deep_research.database.models.library import ExtractionSource assert ExtractionSource.ARXIV_API.value == "arxiv_api" assert ExtractionSource.PUBMED_API.value == "pubmed_api" assert ExtractionSource.PDFPLUMBER.value == "pdfplumber" def test_extraction_quality_enum(self): """ExtractionQuality enum should have expected values.""" from local_deep_research.database.models.library import ( ExtractionQuality, ) assert ExtractionQuality.HIGH.value == "high" assert ExtractionQuality.MEDIUM.value == "medium" assert ExtractionQuality.LOW.value == "low" class TestRAGEnums: """Tests for RAG-related enums.""" def test_distance_metric_enum(self): """DistanceMetric enum should have expected values.""" from local_deep_research.database.models.library import DistanceMetric assert DistanceMetric.COSINE.value == "cosine" assert DistanceMetric.L2.value == "l2" assert DistanceMetric.DOT_PRODUCT.value == "dot_product" def test_index_type_enum(self): """IndexType enum should have expected values.""" from local_deep_research.database.models.library import IndexType assert IndexType.FLAT.value == "flat" assert IndexType.HNSW.value == "hnsw" assert IndexType.IVF.value == "ivf" def test_splitter_type_enum(self): """SplitterType enum should have expected values.""" from local_deep_research.database.models.library import SplitterType assert SplitterType.RECURSIVE.value == "recursive" assert SplitterType.SEMANTIC.value == "semantic" assert SplitterType.TOKEN.value == "token" assert SplitterType.SENTENCE.value == "sentence" class TestPDFStorageMode: """Tests for PDF storage mode enum.""" def test_pdf_storage_mode_enum(self): """PDFStorageMode enum should have expected values.""" from local_deep_research.database.models.library import PDFStorageMode assert PDFStorageMode.NONE.value == "none" assert PDFStorageMode.FILESYSTEM.value == "filesystem" assert PDFStorageMode.DATABASE.value == "database"