From c0def7695efe72af84ca2b1f65f0600417f92318 Mon Sep 17 00:00:00 2001 From: Om Date: Wed, 8 Jul 2026 02:27:57 +0530 Subject: [PATCH] [fix] Reassign shared default templates on org change #1334 Fixes #1334 Signed-off-by: Om --- openwisp_controller/config/api/serializers.py | 4 +++ openwisp_controller/config/tests/test_api.py | 29 +++++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/openwisp_controller/config/api/serializers.py b/openwisp_controller/config/api/serializers.py index d74ca28b9..64e167867 100644 --- a/openwisp_controller/config/api/serializers.py +++ b/openwisp_controller/config/api/serializers.py @@ -341,6 +341,10 @@ def update(self, instance, validated_data): pk_set=None, raw_data=raw_data_for_signal_handlers, ) + # re-assign the default templates of the new organization + # (including shared defaults), mirroring the behavior applied + # when a device is first registered + instance.config.add_default_templates() return super().update(instance, validated_data) diff --git a/openwisp_controller/config/tests/test_api.py b/openwisp_controller/config/tests/test_api.py index dbe9f94d5..f8603f6fe 100644 --- a/openwisp_controller/config/tests/test_api.py +++ b/openwisp_controller/config/tests/test_api.py @@ -541,6 +541,35 @@ def test_device_change_organization_required_templates(self): self.assertEqual(config.templates.count(), 1) self.assertEqual(config.templates.first(), org2_template) + def test_device_change_organization_default_templates(self): + org1 = self._create_org(name="org1") + org2 = self._create_org(name="org2") + shared_default = self._create_template( + name="shared-default", organization=None, default=True + ) + org1_default = self._create_template( + name="org1-default", organization=org1, default=True + ) + org2_default = self._create_template( + name="org2-default", organization=org2, default=True + ) + device = self._create_device(organization=org1) + config = self._create_config(device=device) + # on registration the device receives the shared default and the + # defaults of its own organization + self.assertEqual(set(config.templates.all()), {shared_default, org1_default}) + + path = reverse("config_api:device_detail", args=[device.pk]) + data = {"organization": org2.pk} + response = self.client.patch(path, data=data, content_type="application/json") + self.assertEqual(response.status_code, 200) + device.refresh_from_db() + config.refresh_from_db() + self.assertEqual(device.organization, org2) + # after the org change the shared default and the new organization's + # default are assigned, the previous organization's default is removed + self.assertEqual(set(config.templates.all()), {shared_default, org2_default}) + def test_device_patch_api(self): d1 = self._create_device(name="test-device") path = reverse("config_api:device_detail", args=[d1.pk])