From c598d33565a4afde580ef156ec59b1d16d1a4c49 Mon Sep 17 00:00:00 2001 From: Lautaro Mazzitelli Date: Wed, 25 Oct 2023 12:53:44 +0200 Subject: [PATCH] feat: Script checks search --- tests/munki/test_script_check_views.py | 31 +++++++++++++++++-- zentral/contrib/munki/forms.py | 28 +++++++++++++++++ .../templates/munki/scriptcheck_list.html | 20 +++++++----- zentral/contrib/munki/views.py | 18 +++++++++-- 4 files changed, 86 insertions(+), 11 deletions(-) diff --git a/tests/munki/test_script_check_views.py b/tests/munki/test_script_check_views.py index 1665cc317c..6d7a528f5d 100644 --- a/tests/munki/test_script_check_views.py +++ b/tests/munki/test_script_check_views.py @@ -65,13 +65,40 @@ def test_script_checks_no_create_link(self): self.assertNotContains(response, reverse("munki:create_script_check")) def test_script_checks_with_create_link(self): - sc = force_script_check() + sc_one = force_script_check() + sc_two = force_script_check() self._login("munki.view_scriptcheck", "munki.add_scriptcheck") response = self.client.get(reverse("munki:script_checks")) self.assertEqual(response.status_code, 200) self.assertTemplateUsed(response, "munki/scriptcheck_list.html") - self.assertContains(response, sc.compliance_check.name) self.assertContains(response, reverse("munki:create_script_check")) + self.assertContains(response, sc_one.compliance_check.name) + self.assertContains(response, sc_two.compliance_check.name) + self.assertContains(response, "Script checks (2)") + + def test_script_check_search(self): + sc_one = force_script_check() + sc_two = force_script_check(type=ScriptCheck.Type.ZSH_BOOL) + self._login("munki.view_scriptcheck", "munki.add_scriptcheck") + + response = self.client.get(reverse("munki:script_checks"), {"name": "test"}) + self.assertEqual(response.status_code, 200) + self.assertTemplateUsed(response, "munki/scriptcheck_list.html") + self.assertContains(response, "Script checks (0)") + + response = self.client.get(reverse("munki:script_checks"), + {"name": sc_one.compliance_check.name}) + self.assertEqual(response.status_code, 200) + self.assertTemplateUsed(response, "munki/scriptcheck_list.html") + self.assertContains(response, sc_one.compliance_check.name) + self.assertContains(response, "Script check (1)") + + response = self.client.get(reverse("munki:script_checks"), + {"type": ScriptCheck.Type.ZSH_BOOL}) + self.assertEqual(response.status_code, 200) + self.assertTemplateUsed(response, "munki/scriptcheck_list.html") + self.assertContains(response, sc_two.compliance_check.name) + self.assertContains(response, "Script check (1)") # create diff --git a/zentral/contrib/munki/forms.py b/zentral/contrib/munki/forms.py index fd3c805318..01630883fe 100644 --- a/zentral/contrib/munki/forms.py +++ b/zentral/contrib/munki/forms.py @@ -38,6 +38,34 @@ def __init__(self, *args, **kwargs): self.fields["configuration"].widget = forms.HiddenInput() +class ScriptCheckSearchForm(forms.Form): + template_name = "django/forms/search.html" + + name = forms.CharField( + label='Name', + required=False, + widget=forms.TextInput( + attrs={"autofocus": True, + "size": 32, + } + ) + ) + type = forms.ChoiceField( + choices=[('', '...')] + ScriptCheck.Type.choices, + required=False, + ) + + def get_queryset(self): + qs = ScriptCheck.objects.all() + name = self.cleaned_data.get("name") + if name: + qs = qs.filter(compliance_check__name__icontains=name) + type = self.cleaned_data.get("type") + if type: + qs = qs.filter(type=type) + return qs + + class ScriptCheckForm(forms.ModelForm): class Meta: model = ScriptCheck diff --git a/zentral/contrib/munki/templates/munki/scriptcheck_list.html b/zentral/contrib/munki/templates/munki/scriptcheck_list.html index 642586f99d..34abf1a436 100644 --- a/zentral/contrib/munki/templates/munki/scriptcheck_list.html +++ b/zentral/contrib/munki/templates/munki/scriptcheck_list.html @@ -13,11 +13,21 @@

Script check{{ paginator.count|pluralize }} ({{ paginator.count
{% if perms.munki.add_scriptcheck %} {% url 'munki:create_script_check' as url %} - {% button 'CREATE' url "Create new Configuration" %} + {% button 'CREATE' url "Create new Script check" %} {% endif %}
+
+
+ + {{ form }} + + +
+ {% if object_list %} {% pagination next_url previous_url %} @@ -52,12 +62,8 @@

Script check{{ paginator.count|pluralize }} ({{ paginator.count {% pagination next_url previous_url %} {% else %} - {% if perms.munki.add_scriptcheck %} - {% url 'munki:create_script_check' as link %} - {% no_entities 'Script checks' link %} - {% else %} - {% no_entities 'Script checks' %} - {% endif %} + {% url 'munki:script_checks' as empty_results_url %} + {% empty_results empty_results_url %} {% endif %} {% endblock %} diff --git a/zentral/contrib/munki/views.py b/zentral/contrib/munki/views.py index 615ec9dd65..aecddb029e 100644 --- a/zentral/contrib/munki/views.py +++ b/zentral/contrib/munki/views.py @@ -17,7 +17,8 @@ from zentral.utils.text import encode_args from zentral.utils.views import DeleteViewWithAudit, UserPaginationListView from .compliance_checks import MunkiScriptCheck -from .forms import CreateInstallProbeForm, ConfigurationForm, EnrollmentForm, ScriptCheckForm, UpdateInstallProbeForm +from .forms import (CreateInstallProbeForm, ConfigurationForm, EnrollmentForm, ScriptCheckForm, + ScriptCheckSearchForm, UpdateInstallProbeForm) from .models import Configuration, Enrollment, PrincipalUserDetectionSource, ScriptCheck from .terraform import iter_resources @@ -204,7 +205,20 @@ def post(self, request, *args, **kwargs): class ScriptCheckListView(PermissionRequiredMixin, UserPaginationListView): permission_required = "munki.view_scriptcheck" - model = ScriptCheck + template_name = "munki/scriptcheck_list.html" + + def dispatch(self, request, *args, **kwargs): + self.form = ScriptCheckSearchForm(self.request.GET) + self.form.is_valid() + return super().dispatch(request, *args, **kwargs) + + def get_queryset(self): + return self.form.get_queryset() + + def get_context_data(self, **kwargs): + ctx = super().get_context_data(**kwargs) + ctx["form"] = self.form + return ctx class CreateScriptCheckView(PermissionRequiredMixin, TemplateView):