@@ -1435,12 +1435,38 @@ def test_default_device_backend(self):
14351435 response = self .client .get (path )
14361436 self .assertContains (response , '<option value="netjsonconfig.OpenWrt" selected' )
14371437
1438- def test_existing_device_backend (self ):
1438+ def test_device_backend_readonly_on_change (self ):
14391439 d = self ._create_device ()
14401440 self ._create_config (device = d , backend = "netjsonconfig.OpenWisp" )
14411441 path = reverse (f"admin:{ self .app_label } _device_change" , args = [d .pk ])
14421442 response = self .client .get (path )
1443- self .assertContains (response , '<option value="netjsonconfig.OpenWisp" selected' )
1443+ self .assertContains (response , "field-backend" )
1444+ self .assertNotContains (response , 'name="config-0-backend"' )
1445+
1446+ def test_device_backend_cannot_be_changed_from_change_form (self ):
1447+ template = Template .objects .first ()
1448+ device = self ._create_device ()
1449+ config = self ._create_config (
1450+ device = device ,
1451+ backend = template .backend ,
1452+ config = template .config ,
1453+ )
1454+ path = reverse (f"admin:{ self .app_label } _device_change" , args = [device .pk ])
1455+ params = self ._get_device_params (org = device .organization )
1456+ params .update (
1457+ {
1458+ "name" : "device-backend-unchanged" ,
1459+ "config-0-id" : str (config .pk ),
1460+ "config-0-device" : str (device .pk ),
1461+ "config-0-backend" : "totally.invalid.backend" ,
1462+ "config-0-templates" : str (template .pk ),
1463+ "config-INITIAL_FORMS" : 1 ,
1464+ }
1465+ )
1466+ response = self .client .post (path , params )
1467+ self .assertNotContains (response , "errors field-backend" )
1468+ config .refresh_from_db ()
1469+ self .assertEqual (config .backend , template .backend )
14441470
14451471 def test_device_search (self ):
14461472 d = self ._create_device (name = "admin-search-test" )
@@ -1502,7 +1528,7 @@ def test_default_template_backend(self):
15021528 response = self .client .get (path )
15031529 self .assertContains (response , '<option value="netjsonconfig.OpenWrt" selected' )
15041530
1505- def test_existing_template_backend (self ):
1531+ def test_template_backend_readonly_on_change (self ):
15061532 t = Template .objects .first ()
15071533 t .backend = "netjsonconfig.OpenWisp"
15081534 t .config = {
@@ -1513,7 +1539,34 @@ def test_existing_template_backend(self):
15131539 t .save ()
15141540 path = reverse (f"admin:{ self .app_label } _template_change" , args = [t .pk ])
15151541 response = self .client .get (path )
1516- self .assertContains (response , '<option value="netjsonconfig.OpenWisp" selected' )
1542+ self .assertContains (response , "field-backend" )
1543+ self .assertNotContains (response , 'name="backend"' )
1544+
1545+ def test_template_backend_cannot_be_changed_from_change_form (self ):
1546+ template = self ._create_template ()
1547+ original_backend = template .backend
1548+ path = reverse (f"admin:{ self .app_label } _template_change" , args = [template .pk ])
1549+ params = {
1550+ "name" : "template-backend-unchanged" ,
1551+ "organization" : str (template .organization_id or "" ),
1552+ "type" : template .type ,
1553+ "backend" : "totally.invalid.backend" ,
1554+ "vpn" : str (template .vpn_id or "" ),
1555+ "tags" : "," .join (template .tags .names ()),
1556+ "default_values" : json .dumps (template .default_values or {}),
1557+ "config" : json .dumps (template .config ),
1558+ }
1559+ if template .auto_cert :
1560+ params ["auto_cert" ] = "on"
1561+ if template .default :
1562+ params ["default" ] = "on"
1563+ if template .required :
1564+ params ["required" ] = "on"
1565+ response = self .client .post (path , params )
1566+ self .assertNotContains (response , "errors field-backend" , status_code = 302 )
1567+ template .refresh_from_db ()
1568+ self .assertEqual (template .backend , original_backend )
1569+ self .assertEqual (template .name , "template-backend-unchanged" )
15171570
15181571 def test_preview_variables (self ):
15191572 path = reverse (f"admin:{ self .app_label } _device_preview" )
@@ -1626,6 +1679,39 @@ def test_add_vpn(self):
16261679 response , 'value="openwisp_controller.vpn_backends.OpenVpn" selected'
16271680 )
16281681
1682+ def test_vpn_backend_readonly_on_change (self ):
1683+ vpn = self ._create_vpn ()
1684+ path = reverse (f"admin:{ self .app_label } _vpn_change" , args = [vpn .pk ])
1685+ response = self .client .get (path )
1686+ self .assertContains (response , "field-backend" )
1687+ self .assertNotContains (response , 'name="backend"' )
1688+
1689+ def test_vpn_backend_cannot_be_changed_from_change_form (self ):
1690+ vpn = self ._create_vpn ()
1691+ original_backend = vpn .backend
1692+ path = reverse (f"admin:{ self .app_label } _vpn_change" , args = [vpn .pk ])
1693+ params = {
1694+ "organization" : str (vpn .organization_id or "" ),
1695+ "name" : "vpn-backend-unchanged" ,
1696+ "host" : vpn .host ,
1697+ "key" : vpn .key ,
1698+ "backend" : "totally.invalid.backend" ,
1699+ "ca" : str (vpn .ca_id or "" ),
1700+ "cert" : str (vpn .cert_id or "" ),
1701+ "subnet" : str (vpn .subnet_id or "" ),
1702+ "ip" : str (vpn .ip_id or "" ),
1703+ "webhook_endpoint" : vpn .webhook_endpoint or "" ,
1704+ "auth_token" : vpn .auth_token or "" ,
1705+ "notes" : vpn .notes or "" ,
1706+ "dh" : vpn .dh or "" ,
1707+ "config" : json .dumps (vpn .config ),
1708+ }
1709+ response = self .client .post (path , params )
1710+ self .assertNotContains (response , "errors field-backend" , status_code = 302 )
1711+ vpn .refresh_from_db ()
1712+ self .assertEqual (vpn .backend , original_backend )
1713+ self .assertEqual (vpn .name , "vpn-backend-unchanged" )
1714+
16291715 def test_vpn_clients_deleted (self ):
16301716 def _update_template (templates ):
16311717 params .update (
0 commit comments