mirror of
https://github.com/tiennm99/DocsGPT.git
synced 2026-10-13 06:14:51 +00:00
chore: more tests
This commit is contained in:
1 parent
dc6db847ca
commit
d5c0322e2a
64 files changed
+24436
-140
No files matched your search
@@ -1,117 +1,187 @@
|
||||
import pytest
|
||||
"""Comprehensive tests for application/parser/file/docs_parser.py
|
||||
|
||||
Covers: PDFParser (init, parse with pypdf, parse as image, import error),
|
||||
DocxParser (init, parse, import error).
|
||||
"""
|
||||
|
||||
from pathlib import Path
|
||||
from unittest.mock import patch, MagicMock
|
||||
from unittest.mock import MagicMock, patch, mock_open
|
||||
|
||||
import pytest
|
||||
|
||||
from application.parser.file.docs_parser import PDFParser, DocxParser
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def pdf_parser():
|
||||
return PDFParser()
|
||||
# =====================================================================
|
||||
# PDFParser - Init
|
||||
# =====================================================================
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def docx_parser():
|
||||
return DocxParser()
|
||||
@pytest.mark.unit
|
||||
class TestPDFParserInit:
|
||||
|
||||
def test_init_parser(self):
|
||||
parser = PDFParser()
|
||||
result = parser._init_parser()
|
||||
assert isinstance(result, dict)
|
||||
assert result == {}
|
||||
|
||||
def test_parser_config_not_set_initially(self):
|
||||
parser = PDFParser()
|
||||
assert not parser.parser_config_set
|
||||
|
||||
def test_parser_config_set_after_init(self):
|
||||
parser = PDFParser()
|
||||
parser.init_parser()
|
||||
assert parser.parser_config_set
|
||||
|
||||
|
||||
def test_pdf_init_parser():
|
||||
parser = PDFParser()
|
||||
assert isinstance(parser._init_parser(), dict)
|
||||
assert not parser.parser_config_set
|
||||
parser.init_parser()
|
||||
assert parser.parser_config_set
|
||||
# =====================================================================
|
||||
# PDFParser - Parse File
|
||||
# =====================================================================
|
||||
|
||||
|
||||
def test_docx_init_parser():
|
||||
parser = DocxParser()
|
||||
assert isinstance(parser._init_parser(), dict)
|
||||
assert not parser.parser_config_set
|
||||
parser.init_parser()
|
||||
assert parser.parser_config_set
|
||||
@pytest.mark.unit
|
||||
class TestPDFParserParse:
|
||||
|
||||
@patch("application.parser.file.docs_parser.settings")
|
||||
def test_parse_with_pypdf(self, mock_settings):
|
||||
mock_settings.PARSE_PDF_AS_IMAGE = False
|
||||
|
||||
parser = PDFParser()
|
||||
|
||||
mock_page1 = MagicMock()
|
||||
mock_page1.extract_text.return_value = "Page 1 content"
|
||||
mock_page2 = MagicMock()
|
||||
mock_page2.extract_text.return_value = "Page 2 content"
|
||||
|
||||
mock_reader = MagicMock()
|
||||
mock_reader.pages = [mock_page1, mock_page2]
|
||||
|
||||
with patch("application.parser.file.docs_parser.PdfReader",
|
||||
create=True), \
|
||||
patch("builtins.open", mock_open()):
|
||||
# Need to patch the import inside the function
|
||||
import sys
|
||||
mock_pypdf = MagicMock()
|
||||
mock_pypdf.PdfReader = MagicMock(return_value=mock_reader)
|
||||
sys.modules["pypdf"] = mock_pypdf
|
||||
|
||||
try:
|
||||
result = parser.parse_file(Path("test.pdf"))
|
||||
assert "Page 1 content" in result
|
||||
assert "Page 2 content" in result
|
||||
finally:
|
||||
del sys.modules["pypdf"]
|
||||
|
||||
@patch("application.parser.file.docs_parser.settings")
|
||||
@patch("application.parser.file.docs_parser.requests")
|
||||
def test_parse_as_image(self, mock_requests, mock_settings):
|
||||
mock_settings.PARSE_PDF_AS_IMAGE = True
|
||||
|
||||
mock_response = MagicMock()
|
||||
mock_response.json.return_value = {"markdown": "# OCR Result"}
|
||||
mock_requests.post.return_value = mock_response
|
||||
|
||||
parser = PDFParser()
|
||||
|
||||
with patch("builtins.open", mock_open(read_data=b"fake pdf")):
|
||||
result = parser.parse_file(Path("test.pdf"))
|
||||
assert result == "# OCR Result"
|
||||
|
||||
@patch("application.parser.file.docs_parser.settings")
|
||||
def test_parse_raises_on_missing_pypdf(self, mock_settings):
|
||||
mock_settings.PARSE_PDF_AS_IMAGE = False
|
||||
|
||||
parser = PDFParser()
|
||||
|
||||
# Simulate the import error path
|
||||
original = parser.parse_file
|
||||
|
||||
def mock_parse(*args, **kwargs):
|
||||
raise ValueError("pypdf is required to read PDF files.")
|
||||
|
||||
parser.parse_file = mock_parse
|
||||
|
||||
try:
|
||||
with pytest.raises(ValueError, match="pypdf is required"):
|
||||
parser.parse_file(Path("test.pdf"))
|
||||
finally:
|
||||
parser.parse_file = original
|
||||
|
||||
|
||||
@patch("application.parser.file.docs_parser.settings")
|
||||
def test_parse_pdf_with_pypdf(mock_settings, pdf_parser):
|
||||
mock_settings.PARSE_PDF_AS_IMAGE = False
|
||||
|
||||
# Create mock pages with text content
|
||||
mock_page1 = MagicMock()
|
||||
mock_page1.extract_text.return_value = "Test PDF content page 1"
|
||||
mock_page2 = MagicMock()
|
||||
mock_page2.extract_text.return_value = "Test PDF content page 2"
|
||||
|
||||
mock_reader_instance = MagicMock()
|
||||
mock_reader_instance.pages = [mock_page1, mock_page2]
|
||||
|
||||
original_parse_file = pdf_parser.parse_file
|
||||
|
||||
def mock_parse_file(*args, **kwargs):
|
||||
_ = args, kwargs
|
||||
text_list = []
|
||||
num_pages = len(mock_reader_instance.pages)
|
||||
for page_index in range(num_pages):
|
||||
page = mock_reader_instance.pages[page_index]
|
||||
page_text = page.extract_text()
|
||||
text_list.append(page_text)
|
||||
text = "\n".join(text_list)
|
||||
return text
|
||||
|
||||
pdf_parser.parse_file = mock_parse_file
|
||||
|
||||
try:
|
||||
result = pdf_parser.parse_file(Path("test.pdf"))
|
||||
assert result == "Test PDF content page 1\nTest PDF content page 2"
|
||||
finally:
|
||||
pdf_parser.parse_file = original_parse_file
|
||||
# =====================================================================
|
||||
# DocxParser - Init
|
||||
# =====================================================================
|
||||
|
||||
|
||||
@patch("application.parser.file.docs_parser.settings")
|
||||
def test_parse_pdf_pypdf_import_error(mock_settings, pdf_parser):
|
||||
mock_settings.PARSE_PDF_AS_IMAGE = False
|
||||
@pytest.mark.unit
|
||||
class TestDocxParserInit:
|
||||
|
||||
original_parse_file = pdf_parser.parse_file
|
||||
def test_init_parser(self):
|
||||
parser = DocxParser()
|
||||
result = parser._init_parser()
|
||||
assert isinstance(result, dict)
|
||||
assert result == {}
|
||||
|
||||
def mock_parse_file(*args, **kwargs):
|
||||
_ = args, kwargs
|
||||
raise ValueError("pypdf is required to read PDF files.")
|
||||
def test_parser_config_not_set_initially(self):
|
||||
parser = DocxParser()
|
||||
assert not parser.parser_config_set
|
||||
|
||||
pdf_parser.parse_file = mock_parse_file
|
||||
|
||||
try:
|
||||
with pytest.raises(ValueError, match="pypdf is required to read PDF files"):
|
||||
pdf_parser.parse_file(Path("test.pdf"))
|
||||
finally:
|
||||
pdf_parser.parse_file = original_parse_file
|
||||
def test_parser_config_set_after_init(self):
|
||||
parser = DocxParser()
|
||||
parser.init_parser()
|
||||
assert parser.parser_config_set
|
||||
|
||||
|
||||
def test_parse_docx(docx_parser):
|
||||
original_parse_file = docx_parser.parse_file
|
||||
|
||||
def mock_parse_file(*args, **kwargs):
|
||||
_ = args, kwargs
|
||||
return "Test DOCX content"
|
||||
|
||||
docx_parser.parse_file = mock_parse_file
|
||||
|
||||
try:
|
||||
result = docx_parser.parse_file(Path("test.docx"))
|
||||
assert result == "Test DOCX content"
|
||||
finally:
|
||||
docx_parser.parse_file = original_parse_file
|
||||
# =====================================================================
|
||||
# DocxParser - Parse File
|
||||
# =====================================================================
|
||||
|
||||
|
||||
def test_parse_docx_import_error(docx_parser):
|
||||
original_parse_file = docx_parser.parse_file
|
||||
@pytest.mark.unit
|
||||
class TestDocxParserParse:
|
||||
|
||||
def mock_parse_file(*args, **kwargs):
|
||||
_ = args, kwargs
|
||||
raise ValueError("docx2txt is required to read Microsoft Word files.")
|
||||
def test_parse_file_success(self):
|
||||
parser = DocxParser()
|
||||
|
||||
docx_parser.parse_file = mock_parse_file
|
||||
import sys
|
||||
mock_docx2txt = MagicMock()
|
||||
mock_docx2txt.process.return_value = "DOCX content here"
|
||||
sys.modules["docx2txt"] = mock_docx2txt
|
||||
|
||||
try:
|
||||
with pytest.raises(ValueError, match="docx2txt is required to read Microsoft Word files"):
|
||||
docx_parser.parse_file(Path("test.docx"))
|
||||
finally:
|
||||
docx_parser.parse_file = original_parse_file
|
||||
try:
|
||||
result = parser.parse_file(Path("test.docx"))
|
||||
assert result == "DOCX content here"
|
||||
finally:
|
||||
del sys.modules["docx2txt"]
|
||||
|
||||
def test_parse_raises_on_missing_docx2txt(self):
|
||||
parser = DocxParser()
|
||||
|
||||
original = parser.parse_file
|
||||
|
||||
def mock_parse(*args, **kwargs):
|
||||
raise ValueError("docx2txt is required to read Microsoft Word files.")
|
||||
|
||||
parser.parse_file = mock_parse
|
||||
|
||||
try:
|
||||
with pytest.raises(ValueError, match="docx2txt is required"):
|
||||
parser.parse_file(Path("test.docx"))
|
||||
finally:
|
||||
parser.parse_file = original
|
||||
|
||||
|
||||
# =====================================================================
|
||||
# BaseParser properties
|
||||
# =====================================================================
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
class TestBaseParserProperties:
|
||||
|
||||
def test_get_file_metadata_default(self):
|
||||
parser = PDFParser()
|
||||
meta = parser.get_file_metadata(Path("test.pdf"))
|
||||
assert meta == {}
|
||||
Reference in new issue
Block a user