From 48d3c1140b6b2dba9dae4f99c1edae8a7bbb7ebc Mon Sep 17 00:00:00 2001 From: Douglas Cerna Date: Thu, 29 Aug 2024 14:16:26 -0600 Subject: [PATCH] Prefetch related models in FPR views --- pyproject.toml | 1 + src/dashboard/src/fpr/forms.py | 22 +- src/dashboard/src/fpr/views.py | 22 +- tests/dashboard/fpr/test_views.py | 326 +++++++++++++++++++----------- 4 files changed, 244 insertions(+), 127 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 34d52fe0ee..86d11bc484 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -64,6 +64,7 @@ module = [ "src.MCPClient.lib.clientScripts.policy_check", "src.MCPClient.lib.clientScripts.transcribe_file", "src.MCPClient.lib.clientScripts.validate_file", + "tests.dashboard.fpr.test_views", "tests.MCPClient.conftest", "tests.MCPClient.test_characterize_file", "tests.MCPClient.test_has_packages", diff --git a/src/dashboard/src/fpr/forms.py b/src/dashboard/src/fpr/forms.py index 39ee6a0f1c..e2e23a2ba6 100644 --- a/src/dashboard/src/fpr/forms.py +++ b/src/dashboard/src/fpr/forms.py @@ -79,8 +79,14 @@ class IDRuleForm(forms.ModelForm): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) # Limit to only enabled formats/commands - self.fields["format"].queryset = fprmodels.FormatVersion.active.all() - self.fields["command"].queryset = fprmodels.IDCommand.active.all() + self.fields[ + "format" + ].queryset = fprmodels.FormatVersion.active.all().prefetch_related( + "format__group" + ) + self.fields[ + "command" + ].queryset = fprmodels.IDCommand.active.all().prefetch_related("tool") class Meta: model = fprmodels.IDRule @@ -110,7 +116,11 @@ def __init__(self, *args, **kwargs): self.fields["command"].initial = self.instance.command.uuid # Show only active format versions in the format dropdown - self.fields["format"].queryset = fprmodels.FormatVersion.active.all() + self.fields[ + "format" + ].queryset = fprmodels.FormatVersion.active.all().prefetch_related( + "format__group" + ) def clean(self): cleaned_data = super().clean() @@ -168,6 +178,12 @@ class FPCommandForm(forms.ModelForm): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) + self.fields[ + "output_format" + ].queryset = fprmodels.FormatVersion.active.all().prefetch_related( + "format__group" + ) + verification_commands = fprmodels.FPCommand.active.filter( command_usage="verification" ) diff --git a/src/dashboard/src/fpr/views.py b/src/dashboard/src/fpr/views.py index 378b9dd583..7b15734baa 100644 --- a/src/dashboard/src/fpr/views.py +++ b/src/dashboard/src/fpr/views.py @@ -317,7 +317,9 @@ def idrule_list(request): "replaces_id" ) ] - idrules = fprmodels.IDRule.objects.exclude(uuid__in=replacing_rules) + idrules = fprmodels.IDRule.objects.exclude( + uuid__in=replacing_rules + ).prefetch_related("format__format__group", "command") return render(request, "fpr/idrule/list.html", context(locals())) @@ -391,7 +393,9 @@ def idcommand_list(request): "replaces_id" ) ] - idcommands = fprmodels.IDCommand.objects.exclude(uuid__in=replacing_commands) + idcommands = fprmodels.IDCommand.objects.exclude( + uuid__in=replacing_commands + ).prefetch_related("tool") return render(request, "fpr/idcommand/list.html", context(locals())) @@ -493,7 +497,11 @@ def fprule_list(request, usage=None): else: opts = {} # Display disabled rules as long as they aren't replaced by another rule - fprules = fprmodels.FPRule.objects.filter(**opts).exclude(uuid__in=replacing_rules) + fprules = ( + fprmodels.FPRule.objects.filter(**opts) + .exclude(uuid__in=replacing_rules) + .prefetch_related("format__format__group", "command") + ) return render(request, "fpr/fprule/list.html", context(locals())) @@ -621,8 +629,10 @@ def fpcommand_list(request, usage=None): "replaces_id" ) ] - fpcommands = fprmodels.FPCommand.objects.filter(**opts).exclude( - uuid__in=replacing_commands + fpcommands = ( + fprmodels.FPCommand.objects.filter(**opts) + .exclude(uuid__in=replacing_commands) + .prefetch_related("tool") ) return render(request, "fpr/fpcommand/list.html", context(locals())) @@ -641,7 +651,7 @@ def fpcommand_edit(request, uuid=None): title = _("Replace command %(name)s") % {"name": fpcommand.description} else: fpcommand = None - title = _("Create format version") + title = _("Create format policy command") if request.method == "POST": form = fprforms.FPCommandForm(request.POST, instance=fpcommand) if form.is_valid(): diff --git a/tests/dashboard/fpr/test_views.py b/tests/dashboard/fpr/test_views.py index 3f18822076..6b246d21fd 100644 --- a/tests/dashboard/fpr/test_views.py +++ b/tests/dashboard/fpr/test_views.py @@ -1,122 +1,129 @@ +import uuid + import pytest from components import helpers -from django.contrib.auth.models import User -from django.test import TestCase +from django.test import Client from django.urls import reverse -from fpr.models import Format -from fpr.models import FormatGroup -from fpr.models import FPCommand -from fpr.models import FPTool -from fpr.models import IDTool - - -class TestViews(TestCase): - def setUp(self): - user = User.objects.create_superuser("demo", "demo@example.com", "demo") - self.client.login(username=user.username, password="demo") - helpers.set_setting("dashboard_uuid", "test-uuid") - - def test_idcommand_create(self): - url = reverse("fpr:idcommand_create") - tool = IDTool.objects.create( - uuid="37f3bd7c-bb24-4899-b7c4-785ff1c764ac", - description="Foobar", - version="v1.2.3", - ) - - resp = self.client.get(url) - self.assertEqual(resp.context["form"].initial["tool"], None) - - resp = self.client.get(url, {"parent": "c80458d9-2b62-40f4-b61c-936bfb72901d"}) - self.assertEqual(resp.context["form"].initial["tool"], None) - - resp = self.client.get(url, {"parent": tool.uuid}) - self.assertEqual(resp.context["form"].initial["tool"], tool) - - def test_fpcommand_create(self): - url = reverse("fpr:fpcommand_create") - tool = FPTool.objects.create( - uuid="37f3bd7c-bb24-4899-b7c4-785ff1c764ac", - description="Foobar", - version="v1.2.3", - ) - - resp = self.client.get(url) - self.assertEqual(resp.context["form"].initial["tool"], None) - - resp = self.client.get(url, {"parent": "d993bdcf-a944-4df8-b960-1b20c14ffe68"}) - self.assertEqual(resp.context["form"].initial["tool"], None) - - resp = self.client.get(url, {"parent": tool.uuid}) - self.assertEqual(resp.context["form"].initial["tool"], tool) - - def test_fpcommand_edit(self): - fpcommand_id = "41112047-7ddf-4bf0-9156-39fe96b32d53" - url = reverse("fpr:fpcommand_edit", args=[fpcommand_id]) - - fpcommand = FPCommand.active.get(uuid=fpcommand_id) - self.assertEqual(fpcommand.description, "Copying file to access directory") - - form_data = { - "verification_command": ["ef3ea000-0c3c-4cae-adc2-aa2a6ccbffce"], - "description": ["new description"], - "tool": ["0efc346e-6373-4799-819d-17cc0f21f827"], - "event_detail_command": [""], - "output_location": [ - "%outputDirectory%%prefix%%fileName%%postfix%%fileExtensionWithDot%" - ], - "command_usage": ["normalization"], - "command": [ - 'cp -R "%inputFile%" "%outputDirectory%%prefix%%fileName%%postfix%%fileExtensionWithDot%"' - ], - "csrfmiddlewaretoken": [ - "k5UUufiJuSOLNOGJYlU2ODow5iKPhOuLc9Q0EmUoIXsQLZ7r5Ede7Pf0pSQEm0lP" - ], - "output_format": ["0ab4cd40-90e7-4d75-b294-498177b3897d"], - "script_type": ["command"], - } - resp = self.client.post(url, follow=True, data=form_data) - self.assertEqual(resp.status_code, 200) - - # Our fpcommand is now expected to be disabled. - fpcommand = FPCommand.objects.get(uuid=fpcommand_id) - self.assertEqual(fpcommand.enabled, False) - - # And replaced by a new fpcommand. - fpcommand = FPCommand.active.get(replaces_id=fpcommand_id) - self.assertEqual(fpcommand.description, "new description") - - def test_fpcommand_delete(self): - fpcommand_id = "0fd7935a-ed0d-4f67-aa25-1b44684f6aca" - url = reverse("fpr:fpcommand_delete", args=[fpcommand_id]) - - self.assertEqual(FPCommand.active.filter(uuid=fpcommand_id).exists(), True) - - resp = self.client.post(url, follow=True, data={"disable": True}) - - self.assertEqual(resp.status_code, 200) - self.assertEqual(FPCommand.active.filter(uuid=fpcommand_id).exists(), False) - - def test_fpcommand_revisions(self): - fpcommand_id = "cb335c49-e6ce-445f-a774-494a6f2300c6" - url = reverse("fpr:revision_list", args=["fpcommand", fpcommand_id]) - fpcommand = FPCommand.active.get(uuid=fpcommand_id) - - resp = self.client.get(url, follow=True) - - # Assert that the revision list shows multiple instances. - self.assertContains(resp, fpcommand.uuid) - self.assertContains(resp, fpcommand.replaces_id) +from fpr import models + + +@pytest.fixture +def dashboard_uuid() -> None: + helpers.set_setting("dashboard_uuid", str(uuid.uuid4())) + + +@pytest.mark.django_db +def test_idcommand_create(dashboard_uuid: None, admin_client: Client) -> None: + url = reverse("fpr:idcommand_create") + tool = models.IDTool.objects.create( + uuid="37f3bd7c-bb24-4899-b7c4-785ff1c764ac", + description="Foobar", + version="v1.2.3", + ) + + resp = admin_client.get(url) + assert resp.context["form"].initial["tool"] is None + + resp = admin_client.get(url, {"parent": str(uuid.uuid4())}) + assert resp.context["form"].initial["tool"] is None + + resp = admin_client.get(url, {"parent": tool.uuid}) + assert resp.context["form"].initial["tool"] == tool + + +@pytest.mark.django_db +def test_fpcommand_create(dashboard_uuid: None, admin_client: Client) -> None: + url = reverse("fpr:fpcommand_create") + tool = models.FPTool.objects.create( + uuid="37f3bd7c-bb24-4899-b7c4-785ff1c764ac", + description="Foobar", + version="v1.2.3", + ) + + resp = admin_client.get(url) + assert resp.context["form"].initial["tool"] is None + + resp = admin_client.get(url, {"parent": str(uuid.uuid4())}) + assert resp.context["form"].initial["tool"] is None + + resp = admin_client.get(url, {"parent": tool.uuid}) + assert resp.context["form"].initial["tool"] == tool + + +@pytest.mark.django_db +def test_fpcommand_edit(dashboard_uuid: None, admin_client: Client) -> None: + fpcommand_id = "41112047-7ddf-4bf0-9156-39fe96b32d53" + url = reverse("fpr:fpcommand_edit", args=[fpcommand_id]) + + fpcommand = models.FPCommand.active.get(uuid=fpcommand_id) + assert fpcommand.description == "Copying file to access directory" + + form_data = { + "verification_command": ["ef3ea000-0c3c-4cae-adc2-aa2a6ccbffce"], + "description": ["new description"], + "tool": ["0efc346e-6373-4799-819d-17cc0f21f827"], + "event_detail_command": [""], + "output_location": [ + "%outputDirectory%%prefix%%fileName%%postfix%%fileExtensionWithDot%" + ], + "command_usage": ["normalization"], + "command": [ + 'cp -R "%inputFile%" "%outputDirectory%%prefix%%fileName%%postfix%%fileExtensionWithDot%"' + ], + "csrfmiddlewaretoken": [ + "k5UUufiJuSOLNOGJYlU2ODow5iKPhOuLc9Q0EmUoIXsQLZ7r5Ede7Pf0pSQEm0lP" + ], + "output_format": ["0ab4cd40-90e7-4d75-b294-498177b3897d"], + "script_type": ["command"], + } + resp = admin_client.post(url, follow=True, data=form_data) + assert resp.status_code == 200 + + # Our fpcommand is now expected to be disabled. + fpcommand = models.FPCommand.objects.get(uuid=fpcommand_id) + assert not fpcommand.enabled + + # And replaced by a new fpcommand. + fpcommand = models.FPCommand.active.get(replaces_id=fpcommand_id) + assert fpcommand.description == "new description" + + +@pytest.mark.django_db +def test_fpcommand_delete(dashboard_uuid: None, admin_client: Client) -> None: + fpcommand_id = "0fd7935a-ed0d-4f67-aa25-1b44684f6aca" + url = reverse("fpr:fpcommand_delete", args=[fpcommand_id]) + + assert models.FPCommand.active.filter(uuid=fpcommand_id).exists() + + resp = admin_client.post(url, follow=True, data={"disable": True}) + + assert resp.status_code == 200 + assert not models.FPCommand.active.filter(uuid=fpcommand_id).exists() + + +@pytest.mark.django_db +def test_fpcommand_revisions(dashboard_uuid: None, admin_client: Client) -> None: + fpcommand_id = "cb335c49-e6ce-445f-a774-494a6f2300c6" + url = reverse("fpr:revision_list", args=["fpcommand", fpcommand_id]) + fpcommand = models.FPCommand.active.get(uuid=fpcommand_id) + + resp = admin_client.get(url, follow=True) + + # Assert that the revision list shows multiple instances. + content = resp.content.decode() + assert str(fpcommand.uuid) in content + assert str(fpcommand.replaces_id) in content @pytest.mark.django_db -def test_format_create_creates_format(admin_client): - helpers.set_setting("dashboard_uuid", "test-uuid") +def test_format_create_creates_format( + dashboard_uuid: None, admin_client: Client +) -> None: # Add a new format to the Unknown group. - unknown_group = FormatGroup.objects.get(description="Unknown") + unknown_group = models.FormatGroup.objects.get(description="Unknown") format_description = "My test format" - assert Format.objects.filter(description=format_description).count() == 0 + assert models.Format.objects.filter(description=format_description).count() == 0 response = admin_client.post( reverse("fpr:format_create"), @@ -129,7 +136,7 @@ def test_format_create_creates_format(admin_client): assert "Saved" in content assert "Format My test format" in content assert ( - Format.objects.filter( + models.Format.objects.filter( description=format_description, group=unknown_group ).count() == 1 @@ -137,20 +144,19 @@ def test_format_create_creates_format(admin_client): @pytest.mark.django_db -def test_format_edit_updates_format(admin_client): - helpers.set_setting("dashboard_uuid", "test-uuid") +def test_format_edit_updates_format(dashboard_uuid: None, admin_client: Client) -> None: # Get details of the Matroska format from the Video group. - video_group = FormatGroup.objects.get(description="Video") - format = Format.objects.get(description="Matroska", group=video_group) + video_group = models.FormatGroup.objects.get(description="Video") + format = models.Format.objects.get(description="Matroska", group=video_group) format_uuid = format.uuid format_slug = format.slug # Update the group and description of the Matroska format. - unknown_group = FormatGroup.objects.get(description="Unknown") + unknown_group = models.FormatGroup.objects.get(description="Unknown") new_format_description = "My matroska format" assert ( - Format.objects.filter( + models.Format.objects.filter( description=new_format_description, group=unknown_group ).count() == 0 @@ -167,7 +173,7 @@ def test_format_edit_updates_format(admin_client): assert "Saved" in content assert "Format My matroska format" in content assert ( - Format.objects.filter( + models.Format.objects.filter( uuid=format_uuid, slug=format_slug, description=new_format_description, @@ -175,3 +181,87 @@ def test_format_edit_updates_format(admin_client): ).count() == 1 ) + + +@pytest.mark.django_db +def test_idrule_create(dashboard_uuid: None, admin_client: Client) -> None: + url = reverse("fpr:idrule_create") + + resp = admin_client.get(url) + + assert resp.context["form"].initial == {} + assert "Create identification rule" in resp.content.decode() + + format_version = models.FormatVersion.objects.create( + format=models.Format.objects.create( + group=models.FormatGroup.objects.create(description="Group"), + description="Format", + ), + description="Format version", + ) + command = models.IDCommand.objects.create( + tool=models.IDTool.objects.create(description="Tool") + ) + command_output = ".ppt" + + resp = admin_client.post( + url, + { + "format": format_version.uuid, + "command": command.uuid, + "command_output": command_output, + }, + follow=True, + ) + + assert "Saved." in resp.content.decode() + assert ( + models.IDRule.objects.filter( + format=format_version.uuid, + command=command.uuid, + command_output=command_output, + ).count() + == 1 + ) + + +@pytest.mark.django_db +def test_fprule_create(dashboard_uuid: None, admin_client: Client) -> None: + url = reverse("fpr:fprule_create") + + resp = admin_client.get(url) + + assert resp.context["form"].initial == {} + assert "Create format policy rule" in resp.content.decode() + + purpose = models.FPRule.CHARACTERIZATION + format_version = models.FormatVersion.objects.create( + format=models.Format.objects.create( + group=models.FormatGroup.objects.create(description="Group"), + description="Format", + ), + description="Format version", + ) + command = models.FPCommand.objects.create( + tool=models.FPTool.objects.create(description="Tool") + ) + + resp = admin_client.post( + url, + { + "f-purpose": purpose, + "f-format": format_version.uuid, + "f-command": command.uuid, + }, + follow=True, + ) + + assert "Saved." in resp.content.decode() + assert ( + models.FPRule.objects.filter( + purpose=purpose, + format=format_version.uuid, + command=command.uuid, + ).count() + == 1 + )