"""Tests for JSON metadata writer.""" import json import jsonschema import pytest from pathlib import Path from pdf2imos.models import MaterialAnnotation, PartGeometry, PartMetadata from pdf2imos.output.json_writer import build_metadata, write_metadata from pdf2imos.schema.validator import validate_metadata @pytest.fixture def test_part(): return PartGeometry( width_mm=600.0, height_mm=720.0, depth_mm=18.0, origin=(0.0, 0.0, 0.0), name="test_panel", ) @pytest.fixture def test_annotations(): return PartMetadata( materials=( MaterialAnnotation( text="18mm white melamine MDF", thickness_mm=18.0, material_type="MDF", finish="white", ), ), edgebanding=(), hardware=(), drilling=(), raw_annotations=("Scale: 1:1", "Part Name: test_panel"), ) @pytest.fixture def test_title_info(): return { "part_name": "test_panel", "material": "18mm MDF", "scale": "1:1", "drawing_number": "", } class TestBuildMetadata: def test_returns_dict(self, test_part, test_annotations, test_title_info): result = build_metadata( test_part, test_annotations, test_title_info, "test.pdf" ) assert isinstance(result, dict) def test_required_fields_present( self, test_part, test_annotations, test_title_info ): result = build_metadata( test_part, test_annotations, test_title_info, "test.pdf" ) assert "source_pdf" in result assert "extraction_timestamp" in result assert "part_name" in result assert "overall_dimensions" in result assert "parts" in result assert "raw_annotations" in result def test_dimensions_match_part( self, test_part, test_annotations, test_title_info ): result = build_metadata( test_part, test_annotations, test_title_info, "test.pdf" ) dims = result["overall_dimensions"] assert dims["width_mm"] == 600.0 assert dims["height_mm"] == 720.0 assert dims["depth_mm"] == 18.0 def test_source_pdf_is_filename( self, test_part, test_annotations, test_title_info ): result = build_metadata( test_part, test_annotations, test_title_info, "test.pdf" ) assert result["source_pdf"] == "test.pdf" def test_validates_against_schema( self, test_part, test_annotations, test_title_info ): """Built metadata must pass schema validation.""" result = build_metadata( test_part, test_annotations, test_title_info, "test.pdf" ) validate_metadata(result) # Should not raise def test_raw_annotations_in_output( self, test_part, test_annotations, test_title_info ): result = build_metadata( test_part, test_annotations, test_title_info, "test.pdf" ) assert "Scale: 1:1" in result["raw_annotations"] or len( result["raw_annotations"] ) > 0 class TestWriteMetadata: def test_returns_path( self, test_part, test_annotations, test_title_info, tmp_path ): metadata = build_metadata( test_part, test_annotations, test_title_info, "test.pdf" ) output = tmp_path / "test.json" result = write_metadata(metadata, output) assert isinstance(result, Path) def test_file_created( self, test_part, test_annotations, test_title_info, tmp_path ): metadata = build_metadata( test_part, test_annotations, test_title_info, "test.pdf" ) output = tmp_path / "test.json" write_metadata(metadata, output) assert output.exists() def test_file_is_valid_json( self, test_part, test_annotations, test_title_info, tmp_path ): metadata = build_metadata( test_part, test_annotations, test_title_info, "test.pdf" ) output = tmp_path / "test.json" write_metadata(metadata, output) data = json.loads(output.read_text()) assert isinstance(data, dict) def test_dimensions_in_output_file( self, test_part, test_annotations, test_title_info, tmp_path ): metadata = build_metadata( test_part, test_annotations, test_title_info, "test.pdf" ) output = tmp_path / "test.json" write_metadata(metadata, output) data = json.loads(output.read_text()) assert data["overall_dimensions"]["width_mm"] == 600.0 def test_invalid_metadata_raises(self, tmp_path): """Invalid metadata should raise validation error.""" invalid = {"bad": "data"} output = tmp_path / "bad.json" with pytest.raises(jsonschema.ValidationError): write_metadata(invalid, output) def test_creates_parent_dirs( self, test_part, test_annotations, test_title_info, tmp_path ): """Parent directories created if missing.""" metadata = build_metadata( test_part, test_annotations, test_title_info, "test.pdf" ) output = tmp_path / "nested" / "dir" / "test.json" write_metadata(metadata, output) assert output.exists()