@@ -875,6 +875,142 @@ def test_module_bay_parent_cleared_when_module_removed(self):
875875 self .assertIsNone (bay2 .parent )
876876 self .assertIsNone (bay2 .module )
877877
878+ def test_module_installation_creates_port_mappings (self ):
879+ """
880+ Test that installing a module with front/rear port templates correctly
881+ creates PortMapping instances for the device.
882+ """
883+ device = Device .objects .first ()
884+ manufacturer = Manufacturer .objects .first ()
885+ module_bay = ModuleBay .objects .create (device = device , name = 'Test Bay PortMapping 1' )
886+
887+ # Create a module type with a rear port template
888+ module_type_with_mappings = ModuleType .objects .create (
889+ manufacturer = manufacturer ,
890+ model = 'Module Type With Mappings' ,
891+ )
892+
893+ # Create a rear port template with 12 positions (splice)
894+ rear_port_template = RearPortTemplate .objects .create (
895+ module_type = module_type_with_mappings ,
896+ name = 'Rear Port 1' ,
897+ type = PortTypeChoices .TYPE_SPLICE ,
898+ positions = 12 ,
899+ )
900+
901+ # Create 12 front port templates mapped to the rear port
902+ front_port_templates = []
903+ for i in range (1 , 13 ):
904+ front_port_template = FrontPortTemplate .objects .create (
905+ module_type = module_type_with_mappings ,
906+ name = f'port { i } ' ,
907+ type = PortTypeChoices .TYPE_LC ,
908+ positions = 1 ,
909+ )
910+ front_port_templates .append (front_port_template )
911+
912+ # Create port template mapping
913+ PortTemplateMapping .objects .create (
914+ device_type = None ,
915+ module_type = module_type_with_mappings ,
916+ front_port = front_port_template ,
917+ front_port_position = 1 ,
918+ rear_port = rear_port_template ,
919+ rear_port_position = i ,
920+ )
921+
922+ # Install the module
923+ module = Module .objects .create (
924+ device = device ,
925+ module_bay = module_bay ,
926+ module_type = module_type_with_mappings ,
927+ status = ModuleStatusChoices .STATUS_ACTIVE ,
928+ )
929+
930+ # Verify that front ports were created
931+ front_ports = FrontPort .objects .filter (device = device , module = module )
932+ self .assertEqual (front_ports .count (), 12 )
933+
934+ # Verify that the rear port was created
935+ rear_ports = RearPort .objects .filter (device = device , module = module )
936+ self .assertEqual (rear_ports .count (), 1 )
937+ rear_port = rear_ports .first ()
938+ self .assertEqual (rear_port .positions , 12 )
939+
940+ # Verify that port mappings were created
941+ port_mappings = PortMapping .objects .filter (front_port__module = module )
942+ self .assertEqual (port_mappings .count (), 12 )
943+
944+ # Verify each mapping is correct
945+ for i , front_port_template in enumerate (front_port_templates , start = 1 ):
946+ front_port = FrontPort .objects .get (
947+ device = device ,
948+ name = front_port_template .name ,
949+ module = module ,
950+ )
951+
952+ # Check that a mapping exists for this front port
953+ mapping = PortMapping .objects .get (
954+ device = device ,
955+ front_port = front_port ,
956+ front_port_position = 1 ,
957+ )
958+
959+ self .assertEqual (mapping .rear_port , rear_port )
960+ self .assertEqual (mapping .front_port_position , 1 )
961+ self .assertEqual (mapping .rear_port_position , i )
962+
963+ def test_module_installation_without_mappings (self ):
964+ """
965+ Test that installing a module without port template mappings
966+ doesn't create any PortMapping instances.
967+ """
968+ device = Device .objects .first ()
969+ manufacturer = Manufacturer .objects .first ()
970+ module_bay = ModuleBay .objects .create (device = device , name = 'Test Bay PortMapping 2' )
971+
972+ # Create a module type without any port template mappings
973+ module_type_no_mappings = ModuleType .objects .create (
974+ manufacturer = manufacturer ,
975+ model = 'Module Type Without Mappings' ,
976+ )
977+
978+ # Create a rear port template
979+ RearPortTemplate .objects .create (
980+ module_type = module_type_no_mappings ,
981+ name = 'Rear Port 1' ,
982+ type = PortTypeChoices .TYPE_SPLICE ,
983+ positions = 12 ,
984+ )
985+
986+ # Create front port templates but DO NOT create PortTemplateMapping rows
987+ for i in range (1 , 13 ):
988+ FrontPortTemplate .objects .create (
989+ module_type = module_type_no_mappings ,
990+ name = f'port { i } ' ,
991+ type = PortTypeChoices .TYPE_LC ,
992+ positions = 1 ,
993+ )
994+
995+ # Install the module
996+ module = Module .objects .create (
997+ device = device ,
998+ module_bay = module_bay ,
999+ module_type = module_type_no_mappings ,
1000+ status = ModuleStatusChoices .STATUS_ACTIVE ,
1001+ )
1002+
1003+ # Verify no port mappings were created for this module
1004+ port_mappings = PortMapping .objects .filter (
1005+ device = device ,
1006+ front_port__module = module ,
1007+ front_port_position = 1 ,
1008+ )
1009+ self .assertEqual (port_mappings .count (), 0 )
1010+ self .assertEqual (FrontPort .objects .filter (module = module ).count (), 12 )
1011+ self .assertEqual (RearPort .objects .filter (module = module ).count (), 1 )
1012+ self .assertEqual (PortMapping .objects .filter (front_port__module = module ).count (), 0 )
1013+
8781014
8791015class CableTestCase (TestCase ):
8801016
0 commit comments