""" Tests for services/quality/file_extractor.py Uses real files generated via temporary paths. On Windows, tempfile.NamedTemporaryFile holds the file open and blocks overwrite, so we use a plain temp directory + manual filename instead. """ import tempfile import os from pathlib import Path import pytest from services.quality.file_extractor import ( extract_sample, DEFAULT_MAX_SAMPLES, ) class TestExtractSample: def test_returns_empty_for_missing_file(self): result = extract_sample(Path("/nonexistent/path/file.docx"), ".docx") assert result == [] def test_returns_empty_for_none_path(self): result = extract_sample(None, ".docx") assert result == [] def test_returns_empty_for_unsupported_extension(self): # .txt isn't supported — should return [] silently with tempfile.TemporaryDirectory() as d: p = Path(d) / "test.txt" p.write_text("some text") result = extract_sample(p, ".txt") assert result == [] def _make_tmp_path(suffix: str) -> Path: """Create a unique temp file path. File does not exist yet.""" fd, name = tempfile.mkstemp(suffix=suffix) os.close(fd) return Path(name) class TestDocxExtraction: def test_extracts_paragraphs(self): from docx import Document doc = Document() doc.add_paragraph("Bonjour le monde") doc.add_paragraph("Comment allez-vous?") doc.add_paragraph("Merci beaucoup") p = _make_tmp_path(".docx") try: doc.save(str(p)) result = extract_sample(p, ".docx", max_samples=10) assert len(result) >= 1 texts = [s["translated"] for s in result] assert "Bonjour le monde" in texts finally: try: p.unlink() except (OSError, PermissionError): pass def test_respects_max_samples(self): from docx import Document doc = Document() for i in range(50): doc.add_paragraph(f"Paragraphe numero {i} avec du texte") p = _make_tmp_path(".docx") try: doc.save(str(p)) result = extract_sample(p, ".docx", max_samples=5) assert len(result) == 5 finally: try: p.unlink() except (OSError, PermissionError): pass def test_handles_empty_doc(self): from docx import Document doc = Document() p = _make_tmp_path(".docx") try: doc.save(str(p)) result = extract_sample(p, ".docx") assert result == [] finally: try: p.unlink() except (OSError, PermissionError): pass class TestXlsxExtraction: def test_extracts_cells(self): from openpyxl import Workbook wb = Workbook() ws = wb.active ws["A1"] = "Bonjour" ws["A2"] = "Monde" ws["A3"] = "Comment" p = _make_tmp_path(".xlsx") try: wb.save(str(p)) wb.close() result = extract_sample(p, ".xlsx", max_samples=10) assert len(result) >= 1 texts = [s["translated"] for s in result] assert "Bonjour" in texts finally: try: p.unlink() except (OSError, PermissionError): pass def test_skips_numeric_cells(self): from openpyxl import Workbook wb = Workbook() ws = wb.active ws["A1"] = 100 ws["A2"] = 200 ws["A3"] = "Hello" p = _make_tmp_path(".xlsx") try: wb.save(str(p)) wb.close() result = extract_sample(p, ".xlsx") texts = [s["translated"] for s in result] assert "Hello" in texts assert 100 not in texts # numeric only cells skipped finally: try: p.unlink() except (OSError, PermissionError): pass class TestPptxExtraction: def test_extracts_slide_text(self): from pptx import Presentation pres = Presentation() slide = pres.slides.add_slide(pres.slide_layouts[0]) slide.shapes.title.text = "Bonjour le monde" p = _make_tmp_path(".pptx") try: pres.save(str(p)) result = extract_sample(p, ".pptx") assert len(result) >= 1 assert result[0]["translated"] == "Bonjour le monde" finally: try: p.unlink() except (OSError, PermissionError): pass class TestPdfExtraction: def test_extracts_pdf_text(self): # Create a minimal PDF using reportlab if available, else skip pytest.importorskip("fitz") try: from reportlab.pdfgen import canvas except ImportError: pytest.skip("reportlab not available") p = _make_tmp_path(".pdf") try: c = canvas.Canvas(str(p)) c.drawString(100, 750, "Bonjour le monde") c.drawString(100, 700, "Comment allez vous") c.save() result = extract_sample(p, ".pdf") assert len(result) >= 1 texts = [s["translated"] for s in result] assert any("Bonjour" in t for t in texts) finally: try: p.unlink() except (OSError, PermissionError): pass