# #region TestAgentChat.DocumentParser [C:2] [TYPE Module] [SEMANTICS test,agent,document,parser] # @BRIEF Tests for document parser — PDF, XLSX, unsupported formats, empty files, errors. # @RELATION BINDS_TO -> [AgentChat.Document.Parser] import sys from pathlib import Path sys.path.append(str(Path(__file__).parent.parent.parent / "src")) import os import tempfile import pytest from src.agent.document_parser import parse_pdf, parse_xlsx, parse_upload, ParseError # #region TestAgentChat.DocumentParser.PDF [C:2] [TYPE Function] [SEMANTICS test,parser,pdf] # @BRIEF PDF parsing: extracts text from valid PDF, handles empty and encrypted PDFs gracefully. def test_parse_pdf_valid(): """Parse a valid PDF and verify text extraction.""" # Create a minimal valid PDF pdf_content = ( b"%PDF-1.4\n" b"1 0 obj<>endobj\n" b"2 0 obj<>endobj\n" b"3 0 obj<>>>>>endobj\n" b"4 0 obj<>stream\n" b"BT /F1 12 Tf 100 700 Td (Hello PDF) Tj ET\n" b"endstream\nendobj\n" b"5 0 obj<>endobj\n" b"xref\n" b"0 6\n" b"trailer<>\n" b"startxref\n" b"169\n" b"%%EOF" ) with tempfile.NamedTemporaryFile(suffix=".pdf", delete=False) as f: f.write(pdf_content) tmp_path = f.name try: result = parse_pdf(tmp_path) assert isinstance(result, str) assert "Hello" in result finally: os.unlink(tmp_path) def test_parse_pdf_empty(): """Empty/non-existent PDF file raises ParseError.""" with tempfile.NamedTemporaryFile(suffix=".pdf", delete=False) as f: f.write(b"") tmp_path = f.name try: with pytest.raises(ParseError): parse_pdf(tmp_path) finally: os.unlink(tmp_path) def test_parse_pdf_nonexistent(): """Non-existent PDF file raises ParseError.""" with pytest.raises((ParseError, FileNotFoundError)): parse_pdf("/tmp/nonexistent_file_12345.pdf") # #endregion TestAgentChat.DocumentParser.PDF # #region TestAgentChat.DocumentParser.XLSX [C:2] [TYPE Function] [SEMANTICS test,parser,xlsx] # @BRIEF XLSX parsing: extracts sheet names and cell data. def test_parse_xlsx_valid(): """Parse a valid XLSX and verify sheet+cell extraction.""" import openpyxl wb = openpyxl.Workbook() ws = wb.active ws.title = "Sheet1" ws["A1"] = "Name" ws["B1"] = "Value" ws["A2"] = "Test" ws["B2"] = 42 with tempfile.NamedTemporaryFile(suffix=".xlsx", delete=False) as f: wb.save(f.name) tmp_path = f.name try: result = parse_xlsx(tmp_path) assert isinstance(result, str) assert "Sheet1" in result assert "Name" in result assert "Value" in result assert "Test" in result assert "42" in result finally: os.unlink(tmp_path) def test_parse_xlsx_empty_sheet(): """XLSX with empty sheet returns headers but no data rows.""" import openpyxl wb = openpyxl.Workbook() ws = wb.active ws.title = "EmptySheet" with tempfile.NamedTemporaryFile(suffix=".xlsx", delete=False) as f: wb.save(f.name) tmp_path = f.name try: result = parse_xlsx(tmp_path) assert isinstance(result, str) assert "EmptySheet" in result finally: os.unlink(tmp_path) def test_parse_xlsx_not_excel(): """Non-XLSX file raises ParseError.""" with tempfile.NamedTemporaryFile(suffix=".xlsx", delete=False) as f: f.write(b"not an excel file") tmp_path = f.name try: with pytest.raises(ParseError): parse_xlsx(tmp_path) finally: os.unlink(tmp_path) # #endregion TestAgentChat.DocumentParser.XLSX # #region TestAgentChat.DocumentParser.ParseUpload [C:2] [TYPE Function] [SEMANTICS test,parser,upload] # @BRIEF parse_upload dispatches to correct parser based on extension. Unsupported → error. def test_parse_upload_txt(): """Parse a .txt file returns its content.""" with tempfile.NamedTemporaryFile(suffix=".txt", mode="w", delete=False) as f: f.write("Hello, world!") tmp_path = f.name try: result = parse_upload(tmp_path) assert "Hello" in result finally: os.unlink(tmp_path) def test_parse_upload_json(): """Parse a .json file returns its text.""" with tempfile.NamedTemporaryFile(suffix=".json", mode="w", delete=False) as f: f.write('{"key": "value"}') tmp_path = f.name try: result = parse_upload(tmp_path) assert "key" in result finally: os.unlink(tmp_path) def test_parse_upload_unsupported(): """Unsupported format raises ParseError.""" with tempfile.NamedTemporaryFile(suffix=".exe", delete=False) as f: f.write(b"binary") tmp_path = f.name try: with pytest.raises(ParseError, match="Unsupported format"): parse_upload(tmp_path) finally: os.unlink(tmp_path) def test_parse_upload_dict(): """parse_upload accepts dict with name+path (Gradio file format).""" with tempfile.NamedTemporaryFile(suffix=".txt", mode="w", delete=False) as f: f.write("Dict test") tmp_path = f.name try: result = parse_upload({"name": "test.txt", "path": tmp_path}) assert "Dict test" in result finally: os.unlink(tmp_path) # #endregion TestAgentChat.DocumentParser.ParseUpload # #endregion TestAgentChat.DocumentParser