import unittest from unittest.mock import patch from sn_basis.functions.qgiscore_wrapper import ( MAP_GRID_ANNOTATION_DISPLAY_HIDE_ALL, MAP_GRID_ANNOTATION_DISPLAY_SHOW_X, MAP_GRID_ANNOTATION_DISPLAY_SHOW_Y, MAP_GRID_BORDER_BOTTOM, MAP_GRID_BORDER_LEFT, MAP_GRID_BORDER_RIGHT, MAP_GRID_BORDER_TOP, MAP_GRID_FRAME_STYLE_INTERIOR_TICKS, MAP_GRID_STYLE_FRAME_ANNOTATIONS, TEXT_BACKGROUND_SHAPE_RECTANGLE, TEXT_BACKGROUND_SIZE_BUFFER, TEXT_RENDER_UNIT_MILLIMETERS, TEXT_RENDER_UNIT_POINTS, QgsLayoutItemLegend, QgsLayoutItemMap, QgsPrintLayout, QgsProject, ) from sn_basis.modules.print_layout import PrintLayout class _FakeExtent: def isNull(self) -> bool: return False class _FakeLegendForResize: def __init__(self) -> None: self.last_resize = None def setLocked(self, _enabled: bool) -> None: pass def setColumnCount(self, _count: int) -> None: pass def setEqualColumnWidth(self, _enabled: bool) -> None: pass def refresh(self) -> None: pass def adjustBoxSize(self) -> None: pass def attemptResize(self, size) -> None: self.last_resize = size class TestPrintLayout(unittest.TestCase): def test_create_legend_item_links_map_and_enables_map_filtering(self): project = QgsProject.instance() print_layout = PrintLayout(project=project) layout = QgsPrintLayout(project) linked_map = QgsLayoutItemMap(layout) legend = print_layout._create_legend_item( layout, "legende", linked_map, 10.0, 20.0, width_mm=50.0, height_mm=30.0, ) self.assertIs(legend.linked_map, linked_map) self.assertTrue(legend.auto_update_model) self.assertTrue(legend.legend_filter_by_map_enabled) def test_create_legend_item_does_not_copy_project_layers_into_legend_model(self): project = QgsProject.instance() print_layout = PrintLayout(project=project) layout = QgsPrintLayout(project) linked_map = QgsLayoutItemMap(layout) legend = print_layout._create_legend_item( layout, "legende", linked_map, 10.0, 20.0, ) root_group = legend.model().rootGroup() self.assertEqual(root_group.layers, []) def test_configure_legend_size_uses_content_adaptive_size(self): project = QgsProject.instance() print_layout = PrintLayout(project=project) legend = _FakeLegendForResize() with patch.object(print_layout, "_get_item_size_mm", return_value=(95.0, 33.0)): height = print_layout._configure_legend_size( legend, width_limit_mm=180.0, column_count=2, equal_column_width=True, ) self.assertIsNone(legend.last_resize) self.assertEqual(height, 33.0) def test_configure_hauptkarte_grids_uses_wrapper_constants(self): project = QgsProject.instance() print_layout = PrintLayout(project=project) layout = QgsPrintLayout(project) hauptkarte = QgsLayoutItemMap(layout) print_layout._configure_hauptkarte_grids(hauptkarte) grid_stack = hauptkarte.grids() grids = grid_stack.asList() self.assertEqual(len(grids), 1) frame_grid = grids[0] self.assertEqual(frame_grid.style, MAP_GRID_STYLE_FRAME_ANNOTATIONS) self.assertEqual(frame_grid.frame_style, MAP_GRID_FRAME_STYLE_INTERIOR_TICKS) self.assertTrue(frame_grid.annotation_enabled) self.assertEqual(frame_grid.annotation_display[MAP_GRID_BORDER_LEFT], MAP_GRID_ANNOTATION_DISPLAY_HIDE_ALL) self.assertEqual(frame_grid.annotation_display[MAP_GRID_BORDER_TOP], MAP_GRID_ANNOTATION_DISPLAY_HIDE_ALL) self.assertEqual(frame_grid.annotation_display[MAP_GRID_BORDER_RIGHT], MAP_GRID_ANNOTATION_DISPLAY_SHOW_Y) self.assertEqual(frame_grid.annotation_display[MAP_GRID_BORDER_BOTTOM], MAP_GRID_ANNOTATION_DISPLAY_SHOW_X) text_format = frame_grid.annotation_text_format self.assertIsNotNone(text_format) self.assertEqual(getattr(text_format, "size", None), 10) self.assertEqual(getattr(text_format, "size_unit", None), TEXT_RENDER_UNIT_POINTS) background = getattr(text_format, "background", None) self.assertIsNotNone(background) self.assertTrue(getattr(background, "enabled", False)) self.assertEqual(getattr(background, "shape_type", None), TEXT_BACKGROUND_SHAPE_RECTANGLE) self.assertEqual(getattr(background, "size_type", None), TEXT_BACKGROUND_SIZE_BUFFER) self.assertEqual(getattr(background, "size_unit", None), TEXT_RENDER_UNIT_MILLIMETERS) self.assertEqual(getattr(background, "offset_unit", None), TEXT_RENDER_UNIT_MILLIMETERS) offset = getattr(background, "offset", None) self.assertIsNotNone(offset) if isinstance(offset, tuple): self.assertEqual(offset[1], -1.0) else: y_value = getattr(offset, "y", None) if callable(y_value): self.assertEqual(y_value(), -1.0) else: self.assertEqual(getattr(offset, "y", None), -1.0) @patch("sn_basis.modules.print_layout.open_layout_designer") def test_create_single_page_layout_keeps_legend_linked_to_hauptkarte_and_theme(self, _mock_open_designer): project = QgsProject.instance() print_layout = PrintLayout(project=project) layout = print_layout.create_single_page_layout( name="Testlayout", page_width_mm=420.0, page_height_mm=297.0, map_width_mm=200.0, map_height_mm=150.0, extent=_FakeExtent(), plotmassstab=5000.0, thema="Thema A", ) hauptkarte = next(item for item in layout.items if isinstance(item, QgsLayoutItemMap)) legende = next(item for item in layout.items if isinstance(item, QgsLayoutItemLegend)) self.assertTrue(hauptkarte.follow_visibility_preset) self.assertEqual(hauptkarte.follow_visibility_preset_name, "Thema A") self.assertTrue(hauptkarte.keep_layer_set) self.assertIs(legende.linked_map, hauptkarte) self.assertTrue(legende.auto_update_model) self.assertTrue(legende.legend_filter_by_map_enabled) if __name__ == "__main__": unittest.main()