Files
contracts-flask/tests/README.md
T

44 lines
3.4 KiB
Markdown
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.
# Тесты contracts-flask
Набор pytest-тестов под актуальный код сервиса (`site/`).
Покрытие: юнит (чистая логика), интеграционные (SQLite), HTTP-эндпоинты (Flask test client), безопасность.
## Запуск
```bash
cd contracts-flask
pytest tests/ -q
```
pytest установлен в venv: `/home/naeel/nubes/contracts/.venv/bin/python -m pytest tests/ -q`.
## Файлы
| Файл | Что тестирует |
|---|---|
| `conftest.py` | site/ в `sys.path`; фикстура `db` — изолированная БД (временный `DB_PATH` + свежая схема); защита реальной `/tmp/contracts.db` от пересоздания |
| `test_metrics.py` | `services/metrics.py`: `normalize_date`, `check_arithmetic` (sum == price×qty), `_to_decimal`, `ClassifyMetrics` |
| `test_grouping.py` | `services/grouping.py`: `normalize_number`, `group_documents` (группировка contract+supplement, unresolved), `apply_groups` (mock db) |
| `test_llm_client.py` | `services/llm_client.py`: `FakeLLMClient` (точное/частичное совпадение, default, история вызовов), `HttpxLLMClient` |
| `test_llm.py` | `services/llm.py`: `call_llm` — парсинг plain JSON и markdown-обёрток (```json) |
| `test_classify.py` | `services/classify.py`: garbage-фильтры по имени/заголовку, `_safe_json_parse` (7 edge-case: trailing comma, chatter, пусто), `_smart_extract` |
| `test_parse.py` | `services/parse.py`: `parse_file` (text/docx/pdf, ошибки), `_parse_text` |
| `test_connection.py` | `db/connection.py`: `_pg_to_sqlite` (все замены %s/::jsonb/BOOLEAN/ILIKE/TRUE), `_extract_table` |
| `test_spec_events.py` | `db/spec_events.py`: `apply_ops` (ADD/UPDATE/DELETE/UNRESOLVED/unknown), `clear_current`, `reset`, `_hash`, `get_next_seq` |
| `test_spec_current.py` | `db/spec_current.py`: `list_by_contract` (порядок), `get_elements_json` |
| `test_process_pipeline.py` | `services/process.py`: `run_pipeline` с Fake LLM — **full_replace не дублирует строки**, **трансляция target_id→target_hash**, `_elements_to_text` |
| `test_routes.py` | HTTP-эндпоинты (Flask test client): `/health`, `/api/spec-current`, `/upload`, `/unzip-upload`, `/api/groups` |
| `test_upload_security.py` | `routes/upload_bp.py`: `_check_ext` (допустимые/недопустимые), `_unzip` (path traversal нейтрализуется, битый zip) |
## Ключевые проверки
- `test_full_replace_no_duplicates` — два `full_replace` подряд → в `spec_current` 3 строки, а не 6; история `spec_events` (6 событий) сохранена.
- `test_update_applies` — `target_id: "r1"` транслируется в `target_hash` → UPDATE применяется (status `applied`), а не уходит в UNRESOLVED.
- `test_path_traversal_neutralized` — `../etc/passwd` внутри ZIP → имя файла `passwd` без пути.
## Изоляция
- Каждый тест, работающий с БД, получает свою копию SQLite через фикстуру `db`
(monkeypatch `DB_PATH` → `tmp_path`, `init_db()`).
- LLM-вызовы в пайплайне подменяются через `monkeypatch.setattr("services.llm.call_llm", ...)` — сеть не используется.