Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/add search functionality for models #393

Merged
merged 37 commits into from
Oct 24, 2023
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
d43db6f
Add django-filters to INSTALLED_APPS
wkirdp Sep 15, 2023
ae493dc
Add a BillingProjectList test to test fillters
wkirdp Sep 19, 2023
6569f96
Added more tests for BillingProjectList filter view
wkirdp Sep 19, 2023
3c885ea
Rename BillingProjectFilter to BillingProjectListFilter
wkirdp Sep 19, 2023
9abb3d8
reorder tests so they are consistent
wkirdp Sep 20, 2023
3e5844b
Define filter for MangagedGroupList
wkirdp Sep 20, 2023
73e4db7
Define filter for WorkspaceList
wkirdp Sep 20, 2023
a507fb4
Define filter for AccountList
wkirdp Sep 20, 2023
6c420c6
Add django-filters to base requirements
wkirdp Sep 20, 2023
a600deb
Add django-filter module
wkirdp Sep 21, 2023
3d9315c
Add a custom filter form to display inputs in a single row
amstilp Sep 22, 2023
a457d54
requires a lower version of django-filter
wkirdp Sep 22, 2023
1c94b67
Modify tests: test case sensitive and case insensitive seperately.
wkirdp Oct 6, 2023
5944844
Streamline filter tests
amstilp Oct 11, 2023
5ac4f88
Use inline filter form for all Filter subclasses
amstilp Oct 11, 2023
9214a1d
Bump version number and update CHANGELOG
amstilp Oct 12, 2023
027512e
Merge branch 'main' into feature/add-search-functionality-for-models
amstilp Oct 12, 2023
4bf2620
Use crispy custom FilterForm in AccountList template
amstilp Oct 12, 2023
49d8ef7
Allow user to specify a list filterset class in the Account adapter
amstilp Oct 12, 2023
30eab11
Update the AccountList views to use the adapter filter
amstilp Oct 12, 2023
8bfd1b9
Add info about AccountAdapter to docs
amstilp Oct 12, 2023
6cc66fa
Update api autodocs
amstilp Oct 12, 2023
7f5633c
Merge branch 'main' into feature/add-search-functionality-for-models
amstilp Oct 17, 2023
b8916dd
Raise required django-filter version number
amstilp Oct 17, 2023
acdd04e
Run tox with high verbosity
amstilp Oct 17, 2023
bb15b28
Add verbosity to sqlite tox run
amstilp Oct 17, 2023
bc88e95
Try removing lintr cache from CI
amstilp Oct 17, 2023
5e7cf9f
Remove buildkit lines from CI
amstilp Oct 17, 2023
b2f48d1
Change max-parallel to 10 in CI
amstilp Oct 18, 2023
5b35a55
Set max-parallel to 1 ¯\_(ツ)_/¯
amstilp Oct 18, 2023
eb8e740
Add CI that works in a different branch
amstilp Oct 23, 2023
8dacf26
Fix tox config file for hopefully working CI
amstilp Oct 23, 2023
2536d69
Removing caching from linter setup-python step
amstilp Oct 24, 2023
6753e45
Add tox and CI files that work in a different branch
amstilp Oct 24, 2023
910cda7
Require linter to pass before running other CI
amstilp Oct 24, 2023
6ac8df7
Remove PIP_VERBOSE environment variable from tox
amstilp Oct 24, 2023
d29fdb4
Remove linter requirement for tox CI steps
amstilp Oct 24, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions anvil_consortium_manager/filters.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
from django_filters import FilterSet

from . import models


class AccountListFilter(FilterSet):
class Meta:
model = models.Account
fields = {"email": ["icontains"]}
amstilp marked this conversation as resolved.
Show resolved Hide resolved


class BillingProjectListFilter(FilterSet):
class Meta:
model = models.BillingProject
fields = {"name": ["icontains"]}


class ManagedGroupListFilter(FilterSet):
class Meta:
model = models.ManagedGroup
fields = {"name": ["icontains"]}


class WorkspaceListFilter(FilterSet):
class Meta:
model = models.Workspace
fields = {"name": ["icontains"]}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,12 @@

