feat(ai): integrate local Ollama AI for in-context sentence translation and caching (Task 13)
This commit is contained in:
@@ -1206,3 +1206,69 @@ def test_offline_dictionary_lookup_and_coverage():
|
||||
asyncio.run(run_lookups())
|
||||
|
||||
|
||||
def test_sentence_translation_ai_and_caching():
|
||||
"""Validates local AI sentence translation endpoint, SQLite caching, and in-context word meaning."""
|
||||
import time
|
||||
from app.database import compute_sentence_hash, get_cached_sentence_translation, save_sentence_translation
|
||||
|
||||
# 1. Unauthenticated request must be blocked
|
||||
client.cookies.clear()
|
||||
unauth_res = client.post("/api/translate-sentence", json={"sentence": "He had a prodigious memory."})
|
||||
assert unauth_res.status_code == 401
|
||||
|
||||
# 2. Login as admin
|
||||
login_res = client.post("/api/login", json={"username": "testadmin", "password": "testpass12345"})
|
||||
assert login_res.status_code == 200
|
||||
|
||||
# 3. Empty sentence validation
|
||||
empty_res = client.post("/api/translate-sentence", json={"sentence": " "})
|
||||
assert empty_res.status_code == 400
|
||||
|
||||
# 4. Direct SQLite cache unit test
|
||||
sentence = "He took the matter into his own hands and succeeded."
|
||||
target_word = "matter"
|
||||
h = compute_sentence_hash(sentence, target_word)
|
||||
assert len(h) == 64
|
||||
|
||||
# Initially not cached
|
||||
assert get_cached_sentence_translation(sentence, target_word) is None
|
||||
|
||||
# Save to cache
|
||||
save_sentence_translation(
|
||||
sentence=sentence,
|
||||
translated_text="Он взял дело в свои руки и преуспел.",
|
||||
target_word=target_word,
|
||||
word_meaning="дело, вопрос",
|
||||
source="unit_test",
|
||||
)
|
||||
|
||||
cached_entry = get_cached_sentence_translation(sentence, target_word)
|
||||
assert cached_entry is not None
|
||||
assert cached_entry["translated_text"] == "Он взял дело в свои руки и преуспел."
|
||||
assert cached_entry["word_meaning"] == "дело, вопрос"
|
||||
assert cached_entry["source"] == "unit_test"
|
||||
|
||||
# 5. Fast cached retrieval via HTTP endpoint (< 10ms)
|
||||
t0 = time.perf_counter()
|
||||
api_res = client.post(
|
||||
"/api/translate-sentence",
|
||||
json={"sentence": sentence, "target_word": target_word},
|
||||
)
|
||||
dt_ms = (time.perf_counter() - t0) * 1000
|
||||
assert api_res.status_code == 200
|
||||
data = api_res.json()
|
||||
assert data["cached"] is True
|
||||
assert data["sentence_ru"] == "Он взял дело в свои руки и преуспел."
|
||||
assert data["word_meaning"] == "дело, вопрос"
|
||||
assert dt_ms < 50.0
|
||||
|
||||
# 6. Test AI status endpoint
|
||||
status_res = client.get("/api/ai/status")
|
||||
assert status_res.status_code == 200
|
||||
status_data = status_res.json()
|
||||
assert "online" in status_data
|
||||
assert "models" in status_data
|
||||
assert "active_model" in status_data
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user