ruwiki-test/tests/conftest.py

175 lines
4.8 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import asyncio
import tempfile
from collections.abc import Generator
from pathlib import Path
from unittest.mock import AsyncMock, MagicMock
import pytest
from openai.types.chat import ChatCompletion, ChatCompletionMessage
from openai.types.chat.chat_completion import Choice
from src.models import AppConfig, Article, ArticleCreate, ProcessingStatus
@pytest.fixture(scope="session")
def event_loop() -> Generator[asyncio.AbstractEventLoop, None, None]:
loop = asyncio.new_event_loop()
yield loop
loop.close()
@pytest.fixture
def test_config() -> AppConfig:
with tempfile.TemporaryDirectory() as temp_dir:
db_path = Path(temp_dir) / "test.db"
return AppConfig(
openai_api_key="test_key",
openai_model="gpt-4o-mini",
db_path=str(db_path),
max_concurrent_llm=2,
openai_rpm=10,
max_concurrent_wiki=5,
prompt_template_path="src/prompt.txt",
log_level="DEBUG",
)
@pytest.fixture
def sample_wiki_urls() -> list[str]:
return [
"https://ru.wikipedia.org/wiki/Тест",
"https://ru.wikipedia.org/wiki/Пример",
"https://ru.wikipedia.org/wiki/Образец",
]
@pytest.fixture
def invalid_urls() -> list[str]:
return [
"https://example.com/invalid",
"https://en.wikipedia.org/wiki/English",
"not_a_url",
"",
"https://ru.wikipedia.org/wiki/",
]
@pytest.fixture
def sample_wikitext() -> str:
return """'''Тест''' — это проверка чего-либо.
== Определение ==
Тест может проводиться для различных целей:
* Проверка знаний
* Проверка работоспособности
* Проверка качества
== История ==
Тесты использовались с древних времён.
{{навигация|тема=Тестирование}}
[[Категория:Тестирование]]"""
@pytest.fixture
def simplified_text() -> str:
return """'''Тест''' — это проверка чего-либо для школьников.
== Что такое тест ==
Тест помогает проверить:
* Знания учеников
* Как работают устройства
* Качество продуктов
== Когда появились тесты ==
Люди проверяли друг друга очень давно.
###END###"""
@pytest.fixture
def sample_article_data() -> ArticleCreate:
return ArticleCreate(
url="https://ru.wikipedia.org/wiki/Тест",
title="Тест",
raw_text="Тестовый wiki-текст",
)
@pytest.fixture
def sample_article(sample_article_data: ArticleCreate) -> Article:
return Article(
id=1,
url=sample_article_data.url,
title=sample_article_data.title,
raw_text=sample_article_data.raw_text,
status=ProcessingStatus.PENDING,
)
@pytest.fixture
def completed_article(sample_article: Article, simplified_text: str) -> Article:
article = sample_article.model_copy()
article.mark_completed(
simplified_text=simplified_text,
token_count_raw=100,
token_count_simplified=50,
processing_time=2.5,
)
return article
@pytest.fixture
def mock_openai_response() -> ChatCompletion:
return ChatCompletion(
id="test_completion",
object="chat.completion",
created=1234567890,
model="gpt-4o-mini",
choices=[
Choice(
index=0,
message=ChatCompletionMessage(
role="assistant",
content="Упрощённый текст для школьников.\n\n###END###",
),
finish_reason="stop",
)
],
usage=None,
)
@pytest.fixture
def temp_input_file(sample_wiki_urls: list[str]) -> Generator[str, None, None]:
with tempfile.NamedTemporaryFile(mode="w", suffix=".txt", delete=False) as f:
for url in sample_wiki_urls:
f.write(f"{url}\n")
f.write("# Комментарий\n")
f.write("\n")
f.write("https://ru.wikipedia.org/wiki/Дубликат\n")
f.write("https://ru.wikipedia.org/wiki/Дубликат\n")
temp_path = f.name
yield temp_path
Path(temp_path).unlink(missing_ok=True)
@pytest.fixture
async def mock_wiki_client() -> AsyncMock:
mock_client = AsyncMock()
mock_page = MagicMock()
mock_page.exists = True
mock_page.redirect = False
mock_page.text.return_value = "Тестовый wiki-текст"
mock_client.pages = {"Тест": mock_page}
return mock_client
@pytest.fixture
async def mock_openai_client() -> AsyncMock:
mock_client = AsyncMock()
return mock_client