{% block content %}
<div class="container">
<div class="alert alert-info" role="alert">
<form method="get">
{{ filter.form }}
<button type="submit" class="btn btn-primary">Filter</button>
</form>
</div>

<div class="row">
<div class="col-sm-12">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,13 @@

{% block content %}
<div class="container">
<div class="alert alert-info" role="alert">

<form method="get">
{{ filter.form }}
<button type="submit" class="btn btn-primary">Filter</button>
</form>
</div>

<div class="row">
<div class="col-sm-12">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,13 @@

{% block content %}
<div class="container">
<div class="alert alert-info" role="alert">

<form method="get">
{{ filter.form }}
<button type="submit" class="btn btn-primary">Filter</button>
</form>
</div>

<div class="row">
<div class="col-sm-12">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,12 @@

{% block content %}
<div class="container">
<div class="alert alert-info" role="alert">
<form method="get">
{{ filter.form }}
<button type="submit" class="btn btn-primary">Filter</button>
</form>
</div>

<div class="row">
<div class="col-sm-12">
Expand Down
234 changes: 234 additions & 0 deletions anvil_consortium_manager/tests/test_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -915,6 +915,36 @@ 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_return_no_object(self):
factories.BillingProjectFactory.create(name="Billing_project")
factories.BillingProjectFactory.create(name="Project")
self.client.force_login(self.user)
url = resolve_url(self.get_url() + "?name__icontains=abc")
response = self.client.get(url)
wkirdp marked this conversation as resolved.
Show resolved Hide resolved
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_returns_one_object(self):
factories.BillingProjectFactory.create(name="Billing_project")
factories.BillingProjectFactory.create(name="Project")
self.client.force_login(self.user)
url = resolve_url(self.get_url() + "?name__icontains=bill")
wkirdp marked this conversation as resolved.
Show resolved Hide resolved
response = self.client.get(url)
self.assertEqual(response.status_code, 200)
self.assertIn("table", response.context_data)
self.assertEqual(len(response.context_data["table"].rows), 1)

def test_view_with_filter_returns_all_objects(self):
factories.BillingProjectFactory.create(name="Billing_project")
factories.BillingProjectFactory.create(name="Project")
self.client.force_login(self.user)
url = resolve_url(self.get_url() + "?name__icontains=pro")
response = self.client.get(url)
self.assertEqual(response.status_code, 200)
self.assertIn("table", response.context_data)
self.assertEqual(len(response.context_data["table"].rows), 2)


class BillingProjectAutocompleteTest(TestCase):
def setUp(self):
Expand Down Expand Up @@ -2926,6 +2956,36 @@ 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_return_no_object(self):
factories.AccountFactory.create(email="[email protected]")
factories.AccountFactory.create(email="[email protected]")
self.client.force_login(self.user)
url = resolve_url(self.get_url() + "?email__icontains=abc")
response = self.client.get(url)
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_returns_one_object(self):
factories.AccountFactory.create(email="[email protected]")
factories.AccountFactory.create(email="[email protected]")
self.client.force_login(self.user)
url = resolve_url(self.get_url() + "?email__icontains=tes")
wkirdp marked this conversation as resolved.
Show resolved Hide resolved
response = self.client.get(url)
self.assertEqual(response.status_code, 200)
self.assertIn("table", response.context_data)
self.assertEqual(len(response.context_data["table"].rows), 1)

def test_view_with_filter_returns_all_objects(self):
factories.AccountFactory.create(email="[email protected]")
factories.AccountFactory.create(email="[email protected]")
self.client.force_login(self.user)
url = resolve_url(self.get_url() + "?email__icontains=example")
response = self.client.get(url)
self.assertEqual(response.status_code, 200)
self.assertIn("table", response.context_data)
self.assertEqual(len(response.context_data["table"].rows), 2)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Once you have the AccountAdapter included, you'll want to add a test that checks filtering using the custom fields that a user has specified in the adapter. See the AccountAutocomplete tests for an example. This will requiring modifying the TestAccountAdapter in anvil_consortium_manager/tests/test_app/adapters.py

