# #region Test.Models.Translate [C:2] [TYPE Module] [SEMANTICS test,models,translate,sqlalchemy] # @BRIEF Tests for models/translate.py — TranslationJob, TranslationRun, TranslationBatch, # TranslationRecord, TranslationEvent, TranslationPreviewSession, # TranslationPreviewRecord, TerminologyDictionary, DictionaryEntry, # TranslationSchedule, TranslationJobDictionary, MetricSnapshot, # TranslationLanguage, TranslationPreviewLanguage, TranslationRunLanguageStats. # @RELATION BINDS_TO -> [TranslateModels] # @TEST_EDGE: generate_uuid -> returns a UUID string # @TEST_EDGE: table_names -> all model tables registered # @TEST_EDGE: columns_exist -> key column defaults and nullable config import pytest from datetime import datetime, timezone class TestGenerateUuid: """generate_uuid helper in translate.py.""" def test_returns_string(self): from src.models.translate import generate_uuid uid = generate_uuid() assert isinstance(uid, str) assert len(uid) > 20 def test_unique(self): from src.models.translate import generate_uuid uids = {generate_uuid() for _ in range(50)} assert len(uids) == 50 class TestTranslationJob: """TranslationJob — main job table.""" def test_table_name(self): from src.models.translate import TranslationJob assert TranslationJob.__tablename__ == "translation_jobs" def test_minimal_columns(self): from src.models.translate import TranslationJob obj = TranslationJob(name="Test Job", source_dialect="postgresql", target_dialect="clickhouse") assert obj.name == "Test Job" assert obj.source_dialect == "postgresql" assert obj.target_dialect == "clickhouse" # SQLAlchemy Column(default=...) only applies on INSERT via session, not at instance creation assert obj.status is None assert obj.batch_size is None assert obj.disable_reasoning is None assert obj.insert_method is None def test_with_all_columns(self): from src.models.translate import TranslationJob obj = TranslationJob( id="tj-2", name="Full Job", description="Test", source_dialect="postgresql", target_dialect="clickhouse", database_dialect="postgresql", status="ACTIVE", source_datasource_id="ds-1", source_table="orders", target_schema="public", target_table="orders_translated", source_key_cols=["id"], target_key_cols=["id"], translation_column="name", target_column="name_translated", target_language_column="lang", target_source_column="source_text", target_source_language_column="source_lang", context_columns=["category"], target_languages=["ru", "en"], provider_id="prov-1", batch_size=100, disable_reasoning=True, upsert_strategy="INSERT", environment_id="env-1", target_database_id="db-1", insert_method="direct_db", connection_id="conn-1", created_by="admin", ) assert obj.source_datasource_id == "ds-1" assert obj.batch_size == 100 assert obj.disable_reasoning is True assert obj.upsert_strategy == "INSERT" assert obj.insert_method == "direct_db" assert obj.connection_id == "conn-1" def test_defaults(self): from src.models.translate import TranslationJob obj = TranslationJob(name="J", source_dialect="pg", target_dialect="ch") assert obj.created_by is None # SQLAlchemy Column(default=...) only applies on INSERT via session assert obj.created_at is None assert obj.updated_at is None assert obj.target_languages is None assert obj.provider_id is None assert obj.description is None assert obj.source_table is None class TestTranslationRun: """TranslationRun — execution run table.""" def test_table_name(self): from src.models.translate import TranslationRun assert TranslationRun.__tablename__ == "translation_runs" def test_minimal(self): from src.models.translate import TranslationRun obj = TranslationRun(id="tr-1", job_id="job-1", status="PENDING") assert obj.id == "tr-1" assert obj.job_id == "job-1" assert obj.status == "PENDING" def test_with_fields(self): from src.models.translate import TranslationRun obj = TranslationRun( id="tr-2", job_id="job-1", status="RUNNING", trigger_type="manual", total_records=100, successful_records=80, failed_records=10, skipped_records=10, cache_hits=5, created_by="admin", ) assert obj.trigger_type == "manual" assert obj.total_records == 100 assert obj.cache_hits == 5 class TestTranslationBatch: """TranslationBatch — batch grouping table.""" def test_table_name(self): from src.models.translate import TranslationBatch assert TranslationBatch.__tablename__ == "translation_batches" def test_minimal(self): from src.models.translate import TranslationBatch obj = TranslationBatch(id="tb-1", run_id="run-1", batch_index=0, status="PENDING") assert obj.id == "tb-1" assert obj.run_id == "run-1" assert obj.batch_index == 0 assert obj.status == "PENDING" class TestTranslationRecord: """TranslationRecord — individual translation result table.""" def test_table_name(self): from src.models.translate import TranslationRecord assert TranslationRecord.__tablename__ == "translation_records" def test_minimal(self): from src.models.translate import TranslationRecord obj = TranslationRecord(id="trec-1", batch_id="b-1", run_id="run-1", status="PENDING") assert obj.id == "trec-1" assert obj.batch_id == "b-1" assert obj.status == "PENDING" def test_with_fields(self): from src.models.translate import TranslationRecord obj = TranslationRecord( id="trec-2", batch_id="b-1", run_id="run-1", source_sql="SELECT * FROM t", target_sql="SELECT * FROM t", source_object_type="query", source_object_id="q-1", status="SUCCESS", token_count_input=100, token_count_output=50, ) assert obj.source_sql == "SELECT * FROM t" assert obj.target_sql == "SELECT * FROM t" assert obj.token_count_input == 100 def test_languages_relationship(self): from src.models.translate import TranslationRecord assert hasattr(TranslationRecord, "languages") def test_table_args(self): from src.models.translate import TranslationRecord assert hasattr(TranslationRecord, "__table_args__") class TestTranslationEvent: """TranslationEvent — audit event log.""" def test_table_name(self): from src.models.translate import TranslationEvent assert TranslationEvent.__tablename__ == "translation_events" def test_minimal(self): from src.models.translate import TranslationEvent obj = TranslationEvent(id="te-1", job_id="j-1", event_type="JOB_CREATED") assert obj.id == "te-1" assert obj.job_id == "j-1" assert obj.event_type == "JOB_CREATED" assert obj.run_id is None class TestTranslationPreviewSession: """TranslationPreviewSession — preview session.""" def test_table_name(self): from src.models.translate import TranslationPreviewSession assert TranslationPreviewSession.__tablename__ == "translation_preview_sessions" def test_minimal(self): from src.models.translate import TranslationPreviewSession obj = TranslationPreviewSession(id="tps-1", job_id="j-1", status="ACTIVE") assert obj.id == "tps-1" assert obj.job_id == "j-1" assert obj.status == "ACTIVE" class TestTranslationPreviewRecord: """TranslationPreviewRecord — individual preview entry.""" def test_table_name(self): from src.models.translate import TranslationPreviewRecord assert TranslationPreviewRecord.__tablename__ == "translation_preview_records" def test_minimal(self): from src.models.translate import TranslationPreviewRecord obj = TranslationPreviewRecord(id="tpr-1", session_id="s-1", status="PENDING") assert obj.id == "tpr-1" assert obj.session_id == "s-1" assert obj.status == "PENDING" def test_languages_relationship(self): from src.models.translate import TranslationPreviewRecord assert hasattr(TranslationPreviewRecord, "languages") class TestTerminologyDictionary: """TerminologyDictionary — dictionary collection.""" def test_table_name(self): from src.models.translate import TerminologyDictionary assert TerminologyDictionary.__tablename__ == "terminology_dictionaries" def test_minimal(self): from src.models.translate import TerminologyDictionary obj = TerminologyDictionary(id="td-1", name="My Dict", is_active=True) assert obj.id == "td-1" assert obj.name == "My Dict" assert obj.is_active is True class TestDictionaryEntry: """DictionaryEntry — individual term mapping.""" def test_table_name(self): from src.models.translate import DictionaryEntry assert DictionaryEntry.__tablename__ == "dictionary_entries" def test_minimal(self): from src.models.translate import DictionaryEntry obj = DictionaryEntry( id="de-1", dictionary_id="d-1", source_term="hello", source_term_normalized="hello", target_term="привет", source_language="en", target_language="ru", has_context=False, is_regex=False, ) assert obj.id == "de-1" assert obj.source_term == "hello" assert obj.target_term == "привет" def test_unique_constraint(self): from src.models.translate import DictionaryEntry assert hasattr(DictionaryEntry, "__table_args__") def test_with_all_fields(self): from src.models.translate import DictionaryEntry obj = DictionaryEntry( id="de-2", dictionary_id="d-1", source_term="hello", source_term_normalized="hello", target_term="привет", source_language="en", target_language="ru", context_notes="Greeting", context_data={"formality": "informal"}, usage_notes="Use for casual greetings", has_context=True, is_regex=False, context_source="manual", origin_source_language="en", origin_run_id="run-1", ) assert obj.context_data == {"formality": "informal"} assert obj.has_context is True class TestTranslationSchedule: """TranslationSchedule — cron schedule.""" def test_table_name(self): from src.models.translate import TranslationSchedule assert TranslationSchedule.__tablename__ == "translation_schedules" def test_minimal(self): from src.models.translate import TranslationSchedule obj = TranslationSchedule( id="ts-1", job_id="j-1", cron_expression="0 0 * * *", timezone="UTC", is_active=True, execution_mode="full", ) assert obj.id == "ts-1" assert obj.cron_expression == "0 0 * * *" assert obj.timezone == "UTC" assert obj.is_active is True assert obj.execution_mode == "full" class TestTranslationJobDictionary: """TranslationJobDictionary — many-to-many association.""" def test_table_name(self): from src.models.translate import TranslationJobDictionary assert TranslationJobDictionary.__tablename__ == "translation_job_dictionaries" def test_minimal(self): from src.models.translate import TranslationJobDictionary obj = TranslationJobDictionary(id="tjd-1", job_id="j-1", dictionary_id="d-1") assert obj.id == "tjd-1" assert obj.job_id == "j-1" assert obj.dictionary_id == "d-1" class TestMetricSnapshot: """MetricSnapshot — translation performance metrics.""" def test_table_name(self): from src.models.translate import MetricSnapshot assert MetricSnapshot.__tablename__ == "translation_metric_snapshots" def test_minimal(self): from src.models.translate import MetricSnapshot obj = MetricSnapshot(id="ms-1", key_hash="hash1") assert obj.id == "ms-1" assert obj.key_hash == "hash1" class TestTranslationLanguage: """TranslationLanguage — per-language result.""" def test_table_name(self): from src.models.translate import TranslationLanguage assert TranslationLanguage.__tablename__ == "translation_languages" def test_minimal(self): from src.models.translate import TranslationLanguage obj = TranslationLanguage( id="tl-1", record_id="rec-1", language_code="ru", status="pending", needs_review=False, language_overridden=False, ) assert obj.id == "tl-1" assert obj.language_code == "ru" assert obj.status == "pending" assert obj.needs_review is False assert obj.language_overridden is False def test_relationships(self): from src.models.translate import TranslationLanguage assert hasattr(TranslationLanguage, "record") class TestTranslationPreviewLanguage: """TranslationPreviewLanguage — per-language preview entry.""" def test_table_name(self): from src.models.translate import TranslationPreviewLanguage assert TranslationPreviewLanguage.__tablename__ == "translation_preview_languages" def test_minimal(self): from src.models.translate import TranslationPreviewLanguage obj = TranslationPreviewLanguage( id="tpl-1", preview_record_id="pr-1", language_code="en", status="pending", ) assert obj.id == "tpl-1" assert obj.language_code == "en" assert obj.status == "pending" def test_relationships(self): from src.models.translate import TranslationPreviewLanguage assert hasattr(TranslationPreviewLanguage, "preview_record") class TestTranslationRunLanguageStats: """TranslationRunLanguageStats — per-language run stats.""" def test_table_name(self): from src.models.translate import TranslationRunLanguageStats assert TranslationRunLanguageStats.__tablename__ == "translation_run_language_stats" def test_minimal(self): from src.models.translate import TranslationRunLanguageStats obj = TranslationRunLanguageStats( id="trls-1", run_id="run-1", language_code="ru", total_rows=0, translated_rows=0, token_count=0, estimated_cost=0.0, ) assert obj.id == "trls-1" assert obj.language_code == "ru" assert obj.total_rows == 0 assert obj.estimated_cost == 0.0 def test_relationships(self): from src.models.translate import TranslationRunLanguageStats assert hasattr(TranslationRunLanguageStats, "run") # #endregion Test.Models.Translate