"""Интеграционные тесты HTTP-эндпоинтов (Flask test client).""" import pytest @pytest.fixture def client(tmp_path, monkeypatch): from db import connection as conn monkeypatch.setattr(conn, "DB_PATH", str(tmp_path / "app.db")) from app import create_app app = create_app() app.config["TESTING"] = True yield app.test_client() c = getattr(conn._local, "conn", None) if c is not None: try: c.close() except Exception: pass conn._local.conn = None class TestHealth: def test_health(self, client): from config import VERSION r = client.get("/health") assert r.status_code == 200 data = r.get_json() assert data["ok"] is True assert data["version"] == VERSION class TestHomepage: def test_version_and_asset_urls_use_application_version(self, client): from config import VERSION response = client.get("/") assert response.status_code == 200 html = response.get_data(as_text=True) assert f">v{VERSION}" in html assert f"/static/files.js?v={VERSION}" in html assert f"/file-picker/file-picker.iife.js?v={VERSION}" in html class TestSpecCurrent: def test_missing_contract_id(self, client): r = client.get("/api/spec-current") assert r.status_code == 400 def test_empty(self, client): r = client.get("/api/spec-current?contract_id=missing") assert r.status_code == 200 data = r.get_json() assert data["ok"] is True assert data["rows"] == [] class TestGroups: def test_missing_batch(self, client): r = client.get("/api/groups") assert r.status_code == 400 class TestSync: def test_requires_batch_id(self, client): response = client.post("/api/sync", json={"keep_ids": []}) assert response.status_code == 400 assert response.get_json()["error"] == "batch_id required" def test_only_deletes_documents_in_requested_batch(self, client): from db import documents from db.connection import execute, query doc_a = documents.insert("a.pdf", "application/pdf", "", batch_id="batch-a") doc_b = documents.insert("b.pdf", "application/pdf", "", batch_id="batch-b") execute( "INSERT INTO prompts (id, role, name, body) VALUES (%s, %s, %s, %s)", ("prompt-1", "classify", "custom", "keep me"), ) response = client.post( "/api/sync", json={"batch_id": "batch-a", "keep_ids": []}, ) assert response.status_code == 200 assert response.get_json()["deleted"] == 1 assert documents.get(doc_a["id"]) is None assert documents.get(doc_b["id"]) is not None assert query("SELECT body FROM prompts WHERE id = %s", ("prompt-1",)) == [ {"body": "keep me"} ] def test_cleanup_endpoint_is_not_exposed(self, client): response = client.post("/api/cleanup") assert response.status_code == 404 def test_file_picker_bundle_is_served(self, client): response = client.get("/file-picker/file-picker.iife.js") assert response.status_code == 200 assert b"initFilePicker" in response.data def test_application_startup_preserves_database(self, client): from app import create_app from db import documents doc = documents.insert("keep.pdf", "application/pdf", "", batch_id="batch-a") create_app() assert documents.get(doc["id"]) is not None