From 3bd506e4eba909dbd84d1b99877052aa70e1b6bf Mon Sep 17 00:00:00 2001 From: HERITAGE-XION Date: Fri, 9 Jan 2026 19:55:27 +0100 Subject: [PATCH] metadata-scrubber-tool: added handler for excel files, add comprehensive tests --- pyproject.toml | 1 + src/services/excel_handler.py | 163 +++++++++++++ src/services/metadata_factory.py | 5 +- src/services/pdf_handler.py | 70 ++++-- src/utils/display.py | 2 + .../test_xlsx/file_example_XLSX_1000.xlsx | Bin 0 -> 42669 bytes .../test_xlsx/file_example_XLSX_5000.xlsx | Bin 0 -> 188887 bytes tests/conftest.py | 30 +++ tests/e2e/test_read_command.py | 68 +++--- tests/e2e/test_scrub_command.py | 104 ++++---- tests/integration/test_metadata_factory.py | 226 +++++++----------- tests/unit/test_excel_handler.py | 207 ++++++++++++++++ uv.lock | 23 ++ 13 files changed, 667 insertions(+), 232 deletions(-) create mode 100644 src/services/excel_handler.py create mode 100644 tests/assets/test_xlsx/file_example_XLSX_1000.xlsx create mode 100644 tests/assets/test_xlsx/file_example_XLSX_5000.xlsx create mode 100644 tests/unit/test_excel_handler.py diff --git a/pyproject.toml b/pyproject.toml index d9f43c51..43d9c2ad 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -10,6 +10,7 @@ dependencies = [ "pillow>=12.0.0", "piexif>=1.1.3", "pypdf>=6.5.0", + "openpyxl>=3.1.5", ] [project.optional-dependencies] diff --git a/src/services/excel_handler.py b/src/services/excel_handler.py new file mode 100644 index 00000000..748201ff --- /dev/null +++ b/src/services/excel_handler.py @@ -0,0 +1,163 @@ +""" +Excel metadata handler for Excel files. + +This module provides the ExcelHandler class which implements the MetadataHandler +interface for Excel files (.xlsx, .xlsm, .xltx, .xltm). Uses openpyxl for +reading and writing Excel workbook properties. + +Note: + Does not support password-protected/encrypted workbooks. +""" + +import shutil +from pathlib import Path +from typing import Any + +from openpyxl import load_workbook + +from src.services.metadata_handler import MetadataHandler +from src.utils.exceptions import ( + MetadataNotFoundError, + MetadataReadingError, + UnsupportedFormatError, +) + +# Supported Excel formats +FORMAT_MAP = { + "xlsx": "xlsx", + "xlsm": "xlsm", + "xltx": "xltx", + "xltm": "xltm", +} + +# Properties to preserve (not deleted during wipe) +PRESERVED_PROPERTIES = {"created", "modified", "language"} + + +class ExcelHandler(MetadataHandler): + """ + Excel metadata handler for Excel files. + + Handles extraction and removal of document properties from Excel workbooks + including author, title, subject, keywords, and other core properties. + + Attributes: + keys_to_delete: List of property names to be wiped. + """ + + def __init__(self, filepath: str): + """ + Initialize the Excel handler. + + Args: + filepath: Path to the Excel file to process. + """ + super().__init__(filepath) + self.keys_to_delete: list[str] = [] + + def _detect_format(self) -> str: + """ + Detect Excel format from file extension. + + Returns: + Normalized format string ('xlsx', 'xlsm', 'xltx', or 'xltm'). + + Raises: + UnsupportedFormatError: If file extension is not a supported Excel format. + """ + ext = Path(self.filepath).suffix.lower() + normalised = FORMAT_MAP.get(ext[1:]) # Remove leading dot + if normalised is None: + raise UnsupportedFormatError(f"Unsupported format: {ext}") + + return normalised + + def read(self) -> dict[str, Any]: + """ + Extract metadata properties from the Excel workbook. + + Reads all document properties from the workbook and identifies + which properties should be wiped (excludes created, modified, language). + + Returns: + Dictionary of property names to their values. + + Raises: + MetadataReadingError: If the workbook is password-protected. + MetadataNotFoundError: If no properties are found. + """ + wb = load_workbook(Path(self.filepath)) + try: + if wb.security.workbookPassword is not None: + raise MetadataReadingError("File is encrypted.") + + if wb.properties is None: + raise MetadataNotFoundError("No metadata found in the file.") + + for attr, value in vars(wb.properties).items(): + self.metadata[attr] = value + if attr not in PRESERVED_PROPERTIES: + self.keys_to_delete.append(attr) + + return self.metadata + finally: + wb.close() + + def wipe(self) -> None: + """ + Remove metadata properties from the Excel workbook. + + Clears all properties identified during read() except for + preserved properties (created, modified, language). + + Raises: + MetadataNotFoundError: If no properties are found. + """ + wb = load_workbook(Path(self.filepath)) + try: + if wb.properties is None: + raise MetadataNotFoundError("No metadata found in the file.") + + # Clear each property marked for deletion + for attr in self.keys_to_delete: + if hasattr(wb.properties, attr): + setattr(wb.properties, attr, None) + + self.processed_metadata = wb.properties + finally: + wb.close() + + def save(self, output_path: str | None) -> None: + """ + Save the workbook with cleaned metadata to the output path. + + Creates a copy of the original file and applies the wiped + metadata properties to it. + + Args: + output_path: Path where the cleaned file should be saved. + + Raises: + ValueError: If output_path is None or empty. + """ + if not output_path: + raise ValueError("output_path is required") + + destination_file_path = Path(output_path) + shutil.copy2(self.filepath, destination_file_path) + + # Use keep_vba=True for macro-enabled workbooks + detected_format = self._detect_format() + if detected_format == "xlsm": + wb = load_workbook(destination_file_path, keep_vba=True) + else: + wb = load_workbook(destination_file_path) + + try: + # Apply wiped properties + for attr, value in vars(self.processed_metadata).items(): + setattr(wb.properties, attr, value) + + wb.save(destination_file_path) + finally: + wb.close() diff --git a/src/services/metadata_factory.py b/src/services/metadata_factory.py index ef5aec68..06beff3f 100644 --- a/src/services/metadata_factory.py +++ b/src/services/metadata_factory.py @@ -8,6 +8,7 @@ extensibility for supporting new file formats (PDF, Office docs, etc.). from pathlib import Path +from src.services.excel_handler import ExcelHandler from src.services.image_handler import ImageHandler from src.services.pdf_handler import PDFHandler from src.utils.exceptions import UnsupportedFormatError @@ -48,10 +49,10 @@ class MetadataFactory: return ImageHandler(filepath) elif ext == ".pdf": return PDFHandler(filepath) + elif ext in [".xlsx", ".xlsm", ".xltx", ".xltm"]: + return ExcelHandler(filepath) # TODO: implement other handlers - # elif ext == ".xlsx": - # return ExcelHandler(filepath) # elif ext == ".pptx": # return PowerPointHandler(filepath) else: diff --git a/src/services/pdf_handler.py b/src/services/pdf_handler.py index 57b03b1b..bcef30eb 100644 --- a/src/services/pdf_handler.py +++ b/src/services/pdf_handler.py @@ -1,14 +1,17 @@ """ PDF metadata handler for PDF files. -Does not support encrypted files. -This module provides the PdfHandler class which implements the MetadataHandler -interface for PDF files. It delegates the actual metadata operations to -format-specific processors (PdfProcessor). +This module provides the PDFHandler class which implements the MetadataHandler +interface for PDF files. Uses pypdf library for reading and writing PDF +document information dictionary. + +Note: + Does not support encrypted/password-protected PDF files. """ import shutil from pathlib import Path +from typing import Any from pypdf import PdfReader, PdfWriter @@ -23,39 +26,50 @@ from src.utils.exceptions import ( class PDFHandler(MetadataHandler): """ PDF metadata handler for PDF files. + + Handles extraction and removal of document information from PDF files + including author, creator, title, subject, and other standard PDF metadata. + + Attributes: + keys_to_delete: List of metadata keys to be wiped. """ def __init__(self, filepath: str): """ - Initialize the pdf handler. + Initialize the PDF handler. Args: - filepath: Path to the pdf file to process. + filepath: Path to the PDF file to process. """ super().__init__(filepath) self.keys_to_delete: list[str] = [] def _detect_format(self) -> str: """ - Detect actual pdf format using, not file extension. + Validate that the file has a PDF extension. Returns: Normalized format string ('pdf'). Raises: - UnsupportedFormatError: If format is not supported or undetectable. + UnsupportedFormatError: If file extension is not .pdf. """ - normalise = Path(self.filepath).suffix.lower() - if normalise != ".pdf": - raise UnsupportedFormatError(f"Unsupported format: {normalise}") + ext = Path(self.filepath).suffix.lower() + if ext != ".pdf": + raise UnsupportedFormatError(f"Unsupported format: {ext}") - return normalise[1:] + return ext[1:] # Return 'pdf' without the dot - def read(self): + def read(self) -> dict[str, Any]: """ - Extract metadata from the file. + Extract metadata from the PDF document information dictionary. - Uses actual format detection to select the appropriate processor. + Returns: + Dictionary of metadata keys to their values. + + Raises: + MetadataReadingError: If the PDF is encrypted/password-protected. + MetadataNotFoundError: If no metadata is found in the PDF. """ with PdfReader(Path(self.filepath)) as reader: if reader.is_encrypted: @@ -67,11 +81,17 @@ class PDFHandler(MetadataHandler): for key, value in reader.metadata.items(): self.metadata[key] = value self.keys_to_delete.append(key) + return self.metadata def wipe(self) -> None: """ - Remove metadata from PDF file. + Remove metadata entries from the PDF document. + + Clears all metadata keys identified during read(). + + Raises: + MetadataNotFoundError: If no metadata is found in the PDF. """ with PdfReader(Path(self.filepath)) as reader: metadata = reader.metadata @@ -84,15 +104,25 @@ class PDFHandler(MetadataHandler): self.processed_metadata = metadata - def save(self, output_path: str | Path | None = None) -> None: + def save(self, output_path: str | None) -> None: """ - Save the changes to a copy of the original file. + Save the PDF with cleaned metadata to the output path. + + Creates a copy of the original file and rebuilds the PDF + with the wiped metadata. + + Args: + output_path: Path where the cleaned PDF should be saved. + + Raises: + ValueError: If output_path is None or empty. """ - destination_file_path = Path(output_path) if output_path else None - if not destination_file_path: + if not output_path: raise ValueError("output_path is required") + destination_file_path = Path(output_path) shutil.copy2(self.filepath, destination_file_path) + with PdfReader(destination_file_path) as reader, PdfWriter() as writer: # Copy all pages for page in reader.pages: diff --git a/src/utils/display.py b/src/utils/display.py index 270e15e6..ae1fe4cc 100644 --- a/src/utils/display.py +++ b/src/utils/display.py @@ -59,6 +59,8 @@ def print_metadata_table(metadata: dict[str, Any]): "DateTimeOriginal", "DateTimeDigitized", "OffsetTime", + "created", + "modified", "/CreationDate", "/ModDate", ], diff --git a/tests/assets/test_xlsx/file_example_XLSX_1000.xlsx b/tests/assets/test_xlsx/file_example_XLSX_1000.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..e933f72499afd7a9e0ccc785ee8d7d19984128d1 GIT binary patch literal 42669 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 literal 0 HcmV?d00001 diff --git a/tests/assets/test_xlsx/file_example_XLSX_5000.xlsx b/tests/assets/test_xlsx/file_example_XLSX_5000.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..e79d0802fe552d93225de108f2b615bbc360b192 GIT binary patch literal 188887 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≪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

