2026-04-08 13:56:58 +02:00
import unittest
from unittest.mock import patch
from sn_basis.functions.qgiscore_wrapper import (
2026-04-10 21:30:44 +02:00
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 ,
2026-04-08 13:56:58 +02:00
QgsLayoutItemLegend ,
QgsLayoutItemMap ,
QgsPrintLayout ,
QgsProject ,
)
from sn_basis.modules.print_layout import PrintLayout
class _FakeExtent :
def isNull ( self ) -> bool :
return False
2026-04-10 21:30:44 +02:00
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
2026-04-08 13:56:58 +02:00
class TestPrintLayout ( unittest . TestCase ):
def test_create_legend_item_links_map_and_enables_map_filtering ( self ):
2026-09-16 15:06:16 +02:00
"""Prüft, dass eine erzeugte Legende mit der übergebenen Karte verknüpft ist und automatisch nach deren Sichtbarkeit gefiltert wird."""
2026-04-08 13:56:58 +02:00
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 ):
2026-09-16 15:06:16 +02:00
"""Prüft, dass eine neu erzeugte Legende keine Projekt-Layer in ihr Legendenmodell übernimmt (leere Root-Gruppe)."""
2026-04-08 13:56:58 +02:00
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 , [])
2026-04-10 21:30:44 +02:00
def test_configure_legend_size_uses_content_adaptive_size ( self ):
2026-09-16 15:06:16 +02:00
"""Prüft, dass die Legendengröße inhaltsadaptiv bestimmt wird (kein manuelles Resize) und die ermittelte Höhe zurückgegeben wird."""
2026-04-10 21:30:44 +02:00
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 ):
2026-09-16 15:06:16 +02:00
"""Prüft, dass das Gitternetz der Hauptkarte mit den erwarteten Stil-, Rahmen- und Beschriftungskonstanten (nur rechts/unten beschriftet, Schriftgröße und Hintergrund) konfiguriert wird."""
2026-04-10 21:30:44 +02:00
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 )
2026-04-08 13:56:58 +02:00
@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 ):
2026-09-16 15:06:16 +02:00
"""Prüft, dass ein einseitiges Layout die Hauptkarte auf das übergebene Kartenthema festlegt und die Legende mit dieser Karte verknüpft bleibt."""
2026-04-08 13:56:58 +02:00
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 ()