# #region Test.DictionaryEntryCRUD [C:3] [TYPE Module] [SEMANTICS test,dictionary,entries,crud] # @BRIEF Tests for dictionary_entries.py — DictionaryEntryCRUD. # @RELATION BINDS_TO -> [DictionaryEntryCRUD] # @TEST_EDGE: duplicate_entry -> ValueError # @TEST_EDGE: entry_not_found -> ValueError # @TEST_EDGE: invalid_regex -> ValueError import sys from pathlib import Path sys.path.insert(0, str(Path(__file__).parent.parent.parent.parent / "src")) import pytest from unittest.mock import MagicMock from src.models.translate import DictionaryEntry, TerminologyDictionary from src.plugins.translate.dictionary_entries import DictionaryEntryCRUD class TestAddEntry: """DictionaryEntryCRUD.add_entry.""" def test_add_basic(self, db_session): """Basic add creates entry.""" dict_entry = TerminologyDictionary(id="dict-add-1", name="Test Dict", is_active=True) db_session.add(dict_entry) db_session.commit() entry = DictionaryEntryCRUD.add_entry( db_session, "dict-add-1", "hello", "bonjour", source_language="en", target_language="fr", ) assert entry.source_term == "hello" assert entry.target_term == "bonjour" assert entry.source_language == "en" assert entry.target_language == "fr" def test_add_with_context_notes(self, db_session): """Context notes are stripped.""" dict_entry = TerminologyDictionary(id="dict-add-ctx", name="Test", is_active=True) db_session.add(dict_entry) db_session.commit() entry = DictionaryEntryCRUD.add_entry( db_session, "dict-add-ctx", "hello", "bonjour", context_notes=" formal greeting ", ) assert entry.context_notes == "formal greeting" def test_duplicate_raises(self, db_session): """Duplicate entry raises ValueError.""" dict_entry = TerminologyDictionary(id="dict-add-dup", name="Test", is_active=True) db_session.add(dict_entry) db_session.commit() DictionaryEntryCRUD.add_entry( db_session, "dict-add-dup", "hello", "bonjour", source_language="en", target_language="fr", ) with pytest.raises(ValueError, match="Duplicate"): DictionaryEntryCRUD.add_entry( db_session, "dict-add-dup", "hello", "salut", source_language="en", target_language="fr", ) def test_invalid_source_language(self, db_session): """Invalid source_language raises ValueError.""" dict_entry = TerminologyDictionary(id="dict-add-lang", name="Test", is_active=True) db_session.add(dict_entry) db_session.commit() with pytest.raises(ValueError, match="source_language"): DictionaryEntryCRUD.add_entry( db_session, "dict-add-lang", "hello", "bonjour", source_language="invalid!", ) def test_invalid_regex_raises(self, db_session): """Invalid regex source_term raises ValueError.""" dict_entry = TerminologyDictionary(id="dict-add-regex", name="Test", is_active=True) db_session.add(dict_entry) db_session.commit() with pytest.raises(ValueError, match="Invalid regex"): DictionaryEntryCRUD.add_entry( db_session, "dict-add-regex", r"[invalid", "bonjour", is_regex=True, ) def test_valid_regex(self, db_session): """Valid regex is accepted.""" dict_entry = TerminologyDictionary(id="dict-add-regex2", name="Test", is_active=True) db_session.add(dict_entry) db_session.commit() entry = DictionaryEntryCRUD.add_entry( db_session, "dict-add-regex2", r"\d+", "NUMBER", is_regex=True, ) assert entry.is_regex is True def test_duplicate_different_language_passes(self, db_session): """Same source term with different language pair is OK.""" dict_entry = TerminologyDictionary(id="dict-add-diff", name="Test", is_active=True) db_session.add(dict_entry) db_session.commit() DictionaryEntryCRUD.add_entry( db_session, "dict-add-diff", "hello", "bonjour", source_language="en", target_language="fr", ) entry = DictionaryEntryCRUD.add_entry( db_session, "dict-add-diff", "hello", "hola", source_language="en", target_language="es", ) assert entry.target_term == "hola" class TestEditEntry: """DictionaryEntryCRUD.edit_entry.""" def _setup(self, db_session): dict_entry = TerminologyDictionary(id="dict-edit-1", name="Test", is_active=True) db_session.add(dict_entry) db_session.commit() entry = DictionaryEntryCRUD.add_entry( db_session, "dict-edit-1", "hello", "bonjour", source_language="en", target_language="fr", ) return entry def test_edit_target_term(self, db_session): """Edit target_term.""" entry = self._setup(db_session) updated = DictionaryEntryCRUD.edit_entry( db_session, entry.id, target_term="salut" ) assert updated.target_term == "salut" def test_edit_source_term(self, db_session): """Edit source_term with duplicate check.""" entry = self._setup(db_session) updated = DictionaryEntryCRUD.edit_entry( db_session, entry.id, source_term="hi" ) assert updated.source_term == "hi" def test_edit_languages(self, db_session): """Edit source_language and target_language.""" entry = self._setup(db_session) updated = DictionaryEntryCRUD.edit_entry( db_session, entry.id, source_language="es", target_language="de", ) assert updated.source_language == "es" assert updated.target_language == "de" def test_edit_not_found(self, db_session): """Non-existent entry raises ValueError.""" with pytest.raises(ValueError, match="Entry not found"): DictionaryEntryCRUD.edit_entry(db_session, "nonexistent", source_term="x") def test_edit_context_notes(self, db_session): """Edit context_notes to None.""" entry = self._setup(db_session) updated = DictionaryEntryCRUD.edit_entry( db_session, entry.id, context_notes="" ) assert updated.context_notes is None def test_edit_duplicate_source_term_raises(self, db_session): """Changing source_term to an existing one raises.""" entry1 = self._setup(db_session) entry2 = DictionaryEntryCRUD.add_entry( db_session, "dict-edit-1", "world", "monde", source_language="en", target_language="fr", ) with pytest.raises(ValueError, match="Duplicate"): DictionaryEntryCRUD.edit_entry( db_session, entry2.id, source_term="hello" ) def test_edit_is_regex(self, db_session): """Edit is_regex flag.""" entry = self._setup(db_session) updated = DictionaryEntryCRUD.edit_entry( db_session, entry.id, is_regex=True ) assert updated.is_regex is True def test_edit_regex_source_term_validation(self, db_session): """Setting source_term to invalid regex when entry is regex raises.""" entry = self._setup(db_session) DictionaryEntryCRUD.edit_entry(db_session, entry.id, is_regex=True) with pytest.raises(ValueError, match="Invalid regex"): DictionaryEntryCRUD.edit_entry( db_session, entry.id, source_term=r"[invalid" ) class TestDeleteEntry: """DictionaryEntryCRUD.delete_entry.""" def _setup(self, db_session): dict_entry = TerminologyDictionary(id="dict-del-1", name="Test", is_active=True) db_session.add(dict_entry) db_session.commit() entry = DictionaryEntryCRUD.add_entry( db_session, "dict-del-1", "hello", "bonjour", ) return entry def test_delete(self, db_session): """Delete existing entry.""" entry = self._setup(db_session) entry_id = entry.id DictionaryEntryCRUD.delete_entry(db_session, entry_id) assert db_session.query(DictionaryEntry).filter(DictionaryEntry.id == entry_id).first() is None def test_delete_not_found(self, db_session): """Delete non-existent entry raises ValueError.""" with pytest.raises(ValueError, match="Entry not found"): DictionaryEntryCRUD.delete_entry(db_session, "nonexistent") class TestClearEntries: """DictionaryEntryCRUD.clear_entries.""" def test_clear(self, db_session): """Clear all entries for a dictionary.""" dict_entry = TerminologyDictionary(id="dict-clear-1", name="Test", is_active=True) db_session.add(dict_entry) db_session.commit() DictionaryEntryCRUD.add_entry(db_session, "dict-clear-1", "hello", "bonjour") DictionaryEntryCRUD.add_entry(db_session, "dict-clear-1", "world", "monde") deleted = DictionaryEntryCRUD.clear_entries(db_session, "dict-clear-1") assert deleted == 2 def test_clear_dictionary_not_found(self, db_session): """Clear non-existent dictionary raises ValueError.""" with pytest.raises(ValueError, match="Dictionary not found"): DictionaryEntryCRUD.clear_entries(db_session, "nonexistent") class TestListEntries: """DictionaryEntryCRUD.list_entries.""" def test_list_pagination(self, db_session): """List with pagination.""" dict_entry = TerminologyDictionary(id="dict-list-1", name="Test", is_active=True) db_session.add(dict_entry) db_session.commit() for i in range(5): DictionaryEntryCRUD.add_entry( db_session, "dict-list-1", f"term{i}", f"trans{i}", ) entries, total = DictionaryEntryCRUD.list_entries(db_session, "dict-list-1", page=1, page_size=2) assert len(entries) == 2 assert total == 5 def test_list_empty(self, db_session): """Empty dictionary returns empty list.""" dict_entry = TerminologyDictionary(id="dict-list-empty", name="Test", is_active=True) db_session.add(dict_entry) db_session.commit() entries, total = DictionaryEntryCRUD.list_entries(db_session, "dict-list-empty") assert entries == [] assert total == 0 # #endregion Test.DictionaryEntryCRUD