wellsaid / app /tests /test_api.py
iamspruce
added synonyms generator
ce2ce69
# app/tests/test_api_with_worker.py
import pytest
from httpx import AsyncClient
from unittest.mock import AsyncMock, patch, MagicMock
import asyncio
from app.core.app import create_app
from app.core.config import settings
app = create_app()
TEST_API_KEY = "test_fixture_key"
HEADERS = {"x-api-key": TEST_API_KEY}
@pytest.fixture(autouse=True)
def mock_api_key_dependency():
with patch("app.core.security.verify_api_key", return_value=True):
yield
@pytest.fixture(scope="function")
def fresh_future_and_queue_mock():
"""Creates a fresh future and mocks the task_queue.put logic."""
future = asyncio.Future()
with patch("asyncio.get_event_loop") as mock_loop:
mock_event_loop = MagicMock()
mock_event_loop.create_future.return_value = future
mock_loop.return_value = mock_event_loop
with patch("app.queue.task_queue.put", new_callable=AsyncMock) as mock_put:
def side_effect(task_data):
pass # We'll manually control the future in test
mock_put.side_effect = side_effect
yield future, mock_put
@pytest.fixture(scope="module")
async def client():
async with AsyncClient(app=app, base_url="http://test") as ac:
yield ac
async def test_root(client):
response = await client.get("/")
assert response.status_code == 200
assert response.json() == {"message": "Welcome to Wellsaid API"}
@patch('app.services.grammar.GrammarCorrector.correct', new_callable=AsyncMock)
async def test_grammar(mock_correct, client, fresh_future_and_queue_mock):
future, mock_put = fresh_future_and_queue_mock
original = "She go to school."
corrected = "She goes to school."
mock_correct.return_value = corrected
future.set_result(corrected)
response = await client.post("/grammar", json={"text": original}, headers=HEADERS)
assert response.status_code == 200
data = response.json()["grammar"]
assert data["original_text"] == original
assert data["corrected_text_suggestion"] == corrected
assert "issues" in data
mock_put.assert_called_once()
@patch('app.services.paraphrase.Paraphraser.paraphrase', new_callable=AsyncMock)
async def test_paraphrase(mock_paraphrase, client, fresh_future_and_queue_mock):
future, mock_put = fresh_future_and_queue_mock
input_text = "This is a simple sentence."
result_text = "Here's a straightforward phrase."
mock_paraphrase.return_value = result_text
future.set_result(result_text)
response = await client.post("/paraphrase", json={"text": input_text}, headers=HEADERS)
assert response.status_code == 200
assert response.json()["result"] == result_text
mock_put.assert_called_once()
@patch('app.services.tone.ToneClassifier.classify', new_callable=AsyncMock)
async def test_tone(mock_classify, client, fresh_future_and_queue_mock):
future, mock_put = fresh_future_and_queue_mock
tone_result = "Positive"
mock_classify.return_value = tone_result
future.set_result(tone_result)
response = await client.post("/tone", json={"text": "Great job!"}, headers=HEADERS)
assert response.status_code == 200
assert response.json()["result"] == tone_result
mock_put.assert_called_once()
@patch('app.services.translation.Translator.translate', new_callable=AsyncMock)
async def test_translate(mock_translate, client, fresh_future_and_queue_mock):
future, mock_put = fresh_future_and_queue_mock
translated = "Bonjour"
mock_translate.return_value = translated
future.set_result(translated)
response = await client.post("/translate", json={"text": "Hello", "target_lang": "fr"}, headers=HEADERS)
assert response.status_code == 200
assert response.json()["result"] == translated
mock_put.assert_called_once()
@patch('app.services.voice.VoiceAnalyzer.analyze_voice', new_callable=AsyncMock)
async def test_voice(mock_voice, client, fresh_future_and_queue_mock):
future, mock_put = fresh_future_and_queue_mock
mock_voice.return_value = "Passive"
future.set_result("Passive")
response = await client.post("/voice", json={"text": "The ball was thrown."}, headers=HEADERS)
assert response.status_code == 200
assert response.json()["result"] == "Passive"
mock_put.assert_called_once()