@@ -1602,6 +1602,76 @@ def test_device_detail_api_change_config(self):
16021602 self .assertEqual (response .status_code , 200 )
16031603 self .assertEqual (device .config .templates .count (), 0 )
16041604
1605+ def test_multiple_vpn_client_templates_same_vpn (self ):
1606+ """
1607+ Assigning multiple templates of type 'vpn' referencing the same VPN
1608+ to a device's config raises error.
1609+ """
1610+ org = self ._get_org ()
1611+ vpn = self ._create_vpn (organization = org )
1612+ # Create two templates of type 'vpn' referencing the same VPN
1613+ vpn_template1 = self ._create_template (
1614+ type = "vpn" , vpn = vpn , organization = org , name = "VPN Client 1"
1615+ )
1616+ vpn_template2 = self ._create_template (
1617+ type = "vpn" , vpn = vpn , organization = org , name = "VPN Client 2"
1618+ )
1619+ device = self ._create_device (organization = org )
1620+ config = self ._create_config (device = device )
1621+ path = reverse ("config_api:device_detail" , args = [device .pk ])
1622+ data = {
1623+ "name" : device .name ,
1624+ "organization" : str (org .id ),
1625+ "mac_address" : device .mac_address ,
1626+ "config" : {
1627+ "backend" : "netjsonconfig.OpenWrt" ,
1628+ "context" : {"lan_ip" : "192.168.1.1" },
1629+ "config" : {"interfaces" : [{"name" : "wlan0" , "type" : "wireless" }]},
1630+ },
1631+ }
1632+ expected_error_message = (
1633+ "You cannot select multiple VPN client templates related"
1634+ " to the same VPN server.\n "
1635+ 'The templates "VPN Client 1" and "VPN Client 2" are all '
1636+ 'linked to the same VPN server: "test".'
1637+ )
1638+
1639+ with self .subTest ("Add both templates at once" ):
1640+ data ["config" ]["templates" ] = [str (vpn_template1 .pk ), str (vpn_template2 .pk )]
1641+ response = self .client .put (path , data , content_type = "application/json" )
1642+ self .assertEqual (response .status_code , 400 )
1643+ self .assertEqual (
1644+ str (response .data ["config" ][0 ]),
1645+ expected_error_message ,
1646+ )
1647+ self .assertEqual (config .templates .count (), 0 )
1648+ self .assertEqual (config .vpnclient_set .count (), 0 )
1649+
1650+ with self .subTest ("Add one template at a time" ):
1651+ data ["config" ]["templates" ] = [str (vpn_template1 .pk )]
1652+ response = self .client .put (path , data , content_type = "application/json" )
1653+ self .assertEqual (response .status_code , 200 )
1654+ self .assertEqual (config .templates .count (), 1 )
1655+ self .assertEqual (config .vpnclient_set .count (), 1 )
1656+
1657+ # Now add the second template
1658+ data ["config" ]["templates" ] = [str (vpn_template1 .pk ), str (vpn_template2 .pk )]
1659+ response = self .client .put (path , data , content_type = "application/json" )
1660+ self .assertEqual (response .status_code , 400 )
1661+ self .assertEqual (
1662+ str (response .data ["config" ][0 ]),
1663+ expected_error_message ,
1664+ )
1665+ self .assertEqual (config .templates .filter (id = vpn_template1 .id ).count (), 1 )
1666+ self .assertEqual (config .vpnclient_set .count (), 1 )
1667+
1668+ with self .subTest ("Change existing template with another" ):
1669+ data ["config" ]["templates" ] = [str (vpn_template2 .pk )]
1670+ response = self .client .put (path , data , content_type = "application/json" )
1671+ self .assertEqual (response .status_code , 200 )
1672+ self .assertEqual (config .templates .filter (id = vpn_template2 .id ).count (), 1 )
1673+ self .assertEqual (config .vpnclient_set .count (), 1 )
1674+
16051675 def test_device_patch_with_templates_of_same_org (self ):
16061676 org1 = self ._create_org (name = "testorg" )
16071677 d1 = self ._create_device (name = "org1-config" , organization = org1 )
0 commit comments