import tempfile import unittest from pathlib import Path from unittest.mock import patch from search.api import Api, ApiError class SearchReviewTest(unittest.TestCase): def test_review_must_cover_each_snapshot_rank_once(self): with tempfile.TemporaryDirectory() as temporary: api = Api("http://opensearch:9200", "current", Path(temporary), Path(temporary) / "reviews.sqlite3", b"test-secret") response = {"hits": {"hits": [{"_index": "search-20260827", "_source": {"document_code": "7", "edition_code": "10", "document_name_ru": "Закон"}}, {"_index": "search-20260827", "_source": {"document_code": "8", "edition_code": "11", "document_name_ru": "Кодекс"}}]}} with patch("search.api.request_json", return_value=response): result = api.handle("GET", "/search?q=test&language=ru&page_size=2")[1] with self.assertRaisesRegex(ApiError, "exactly once"): api.handle("POST", "/search-reviews", {"review_token": result["review_token"], "reviewer": "Юрист", "results": [{"rank": 1, "code": "7", "rating": 3}]}) def test_saves_signed_search_snapshot_and_rejects_tampering(self): with tempfile.TemporaryDirectory() as temporary: api = Api("http://opensearch:9200", "current", Path(temporary), Path(temporary) / "reviews.sqlite3", b"test-secret") response = {"hits": {"hits": [{"_source": {"document_code": "7", "edition_code": "10", "document_name_ru": "Закон"}}]}} with patch("search.api.request_json", return_value=response): result = api.handle("GET", "/search?q=%D0%B7%D0%B0%D0%BA%D0%BE%D0%BD&language=ru")[1] saved = api.handle("POST", "/search-reviews", {"review_token": result["review_token"], "reviewer": "Юрист", "results": [{"rank": 1, "code": "7", "rating": 3, "comment": "Прямой ответ"}]}) self.assertEqual(saved[0], 201) exported = api.handle("GET", "/search-reviews/export")[1]["reviews"] self.assertEqual(exported[0]["top_result_code"], "7") self.assertEqual(exported[0]["results"][0]["rating"], 3) with self.assertRaisesRegex(ApiError, "does not match"): api.handle("POST", "/search-reviews", {"review_token": result["review_token"], "reviewer": "Юрист", "results": [{"rank": 1, "code": "8", "rating": 3}]}) def test_snapshot_and_review_page_are_available(self): with tempfile.TemporaryDirectory() as temporary: api = Api("http://opensearch:9200", "current", Path(temporary)) page = api.review_page() self.assertIn("Оценка поисковой выдачи", page) self.assertIn("akyldash-search-review-draft", page) self.assertIn("localStorage", page) if __name__ == "__main__": unittest.main()