From 2e0ce850fb5a952b98b28d62570433e8da911a58 Mon Sep 17 00:00:00 2001 From: Adrienne Stilp Date: Thu, 19 Dec 2024 15:34:00 -0800 Subject: [PATCH] Add filtering to IgnoredManagedGroupMembership list view --- anvil_consortium_manager/auditor/filters.py | 12 ++ .../auditor/tests/test_views.py | 113 ++++++++++++++++++ anvil_consortium_manager/auditor/views.py | 9 +- .../ignoredmanagedgroupmembership_list.html | 6 + 4 files changed, 137 insertions(+), 3 deletions(-) create mode 100644 anvil_consortium_manager/auditor/filters.py diff --git a/anvil_consortium_manager/auditor/filters.py b/anvil_consortium_manager/auditor/filters.py new file mode 100644 index 00000000..30992a0b --- /dev/null +++ b/anvil_consortium_manager/auditor/filters.py @@ -0,0 +1,12 @@ +from django_filters import FilterSet + +from anvil_consortium_manager.forms import FilterForm + +from . import models + + +class IgnoredManagedGroupMembershipFilter(FilterSet): + class Meta: + model = models.IgnoredManagedGroupMembership + fields = {"group__name": ["icontains"], "ignored_email": ["icontains"]} + form = FilterForm diff --git a/anvil_consortium_manager/auditor/tests/test_views.py b/anvil_consortium_manager/auditor/tests/test_views.py index cd4db9d7..c331b3e6 100644 --- a/anvil_consortium_manager/auditor/tests/test_views.py +++ b/anvil_consortium_manager/auditor/tests/test_views.py @@ -1669,6 +1669,119 @@ def test_view_with_two_objects(self): self.assertIn("table", response.context_data) self.assertEqual(len(response.context_data["table"].rows), 2) + def test_view_with_filter_group_name_return_no_object(self): + factories.IgnoredManagedGroupMembershipFactory.create(group__name="foo") + factories.IgnoredManagedGroupMembershipFactory.create(group__name="bar") + self.client.force_login(self.user) + response = self.client.get(self.get_url(), {"group__name__icontains": "abc"}) + self.assertEqual(response.status_code, 200) + self.assertIn("table", response.context_data) + self.assertEqual(len(response.context_data["table"].rows), 0) + + def test_view_with_filter_group_name_returns_one_object_exact(self): + instance = factories.IgnoredManagedGroupMembershipFactory.create(group__name="foo") + factories.IgnoredManagedGroupMembershipFactory.create(group__name="bar") + self.client.force_login(self.user) + response = self.client.get(self.get_url(), {"group__name__icontains": "foo"}) + self.assertEqual(response.status_code, 200) + self.assertIn("table", response.context_data) + self.assertEqual(len(response.context_data["table"].rows), 1) + self.assertIn(instance, response.context_data["table"].data) + + def test_view_with_filter_group_name_returns_one_object_case_insensitive(self): + instance = factories.IgnoredManagedGroupMembershipFactory.create(group__name="Foo") + factories.IgnoredManagedGroupMembershipFactory.create(group__name="bar") + self.client.force_login(self.user) + response = self.client.get(self.get_url(), {"group__name__icontains": "foo"}) + self.assertEqual(response.status_code, 200) + self.assertIn("table", response.context_data) + self.assertEqual(len(response.context_data["table"].rows), 1) + self.assertIn(instance, response.context_data["table"].data) + + def test_view_with_filter_group_name_returns_one_object_case_contains(self): + instance = factories.IgnoredManagedGroupMembershipFactory.create(group__name="foo") + factories.IgnoredManagedGroupMembershipFactory.create(group__name="bar") + self.client.force_login(self.user) + response = self.client.get(self.get_url(), {"group__name__icontains": "oo"}) + self.assertEqual(response.status_code, 200) + self.assertIn("table", response.context_data) + self.assertEqual(len(response.context_data["table"].rows), 1) + self.assertIn(instance, response.context_data["table"].data) + + def test_view_with_filter_group_name_returns_multiple_objects(self): + instance_1 = factories.IgnoredManagedGroupMembershipFactory.create(group__name="group1") + instance_2 = factories.IgnoredManagedGroupMembershipFactory.create(group__name="group2") + self.client.force_login(self.user) + response = self.client.get(self.get_url(), {"group__name__icontains": "group"}) + self.assertEqual(response.status_code, 200) + self.assertIn("table", response.context_data) + self.assertEqual(len(response.context_data["table"].rows), 2) + self.assertIn(instance_1, response.context_data["table"].data) + self.assertIn(instance_2, response.context_data["table"].data) + + def test_view_with_filter_email_return_no_object(self): + factories.IgnoredManagedGroupMembershipFactory.create(ignored_email="foo@test.com") + factories.IgnoredManagedGroupMembershipFactory.create(ignored_email="bar") + self.client.force_login(self.user) + response = self.client.get(self.get_url(), {"ignored_email__icontains": "abc"}) + self.assertEqual(response.status_code, 200) + self.assertIn("table", response.context_data) + self.assertEqual(len(response.context_data["table"].rows), 0) + + def test_view_with_filter_email_returns_one_object_exact(self): + instance = factories.IgnoredManagedGroupMembershipFactory.create(ignored_email="foo@test.com") + factories.IgnoredManagedGroupMembershipFactory.create(ignored_email="bar@test.com") + self.client.force_login(self.user) + response = self.client.get(self.get_url(), {"ignored_email__icontains": "foo@test.com"}) + self.assertEqual(response.status_code, 200) + self.assertIn("table", response.context_data) + self.assertEqual(len(response.context_data["table"].rows), 1) + self.assertIn(instance, response.context_data["table"].data) + + def test_view_with_filter_email_returns_one_object_case_insensitive(self): + instance = factories.IgnoredManagedGroupMembershipFactory.create(ignored_email="Foo@test.com") + factories.IgnoredManagedGroupMembershipFactory.create(ignored_email="bar@test.com") + self.client.force_login(self.user) + response = self.client.get(self.get_url(), {"ignored_email__icontains": "foo@test.com"}) + self.assertEqual(response.status_code, 200) + self.assertIn("table", response.context_data) + self.assertEqual(len(response.context_data["table"].rows), 1) + self.assertIn(instance, response.context_data["table"].data) + + def test_view_with_filter_email_returns_one_object_case_contains(self): + instance = factories.IgnoredManagedGroupMembershipFactory.create(ignored_email="foo@test.com") + factories.IgnoredManagedGroupMembershipFactory.create(ignored_email="bar@test.com") + self.client.force_login(self.user) + response = self.client.get(self.get_url(), {"ignored_email__icontains": "oo"}) + self.assertEqual(response.status_code, 200) + self.assertIn("table", response.context_data) + self.assertEqual(len(response.context_data["table"].rows), 1) + self.assertIn(instance, response.context_data["table"].data) + + def test_view_with_filter_email_returns_multiple_objects(self): + instance_1 = factories.IgnoredManagedGroupMembershipFactory.create(ignored_email="foo1@test.com") + instance_2 = factories.IgnoredManagedGroupMembershipFactory.create(ignored_email="foo2@test.com") + self.client.force_login(self.user) + response = self.client.get(self.get_url(), {"ignored_email__icontains": "foo"}) + self.assertEqual(response.status_code, 200) + self.assertIn("table", response.context_data) + self.assertEqual(len(response.context_data["table"].rows), 2) + self.assertIn(instance_1, response.context_data["table"].data) + self.assertIn(instance_2, response.context_data["table"].data) + + def test_view_with_filter_group_name_and_email(self): + factories.IgnoredManagedGroupMembershipFactory.create(group__name="abc", ignored_email="foo@test.com") + instance = factories.IgnoredManagedGroupMembershipFactory.create( + group__name="def", ignored_email="foo@test.com" + ) + factories.IgnoredManagedGroupMembershipFactory.create(group__name="def", ignored_email="bar@test.com") + self.client.force_login(self.user) + response = self.client.get(self.get_url(), {"group__name__icontains": "def", "ignored_email__icontains": "foo"}) + self.assertEqual(response.status_code, 200) + self.assertIn("table", response.context_data) + self.assertEqual(len(response.context_data["table"].rows), 1) + self.assertIn(instance, response.context_data["table"].data) + class IgnoredManagedGroupMembershipUpdateTest(TestCase): def setUp(self): diff --git a/anvil_consortium_manager/auditor/views.py b/anvil_consortium_manager/auditor/views.py index e8068202..4b914311 100644 --- a/anvil_consortium_manager/auditor/views.py +++ b/anvil_consortium_manager/auditor/views.py @@ -5,12 +5,13 @@ from django.utils.translation import gettext_lazy as _ from django.views.generic import CreateView, DeleteView, DetailView, TemplateView, UpdateView from django.views.generic.detail import SingleObjectMixin -from django_tables2.views import SingleTableView +from django_filters.views import FilterView +from django_tables2.views import SingleTableMixin from anvil_consortium_manager import auth from anvil_consortium_manager.models import ManagedGroup, Workspace -from . import forms, models, tables, viewmixins +from . import filters, forms, models, tables, viewmixins from .audit import accounts as account_audit from .audit import billing_projects as billing_project_audit from .audit import managed_groups as managed_group_audit @@ -158,11 +159,13 @@ def form_valid(self, form): return super().form_valid(form) -class IgnoredManagedGroupMembershipList(auth.AnVILConsortiumManagerStaffViewRequired, SingleTableView): +class IgnoredManagedGroupMembershipList(auth.AnVILConsortiumManagerStaffViewRequired, SingleTableMixin, FilterView): """View to display a list of models.IgnoredManagedGroupMembership.""" model = models.IgnoredManagedGroupMembership table_class = tables.IgnoredManagedGroupMembershipTable + template_name = "auditor/ignoredmanagedgroupmembership_list.html" + filterset_class = filters.IgnoredManagedGroupMembershipFilter class IgnoredManagedGroupMembershipUpdate( diff --git a/anvil_consortium_manager/templates/auditor/ignoredmanagedgroupmembership_list.html b/anvil_consortium_manager/templates/auditor/ignoredmanagedgroupmembership_list.html index 1138b16d..e4dcdf0d 100644 --- a/anvil_consortium_manager/templates/auditor/ignoredmanagedgroupmembership_list.html +++ b/anvil_consortium_manager/templates/auditor/ignoredmanagedgroupmembership_list.html @@ -2,6 +2,7 @@ {% load static %} {% load render_table from django_tables2 %} +{% load crispy_forms_tags %} {% block title %}Ignored Managed Group membership audit records{% endblock %} @@ -16,6 +17,11 @@

Ignored Managed Group membership audit records

The following records will be ignored when running AnVIL audits for group membership.

+ +
+ {% crispy filter.form %} +
+ {% render_table table %}