cognee 0.5.1.dev0__py3-none-any.whl → 0.5.2.dev0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- cognee/__init__.py +2 -0
- cognee/alembic/README +1 -0
- cognee/alembic/env.py +107 -0
- cognee/alembic/script.py.mako +26 -0
- cognee/alembic/versions/1a58b986e6e1_enable_delete_for_old_tutorial_notebooks.py +52 -0
- cognee/alembic/versions/1d0bb7fede17_add_pipeline_run_status.py +33 -0
- cognee/alembic/versions/1daae0df1866_incremental_loading.py +48 -0
- cognee/alembic/versions/211ab850ef3d_add_sync_operations_table.py +118 -0
- cognee/alembic/versions/45957f0a9849_add_notebook_table.py +46 -0
- cognee/alembic/versions/46a6ce2bd2b2_expand_dataset_database_with_json_.py +333 -0
- cognee/alembic/versions/482cd6517ce4_add_default_user.py +30 -0
- cognee/alembic/versions/76625596c5c3_expand_dataset_database_for_multi_user.py +98 -0
- cognee/alembic/versions/8057ae7329c2_initial_migration.py +25 -0
- cognee/alembic/versions/9e7a3cb85175_loader_separation.py +104 -0
- cognee/alembic/versions/a1b2c3d4e5f6_add_label_column_to_data.py +38 -0
- cognee/alembic/versions/ab7e313804ae_permission_system_rework.py +236 -0
- cognee/alembic/versions/b9274c27a25a_kuzu_11_migration.py +75 -0
- cognee/alembic/versions/c946955da633_multi_tenant_support.py +137 -0
- cognee/alembic/versions/e1ec1dcb50b6_add_last_accessed_to_data.py +51 -0
- cognee/alembic/versions/e4ebee1091e7_expand_data_model_info.py +140 -0
- cognee/alembic.ini +117 -0
- cognee/api/v1/add/routers/get_add_router.py +2 -0
- cognee/api/v1/cognify/cognify.py +11 -6
- cognee/api/v1/cognify/routers/get_cognify_router.py +8 -0
- cognee/api/v1/config/config.py +60 -0
- cognee/api/v1/datasets/routers/get_datasets_router.py +45 -3
- cognee/api/v1/memify/routers/get_memify_router.py +2 -0
- cognee/api/v1/search/routers/get_search_router.py +21 -6
- cognee/api/v1/search/search.py +25 -5
- cognee/api/v1/sync/routers/get_sync_router.py +3 -3
- cognee/cli/commands/add_command.py +1 -1
- cognee/cli/commands/cognify_command.py +6 -0
- cognee/cli/commands/config_command.py +1 -1
- cognee/context_global_variables.py +5 -1
- cognee/eval_framework/answer_generation/answer_generation_executor.py +7 -8
- cognee/infrastructure/databases/cache/cache_db_interface.py +38 -1
- cognee/infrastructure/databases/cache/config.py +6 -0
- cognee/infrastructure/databases/cache/fscache/FsCacheAdapter.py +21 -0
- cognee/infrastructure/databases/cache/get_cache_engine.py +9 -3
- cognee/infrastructure/databases/cache/redis/RedisAdapter.py +60 -1
- cognee/infrastructure/databases/dataset_database_handler/supported_dataset_database_handlers.py +7 -0
- cognee/infrastructure/databases/graph/get_graph_engine.py +29 -1
- cognee/infrastructure/databases/graph/neo4j_driver/Neo4jAuraDevDatasetDatabaseHandler.py +62 -27
- cognee/infrastructure/databases/hybrid/neptune_analytics/NeptuneAnalyticsAdapter.py +17 -4
- cognee/infrastructure/databases/relational/sqlalchemy/SqlAlchemyAdapter.py +2 -1
- cognee/infrastructure/databases/vector/chromadb/ChromaDBAdapter.py +2 -0
- cognee/infrastructure/databases/vector/config.py +6 -0
- cognee/infrastructure/databases/vector/create_vector_engine.py +69 -22
- cognee/infrastructure/databases/vector/embeddings/LiteLLMEmbeddingEngine.py +64 -9
- cognee/infrastructure/databases/vector/embeddings/OllamaEmbeddingEngine.py +13 -2
- cognee/infrastructure/databases/vector/lancedb/LanceDBAdapter.py +16 -3
- cognee/infrastructure/databases/vector/models/ScoredResult.py +3 -3
- cognee/infrastructure/databases/vector/pgvector/PGVectorAdapter.py +16 -3
- cognee/infrastructure/databases/vector/pgvector/PGVectorDatasetDatabaseHandler.py +86 -0
- cognee/infrastructure/databases/vector/pgvector/create_db_and_tables.py +81 -2
- cognee/infrastructure/databases/vector/vector_db_interface.py +8 -0
- cognee/infrastructure/files/utils/get_data_file_path.py +33 -27
- cognee/infrastructure/llm/prompts/extract_query_time.txt +1 -1
- cognee/infrastructure/llm/prompts/generate_event_entity_prompt.txt +1 -1
- cognee/infrastructure/llm/prompts/generate_event_graph_prompt.txt +1 -1
- cognee/infrastructure/llm/prompts/generate_graph_prompt.txt +2 -2
- cognee/infrastructure/llm/prompts/generate_graph_prompt_guided.txt +1 -1
- cognee/infrastructure/llm/prompts/generate_graph_prompt_oneshot.txt +2 -2
- cognee/infrastructure/llm/prompts/generate_graph_prompt_simple.txt +1 -1
- cognee/infrastructure/llm/prompts/generate_graph_prompt_strict.txt +1 -1
- cognee/infrastructure/llm/prompts/search_type_selector_prompt.txt +6 -6
- cognee/infrastructure/llm/prompts/test.txt +1 -1
- cognee/infrastructure/llm/prompts/translate_content.txt +19 -0
- cognee/infrastructure/llm/structured_output_framework/litellm_instructor/llm/get_llm_client.py +24 -0
- cognee/infrastructure/llm/structured_output_framework/litellm_instructor/llm/llama_cpp/adapter.py +191 -0
- cognee/modules/chunking/models/DocumentChunk.py +0 -1
- cognee/modules/cognify/config.py +2 -0
- cognee/modules/data/models/Data.py +1 -0
- cognee/modules/engine/models/Entity.py +0 -1
- cognee/modules/engine/operations/setup.py +6 -0
- cognee/modules/graph/cognee_graph/CogneeGraph.py +150 -37
- cognee/modules/graph/cognee_graph/CogneeGraphElements.py +48 -2
- cognee/modules/graph/utils/__init__.py +1 -0
- cognee/modules/graph/utils/get_entity_nodes_from_triplets.py +12 -0
- cognee/modules/notebooks/methods/__init__.py +1 -0
- cognee/modules/notebooks/methods/create_notebook.py +0 -34
- cognee/modules/notebooks/methods/create_tutorial_notebooks.py +191 -0
- cognee/modules/notebooks/methods/get_notebooks.py +12 -8
- cognee/modules/notebooks/tutorials/cognee-basics/cell-1.md +3 -0
- cognee/modules/notebooks/tutorials/cognee-basics/cell-2.md +10 -0
- cognee/modules/notebooks/tutorials/cognee-basics/cell-3.md +7 -0
- cognee/modules/notebooks/tutorials/cognee-basics/cell-4.py +28 -0
- cognee/modules/notebooks/tutorials/cognee-basics/cell-5.py +3 -0
- cognee/modules/notebooks/tutorials/cognee-basics/cell-6.py +9 -0
- cognee/modules/notebooks/tutorials/cognee-basics/cell-7.py +17 -0
- cognee/modules/notebooks/tutorials/cognee-basics/config.json +4 -0
- cognee/modules/notebooks/tutorials/python-development-with-cognee/cell-1.md +3 -0
- cognee/modules/notebooks/tutorials/python-development-with-cognee/cell-10.md +3 -0
- cognee/modules/notebooks/tutorials/python-development-with-cognee/cell-11.md +3 -0
- cognee/modules/notebooks/tutorials/python-development-with-cognee/cell-12.py +3 -0
- cognee/modules/notebooks/tutorials/python-development-with-cognee/cell-13.md +7 -0
- cognee/modules/notebooks/tutorials/python-development-with-cognee/cell-14.py +6 -0
- cognee/modules/notebooks/tutorials/python-development-with-cognee/cell-15.md +3 -0
- cognee/modules/notebooks/tutorials/python-development-with-cognee/cell-16.py +7 -0
- cognee/modules/notebooks/tutorials/python-development-with-cognee/cell-2.md +9 -0
- cognee/modules/notebooks/tutorials/python-development-with-cognee/cell-3.md +7 -0
- cognee/modules/notebooks/tutorials/python-development-with-cognee/cell-4.md +9 -0
- cognee/modules/notebooks/tutorials/python-development-with-cognee/cell-5.md +5 -0
- cognee/modules/notebooks/tutorials/python-development-with-cognee/cell-6.py +13 -0
- cognee/modules/notebooks/tutorials/python-development-with-cognee/cell-7.md +3 -0
- cognee/modules/notebooks/tutorials/python-development-with-cognee/cell-8.md +3 -0
- cognee/modules/notebooks/tutorials/python-development-with-cognee/cell-9.py +31 -0
- cognee/modules/notebooks/tutorials/python-development-with-cognee/config.json +4 -0
- cognee/modules/notebooks/tutorials/python-development-with-cognee/data/copilot_conversations.json +107 -0
- cognee/modules/notebooks/tutorials/python-development-with-cognee/data/guido_contributions.json +976 -0
- cognee/modules/notebooks/tutorials/python-development-with-cognee/data/my_developer_rules.md +79 -0
- cognee/modules/notebooks/tutorials/python-development-with-cognee/data/pep_style_guide.md +74 -0
- cognee/modules/notebooks/tutorials/python-development-with-cognee/data/zen_principles.md +74 -0
- cognee/modules/retrieval/EntityCompletionRetriever.py +51 -38
- cognee/modules/retrieval/__init__.py +0 -1
- cognee/modules/retrieval/base_retriever.py +66 -10
- cognee/modules/retrieval/chunks_retriever.py +57 -49
- cognee/modules/retrieval/coding_rules_retriever.py +12 -5
- cognee/modules/retrieval/completion_retriever.py +29 -28
- cognee/modules/retrieval/cypher_search_retriever.py +25 -20
- cognee/modules/retrieval/graph_completion_context_extension_retriever.py +42 -46
- cognee/modules/retrieval/graph_completion_cot_retriever.py +68 -51
- cognee/modules/retrieval/graph_completion_retriever.py +78 -63
- cognee/modules/retrieval/graph_summary_completion_retriever.py +2 -0
- cognee/modules/retrieval/lexical_retriever.py +34 -12
- cognee/modules/retrieval/natural_language_retriever.py +18 -15
- cognee/modules/retrieval/summaries_retriever.py +51 -34
- cognee/modules/retrieval/temporal_retriever.py +59 -49
- cognee/modules/retrieval/triplet_retriever.py +31 -32
- cognee/modules/retrieval/utils/access_tracking.py +88 -0
- cognee/modules/retrieval/utils/brute_force_triplet_search.py +99 -85
- cognee/modules/retrieval/utils/node_edge_vector_search.py +174 -0
- cognee/modules/search/methods/__init__.py +1 -0
- cognee/modules/search/methods/get_retriever_output.py +53 -0
- cognee/modules/search/methods/get_search_type_retriever_instance.py +252 -0
- cognee/modules/search/methods/search.py +90 -215
- cognee/modules/search/models/SearchResultPayload.py +67 -0
- cognee/modules/search/types/SearchResult.py +1 -8
- cognee/modules/search/types/SearchType.py +1 -2
- cognee/modules/search/types/__init__.py +1 -1
- cognee/modules/search/utils/__init__.py +1 -2
- cognee/modules/search/utils/transform_insights_to_graph.py +2 -2
- cognee/modules/search/utils/{transform_context_to_graph.py → transform_triplets_to_graph.py} +2 -2
- cognee/modules/users/authentication/default/default_transport.py +11 -1
- cognee/modules/users/authentication/get_api_auth_backend.py +2 -1
- cognee/modules/users/authentication/get_client_auth_backend.py +2 -1
- cognee/modules/users/methods/create_user.py +0 -9
- cognee/modules/users/permissions/methods/has_user_management_permission.py +29 -0
- cognee/modules/visualization/cognee_network_visualization.py +1 -1
- cognee/run_migrations.py +48 -0
- cognee/shared/exceptions/__init__.py +1 -3
- cognee/shared/exceptions/exceptions.py +11 -1
- cognee/shared/usage_logger.py +332 -0
- cognee/shared/utils.py +12 -5
- cognee/tasks/cleanup/cleanup_unused_data.py +172 -0
- cognee/tasks/memify/extract_usage_frequency.py +613 -0
- cognee/tasks/summarization/models.py +0 -2
- cognee/tasks/temporal_graph/__init__.py +0 -1
- cognee/tasks/translation/__init__.py +96 -0
- cognee/tasks/translation/config.py +110 -0
- cognee/tasks/translation/detect_language.py +190 -0
- cognee/tasks/translation/exceptions.py +62 -0
- cognee/tasks/translation/models.py +72 -0
- cognee/tasks/translation/providers/__init__.py +44 -0
- cognee/tasks/translation/providers/azure_provider.py +192 -0
- cognee/tasks/translation/providers/base.py +85 -0
- cognee/tasks/translation/providers/google_provider.py +158 -0
- cognee/tasks/translation/providers/llm_provider.py +143 -0
- cognee/tasks/translation/translate_content.py +282 -0
- cognee/tasks/web_scraper/default_url_crawler.py +6 -2
- cognee/tests/cli_tests/cli_unit_tests/test_cli_commands.py +1 -0
- cognee/tests/cli_tests/cli_unit_tests/test_cli_edge_cases.py +3 -0
- cognee/tests/integration/retrieval/test_brute_force_triplet_search_with_cognify.py +62 -0
- cognee/tests/integration/retrieval/test_chunks_retriever.py +115 -16
- cognee/tests/integration/retrieval/test_graph_completion_retriever.py +13 -5
- cognee/tests/integration/retrieval/test_graph_completion_retriever_context_extension.py +22 -20
- cognee/tests/integration/retrieval/test_graph_completion_retriever_cot.py +23 -24
- cognee/tests/integration/retrieval/test_rag_completion_retriever.py +70 -5
- cognee/tests/integration/retrieval/test_structured_output.py +62 -18
- cognee/tests/integration/retrieval/test_summaries_retriever.py +20 -9
- cognee/tests/integration/retrieval/test_temporal_retriever.py +38 -8
- cognee/tests/integration/retrieval/test_triplet_retriever.py +13 -4
- cognee/tests/integration/shared/test_usage_logger_integration.py +255 -0
- cognee/tests/tasks/translation/README.md +147 -0
- cognee/tests/tasks/translation/__init__.py +1 -0
- cognee/tests/tasks/translation/config_test.py +93 -0
- cognee/tests/tasks/translation/detect_language_test.py +118 -0
- cognee/tests/tasks/translation/providers_test.py +151 -0
- cognee/tests/tasks/translation/translate_content_test.py +213 -0
- cognee/tests/test_chromadb.py +1 -1
- cognee/tests/test_cleanup_unused_data.py +165 -0
- cognee/tests/test_delete_by_id.py +6 -6
- cognee/tests/test_extract_usage_frequency.py +308 -0
- cognee/tests/test_kuzu.py +17 -7
- cognee/tests/test_lancedb.py +3 -1
- cognee/tests/test_library.py +1 -1
- cognee/tests/test_neo4j.py +17 -7
- cognee/tests/test_neptune_analytics_vector.py +3 -1
- cognee/tests/test_permissions.py +172 -187
- cognee/tests/test_pgvector.py +3 -1
- cognee/tests/test_relational_db_migration.py +15 -1
- cognee/tests/test_remote_kuzu.py +3 -1
- cognee/tests/test_s3_file_storage.py +1 -1
- cognee/tests/test_search_db.py +97 -110
- cognee/tests/test_usage_logger_e2e.py +268 -0
- cognee/tests/unit/api/test_get_raw_data_endpoint.py +206 -0
- cognee/tests/unit/eval_framework/answer_generation_test.py +4 -3
- cognee/tests/unit/infrastructure/databases/cache/test_cache_config.py +2 -0
- cognee/tests/unit/modules/graph/cognee_graph_elements_test.py +42 -2
- cognee/tests/unit/modules/graph/cognee_graph_test.py +329 -31
- cognee/tests/unit/modules/retrieval/chunks_retriever_test.py +31 -59
- cognee/tests/unit/modules/retrieval/graph_completion_retriever_context_extension_test.py +70 -33
- cognee/tests/unit/modules/retrieval/graph_completion_retriever_cot_test.py +72 -52
- cognee/tests/unit/modules/retrieval/graph_completion_retriever_test.py +27 -33
- cognee/tests/unit/modules/retrieval/rag_completion_retriever_test.py +28 -15
- cognee/tests/unit/modules/retrieval/summaries_retriever_test.py +37 -42
- cognee/tests/unit/modules/retrieval/temporal_retriever_test.py +48 -64
- cognee/tests/unit/modules/retrieval/test_brute_force_triplet_search.py +263 -24
- cognee/tests/unit/modules/retrieval/test_node_edge_vector_search.py +273 -0
- cognee/tests/unit/modules/retrieval/triplet_retriever_test.py +30 -16
- cognee/tests/unit/modules/search/test_get_search_type_retriever_instance.py +125 -0
- cognee/tests/unit/modules/search/test_search.py +176 -0
- cognee/tests/unit/modules/search/test_search_prepare_search_result_contract.py +190 -0
- cognee/tests/unit/modules/users/test_tutorial_notebook_creation.py +511 -297
- cognee/tests/unit/shared/test_usage_logger.py +241 -0
- cognee/tests/unit/users/permissions/test_has_user_management_permission.py +46 -0
- {cognee-0.5.1.dev0.dist-info → cognee-0.5.2.dev0.dist-info}/METADATA +17 -10
- {cognee-0.5.1.dev0.dist-info → cognee-0.5.2.dev0.dist-info}/RECORD +232 -144
- cognee/api/.env.example +0 -5
- cognee/modules/retrieval/base_graph_retriever.py +0 -24
- cognee/modules/search/methods/get_search_type_tools.py +0 -223
- cognee/modules/search/methods/no_access_control_search.py +0 -62
- cognee/modules/search/utils/prepare_search_result.py +0 -63
- cognee/tests/test_feedback_enrichment.py +0 -174
- {cognee-0.5.1.dev0.dist-info → cognee-0.5.2.dev0.dist-info}/WHEEL +0 -0
- {cognee-0.5.1.dev0.dist-info → cognee-0.5.2.dev0.dist-info}/entry_points.txt +0 -0
- {cognee-0.5.1.dev0.dist-info → cognee-0.5.2.dev0.dist-info}/licenses/LICENSE +0 -0
- {cognee-0.5.1.dev0.dist-info → cognee-0.5.2.dev0.dist-info}/licenses/NOTICE.md +0 -0
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
"""Integration tests for usage logger with real Redis components."""
|
|
2
|
+
|
|
3
|
+
import os
|
|
4
|
+
import pytest
|
|
5
|
+
import asyncio
|
|
6
|
+
from datetime import datetime, timezone
|
|
7
|
+
from types import SimpleNamespace
|
|
8
|
+
from uuid import UUID
|
|
9
|
+
from unittest.mock import patch
|
|
10
|
+
|
|
11
|
+
from cognee.shared.usage_logger import log_usage
|
|
12
|
+
from cognee.infrastructure.databases.cache.config import get_cache_config
|
|
13
|
+
from cognee.infrastructure.databases.cache.get_cache_engine import (
|
|
14
|
+
get_cache_engine,
|
|
15
|
+
create_cache_engine,
|
|
16
|
+
)
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
@pytest.fixture
|
|
20
|
+
def usage_logging_config():
|
|
21
|
+
"""Fixture to enable usage logging via environment variables."""
|
|
22
|
+
original_env = os.environ.copy()
|
|
23
|
+
os.environ["USAGE_LOGGING"] = "true"
|
|
24
|
+
os.environ["CACHE_BACKEND"] = "redis"
|
|
25
|
+
os.environ["CACHE_HOST"] = "localhost"
|
|
26
|
+
os.environ["CACHE_PORT"] = "6379"
|
|
27
|
+
get_cache_config.cache_clear()
|
|
28
|
+
create_cache_engine.cache_clear()
|
|
29
|
+
yield
|
|
30
|
+
os.environ.clear()
|
|
31
|
+
os.environ.update(original_env)
|
|
32
|
+
get_cache_config.cache_clear()
|
|
33
|
+
create_cache_engine.cache_clear()
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
@pytest.fixture
|
|
37
|
+
def usage_logging_disabled():
|
|
38
|
+
"""Fixture to disable usage logging via environment variables."""
|
|
39
|
+
original_env = os.environ.copy()
|
|
40
|
+
os.environ["USAGE_LOGGING"] = "false"
|
|
41
|
+
os.environ["CACHE_BACKEND"] = "redis"
|
|
42
|
+
get_cache_config.cache_clear()
|
|
43
|
+
create_cache_engine.cache_clear()
|
|
44
|
+
yield
|
|
45
|
+
os.environ.clear()
|
|
46
|
+
os.environ.update(original_env)
|
|
47
|
+
get_cache_config.cache_clear()
|
|
48
|
+
create_cache_engine.cache_clear()
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
@pytest.fixture
|
|
52
|
+
def redis_adapter():
|
|
53
|
+
"""Real RedisAdapter instance for testing."""
|
|
54
|
+
from cognee.infrastructure.databases.cache.redis.RedisAdapter import RedisAdapter
|
|
55
|
+
|
|
56
|
+
try:
|
|
57
|
+
yield RedisAdapter(host="localhost", port=6379, log_key="test_usage_logs")
|
|
58
|
+
except Exception as e:
|
|
59
|
+
pytest.skip(f"Redis not available: {e}")
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
@pytest.fixture
|
|
63
|
+
def test_user():
|
|
64
|
+
"""Test user object."""
|
|
65
|
+
return SimpleNamespace(id="test-user-123")
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
class TestDecoratorBehavior:
|
|
69
|
+
"""Test decorator behavior with real components."""
|
|
70
|
+
|
|
71
|
+
@pytest.mark.asyncio
|
|
72
|
+
async def test_decorator_configuration(
|
|
73
|
+
self, usage_logging_disabled, usage_logging_config, redis_adapter
|
|
74
|
+
):
|
|
75
|
+
"""Test decorator skips when disabled and logs when enabled."""
|
|
76
|
+
# Test disabled
|
|
77
|
+
call_count = 0
|
|
78
|
+
|
|
79
|
+
@log_usage(function_name="test_func", log_type="test")
|
|
80
|
+
async def test_func():
|
|
81
|
+
nonlocal call_count
|
|
82
|
+
call_count += 1
|
|
83
|
+
return "result"
|
|
84
|
+
|
|
85
|
+
assert await test_func() == "result"
|
|
86
|
+
assert call_count == 1
|
|
87
|
+
|
|
88
|
+
# Test enabled with cache engine None
|
|
89
|
+
with patch("cognee.shared.usage_logger.get_cache_engine") as mock_get:
|
|
90
|
+
mock_get.return_value = None
|
|
91
|
+
assert await test_func() == "result"
|
|
92
|
+
|
|
93
|
+
@pytest.mark.asyncio
|
|
94
|
+
async def test_decorator_logging(self, usage_logging_config, redis_adapter, test_user):
|
|
95
|
+
"""Test decorator logs to Redis with correct structure."""
|
|
96
|
+
|
|
97
|
+
@log_usage(function_name="test_func", log_type="test")
|
|
98
|
+
async def test_func(param1: str, param2: int = 42, user=None):
|
|
99
|
+
await asyncio.sleep(0.01)
|
|
100
|
+
return {"result": f"{param1}_{param2}"}
|
|
101
|
+
|
|
102
|
+
with patch("cognee.shared.usage_logger.get_cache_engine") as mock_get:
|
|
103
|
+
mock_get.return_value = redis_adapter
|
|
104
|
+
|
|
105
|
+
result = await test_func("value1", user=test_user)
|
|
106
|
+
assert result == {"result": "value1_42"}
|
|
107
|
+
|
|
108
|
+
logs = await redis_adapter.get_usage_logs("test-user-123", limit=10)
|
|
109
|
+
log = logs[0]
|
|
110
|
+
assert log["function_name"] == "test_func"
|
|
111
|
+
assert log["type"] == "test"
|
|
112
|
+
assert log["user_id"] == "test-user-123"
|
|
113
|
+
assert log["parameters"]["param1"] == "value1"
|
|
114
|
+
assert log["parameters"]["param2"] == 42
|
|
115
|
+
assert log["success"] is True
|
|
116
|
+
assert all(
|
|
117
|
+
field in log
|
|
118
|
+
for field in [
|
|
119
|
+
"timestamp",
|
|
120
|
+
"result",
|
|
121
|
+
"error",
|
|
122
|
+
"duration_ms",
|
|
123
|
+
"start_time",
|
|
124
|
+
"end_time",
|
|
125
|
+
"metadata",
|
|
126
|
+
]
|
|
127
|
+
)
|
|
128
|
+
assert "cognee_version" in log["metadata"]
|
|
129
|
+
|
|
130
|
+
@pytest.mark.asyncio
|
|
131
|
+
async def test_multiple_calls(self, usage_logging_config, redis_adapter, test_user):
|
|
132
|
+
"""Test multiple consecutive calls are all logged."""
|
|
133
|
+
|
|
134
|
+
@log_usage(function_name="multi_test", log_type="test")
|
|
135
|
+
async def multi_func(call_num: int, user=None):
|
|
136
|
+
return {"call": call_num}
|
|
137
|
+
|
|
138
|
+
with patch("cognee.shared.usage_logger.get_cache_engine") as mock_get:
|
|
139
|
+
mock_get.return_value = redis_adapter
|
|
140
|
+
|
|
141
|
+
for i in range(3):
|
|
142
|
+
await multi_func(i, user=test_user)
|
|
143
|
+
|
|
144
|
+
logs = await redis_adapter.get_usage_logs("test-user-123", limit=10)
|
|
145
|
+
assert len(logs) >= 3
|
|
146
|
+
call_nums = {log["parameters"]["call_num"] for log in logs[:3]}
|
|
147
|
+
assert call_nums == {0, 1, 2}
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
class TestRealRedisIntegration:
|
|
151
|
+
"""Test real Redis integration."""
|
|
152
|
+
|
|
153
|
+
@pytest.mark.asyncio
|
|
154
|
+
async def test_redis_storage_retrieval_and_ttl(
|
|
155
|
+
self, usage_logging_config, redis_adapter, test_user
|
|
156
|
+
):
|
|
157
|
+
"""Test logs are stored, retrieved with correct order/limits, and TTL is set."""
|
|
158
|
+
|
|
159
|
+
@log_usage(function_name="redis_test", log_type="test")
|
|
160
|
+
async def redis_func(data: str, user=None):
|
|
161
|
+
return {"processed": data}
|
|
162
|
+
|
|
163
|
+
@log_usage(function_name="order_test", log_type="test")
|
|
164
|
+
async def order_func(num: int, user=None):
|
|
165
|
+
return {"num": num}
|
|
166
|
+
|
|
167
|
+
with patch("cognee.shared.usage_logger.get_cache_engine") as mock_get:
|
|
168
|
+
mock_get.return_value = redis_adapter
|
|
169
|
+
|
|
170
|
+
# Storage
|
|
171
|
+
await redis_func("test_data", user=test_user)
|
|
172
|
+
logs = await redis_adapter.get_usage_logs("test-user-123", limit=10)
|
|
173
|
+
assert logs[0]["function_name"] == "redis_test"
|
|
174
|
+
assert logs[0]["parameters"]["data"] == "test_data"
|
|
175
|
+
|
|
176
|
+
# Order (most recent first)
|
|
177
|
+
for i in range(3):
|
|
178
|
+
await order_func(i, user=test_user)
|
|
179
|
+
await asyncio.sleep(0.01)
|
|
180
|
+
|
|
181
|
+
logs = await redis_adapter.get_usage_logs("test-user-123", limit=10)
|
|
182
|
+
assert [log["parameters"]["num"] for log in logs[:3]] == [2, 1, 0]
|
|
183
|
+
|
|
184
|
+
# Limit
|
|
185
|
+
assert len(await redis_adapter.get_usage_logs("test-user-123", limit=2)) == 2
|
|
186
|
+
|
|
187
|
+
# TTL
|
|
188
|
+
ttl = await redis_adapter.async_redis.ttl("test_usage_logs:test-user-123")
|
|
189
|
+
assert 0 < ttl <= 604800
|
|
190
|
+
|
|
191
|
+
|
|
192
|
+
class TestEdgeCases:
|
|
193
|
+
"""Test edge cases in integration tests."""
|
|
194
|
+
|
|
195
|
+
@pytest.mark.asyncio
|
|
196
|
+
async def test_edge_cases(self, usage_logging_config, redis_adapter, test_user):
|
|
197
|
+
"""Test no params, defaults, complex structures, exceptions, None, circular refs."""
|
|
198
|
+
|
|
199
|
+
@log_usage(function_name="no_params", log_type="test")
|
|
200
|
+
async def no_params_func(user=None):
|
|
201
|
+
return "result"
|
|
202
|
+
|
|
203
|
+
@log_usage(function_name="defaults_only", log_type="test")
|
|
204
|
+
async def defaults_only_func(param1: str = "default1", param2: int = 42, user=None):
|
|
205
|
+
return {"param1": param1, "param2": param2}
|
|
206
|
+
|
|
207
|
+
@log_usage(function_name="complex_test", log_type="test")
|
|
208
|
+
async def complex_func(user=None):
|
|
209
|
+
return {
|
|
210
|
+
"nested": {
|
|
211
|
+
"list": [1, 2, 3],
|
|
212
|
+
"uuid": UUID("123e4567-e89b-12d3-a456-426614174000"),
|
|
213
|
+
"datetime": datetime(2024, 1, 15, tzinfo=timezone.utc),
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
@log_usage(function_name="exception_test", log_type="test")
|
|
218
|
+
async def exception_func(user=None):
|
|
219
|
+
raise RuntimeError("Test exception")
|
|
220
|
+
|
|
221
|
+
@log_usage(function_name="none_test", log_type="test")
|
|
222
|
+
async def none_func(user=None):
|
|
223
|
+
return None
|
|
224
|
+
|
|
225
|
+
with patch("cognee.shared.usage_logger.get_cache_engine") as mock_get:
|
|
226
|
+
mock_get.return_value = redis_adapter
|
|
227
|
+
|
|
228
|
+
# No parameters
|
|
229
|
+
await no_params_func(user=test_user)
|
|
230
|
+
logs = await redis_adapter.get_usage_logs("test-user-123", limit=10)
|
|
231
|
+
assert logs[0]["parameters"] == {}
|
|
232
|
+
|
|
233
|
+
# Default parameters
|
|
234
|
+
await defaults_only_func(user=test_user)
|
|
235
|
+
logs = await redis_adapter.get_usage_logs("test-user-123", limit=10)
|
|
236
|
+
assert logs[0]["parameters"]["param1"] == "default1"
|
|
237
|
+
assert logs[0]["parameters"]["param2"] == 42
|
|
238
|
+
|
|
239
|
+
# Complex nested structures
|
|
240
|
+
await complex_func(user=test_user)
|
|
241
|
+
logs = await redis_adapter.get_usage_logs("test-user-123", limit=10)
|
|
242
|
+
assert isinstance(logs[0]["result"]["nested"]["uuid"], str)
|
|
243
|
+
assert isinstance(logs[0]["result"]["nested"]["datetime"], str)
|
|
244
|
+
|
|
245
|
+
# Exception handling
|
|
246
|
+
with pytest.raises(RuntimeError):
|
|
247
|
+
await exception_func(user=test_user)
|
|
248
|
+
logs = await redis_adapter.get_usage_logs("test-user-123", limit=10)
|
|
249
|
+
assert logs[0]["success"] is False
|
|
250
|
+
assert "Test exception" in logs[0]["error"]
|
|
251
|
+
|
|
252
|
+
# None return value
|
|
253
|
+
assert await none_func(user=test_user) is None
|
|
254
|
+
logs = await redis_adapter.get_usage_logs("test-user-123", limit=10)
|
|
255
|
+
assert logs[0]["result"] is None
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
# Translation Task Tests
|
|
2
|
+
|
|
3
|
+
Unit and integration tests for the multilingual content translation feature.
|
|
4
|
+
|
|
5
|
+
## Test Files
|
|
6
|
+
|
|
7
|
+
- **config_test.py** - Tests for translation configuration
|
|
8
|
+
- Default configuration
|
|
9
|
+
- Provider type validation
|
|
10
|
+
- Confidence threshold bounds
|
|
11
|
+
- Multiple provider API keys
|
|
12
|
+
|
|
13
|
+
- **detect_language_test.py** - Tests for language detection functionality
|
|
14
|
+
- English, Spanish, French, German, Chinese detection
|
|
15
|
+
- Confidence thresholds
|
|
16
|
+
- Edge cases (empty text, short text, mixed languages)
|
|
17
|
+
|
|
18
|
+
- **providers_test.py** - Tests for translation provider implementations
|
|
19
|
+
- LLM provider basic translation
|
|
20
|
+
- Auto-detection of source language
|
|
21
|
+
- Batch translation
|
|
22
|
+
- Special characters and formatting preservation
|
|
23
|
+
- Error handling
|
|
24
|
+
|
|
25
|
+
- **translate_content_test.py** - Tests for the main translate_content task
|
|
26
|
+
- Basic translation workflow
|
|
27
|
+
- Original text preservation
|
|
28
|
+
- Multiple chunks processing
|
|
29
|
+
- Language metadata creation
|
|
30
|
+
- Skip translation for target language
|
|
31
|
+
- Confidence threshold customization
|
|
32
|
+
|
|
33
|
+
## Running Tests
|
|
34
|
+
|
|
35
|
+
### Run all translation tests
|
|
36
|
+
```bash
|
|
37
|
+
uv run pytest cognee/tests/tasks/translation/ -v
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### Run specific test file
|
|
41
|
+
```bash
|
|
42
|
+
uv run pytest cognee/tests/tasks/translation/detect_language_test.py -v
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### Run tests directly (without pytest)
|
|
46
|
+
```bash
|
|
47
|
+
uv run python cognee/tests/tasks/translation/config_test.py
|
|
48
|
+
uv run python cognee/tests/tasks/translation/detect_language_test.py
|
|
49
|
+
uv run python cognee/tests/tasks/translation/providers_test.py
|
|
50
|
+
uv run python cognee/tests/tasks/translation/translate_content_test.py
|
|
51
|
+
uv run python cognee/tests/tasks/translation/integration_test.py
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### Run all tests at once
|
|
55
|
+
```bash
|
|
56
|
+
for f in cognee/tests/tasks/translation/*_test.py; do uv run python "$f"; done
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### Run with coverage
|
|
60
|
+
```bash
|
|
61
|
+
uv run pytest cognee/tests/tasks/translation/ --cov=cognee.tasks.translation --cov-report=html
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## Prerequisites
|
|
65
|
+
|
|
66
|
+
- LLM API key set in environment: `LLM_API_KEY=your_key`
|
|
67
|
+
- Tests will be skipped if no API key is available
|
|
68
|
+
|
|
69
|
+
**Note:** The translation feature uses the same LLM model configured for other cognee tasks (via `LLM_MODEL` and `LLM_PROVIDER` environment variables). This means any LLM provider supported by cognee (OpenAI, Azure, Anthropic, Ollama, etc.) can be used for translation.
|
|
70
|
+
|
|
71
|
+
## Usage Example
|
|
72
|
+
|
|
73
|
+
```python
|
|
74
|
+
import cognee
|
|
75
|
+
from cognee.tasks.translation import translate_text
|
|
76
|
+
|
|
77
|
+
# Configure translation (optional - defaults to LLM provider)
|
|
78
|
+
cognee.config.set_translation_config(
|
|
79
|
+
provider="llm", # Uses configured LLM (default)
|
|
80
|
+
target_language="en", # Target language code
|
|
81
|
+
confidence_threshold=0.7 # Minimum confidence for language detection
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
# Translate text directly
|
|
85
|
+
result = await translate_text(
|
|
86
|
+
text="Bonjour le monde",
|
|
87
|
+
target_language="en"
|
|
88
|
+
)
|
|
89
|
+
print(result.translated_text) # "Hello world"
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### Alternative Translation Providers
|
|
93
|
+
|
|
94
|
+
```python
|
|
95
|
+
# Use Google Cloud Translate (requires GOOGLE_TRANSLATE_API_KEY)
|
|
96
|
+
cognee.config.set_translation_provider("google")
|
|
97
|
+
|
|
98
|
+
# Use Azure Translator (requires AZURE_TRANSLATOR_KEY and AZURE_TRANSLATOR_REGION)
|
|
99
|
+
cognee.config.set_translation_provider("azure")
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
## Test Summary
|
|
103
|
+
|
|
104
|
+
| Test File | Tests | Description |
|
|
105
|
+
|-----------|-------|-------------|
|
|
106
|
+
| config_test.py | 4 | Configuration validation |
|
|
107
|
+
| detect_language_test.py | 10 | Language detection |
|
|
108
|
+
| providers_test.py | 9 | Translation providers |
|
|
109
|
+
| translate_content_test.py | 9 | Content translation task |
|
|
110
|
+
| integration_test.py | 2 | Standalone translation tests |
|
|
111
|
+
| **Total** | **34** | |
|
|
112
|
+
|
|
113
|
+
## Test Categories
|
|
114
|
+
|
|
115
|
+
### Configuration (4 tests)
|
|
116
|
+
- ✅ Default configuration values
|
|
117
|
+
- ✅ Provider type literal validation
|
|
118
|
+
- ✅ Confidence threshold bounds
|
|
119
|
+
- ✅ Multiple provider API keys
|
|
120
|
+
|
|
121
|
+
### Language Detection (10 tests)
|
|
122
|
+
- ✅ Multiple language detection (EN, ES, FR, DE, ZH)
|
|
123
|
+
- ✅ Confidence scoring
|
|
124
|
+
- ✅ Target language matching
|
|
125
|
+
- ✅ Short and empty text handling
|
|
126
|
+
- ✅ Mixed language detection
|
|
127
|
+
|
|
128
|
+
### Translation Providers (9 tests)
|
|
129
|
+
- ✅ Provider factory function
|
|
130
|
+
- ✅ LLM translation
|
|
131
|
+
- ✅ Batch operations
|
|
132
|
+
- ✅ Auto source language detection
|
|
133
|
+
- ✅ Long text handling
|
|
134
|
+
- ✅ Special characters preservation
|
|
135
|
+
- ✅ Error handling
|
|
136
|
+
|
|
137
|
+
### Content Translation (9 tests)
|
|
138
|
+
- ✅ DocumentChunk processing
|
|
139
|
+
- ✅ Metadata creation (LanguageMetadata, TranslatedContent)
|
|
140
|
+
- ✅ Original text preservation
|
|
141
|
+
- ✅ Multiple chunk handling
|
|
142
|
+
- ✅ Empty text/list handling
|
|
143
|
+
- ✅ Confidence threshold customization
|
|
144
|
+
|
|
145
|
+
### Integration (2 tests)
|
|
146
|
+
- ✅ Direct translate_text function
|
|
147
|
+
- ✅ Language detection functionality
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""Translation task tests"""
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Unit tests for translation configuration
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from typing import get_args
|
|
6
|
+
|
|
7
|
+
from pydantic import ValidationError
|
|
8
|
+
|
|
9
|
+
from cognee.tasks.translation.config import (
|
|
10
|
+
get_translation_config,
|
|
11
|
+
TranslationConfig,
|
|
12
|
+
TranslationProviderType,
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def test_default_translation_config():
|
|
17
|
+
"""Test default translation configuration"""
|
|
18
|
+
config = get_translation_config()
|
|
19
|
+
|
|
20
|
+
assert isinstance(config, TranslationConfig), "Config should be TranslationConfig instance"
|
|
21
|
+
assert config.translation_provider in [
|
|
22
|
+
"llm",
|
|
23
|
+
"google",
|
|
24
|
+
"azure",
|
|
25
|
+
], f"Invalid provider: {config.translation_provider}"
|
|
26
|
+
assert 0.0 <= config.confidence_threshold <= 1.0, (
|
|
27
|
+
f"Confidence threshold {config.confidence_threshold} out of bounds [0.0, 1.0]"
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def test_translation_provider_type_literal():
|
|
32
|
+
"""Test TranslationProviderType Literal type values"""
|
|
33
|
+
# Get the allowed values from the Literal type
|
|
34
|
+
allowed_values = get_args(TranslationProviderType)
|
|
35
|
+
|
|
36
|
+
assert "llm" in allowed_values, "llm should be an allowed provider"
|
|
37
|
+
assert "google" in allowed_values, "google should be an allowed provider"
|
|
38
|
+
assert "azure" in allowed_values, "azure should be an allowed provider"
|
|
39
|
+
assert len(allowed_values) == 3, f"Expected 3 providers, got {len(allowed_values)}"
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def test_confidence_threshold_bounds():
|
|
43
|
+
"""Test confidence threshold validation"""
|
|
44
|
+
config = TranslationConfig(translation_provider="llm", confidence_threshold=0.9)
|
|
45
|
+
|
|
46
|
+
assert 0.0 <= config.confidence_threshold <= 1.0, (
|
|
47
|
+
f"Confidence threshold {config.confidence_threshold} out of bounds [0.0, 1.0]"
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def test_confidence_threshold_validation():
|
|
52
|
+
"""Test that invalid confidence thresholds are rejected or clamped"""
|
|
53
|
+
# Test boundary values - these should work
|
|
54
|
+
config_min = TranslationConfig(translation_provider="llm", confidence_threshold=0.0)
|
|
55
|
+
assert config_min.confidence_threshold == 0.0, "Minimum bound (0.0) should be valid"
|
|
56
|
+
|
|
57
|
+
config_max = TranslationConfig(translation_provider="llm", confidence_threshold=1.0)
|
|
58
|
+
assert config_max.confidence_threshold == 1.0, "Maximum bound (1.0) should be valid"
|
|
59
|
+
|
|
60
|
+
# Test invalid values - these should either raise ValidationError or be clamped
|
|
61
|
+
try:
|
|
62
|
+
config_invalid_low = TranslationConfig(
|
|
63
|
+
translation_provider="llm", confidence_threshold=-0.1
|
|
64
|
+
)
|
|
65
|
+
# If no error, verify it was clamped to valid range
|
|
66
|
+
assert 0.0 <= config_invalid_low.confidence_threshold <= 1.0, (
|
|
67
|
+
f"Invalid low value should be clamped, got {config_invalid_low.confidence_threshold}"
|
|
68
|
+
)
|
|
69
|
+
except ValidationError:
|
|
70
|
+
pass # Expected validation error
|
|
71
|
+
|
|
72
|
+
try:
|
|
73
|
+
config_invalid_high = TranslationConfig(
|
|
74
|
+
translation_provider="llm", confidence_threshold=1.5
|
|
75
|
+
)
|
|
76
|
+
# If no error, verify it was clamped to valid range
|
|
77
|
+
assert 0.0 <= config_invalid_high.confidence_threshold <= 1.0, (
|
|
78
|
+
f"Invalid high value should be clamped, got {config_invalid_high.confidence_threshold}"
|
|
79
|
+
)
|
|
80
|
+
except ValidationError:
|
|
81
|
+
pass # Expected validation error
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
def test_multiple_provider_keys():
|
|
85
|
+
"""Test configuration with multiple provider API keys"""
|
|
86
|
+
config = TranslationConfig(
|
|
87
|
+
translation_provider="llm",
|
|
88
|
+
google_translate_api_key="google_key",
|
|
89
|
+
azure_translator_key="azure_key",
|
|
90
|
+
)
|
|
91
|
+
|
|
92
|
+
assert config.google_translate_api_key == "google_key", "Google API key not set correctly"
|
|
93
|
+
assert config.azure_translator_key == "azure_key", "Azure API key not set correctly"
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Unit tests for language detection functionality
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import pytest
|
|
6
|
+
from cognee.tasks.translation.detect_language import (
|
|
7
|
+
detect_language_async,
|
|
8
|
+
LanguageDetectionResult,
|
|
9
|
+
)
|
|
10
|
+
from cognee.tasks.translation.exceptions import LanguageDetectionError
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
@pytest.mark.asyncio
|
|
14
|
+
async def test_detect_english():
|
|
15
|
+
"""Test detection of English text"""
|
|
16
|
+
result = await detect_language_async("Hello world, this is a test.", target_language="en")
|
|
17
|
+
|
|
18
|
+
assert result.language_code == "en"
|
|
19
|
+
assert result.requires_translation is False
|
|
20
|
+
assert result.confidence > 0.9
|
|
21
|
+
assert result.language_name == "English"
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
@pytest.mark.asyncio
|
|
25
|
+
async def test_detect_spanish():
|
|
26
|
+
"""Test detection of Spanish text"""
|
|
27
|
+
result = await detect_language_async("Hola mundo, esta es una prueba.", target_language="en")
|
|
28
|
+
|
|
29
|
+
assert result.language_code == "es"
|
|
30
|
+
assert result.requires_translation is True
|
|
31
|
+
assert result.confidence > 0.9
|
|
32
|
+
assert result.language_name == "Spanish"
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
@pytest.mark.asyncio
|
|
36
|
+
async def test_detect_french():
|
|
37
|
+
"""Test detection of French text"""
|
|
38
|
+
result = await detect_language_async(
|
|
39
|
+
"Bonjour le monde, ceci est un test.", target_language="en"
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
assert result.language_code == "fr"
|
|
43
|
+
assert result.requires_translation is True
|
|
44
|
+
assert result.confidence > 0.9
|
|
45
|
+
assert result.language_name == "French"
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
@pytest.mark.asyncio
|
|
49
|
+
async def test_detect_german():
|
|
50
|
+
"""Test detection of German text"""
|
|
51
|
+
result = await detect_language_async("Hallo Welt, das ist ein Test.", target_language="en")
|
|
52
|
+
|
|
53
|
+
assert result.language_code == "de"
|
|
54
|
+
assert result.requires_translation is True
|
|
55
|
+
assert result.confidence > 0.9
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
@pytest.mark.asyncio
|
|
59
|
+
async def test_detect_chinese():
|
|
60
|
+
"""Test detection of Chinese text"""
|
|
61
|
+
result = await detect_language_async("你好世界,这是一个测试。", target_language="en")
|
|
62
|
+
|
|
63
|
+
assert result.language_code.startswith("zh"), f"Expected Chinese, got {result.language_code}"
|
|
64
|
+
assert result.requires_translation is True
|
|
65
|
+
assert result.confidence > 0.9
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
@pytest.mark.asyncio
|
|
69
|
+
async def test_already_target_language():
|
|
70
|
+
"""Test when text is already in target language"""
|
|
71
|
+
result = await detect_language_async("This text is already in English.", target_language="en")
|
|
72
|
+
|
|
73
|
+
assert result.requires_translation is False
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
@pytest.mark.asyncio
|
|
77
|
+
async def test_short_text():
|
|
78
|
+
"""Test detection with very short text"""
|
|
79
|
+
result = await detect_language_async("Hi", target_language="es")
|
|
80
|
+
|
|
81
|
+
# Short text may return 'unknown' if langdetect can't reliably detect
|
|
82
|
+
assert result.language_code in ["en", "unknown"]
|
|
83
|
+
assert result.character_count == 2
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
@pytest.mark.asyncio
|
|
87
|
+
async def test_empty_text():
|
|
88
|
+
"""Test detection with empty text - returns unknown by default"""
|
|
89
|
+
result = await detect_language_async("", target_language="en")
|
|
90
|
+
|
|
91
|
+
# With skip_detection_for_short_text=True (default), returns unknown
|
|
92
|
+
assert result.language_code == "unknown"
|
|
93
|
+
assert result.language_name == "Unknown"
|
|
94
|
+
assert result.confidence == 0.0
|
|
95
|
+
assert result.requires_translation is False
|
|
96
|
+
assert result.character_count == 0
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
@pytest.mark.asyncio
|
|
100
|
+
async def test_confidence_threshold():
|
|
101
|
+
"""Test detection respects confidence threshold"""
|
|
102
|
+
result = await detect_language_async(
|
|
103
|
+
"Hello world", target_language="es", confidence_threshold=0.5
|
|
104
|
+
)
|
|
105
|
+
|
|
106
|
+
assert result.confidence >= 0.5
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
@pytest.mark.asyncio
|
|
110
|
+
async def test_mixed_language_text():
|
|
111
|
+
"""Test detection with mixed language text (predominantly one language)"""
|
|
112
|
+
# Predominantly Spanish with English word
|
|
113
|
+
result = await detect_language_async(
|
|
114
|
+
"La inteligencia artificial es muy importante en technology moderna.", target_language="en"
|
|
115
|
+
)
|
|
116
|
+
|
|
117
|
+
assert result.language_code == "es" # Should detect as Spanish
|
|
118
|
+
assert result.requires_translation is True
|