|
9 | 9 |
|
10 | 10 | from .. import settings as app_settings |
11 | 11 | from ..signals import group_templates_changed |
12 | | -from .utils import CreateDeviceGroupMixin, CreateTemplateMixin |
| 12 | +from .utils import CreateDeviceGroupMixin, CreateDeviceMixin, CreateTemplateMixin |
13 | 13 |
|
| 14 | +Config = load_model("config", "Config") |
| 15 | +Device = load_model("config", "Device") |
14 | 16 | DeviceGroup = load_model("config", "DeviceGroup") |
| 17 | +Template = load_model("config", "Template") |
15 | 18 |
|
16 | 19 |
|
17 | | -class TestDeviceGroup(CreateDeviceGroupMixin, CreateTemplateMixin, TestCase): |
| 20 | +class TestDeviceGroup( |
| 21 | + CreateDeviceMixin, CreateDeviceGroupMixin, CreateTemplateMixin, TestCase |
| 22 | +): |
18 | 23 | def test_device_group(self): |
19 | 24 | self._create_device_group( |
20 | 25 | meta_data={"captive_portal_url": "https//example.com"} |
@@ -61,3 +66,51 @@ def test_device_group_signals(self): |
61 | 66 | raw=False, |
62 | 67 | using="default", |
63 | 68 | ) |
| 69 | + |
| 70 | + def test_manage_devices_group_templates_no_early_termination(self): |
| 71 | + """ |
| 72 | + Regression test: when the first device in the batch has no config |
| 73 | + (because its group has no templates), the loop must continue and |
| 74 | + still apply group templates to the second device. |
| 75 | + """ |
| 76 | + org = self._get_org() |
| 77 | + t1 = self._create_template(name="t1") |
| 78 | + # group_with_templates has a template; group_without does not |
| 79 | + group_with_templates = self._create_device_group( |
| 80 | + name="group-with-tpl", organization=org |
| 81 | + ) |
| 82 | + group_with_templates.templates.add(t1) |
| 83 | + group_without_templates = self._create_device_group( |
| 84 | + name="group-without-tpl", organization=org |
| 85 | + ) |
| 86 | + # device1: belongs to a group without templates → no config created |
| 87 | + device1 = self._create_device( |
| 88 | + name="device-no-config", |
| 89 | + organization=org, |
| 90 | + group=group_without_templates, |
| 91 | + mac_address="00:00:00:00:00:01", |
| 92 | + ) |
| 93 | + self.assertFalse(hasattr(device1, "config")) |
| 94 | + # device2: has a config object |
| 95 | + device2 = self._create_device( |
| 96 | + name="device-with-config", |
| 97 | + organization=org, |
| 98 | + mac_address="00:00:00:00:00:02", |
| 99 | + ) |
| 100 | + Config.objects.create( |
| 101 | + device=device2, |
| 102 | + backend="netjsonconfig.OpenWrt", |
| 103 | + ) |
| 104 | + device2.refresh_from_db() |
| 105 | + self.assertTrue(hasattr(device2, "config")) |
| 106 | + self.assertEqual(device2.config.templates.count(), 0) |
| 107 | + # Call manage_devices_group_templates with device1 (no config) first, |
| 108 | + # then device2 (has config). device1 should be skipped, device2 must |
| 109 | + # still get group_with_templates's template applied. |
| 110 | + Device.manage_devices_group_templates( |
| 111 | + device_ids=[device1.pk, device2.pk], |
| 112 | + old_group_ids=[None, None], |
| 113 | + group_id=group_with_templates.pk, |
| 114 | + ) |
| 115 | + device2.refresh_from_db() |
| 116 | + self.assertIn(t1, device2.config.templates.all()) |
0 commit comments