"""Unit tests for the STL thumbnail service.""" import os import tempfile from pathlib import Path from unittest.mock import MagicMock, patch import pytest class TestSTLThumbnailService: """Tests for STL thumbnail generation.""" def test_generate_thumbnail_ascii_stl(self): """Test generating thumbnail from ASCII STL file.""" from backend.app.services.stl_thumbnail import generate_stl_thumbnail # Create a simple ASCII STL cube ascii_stl = """solid cube facet normal 0 0 -1 outer loop vertex 0 0 0 vertex 1 0 0 vertex 1 1 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 0 0 0 vertex 1 1 0 vertex 0 1 0 endloop endfacet facet normal 0 0 1 outer loop vertex 0 0 1 vertex 1 1 1 vertex 1 0 1 endloop endfacet facet normal 0 0 1 outer loop vertex 0 0 1 vertex 0 1 1 vertex 1 1 1 endloop endfacet facet normal 0 -1 0 outer loop vertex 0 0 0 vertex 1 0 1 vertex 1 0 0 endloop endfacet facet normal 0 -1 0 outer loop vertex 0 0 0 vertex 0 0 1 vertex 1 0 1 endloop endfacet facet normal 1 0 0 outer loop vertex 1 0 0 vertex 1 1 1 vertex 1 1 0 endloop endfacet facet normal 1 0 0 outer loop vertex 1 0 0 vertex 1 0 1 vertex 1 1 1 endloop endfacet facet normal 0 1 0 outer loop vertex 0 1 0 vertex 1 1 0 vertex 1 1 1 endloop endfacet facet normal 0 1 0 outer loop vertex 0 1 0 vertex 1 1 1 vertex 0 1 1 endloop endfacet facet normal -1 0 0 outer loop vertex 0 0 0 vertex 0 1 0 vertex 0 1 1 endloop endfacet facet normal -1 0 0 outer loop vertex 0 0 0 vertex 0 1 1 vertex 0 0 1 endloop endfacet endsolid cube """ with tempfile.NamedTemporaryFile(suffix=".stl", delete=False, mode="w") as stl_file: stl_file.write(ascii_stl) stl_path = stl_file.name with tempfile.NamedTemporaryFile(suffix=".png", delete=False) as png_file: png_path = png_file.name try: result = generate_stl_thumbnail(stl_path, png_path) assert result is True assert os.path.exists(png_path) # Check it's a valid PNG (starts with PNG magic bytes) with open(png_path, "rb") as f: header = f.read(8) assert header[:4] == b"\x89PNG" finally: os.unlink(stl_path) if os.path.exists(png_path): os.unlink(png_path) def test_generate_thumbnail_binary_stl(self): """Test generating thumbnail from binary STL file.""" import struct from backend.app.services.stl_thumbnail import generate_stl_thumbnail # Create a simple binary STL cube (minimal version) # Binary STL format: # - 80 bytes header # - 4 bytes number of triangles (uint32) # - For each triangle: # - 12 bytes normal (3 floats) # - 36 bytes vertices (9 floats, 3 vertices x 3 coords) # - 2 bytes attribute byte count (usually 0) header = b"\x00" * 80 # Empty header num_triangles = 12 # A cube has 12 triangles (2 per face) # Define cube vertices vertices = [ # Bottom face (z=0) ((0, 0, -1), [(0, 0, 0), (1, 0, 0), (1, 1, 0)]), ((0, 0, -1), [(0, 0, 0), (1, 1, 0), (0, 1, 0)]), # Top face (z=1) ((0, 0, 1), [(0, 0, 1), (1, 1, 1), (1, 0, 1)]), ((0, 0, 1), [(0, 0, 1), (0, 1, 1), (1, 1, 1)]), # Front face (y=0) ((0, -1, 0), [(0, 0, 0), (1, 0, 1), (1, 0, 0)]), ((0, -1, 0), [(0, 0, 0), (0, 0, 1), (1, 0, 1)]), # Back face (y=1) ((0, 1, 0), [(0, 1, 0), (1, 1, 0), (1, 1, 1)]), ((0, 1, 0), [(0, 1, 0), (1, 1, 1), (0, 1, 1)]), # Left face (x=0) ((-1, 0, 0), [(0, 0, 0), (0, 1, 0), (0, 1, 1)]), ((-1, 0, 0), [(0, 0, 0), (0, 1, 1), (0, 0, 1)]), # Right face (x=1) ((1, 0, 0), [(1, 0, 0), (1, 1, 1), (1, 1, 0)]), ((1, 0, 0), [(1, 0, 0), (1, 0, 1), (1, 1, 1)]), ] binary_data = header + struct.pack("