^ce49uxU;ydjvU5u%RU2%5y5 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 z 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 OM+X str: def get_test_pdfs_dir() -> str: """Get test PDFs directory path as string.""" return str(TEST_PDFS_DIR) + + +# Excel fixtures +@pytest.fixture +def xlsx_test_file() -> Path: + """Return path to an XLSX test file with metadata.""" + return TEST_XLSX_DIR / "file_example_XLSX_1000.xlsx" + + +@pytest.fixture +def test_xlsx_dir() -> Path: + """Return path to test XLSX directory.""" + return TEST_XLSX_DIR + + +# String versions for parametrize (Excel) +def get_xlsx_test_file() -> str: + """Get XLSX test file path as string.""" + return str(TEST_XLSX_DIR / "file_example_XLSX_1000.xlsx") + + +def get_large_xlsx_test_file() -> str: + """Get large XLSX test file path as string.""" + return str(TEST_XLSX_DIR / "file_example_XLSX_5000.xlsx") + + +def get_test_xlsx_dir() -> str: + """Get test XLSX directory path as string.""" + return str(TEST_XLSX_DIR) diff --git a/tests/e2e/test_read_command.py b/tests/e2e/test_read_command.py index fc17ad3e..173cc44e 100644 --- a/tests/e2e/test_read_command.py +++ b/tests/e2e/test_read_command.py @@ -1,3 +1,9 @@ +""" +E2E tests for the 'read' command. + +Tests the full CLI flow for reading metadata from files. +""" + from pathlib import Path import pytest @@ -12,6 +18,8 @@ from tests.conftest import ( get_png_test_file, get_test_images_dir, get_test_pdfs_dir, + get_test_xlsx_dir, + get_xlsx_test_file, ) runner = CliRunner() @@ -22,16 +30,16 @@ PNG_TEST_FILE = get_png_test_file() TEST_DIR = get_test_images_dir() PDF_TEST_FILE = get_pdf_test_file() PDF_DIR = get_test_pdfs_dir() +XLSX_TEST_FILE = get_xlsx_test_file() +XLSX_DIR = get_test_xlsx_dir() -# ============== Success Case Tests ============== +# ============== Image Tests ============== @pytest.mark.parametrize("x", [JPG_TEST_FILE, PNG_TEST_FILE]) def test_read_command_single_file_success(x): - """ - Test the 'read' command with a single file (JPG and PNG). - """ + """Test the 'read' command with a single image file.""" result = runner.invoke(app, ["read", str(x)]) assert result.exit_code == 0, f"Failed with: {result.stdout}" @@ -41,9 +49,7 @@ def test_read_command_single_file_success(x): @pytest.mark.parametrize("ext", ["jpg", "png"]) def test_read_command_recursive_directory_success(ext): - """ - Test the 'read' command with recursive directory processing. - """ + """Test the 'read' command with recursive directory processing.""" result = runner.invoke(app, ["read", TEST_DIR, "-r", "-ext", ext]) assert result.exit_code == 0, f"Failed with: {result.stdout}" @@ -51,46 +57,34 @@ def test_read_command_recursive_directory_success(ext): def test_read_command_requires_ext_with_recursive(): - """ - Test that --recursive requires --extension flag. - """ + """Test that --recursive requires --extension flag.""" result = runner.invoke(app, ["read", TEST_DIR, "-r"]) - assert result.exit_code != 0 - # Should fail with bad parameter error def test_read_command_requires_recursive_with_ext(): - """ - Test that --extension requires --recursive flag. - """ + """Test that --extension requires --recursive flag.""" result = runner.invoke(app, ["read", JPG_TEST_FILE, "-ext", "jpg"]) - assert result.exit_code != 0 -# ============== Error Case Tests ============== +# ============== Error Tests ============== def test_read_command_file_not_found(): - """ - Test that the app handles missing files gracefully. - """ + """Test that the app handles missing files gracefully.""" result = runner.invoke(app, ["read", "ghost_file.jpg"]) - # Typer returns exit code 2 (Usage Error) for bad arguments assert result.exit_code == 2 assert "Invalid value for 'FILE_PATH'" in result.stderr assert "does not exist" in result.stderr -# ============== PDF E2E Read Tests ============== +# ============== PDF Tests ============== def test_read_command_pdf_single_file_success(): - """ - Test the 'read' command with a single PDF file. - """ + """Test the 'read' command with a single PDF file.""" result = runner.invoke(app, ["read", PDF_TEST_FILE]) assert result.exit_code == 0, f"Failed with: {result.stdout}" @@ -99,10 +93,28 @@ def test_read_command_pdf_single_file_success(): def test_read_command_recursive_pdf_success(): - """ - Test the 'read' command with recursive directory processing for PDF. - """ + """Test the 'read' command with recursive PDF directory processing.""" result = runner.invoke(app, ["read", PDF_DIR, "-r", "-ext", "pdf"]) assert result.exit_code == 0, f"Failed with: {result.stdout}" assert "Reading" in result.stdout + + +# ============== Excel Tests ============== + + +def test_read_command_xlsx_single_file_success(): + """Test the 'read' command with a single Excel file.""" + result = runner.invoke(app, ["read", XLSX_TEST_FILE]) + + assert result.exit_code == 0, f"Failed with: {result.stdout}" + assert "Reading" in result.stdout + assert Path(XLSX_TEST_FILE).name in result.stdout + + +def test_read_command_recursive_xlsx_success(): + """Test the 'read' command with recursive Excel directory processing.""" + result = runner.invoke(app, ["read", XLSX_DIR, "-r", "-ext", "xlsx"]) + + assert result.exit_code == 0, f"Failed with: {result.stdout}" + assert "Reading" in result.stdout diff --git a/tests/e2e/test_scrub_command.py b/tests/e2e/test_scrub_command.py index 5e593cd9..2d974696 100644 --- a/tests/e2e/test_scrub_command.py +++ b/tests/e2e/test_scrub_command.py @@ -18,6 +18,8 @@ from tests.conftest import ( get_png_test_file, get_test_images_dir, get_test_pdfs_dir, + get_test_xlsx_dir, + get_xlsx_test_file, ) runner = CliRunner() @@ -28,6 +30,8 @@ PNG_TEST_FILE = get_png_test_file() EXAMPLES_DIR = get_test_images_dir() PDF_TEST_FILE = get_pdf_test_file() PDF_DIR = get_test_pdfs_dir() +XLSX_TEST_FILE = get_xlsx_test_file() +XLSX_DIR = get_test_xlsx_dir() @pytest.fixture @@ -38,56 +42,44 @@ def output_dir(tmp_path): return output -# ============== Success Case Tests ============== +# ============== Image Tests ============== @pytest.mark.parametrize("x", [JPG_TEST_FILE, PNG_TEST_FILE]) def test_scrub_command_single_file_success(x, output_dir): - """ - Test the 'scrub' command with a single file. - """ + """Test the 'scrub' command with a single image file.""" result = runner.invoke(app, ["scrub", x, "--output", str(output_dir)]) assert result.exit_code == 0, f"Failed with: {result.stdout}" - # Check output file was created (has processed_ prefix) output_file = output_dir / f"processed_{Path(x).name}" assert output_file.exists() def test_scrub_command_recursive_jpg_success(output_dir): - """ - Test the 'scrub' command with recursive directory processing for JPG. - Uses examples folder (smaller) for faster tests. - """ + """Test the 'scrub' command with recursive directory processing for JPG.""" result = runner.invoke( app, ["scrub", EXAMPLES_DIR, "-r", "-ext", "jpg", "--output", str(output_dir)] ) assert result.exit_code == 0, f"Failed with: {result.stdout}" - # Check at least one output file was created output_files = list(output_dir.glob("processed_*.jpg")) assert len(output_files) > 0 def test_scrub_command_dry_run(output_dir): - """ - Test that --dry-run doesn't create files. - """ + """Test that --dry-run doesn't create files.""" result = runner.invoke( app, ["scrub", JPG_TEST_FILE, "--output", str(output_dir), "--dry-run"] ) assert result.exit_code == 0, f"Failed with: {result.stdout}" assert "DRY-RUN" in result.stdout - # No files should be created in dry-run mode output_file = output_dir / f"processed_{Path(JPG_TEST_FILE).name}" assert not output_file.exists() def test_scrub_command_with_workers(output_dir): - """ - Test the --workers option for concurrent processing. - """ + """Test the --workers option for concurrent processing.""" result = runner.invoke( app, [ @@ -106,13 +98,11 @@ def test_scrub_command_with_workers(output_dir): assert result.exit_code == 0, f"Failed with: {result.stdout}" -# ============== Error Case Tests ============== +# ============== Error Tests ============== def test_scrub_command_file_not_found(): - """ - Test that the app handles missing files gracefully. - """ + """Test that the app handles missing files gracefully.""" result = runner.invoke(app, ["scrub", "ghost_file.jpg"]) assert result.exit_code == 2 @@ -120,79 +110,97 @@ def test_scrub_command_file_not_found(): def test_scrub_command_requires_ext_with_recursive(): - """ - Test that --recursive requires --extension flag. - """ + """Test that --recursive requires --extension flag.""" result = runner.invoke(app, ["scrub", EXAMPLES_DIR, "-r"]) - assert result.exit_code != 0 def test_scrub_command_requires_recursive_with_ext(): - """ - Test that --extension requires --recursive flag. - """ + """Test that --extension requires --recursive flag.""" result = runner.invoke(app, ["scrub", JPG_TEST_FILE, "-ext", "jpg"]) - assert result.exit_code != 0 -# ============== PDF E2E Tests ============== +# ============== PDF Tests ============== def test_scrub_command_pdf_single_file_success(output_dir): - """ - Test the 'scrub' command with a single PDF file. - """ + """Test the 'scrub' command with a single PDF file.""" result = runner.invoke(app, ["scrub", PDF_TEST_FILE, "--output", str(output_dir)]) assert result.exit_code == 0, f"Failed with: {result.stdout}" - # Check output file was created (has processed_ prefix) output_file = output_dir / f"processed_{Path(PDF_TEST_FILE).name}" assert output_file.exists() def test_scrub_command_recursive_pdf_success(output_dir): - """ - Test the 'scrub' command with recursive directory processing for PDF. - """ + """Test the 'scrub' command with recursive directory processing for PDF.""" result = runner.invoke( app, ["scrub", PDF_DIR, "-r", "-ext", "pdf", "--output", str(output_dir)] ) assert result.exit_code == 0, f"Failed with: {result.stdout}" - # Check at least one output file was created output_files = list(output_dir.glob("processed_*.pdf")) assert len(output_files) > 0 def test_scrub_command_pdf_dry_run(output_dir): - """ - Test that --dry-run doesn't create PDF files. - """ + """Test that --dry-run doesn't create PDF files.""" result = runner.invoke( app, ["scrub", PDF_TEST_FILE, "--output", str(output_dir), "--dry-run"] ) assert result.exit_code == 0, f"Failed with: {result.stdout}" assert "DRY-RUN" in result.stdout - # No files should be created in dry-run mode output_file = output_dir / f"processed_{Path(PDF_TEST_FILE).name}" assert not output_file.exists() -def test_scrub_command_pdf_with_workers(output_dir): - """ - Test the --workers option for concurrent PDF processing. - """ +# ============== Excel Tests ============== + + +def test_scrub_command_xlsx_single_file_success(output_dir): + """Test the 'scrub' command with a single Excel file.""" + result = runner.invoke(app, ["scrub", XLSX_TEST_FILE, "--output", str(output_dir)]) + + assert result.exit_code == 0, f"Failed with: {result.stdout}" + output_file = output_dir / f"processed_{Path(XLSX_TEST_FILE).name}" + assert output_file.exists() + + +def test_scrub_command_recursive_xlsx_success(output_dir): + """Test the 'scrub' command with recursive directory processing for Excel.""" + result = runner.invoke( + app, ["scrub", XLSX_DIR, "-r", "-ext", "xlsx", "--output", str(output_dir)] + ) + + assert result.exit_code == 0, f"Failed with: {result.stdout}" + output_files = list(output_dir.glob("processed_*.xlsx")) + assert len(output_files) > 0 + + +def test_scrub_command_xlsx_dry_run(output_dir): + """Test that --dry-run doesn't create Excel files.""" + result = runner.invoke( + app, ["scrub", XLSX_TEST_FILE, "--output", str(output_dir), "--dry-run"] + ) + + assert result.exit_code == 0, f"Failed with: {result.stdout}" + assert "DRY-RUN" in result.stdout + output_file = output_dir / f"processed_{Path(XLSX_TEST_FILE).name}" + assert not output_file.exists() + + +def test_scrub_command_xlsx_with_workers(output_dir): + """Test the --workers option for concurrent Excel processing.""" result = runner.invoke( app, [ "scrub", - PDF_DIR, + XLSX_DIR, "-r", "-ext", - "pdf", + "xlsx", "--output", str(output_dir), "--workers", diff --git a/tests/integration/test_metadata_factory.py b/tests/integration/test_metadata_factory.py index 3f3fbbc3..18bffb66 100644 --- a/tests/integration/test_metadata_factory.py +++ b/tests/integration/test_metadata_factory.py @@ -1,3 +1,9 @@ +""" +Integration tests for MetadataFactory. + +Tests the factory pattern integration with all handler types (Image, PDF, Excel). +""" + import shutil from pathlib import Path @@ -5,168 +11,91 @@ import pytest from src.core.jpeg_metadata import JpegProcessor from src.core.png_metadata import PngProcessor +from src.services.excel_handler import ExcelHandler from src.services.metadata_factory import MetadataFactory from src.services.pdf_handler import PDFHandler -from src.utils.exceptions import MetadataNotFoundError, UnsupportedFormatError +from src.utils.exceptions import UnsupportedFormatError # Import path helpers from conftest -from tests.conftest import get_jpg_test_file, get_pdf_test_file, get_png_test_file +from tests.conftest import ( + get_jpg_test_file, + get_pdf_test_file, + get_png_test_file, + get_xlsx_test_file, +) # Test file paths (cross-platform) JPG_TEST_FILE = get_jpg_test_file() PNG_TEST_FILE = get_png_test_file() PDF_TEST_FILE = get_pdf_test_file() +XLSX_TEST_FILE = get_xlsx_test_file() -# ============== Success Case Tests ============== +# ============== Image Tests ============== @pytest.mark.parametrize("x", [JPG_TEST_FILE, PNG_TEST_FILE]) -def test_read_metadata(x): - """ - test for reading image metadata - """ - # checks if file exists +def test_read_image_metadata(x): + """Test reading image metadata through factory.""" assert Path(x).exists(), f"Test file not found: {x}" handler = MetadataFactory.get_handler(str(x)) metadata = handler.read() - # checks if metadata is not empty assert handler.metadata == metadata + assert isinstance(metadata, dict) if isinstance(handler, JpegProcessor | PngProcessor): - # checks if tags_to_delete or text_keys_to_delete is not empty assert ( handler.tags_to_delete is not None or handler.text_keys_to_delete is not None ) - # checks if metadata is a dictionary - assert isinstance(metadata, dict) - @pytest.mark.parametrize("x", [JPG_TEST_FILE, PNG_TEST_FILE]) def test_wipe_image_metadata(x): - """ - test for wiping image metadata - """ - # checks if file exists + """Test wiping image metadata through factory.""" assert Path(x).exists(), f"Test file not found: {x}" handler = MetadataFactory.get_handler(str(x)) metadata = handler.read() handler.wipe() - # checks if processed_metadata is not equal to metadata assert handler.processed_metadata != metadata @pytest.mark.parametrize("x", [JPG_TEST_FILE, PNG_TEST_FILE]) def test_save_processed_image_metadata(x): - """ - test for saving image processed metadata to a copy of the file - """ - # creates output directory + """Test saving processed image metadata through factory.""" output_dir = Path("./tests/assets/output") output_dir.mkdir(parents=True, exist_ok=True) handler = MetadataFactory.get_handler(str(x)) - metadata = handler.read() + handler.read() handler.wipe() - # checks if processed_metadata is not equal to metadata - assert handler.processed_metadata != metadata - - # Pass full file path output_file = output_dir / Path(x).name handler.save(str(output_file)) - # checks if output file exists and then deletes it assert output_file.exists() shutil.rmtree(output_dir) -@pytest.mark.parametrize("x", [JPG_TEST_FILE, PNG_TEST_FILE]) -def test_output_file_has_less_metadata(x): - """ - Test that the output file has metadata stripped - """ - output_dir = Path("./tests/assets/output") - output_dir.mkdir(parents=True, exist_ok=True) - - # Process original file - handler = MetadataFactory.get_handler(str(x)) - original_metadata = handler.read() - original_count = len(original_metadata) - handler.wipe() - - # Save processed file - output_file = output_dir / Path(x).name - handler.save(str(output_file)) - - # Read output file and verify metadata is reduced or gone - try: - output_processor = MetadataFactory.get_handler(str(output_file)) - output_metadata = output_processor.read() - # Output should have fewer metadata entries - assert len(output_metadata) < original_count - except MetadataNotFoundError: - # If no metadata found, that's expected for fully stripped files - pass - # clean up - shutil.rmtree(output_dir) - - -def test_format_detection_works(): - """ - Test that format detection uses Pillow, not file extension - """ +def test_image_format_detection(): + """Test format detection for images.""" handler = MetadataFactory.get_handler(JPG_TEST_FILE) - detected = handler._detect_format() - assert detected == "jpeg" + assert handler._detect_format() == "jpeg" handler_png = MetadataFactory.get_handler(PNG_TEST_FILE) - detected_png = handler_png._detect_format() - assert detected_png == "png" + assert handler_png._detect_format() == "png" -# ============== Error Case Tests ============== - - -def test_unsupported_format_raises_error(tmp_path): - """ - Test that unsupported file formats raise an error - """ - # Create a fake text file - fake_file = tmp_path / "test.txt" - fake_file.write_text("not an image") - - # MetadataFactory.get_handler() raises UnsupportedFormatError for .txt files - with pytest.raises(UnsupportedFormatError): - MetadataFactory.get_handler(str(fake_file)) - - -def test_save_without_output_path_raises_error(): - """ - Test that save() raises ValueError when output_path is None - """ - handler = MetadataFactory.get_handler(JPG_TEST_FILE) - handler.read() - handler.wipe() - with pytest.raises(ValueError): - handler.save(None) - - -# ============== PDF Integration Tests ============== +# ============== PDF Tests ============== def test_read_pdf_metadata_via_factory(): - """ - Test reading PDF metadata through MetadataFactory. - """ + """Test reading PDF metadata through MetadataFactory.""" assert Path(PDF_TEST_FILE).exists(), f"Test file not found: {PDF_TEST_FILE}" handler = MetadataFactory.get_handler(PDF_TEST_FILE) - # Verify correct handler type is returned assert isinstance(handler, PDFHandler) metadata = handler.read() @@ -176,10 +105,7 @@ def test_read_pdf_metadata_via_factory(): def test_wipe_pdf_metadata_via_factory(): - """ - Test wiping PDF metadata through MetadataFactory. - """ - assert Path(PDF_TEST_FILE).exists(), f"Test file not found: {PDF_TEST_FILE}" + """Test wiping PDF metadata through MetadataFactory.""" handler = MetadataFactory.get_handler(PDF_TEST_FILE) metadata = handler.read() handler.wipe() @@ -188,18 +114,14 @@ def test_wipe_pdf_metadata_via_factory(): def test_save_processed_pdf_metadata_via_factory(): - """ - Test saving processed PDF metadata through MetadataFactory. - """ + """Test saving processed PDF metadata through MetadataFactory.""" output_dir = Path("./tests/assets/output") output_dir.mkdir(parents=True, exist_ok=True) handler = MetadataFactory.get_handler(PDF_TEST_FILE) - metadata = handler.read() + handler.read() handler.wipe() - assert handler.processed_metadata != metadata - output_file = output_dir / Path(PDF_TEST_FILE).name handler.save(str(output_file)) @@ -207,39 +129,75 @@ def test_save_processed_pdf_metadata_via_factory(): shutil.rmtree(output_dir) -def test_pdf_format_detection_via_factory(): - """ - Test that format detection returns 'pdf' for PDF files. - """ +def test_pdf_format_detection(): + """Test format detection for PDF files.""" handler = MetadataFactory.get_handler(PDF_TEST_FILE) - detected = handler._detect_format() - assert detected == "pdf" + assert handler._detect_format() == "pdf" -def test_output_pdf_file_has_less_metadata(): - """ - Test that the output PDF file has metadata stripped. - """ +# ============== Excel Tests ============== + + +def test_read_excel_metadata_via_factory(): + """Test reading Excel metadata through MetadataFactory.""" + assert Path(XLSX_TEST_FILE).exists(), f"Test file not found: {XLSX_TEST_FILE}" + handler = MetadataFactory.get_handler(XLSX_TEST_FILE) + + assert isinstance(handler, ExcelHandler) + + metadata = handler.read() + assert handler.metadata == metadata + assert isinstance(metadata, dict) + assert handler.keys_to_delete is not None + + +def test_wipe_excel_metadata_via_factory(): + """Test wiping Excel metadata through MetadataFactory.""" + handler = MetadataFactory.get_handler(XLSX_TEST_FILE) + metadata = handler.read() + handler.wipe() + + assert handler.processed_metadata != metadata + + +def test_save_processed_excel_metadata_via_factory(): + """Test saving processed Excel metadata through MetadataFactory.""" output_dir = Path("./tests/assets/output") output_dir.mkdir(parents=True, exist_ok=True) - # Process original file - handler = MetadataFactory.get_handler(PDF_TEST_FILE) - original_metadata = handler.read() - original_count = len(original_metadata) + handler = MetadataFactory.get_handler(XLSX_TEST_FILE) + handler.read() handler.wipe() - # Save processed file - output_file = output_dir / Path(PDF_TEST_FILE).name + output_file = output_dir / Path(XLSX_TEST_FILE).name handler.save(str(output_file)) - # Read output file and verify metadata is reduced or gone - try: - output_handler = MetadataFactory.get_handler(str(output_file)) - output_metadata = output_handler.read() - assert len(output_metadata) < original_count - except MetadataNotFoundError: - # If no metadata found, that's expected for fully stripped files - pass - + assert output_file.exists() shutil.rmtree(output_dir) + + +def test_excel_format_detection(): + """Test format detection for Excel files.""" + handler = MetadataFactory.get_handler(XLSX_TEST_FILE) + assert handler._detect_format() == "xlsx" + + +# ============== Error Tests ============== + + +def test_unsupported_format_raises_error(tmp_path): + """Test that unsupported file formats raise an error.""" + fake_file = tmp_path / "test.txt" + fake_file.write_text("not an image") + + with pytest.raises(UnsupportedFormatError): + MetadataFactory.get_handler(str(fake_file)) + + +def test_save_without_output_path_raises_error(): + """Test that save() raises ValueError when output_path is empty.""" + handler = MetadataFactory.get_handler(JPG_TEST_FILE) + handler.read() + handler.wipe() + with pytest.raises(ValueError): + handler.save("") diff --git a/tests/unit/test_excel_handler.py b/tests/unit/test_excel_handler.py new file mode 100644 index 00000000..03c3e80a --- /dev/null +++ b/tests/unit/test_excel_handler.py @@ -0,0 +1,207 @@ +""" +Unit tests for ExcelHandler. + +Tests the ExcelHandler class in isolation, focusing on individual methods +and edge cases including encrypted workbooks, missing metadata, and corrupted files. +""" + +import shutil +from pathlib import Path + +import pytest +from openpyxl.utils.exceptions import InvalidFileException + +from src.services.excel_handler import ExcelHandler +from src.utils.exceptions import ( + MetadataNotFoundError, + UnsupportedFormatError, +) + +# Import path helpers from conftest +from tests.conftest import get_large_xlsx_test_file, get_xlsx_test_file + +# Test file paths (cross-platform) +XLSX_TEST_FILE = get_xlsx_test_file() +LARGE_XLSX_TEST_FILE = get_large_xlsx_test_file() + + +# ============== Success Case Tests ============== + + +@pytest.mark.parametrize("xlsx_file", [XLSX_TEST_FILE, LARGE_XLSX_TEST_FILE]) +def test_read_excel_metadata(xlsx_file): + """ + Test reading metadata from Excel files. + Verifies that read() extracts metadata and populates keys_to_delete. + """ + assert Path(xlsx_file).exists(), f"Test file not found: {xlsx_file}" + handler = ExcelHandler(xlsx_file) + metadata = handler.read() + + # Check metadata was extracted + assert handler.metadata == metadata + assert isinstance(metadata, dict) + + # Check keys_to_delete is populated + assert handler.keys_to_delete is not None + assert len(handler.keys_to_delete) > 0 + + +@pytest.mark.parametrize("xlsx_file", [XLSX_TEST_FILE, LARGE_XLSX_TEST_FILE]) +def test_wipe_excel_metadata(xlsx_file): + """ + Test wiping metadata from Excel files. + Verifies that wipe() removes metadata entries. + """ + assert Path(xlsx_file).exists(), f"Test file not found: {xlsx_file}" + handler = ExcelHandler(xlsx_file) + metadata = handler.read() + handler.wipe() + + # processed_metadata should differ from original + assert handler.processed_metadata != metadata + + +@pytest.mark.parametrize("xlsx_file", [XLSX_TEST_FILE, LARGE_XLSX_TEST_FILE]) +def test_save_processed_excel_metadata(xlsx_file): + """ + Test saving processed Excel to output path. + """ + output_dir = Path("./tests/assets/output") + output_dir.mkdir(parents=True, exist_ok=True) + + handler = ExcelHandler(xlsx_file) + handler.read() + handler.wipe() + + output_file = output_dir / Path(xlsx_file).name + handler.save(str(output_file)) + + # Verify output file exists + assert output_file.exists() + + # Cleanup + shutil.rmtree(output_dir) + + +def test_format_detection_xlsx(): + """ + Test that _detect_format() correctly identifies XLSX files. + """ + handler = ExcelHandler(XLSX_TEST_FILE) + detected = handler._detect_format() + assert detected == "xlsx" + + +@pytest.mark.parametrize("xlsx_file", [XLSX_TEST_FILE, LARGE_XLSX_TEST_FILE]) +def test_output_file_has_less_metadata(xlsx_file): + """ + Test that the output file has metadata stripped. + """ + output_dir = Path("./tests/assets/output") + output_dir.mkdir(parents=True, exist_ok=True) + + # Process original file + handler = ExcelHandler(xlsx_file) + original_metadata = handler.read() + handler.wipe() + + # Save processed file + output_file = output_dir / Path(xlsx_file).name + handler.save(str(output_file)) + + # Read output file and verify metadata is reduced or gone + try: + output_handler = ExcelHandler(str(output_file)) + output_metadata = output_handler.read() + # Output should have fewer metadata entries (some are None now) + non_none_original = sum(1 for v in original_metadata.values() if v is not None) + non_none_output = sum(1 for v in output_metadata.values() if v is not None) + assert non_none_output <= non_none_original + except MetadataNotFoundError: + # If no metadata found, that's expected for fully stripped files + pass + + # Cleanup + shutil.rmtree(output_dir) + + +def test_preserved_properties_not_deleted(): + """ + Test that created, modified, and language properties are preserved. + """ + handler = ExcelHandler(XLSX_TEST_FILE) + handler.read() + + # These should NOT be in keys_to_delete + assert "created" not in handler.keys_to_delete + assert "modified" not in handler.keys_to_delete + assert "language" not in handler.keys_to_delete + + +# ============== Error Case Tests ============== + + +def test_unsupported_format_raises_error(tmp_path): + """ + Test that non-Excel files raise UnsupportedFormatError. + """ + # Create a fake text file with .txt extension + fake_file = tmp_path / "test.txt" + fake_file.write_text("not an excel file") + + handler = ExcelHandler(str(fake_file)) + with pytest.raises(UnsupportedFormatError): + handler._detect_format() + + +def test_save_without_output_path_raises_error(): + """ + Test that save() raises ValueError when output_path is None or empty. + """ + handler = ExcelHandler(XLSX_TEST_FILE) + handler.read() + handler.wipe() + with pytest.raises(ValueError): + handler.save("") + + +def test_save_with_none_raises_error(): + """ + Test that save() raises ValueError when output_path is None. + """ + handler = ExcelHandler(XLSX_TEST_FILE) + handler.read() + handler.wipe() + with pytest.raises((ValueError, TypeError)): + handler.save(None) + + +# ============== Edge Case Tests ============== + + +def test_corrupted_excel_graceful_error(tmp_path): + """ + Test that corrupted Excel files are handled gracefully. + """ + # Create a corrupted Excel file (invalid structure) + corrupted_xlsx = tmp_path / "corrupted.xlsx" + corrupted_xlsx.write_bytes(b"not a valid xlsx content at all") + + handler = ExcelHandler(str(corrupted_xlsx)) + # Should raise InvalidFileException or similar from openpyxl + with pytest.raises((InvalidFileException, Exception)): + handler.read() + + +def test_format_detection_all_excel_types(tmp_path): + """ + Test format detection for all supported Excel extensions. + """ + for ext in ["xlsx", "xlsm", "xltx", "xltm"]: + fake_file = tmp_path / f"test.{ext}" + fake_file.write_bytes(b"dummy") # Not valid, but we're only testing detection + + handler = ExcelHandler(str(fake_file)) + detected = handler._detect_format() + assert detected == ext diff --git a/uv.lock b/uv.lock index 97a4212e..fe384a1e 100644 --- a/uv.lock +++ b/uv.lock @@ -127,6 +127,15 @@ toml = [ { name = "tomli", marker = "python_full_version <= '3.11'" }, ] +[[package]] +name = "et-xmlfile" +version = "2.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d3/38/af70d7ab1ae9d4da450eeec1fa3918940a5fafb9055e934af8d6eb0c2313/et_xmlfile-2.0.0.tar.gz", hash = "sha256:dab3f4764309081ce75662649be815c4c9081e88f0837825f90fd28317d4da54", size = 17234, upload-time = "2024-10-25T17:25:40.039Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c1/8b/5fe2cc11fee489817272089c4203e679c63b570a5aaeb18d852ae3cbba6a/et_xmlfile-2.0.0-py3-none-any.whl", hash = "sha256:7a91720bc756843502c3b7504c77b8fe44217c85c537d85037f0f536151b2caa", size = 18059, upload-time = "2024-10-25T17:25:39.051Z" }, +] + [[package]] name = "exceptiongroup" version = "1.3.1" @@ -247,6 +256,7 @@ name = "metadata-scrubber" version = "0.1.1" source = { editable = "." } dependencies = [ + { name = "openpyxl" }, { name = "piexif" }, { name = "pillow" }, { name = "pypdf" }, @@ -265,6 +275,7 @@ dev = [ [package.metadata] requires-dist = [ { name = "mypy", marker = "extra == 'dev'", specifier = ">=1.19.0" }, + { name = "openpyxl", specifier = ">=3.1.5" }, { name = "piexif", specifier = ">=1.1.3" }, { name = "pillow", specifier = ">=12.0.0" }, { name = "pypdf", specifier = ">=6.5.0" }, @@ -331,6 +342,18 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/79/7b/2c79738432f5c924bef5071f933bcc9efd0473bac3b4aa584a6f7c1c8df8/mypy_extensions-1.1.0-py3-none-any.whl", hash = "sha256:1be4cccdb0f2482337c4743e60421de3a356cd97508abadd57d47403e94f5505", size = 4963, upload-time = "2025-04-22T14:54:22.983Z" }, ] +[[package]] +name = "openpyxl" +version = "3.1.5" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "et-xmlfile" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/3d/f9/88d94a75de065ea32619465d2f77b29a0469500e99012523b91cc4141cd1/openpyxl-3.1.5.tar.gz", hash = "sha256:cf0e3cf56142039133628b5acffe8ef0c12bc902d2aadd3e0fe5878dc08d1050", size = 186464, upload-time = "2024-06-28T14:03:44.161Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c0/da/977ded879c29cbd04de313843e76868e6e13408a94ed6b987245dc7c8506/openpyxl-3.1.5-py2.py3-none-any.whl", hash = "sha256:5282c12b107bffeef825f4617dc029afaf41d0ea60823bbb665ef3079dc79de2", size = 250910, upload-time = "2024-06-28T14:03:41.161Z" }, +] + [[package]] name = "packaging" version = "25.0"