def test_view_with_service_account(self):
factories.AccountFactory.create(is_service_account=True)
factories.AccountFactory.create(is_service_account=False)
Expand Down Expand Up @@ -3034,6 +3094,48 @@ 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_return_no_object(self):
factories.AccountFactory.create(
email="[email protected]", status=models.Account.ACTIVE_STATUS
)
factories.AccountFactory.create(
email="[email protected]", status=models.Account.ACTIVE_STATUS
)
self.client.force_login(self.user)
url = resolve_url(self.get_url() + "?email__icontains=abc")
response = self.client.get(url)
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_returns_one_object(self):
factories.AccountFactory.create(
email="[email protected]", status=models.Account.ACTIVE_STATUS
)
factories.AccountFactory.create(
email="[email protected]", status=models.Account.ACTIVE_STATUS
)
self.client.force_login(self.user)
url = resolve_url(self.get_url() + "?email__icontains=tes")
response = self.client.get(url)
self.assertEqual(response.status_code, 200)
self.assertIn("table", response.context_data)
self.assertEqual(len(response.context_data["table"].rows), 1)

def test_view_with_filter_returns_all_objects(self):
factories.AccountFactory.create(
email="[email protected]", status=models.Account.ACTIVE_STATUS
)
factories.AccountFactory.create(
email="[email protected]", status=models.Account.ACTIVE_STATUS
)
self.client.force_login(self.user)
url = resolve_url(self.get_url() + "?email__icontains=example")
response = self.client.get(url)
self.assertEqual(response.status_code, 200)
self.assertIn("table", response.context_data)
self.assertEqual(len(response.context_data["table"].rows), 2)

amstilp marked this conversation as resolved.
Show resolved Hide resolved
def test_view_with_service_account(self):
factories.AccountFactory.create(is_service_account=True)
factories.AccountFactory.create(is_service_account=False)
Expand Down Expand Up @@ -3142,6 +3244,48 @@ 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_return_no_object(self):
factories.AccountFactory.create(
email="[email protected]", status=models.Account.INACTIVE_STATUS
)
factories.AccountFactory.create(
email="[email protected]", status=models.Account.INACTIVE_STATUS
)
self.client.force_login(self.user)
url = resolve_url(self.get_url() + "?email__icontains=abc")
response = self.client.get(url)
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_returns_one_object(self):
factories.AccountFactory.create(
email="[email protected]", status=models.Account.INACTIVE_STATUS
)
factories.AccountFactory.create(
email="[email protected]", status=models.Account.INACTIVE_STATUS
)
self.client.force_login(self.user)
url = resolve_url(self.get_url() + "?email__icontains=tes")
response = self.client.get(url)
self.assertEqual(response.status_code, 200)
self.assertIn("table", response.context_data)
self.assertEqual(len(response.context_data["table"].rows), 1)

def test_view_with_filter_returns_all_objects(self):
factories.AccountFactory.create(
email="[email protected]", status=models.Account.INACTIVE_STATUS
)
factories.AccountFactory.create(
email="[email protected]", status=models.Account.INACTIVE_STATUS
)
self.client.force_login(self.user)
url = resolve_url(self.get_url() + "?email__icontains=example")
response = self.client.get(url)
self.assertEqual(response.status_code, 200)
self.assertIn("table", response.context_data)
self.assertEqual(len(response.context_data["table"].rows), 2)

amstilp marked this conversation as resolved.
Show resolved Hide resolved
def test_view_with_service_account(self):
factories.AccountFactory.create(
status=models.Account.INACTIVE_STATUS, is_service_account=True
Expand Down Expand Up @@ -5123,6 +5267,36 @@ 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_return_no_object(self):
factories.ManagedGroupFactory.create(name="Managed_group")
factories.ManagedGroupFactory.create(name="Group")
self.client.force_login(self.user)
url = resolve_url(self.get_url() + "?name__icontains=abc")
response = self.client.get(url)
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_returns_one_object(self):
factories.ManagedGroupFactory.create(name="Managed_group")
factories.ManagedGroupFactory.create(name="Group")
self.client.force_login(self.user)
url = resolve_url(self.get_url() + "?name__icontains=man")
wkirdp marked this conversation as resolved.
Show resolved Hide resolved
response = self.client.get(url)
self.assertEqual(response.status_code, 200)
self.assertIn("table", response.context_data)
self.assertEqual(len(response.context_data["table"].rows), 1)

def test_view_with_filter_returns_all_objects(self):
factories.ManagedGroupFactory.create(name="Managed_group")
factories.ManagedGroupFactory.create(name="Group")
self.client.force_login(self.user)
url = resolve_url(self.get_url() + "?name__icontains=gro")
wkirdp marked this conversation as resolved.
Show resolved Hide resolved
response = self.client.get(url)
self.assertEqual(response.status_code, 200)
self.assertIn("table", response.context_data)
self.assertEqual(len(response.context_data["table"].rows), 2)


class ManagedGroupDeleteTest(AnVILAPIMockTestMixin, TestCase):

Expand Down Expand Up @@ -10700,6 +10874,36 @@ def test_context_workspace_type_display_name(self):
response.context_data["workspace_type_display_name"], "All workspace"
)

