import pytest from sqlalchemy import create_engine from sqlalchemy.exc import IntegrityError from sqlalchemy.orm import Session from app.db import Base, create_sqlite_engine from app.models import Comment, ContentItem, Hotspot, Report, Task, create_report_record def test_all_t03_tables_can_be_created_in_memory_sqlite(): engine = create_engine("sqlite:///:memory:", connect_args={"check_same_thread": False}) try: Base.metadata.create_all(engine) assert set(Base.metadata.tables) >= { "tasks", "hotspots", "content_items", "comments", "reports", } finally: engine.dispose() def test_sqlite_engine_uses_required_connection_options(): engine = create_sqlite_engine("sqlite:///data/app.db") try: assert engine.url.database == "data/app.db" assert engine.dialect.connect_args["check_same_thread"] is False assert engine.dialect.connect_args["timeout"] == 10 finally: engine.dispose() def test_task_status_rejects_partial_status_values(): engine = create_engine("sqlite:///:memory:", connect_args={"check_same_thread": False}) try: Base.metadata.create_all(engine) with Session(engine) as session: session.add(Task(platform="douyin", status="partial_success")) with pytest.raises(IntegrityError): session.commit() finally: engine.dispose() def test_analysis_status_insufficient_does_not_change_task_status(): task = Task( platform="xiaohongshu", status="success", analysis_status="insufficient", analysis_success_rate=0.5, ) assert task.status == "success" assert task.analysis_status == "insufficient" def test_models_define_relationships_and_indexes(): assert any(index.name == "ix_comments_task_content_item" for index in Comment.__table__.indexes) assert any(index.name == "ix_content_items_task_hotspot" for index in ContentItem.__table__.indexes) assert any(index.name == "ix_reports_task_report_type" for index in Report.__table__.indexes) assert Hotspot.task.property.mapper.class_ is Task assert ContentItem.hotspot.property.mapper.class_ is Hotspot assert Comment.content_item.property.mapper.class_ is ContentItem assert Report.task.property.mapper.class_ is Task def test_report_record_application_constraint_requires_matching_owner_id(): with pytest.raises(ValueError, match="hotspot_id"): create_report_record(task_id="task-1", report_type="hotspot", title="热点报告") with pytest.raises(ValueError, match="content_item_id"): create_report_record(task_id="task-1", report_type="content_item", title="内容报告") report = create_report_record( task_id="task-1", report_type="hotspot", title="热点报告", hotspot_id="hot-1", ) assert report.hotspot_id == "hot-1"