Skip to content

Commit 66d3cf9

Browse files
committed
[chores] Refactoring in test cases and model checks
Modified checks in model for better readability. Choices labels are now being shown in browseable API form using `COMMAND_CHOICES`. `test_available_commands` is modified to check using browseable api form instead of serializer. Also, added additional test case for Connection model. Signed-off-by: DragnEmperor <dragnemperor@gmail.com>
1 parent 9ca3710 commit 66d3cf9

4 files changed

Lines changed: 35 additions & 29 deletions

File tree

openwisp_controller/connection/api/serializers.py

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
from openwisp_utils.api.serializers import ValidatedModelSerializer
66

77
from ...serializers import BaseSerializer
8+
from ..commands import COMMAND_CHOICES
89

910
Command = load_model('connection', 'Command')
1011
DeviceConnection = load_model('connection', 'DeviceConnection')
@@ -34,17 +35,18 @@ class CommandSerializer(ValidatedDeviceFieldSerializer):
3435
def __init__(self, *args, **kwargs):
3536
super().__init__(*args, **kwargs)
3637
# show only connections and command types available for the device
37-
if (
38-
device := Device.objects.filter(pk=self.context.get('device_id'))
39-
.only('organization_id', 'id')
40-
.first()
41-
):
42-
self.fields['connection'].queryset = DeviceConnection.objects.filter(
43-
device=device
44-
)
45-
self.fields['type'].choices = Command.get_org_choices(
46-
device.organization_id
47-
)
38+
if device_id := self.context.get('device_id'):
39+
self.fields['connection'].queryset = self.fields[
40+
'connection'
41+
].queryset.filter(device_id=device_id)
42+
device = Device.objects.only('organization_id', 'id').get(pk=device_id)
43+
# filter command types based on the device's organization
44+
allowed_commands = Command.get_org_choices(device.organization_id)
45+
# this translates the commands to their labels
46+
commands_map = dict(COMMAND_CHOICES)
47+
self.fields['type'].choices = [
48+
(i, commands_map[i]) for i in commands_map if i in allowed_commands
49+
]
4850

4951
def to_representation(self, instance):
5052
repr = super().to_representation(instance)

openwisp_controller/connection/base/models.py

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -467,12 +467,7 @@ def clean(self):
467467

468468
def _verify_connection(self):
469469
"""Raises validation error if device has no connection and credentials."""
470-
DeviceConnection = load_model('connection', 'DeviceConnection')
471-
472-
if not DeviceConnection.objects.filter(
473-
device=self.device,
474-
credentials__isnull=False,
475-
).exists():
470+
if self.device and not self.device.deviceconnection_set.exists():
476471
raise ValidationError({'device': _('Device has no credentials assigned.')})
477472

478473
def _verify_command_type_allowed(self):

openwisp_controller/connection/tests/test_api.py

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
from rest_framework.exceptions import ErrorDetail
1111
from swapper import load_model
1212

13-
from openwisp_controller.connection.api.serializers import CommandSerializer
1413
from openwisp_controller.tests.utils import TestAdminMixin
1514
from openwisp_users.tests.test_api import AuthenticationMixin
1615

@@ -178,12 +177,6 @@ def test_command_attributes(self, payload):
178177

179178
# for ensuring that only related connections are shown
180179
def test_available_connections(self):
181-
url = self._get_path('device_command_list', self.device_id)
182-
response = self.client.get(url)
183-
serializer = CommandSerializer(
184-
instance=self.device_conn.device,
185-
context={'device_id': self.device_id, 'request': response.wsgi_request},
186-
)
187180
device = self._create_device(
188181
name='default.test.device2', mac_address='12:23:34:45:56:67'
189182
)
@@ -192,11 +185,11 @@ def test_available_connections(self):
192185
device_conn2 = self._create_device_connection(
193186
device=device, credentials=credentials_2
194187
)
195-
connections = serializer.fields['connection']
196-
queryset = list(connections.get_queryset().values_list('id', flat=True))
197-
queryset = [str(i) for i in queryset]
198-
self.assertIn(str(self.device_conn.id), queryset)
199-
self.assertNotIn(device_conn2.id, queryset)
188+
url = self._get_path('device_command_list', self.device_id)
189+
response = self.client.get(url, {'format': 'api'})
190+
self.assertEqual(response.status_code, 200)
191+
self.assertContains(response, str(self.device_conn.id))
192+
self.assertNotContains(response, device_conn2.id)
200193

201194
def test_command_details_api(self):
202195
command_obj = self._create_command(device_conn=self.device_conn)

openwisp_controller/connection/tests/test_models.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -563,6 +563,22 @@ def test_command_validation(self):
563563
],
564564
)
565565

566+
with self.subTest('Test command creation without device connection'):
567+
device = self._create_device(
568+
name='default.test.device2', mac_address='11:22:33:44:55:66'
569+
)
570+
new_command = Command(
571+
device=device, type='custom', input={'command': 'echo test'}
572+
)
573+
with self.assertRaises(ValidationError) as context_manager:
574+
new_command.full_clean()
575+
exception = context_manager.exception
576+
self.assertIn('device', exception.message_dict)
577+
self.assertEqual(
578+
exception.message_dict['device'],
579+
['Device has no credentials assigned.'],
580+
)
581+
566582
@tag('skip_prod')
567583
def test_enabled_command(self):
568584
self.assertEqual(

0 commit comments

Comments
 (0)