import unittest from unittest.mock import Mock, patch from ocr_dashboard_service import export_evidences, get_comparison, get_summary, list_batches, list_configured_notes, list_evidences, list_results from task_service import TaskError class OcrDashboardServiceTest(unittest.TestCase): @patch("ocr_dashboard_service.Config.EVIDENCE_ADMIN_BASE_URL", "http://admin") @patch("ocr_dashboard_service._get") @patch("ocr_dashboard_service.SESSION.get") def test_evidences_use_exact_admin_scope_as_display_source(self, get, upstream_get): upstream_get.return_value = {"items": [{"cos_object_key": "old.jpg"}], "total": 1} response = Mock() response.json.return_value = {"data": {"items": [{ "id": 2, "image_id": 3, "evidence_type": "first_screen", "cos_object_key": "managed.jpg", "sort_order": 1, "is_published": True, }], "total": 1, "limit": 100, "is_complete": True}} get.return_value = response result = list_evidences({ "batch_key": "b1", "collection_key": "c1", "question_code": "Q1", "limit": 100, }) self.assertEqual([item["cos_object_key"] for item in result["items"]], ["managed.jpg"]) self.assertEqual(result["total"], 1) self.assertEqual(get.call_args.kwargs["params"], { "batch_key": "b1", "collection_key": "c1", "question_code": "Q1", "limit": 100, }) self.assertTrue(get.call_args.args[0].endswith("/api/published-evidences")) upstream_get.assert_not_called() @patch("ocr_dashboard_service.SESSION.get") def test_configured_notes_reads_admin_list(self, get): response = Mock() response.json.return_value = {"data": [{"note_id": "note-1"}]} get.return_value = response self.assertEqual(list_configured_notes(), [{"note_id": "note-1"}]) self.assertTrue(get.call_args.args[0].endswith("/api/notes")) @patch("ocr_dashboard_service.SESSION.get") def test_list_batches_unwraps_framework_response(self, get): response = Mock() response.json.return_value = {"success": True, "code": 200, "data": [{"batch_key": "b1"}]} get.return_value = response self.assertEqual(list_batches()[0]["batch_key"], "b1") @patch("ocr_dashboard_service.SESSION.get") def test_summary_forwards_scope(self, get): response = Mock() response.json.return_value = {"success": True, "code": 200, "data": {"questions": []}} get.return_value = response get_summary("b1", "c1") self.assertEqual(get.call_args.kwargs["params"], {"batch_key": "b1", "collection_key": "c1"}) @patch("ocr_dashboard_service.SESSION.get") def test_summary_forwards_subject_name(self, get): response = Mock() response.json.return_value = {"success": True, "code": 200, "data": {"questions": []}} get.return_value = response get_summary(start_date="2026-08-01", end_date="2026-09-03", subject_name="民生银行") self.assertEqual(get.call_args.kwargs["params"], { "start_date": "2026-08-01", "end_date": "2026-09-03", "subject_name": "民生银行", }) @patch("ocr_dashboard_service.SESSION.get") def test_comparison_forwards_scope(self, get): response = Mock() response.json.return_value = { "success": True, "code": 200, "data": {"current": {}, "previous": {}}, } get.return_value = response result = get_comparison("b1", "c1") self.assertIn("current", result) self.assertEqual( get.call_args.kwargs["params"], {"batch_key": "b1", "collection_key": "c1"}, ) def test_results_rejects_oversized_page(self): with self.assertRaises(TaskError): list_results({"page_size": "201"}) @patch("ocr_dashboard_service.SESSION.get") @patch("ocr_dashboard_service.list_evidences") def test_export_evidences_builds_zip(self, list_evidences, get): list_evidences.return_value = {"items": [{ "question_code": "Q1", "search_keyword": "山姆会员卡", "device_code": "DEV-1", "city": "厦门", "sort_order": 1, "source_file_name": "shot.jpg", "cos_url": "https://bucket.cos.ap-guangzhou.myqcloud.com/shot.jpg", }]} response = Mock(content=b"image-bytes") get.return_value = response payload, filename, count = export_evidences({"batch_key": "b1", "collection_key": "c1"}) self.assertEqual(filename, "holy-crab-evidences-all.zip") self.assertEqual(count, 1) self.assertTrue(payload.read(2) == b"PK") if __name__ == "__main__": unittest.main()