Closes #21862: Stabilize ScriptModule tests and reduce CI noise (#21867)

This commit is contained in:
Martin Hauser
2026-04-09 16:33:55 +02:00
committed by GitHub
parent cb7e97c7f7
commit a93aae12fa
2 changed files with 40 additions and 9 deletions

View File

@@ -1,5 +1,6 @@
import datetime
import hashlib
import io
from unittest.mock import MagicMock, patch
from django.contrib.contenttypes.models import ContentType
@@ -1013,10 +1014,14 @@ class ScriptTest(APITestCase):
@classmethod
def setUpTestData(cls):
module = ScriptModule.objects.create(
file_root=ManagedFileRootPathChoices.SCRIPTS,
file_path='script.py',
)
# Avoid trying to import a non-existent on-disk module during setup.
# This test creates the Script row explicitly and monkey-patches
# Script.python_class below.
with patch.object(ScriptModule, 'sync_classes'):
module = ScriptModule.objects.create(
file_root=ManagedFileRootPathChoices.SCRIPTS,
file_path='script.py',
)
script = Script.objects.create(
module=module,
name='Test script',
@@ -1419,9 +1424,20 @@ class ScriptModuleTest(APITestCase):
upload_file = SimpleUploadedFile('test_upload.py', script_content, content_type='text/plain')
mock_storage = MagicMock()
mock_storage.save.return_value = 'test_upload.py'
with patch('extras.api.serializers_.scripts.storages') as mock_storages:
mock_storages.create_storage.return_value = mock_storage
mock_storages.backends = {'scripts': {}}
# The upload serializer writes the file via storages.create_storage(...).save(),
# but ScriptModule.sync_classes() later imports it via storages["scripts"].open().
# Provide both behaviors so the uploaded module can actually be loaded during the test.
mock_storage.open.side_effect = lambda *args, **kwargs: io.BytesIO(script_content)
with (
patch('extras.api.serializers_.scripts.storages') as mock_serializer_storages,
patch('extras.models.mixins.storages') as mock_module_storages,
):
mock_serializer_storages.create_storage.return_value = mock_storage
mock_serializer_storages.backends = {'scripts': {}}
mock_module_storages.__getitem__.return_value = mock_storage
response = self.client.post(
self.url,
{'file': upload_file},
@@ -1432,6 +1448,7 @@ class ScriptModuleTest(APITestCase):
self.assertEqual(response.data['file_path'], 'test_upload.py')
mock_storage.save.assert_called_once()
self.assertTrue(ScriptModule.objects.filter(file_path='test_upload.py').exists())
self.assertTrue(Script.objects.filter(module__file_path='test_upload.py', name='TestScript').exists())
def test_upload_script_module_without_file_fails(self):
self.add_permissions('extras.add_scriptmodule', 'core.add_managedfile')

View File

@@ -924,7 +924,14 @@ class ScriptValidationErrorTest(TestCase):
@classmethod
def setUpTestData(cls):
module = ScriptModule.objects.create(file_root=ManagedFileRootPathChoices.SCRIPTS, file_path='test_script.py')
# Avoid trying to import a non-existent on-disk module during setup.
# This test creates the Script row explicitly and monkey-patches
# Script.python_class below.
with patch.object(ScriptModule, 'sync_classes'):
module = ScriptModule.objects.create(
file_root=ManagedFileRootPathChoices.SCRIPTS,
file_path='test_script.py',
)
cls.script = Script.objects.create(module=module, name='Test script', is_executable=True)
def setUp(self):
@@ -986,7 +993,14 @@ class ScriptDefaultValuesTest(TestCase):
@classmethod
def setUpTestData(cls):
module = ScriptModule.objects.create(file_root=ManagedFileRootPathChoices.SCRIPTS, file_path='test_script.py')
# Avoid trying to import a non-existent on-disk module during setup.
# This test creates the Script row explicitly and monkey-patches
# Script.python_class below.
with patch.object(ScriptModule, 'sync_classes'):
module = ScriptModule.objects.create(
file_root=ManagedFileRootPathChoices.SCRIPTS,
file_path='test_script.py',
)
cls.script = Script.objects.create(module=module, name='Test script', is_executable=True)
def setUp(self):