55from django .core .exceptions import ValidationError
66from django .http .response import Http404
77from django .test import TestCase
8- from django .urls import reverse
8+ from django .urls import reverse , reverse_lazy
99from swapper import load_model
1010
1111from openwisp_utils .tests import capture_any_output , catch_signal
3838Organization = load_model ("openwisp_users" , "Organization" )
3939
4040
41- class TestController (CreateConfigTemplateMixin , TestVpnX509Mixin , TestCase ):
42- """
43- tests for config.controller
44- """
45-
46- def setUp (self ):
47- self .register_url = reverse ("controller:device_register" )
41+ class TestRegistrationMixin :
42+ register_url = reverse_lazy ("controller:device_register" )
4843
4944 def _create_org (self , shared_secret = TEST_ORG_SHARED_SECRET , ** kwargs ):
5045 org = super ()._create_org (** kwargs )
@@ -53,6 +48,27 @@ def _create_org(self, shared_secret=TEST_ORG_SHARED_SECRET, **kwargs):
5348 )
5449 return org
5550
51+ def _get_reregistration_payload (self , device , ** kwargs ):
52+ data = {
53+ "secret" : str (device .organization .config_settings .shared_secret ),
54+ "key" : TEST_CONSISTENT_KEY ,
55+ "mac_address" : device .mac_address ,
56+ "backend" : "netjsonconfig.OpenWrt" ,
57+ "model" : "TP-Link TL-WDR4300 v2" ,
58+ "os" : "OpenWrt 18.06-SNAPSHOT r7312-e60be11330" ,
59+ "system" : "Atheros AR9344 rev 3" ,
60+ }
61+ data .update (** kwargs )
62+ return data
63+
64+
65+ class TestController (
66+ TestRegistrationMixin , CreateConfigTemplateMixin , TestVpnX509Mixin , TestCase
67+ ):
68+ """
69+ tests for config.controller
70+ """
71+
5672 def _check_header (self , response ):
5773 self .assertEqual (response ["X-Openwisp-Controller" ], "true" )
5874
@@ -820,6 +836,83 @@ def test_device_registration_update_hw_info_no_config(self):
820836 self .assertEqual (d .system , params ["system" ])
821837 self .assertEqual (d .model , params ["model" ])
822838
839+ @patch .object (Device , "skip_push_update_on_save" )
840+ def test_device_registration_update_hostname (self , mocked_method ):
841+ """
842+ Test that hostname is updated when the name in payload
843+ is not the MAC address stored in OpenWISP
844+ """
845+ device = self ._create_device_config (
846+ device_opts = {
847+ "name" : "old-hostname" ,
848+ "mac_address" : TEST_MACADDR ,
849+ "key" : TEST_CONSISTENT_KEY ,
850+ }
851+ )
852+ params = self ._get_reregistration_payload (
853+ device = device ,
854+ name = "new-custom-hostname" ,
855+ )
856+ self .assertNotEqual (device .name , params ["name" ])
857+ response = self .client .post (self .register_url , params )
858+ self .assertEqual (response .status_code , 201 )
859+ device .refresh_from_db ()
860+ self .assertEqual (device .name , "new-custom-hostname" )
861+ mocked_method .assert_called_once ()
862+
863+ @patch .object (Device , "skip_push_update_on_save" )
864+ def test_device_registration_hostname_not_updated_when_mac_address (
865+ self , mocked_method
866+ ):
867+ """
868+ Test that hostname is not updated when the name in payload
869+ equals the MAC address (agents send MAC address as hostname
870+ when hostname is OpenWrt or if default_hostname is set to *)
871+ """
872+ device = self ._create_device_config (
873+ device_opts = {
874+ "name" : "meaningful-hostname" ,
875+ "key" : TEST_CONSISTENT_KEY ,
876+ }
877+ )
878+ params = self ._get_reregistration_payload (
879+ device = device ,
880+ name = TEST_MACADDR ,
881+ )
882+ response = self .client .post (self .register_url , params )
883+ self .assertEqual (response .status_code , 201 )
884+ device .refresh_from_db ()
885+ self .assertEqual (device .name , "meaningful-hostname" )
886+ mocked_method .assert_not_called ()
887+
888+ @patch .object (Device , "skip_push_update_on_save" )
889+ def test_device_registration_hostname_comparison_case_insensitive (
890+ self , mocked_method
891+ ):
892+ """
893+ Test that MAC address comparison is case-insensitive and works
894+ with different formats (colons, dashes, no separators)
895+ """
896+ mac_address = "00:11:22:33:aa:BB"
897+ name = mac_address .replace (":" , "-" )
898+ device = self ._create_device_config (
899+ device_opts = {
900+ "mac_address" : mac_address ,
901+ "name" : name ,
902+ "key" : TEST_CONSISTENT_KEY ,
903+ }
904+ )
905+ params = self ._get_reregistration_payload (
906+ device = device ,
907+ name = "00-11-22-33-aa-bb" ,
908+ )
909+ response = self .client .post (self .register_url , params )
910+ self .assertEqual (response .status_code , 201 )
911+ device .refresh_from_db ()
912+ # Hostname should not be changed
913+ self .assertEqual (device .name , name )
914+ mocked_method .assert_not_called ()
915+
823916 def test_device_report_status_running (self ):
824917 """
825918 maintained for backward compatibility
0 commit comments