def test_view_with_filter_return_no_object(self):
factories.WorkspaceFactory.create(name="Workspace_test")
factories.WorkspaceFactory.create(name="Test")
self.client.force_login(self.user)
url = resolve_url(self.get_url() + "?name__icontains=abc")
response = self.client.get(url)
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_returns_one_object(self):
factories.WorkspaceFactory.create(name="Workspace_test")
factories.WorkspaceFactory.create(name="Test")
self.client.force_login(self.user)
url = resolve_url(self.get_url() + "?name__icontains=work")
wkirdp marked this conversation as resolved.
Show resolved Hide resolved
response = self.client.get(url)
self.assertEqual(response.status_code, 200)
self.assertIn("table", response.context_data)
self.assertEqual(len(response.context_data["table"].rows), 1)

def test_view_with_filter_returns_all_objects(self):
factories.WorkspaceFactory.create(name="Workspace_test")
factories.WorkspaceFactory.create(name="Test")
self.client.force_login(self.user)
url = resolve_url(self.get_url() + "?name__icontains=tes")
wkirdp marked this conversation as resolved.
Show resolved Hide resolved
response = self.client.get(url)
self.assertEqual(response.status_code, 200)
self.assertIn("table", response.context_data)
self.assertEqual(len(response.context_data["table"].rows), 2)


class WorkspaceListByTypeTest(TestCase):
def setUp(self):
Expand Down Expand Up @@ -10825,6 +11029,36 @@ def test_only_shows_workspaces_with_correct_type(self):
self.assertIn("table", response.context_data)
self.assertEqual(len(response.context_data["table"].rows), 0)

def test_view_with_filter_return_no_object(self):
factories.WorkspaceFactory.create(name="Workspace_test")
factories.WorkspaceFactory.create(name="Test")
self.client.force_login(self.user)
url = resolve_url(self.get_url(self.workspace_type) + "?name__icontains=abc")
response = self.client.get(url)
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_returns_one_object(self):
factories.WorkspaceFactory.create(name="Workspace_test")
factories.WorkspaceFactory.create(name="Test")
self.client.force_login(self.user)
url = resolve_url(self.get_url(self.workspace_type) + "?name__icontains=work")
wkirdp marked this conversation as resolved.
Show resolved Hide resolved
response = self.client.get(url)
self.assertEqual(response.status_code, 200)
self.assertIn("table", response.context_data)
self.assertEqual(len(response.context_data["table"].rows), 1)

def test_view_with_filter_returns_all_objects(self):
factories.WorkspaceFactory.create(name="Workspace_test")
factories.WorkspaceFactory.create(name="Test")
self.client.force_login(self.user)
url = resolve_url(self.get_url(self.workspace_type) + "?name__icontains=tes")
wkirdp marked this conversation as resolved.
Show resolved Hide resolved
response = self.client.get(url)
self.assertEqual(response.status_code, 200)
self.assertIn("table", response.context_data)
self.assertEqual(len(response.context_data["table"].rows), 2)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add a test for a user-specified workspace type - see the test_adapter method in this test case for an example. You'll want to test that it only finds the workspace of the correct type, not the workspace of the other type, even if both have a name that matches your querystring.


class WorkspaceDeleteTest(AnVILAPIMockTestMixin, TestCase):

Expand Down
Loading