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

Set up deploy/stage branch for ubuntu 22.04 upgrade #680

Merged
merged 56 commits into from
Jul 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
56 commits
Select commit Hold shift + click to select a range
bdfe771
Hide inactive users in study site table
amstilp Jul 11, 2024
548b2c9
Merge pull request #652 from UW-GAC/bugfix/hide-inactive-users-on-stu…
amstilp Jul 11, 2024
25501e7
Add the crontab file to the activate script
amstilp Jul 11, 2024
e1ec777
Bump types-requests from 2.32.0.20240622 to 2.32.0.20240712
dependabot[bot] Jul 14, 2024
e2e8f97
Fix failing test for mysql
amstilp Jul 22, 2024
854f241
Merge pull request #664 from UW-GAC/maint/fix-mysql-failing-test
amstilp Jul 22, 2024
387a7f4
Bump github/combine-prs from 5.0.0 to 5.1.0
dependabot[bot] Jul 22, 2024
e654f7c
Bump pytest from 8.2.2 to 8.3.1
dependabot[bot] Jul 22, 2024
813c7da
Bump django-debug-toolbar from 4.4.5 to 4.4.6
dependabot[bot] Jul 22, 2024
0ba4d73
Bump mypy from 1.10.1 to 1.11.0
dependabot[bot] Jul 22, 2024
5459829
Bump ruff from 0.5.1 to 0.5.4
dependabot[bot] Jul 22, 2024
1be2027
Bump jsonschema from 4.22.0 to 4.23.0
dependabot[bot] Jul 22, 2024
3fec6d8
Bump django-crispy-forms from 2.2 to 2.3
dependabot[bot] Jul 22, 2024
c4911a8
Bump sqlparse from 0.5.0 to 0.5.1
dependabot[bot] Jul 22, 2024
e78f63a
Merge dependabot/github_actions/github/combine-prs-5.1.0 into combine…
github-actions[bot] Jul 22, 2024
9aded02
Merge dependabot/pip/pytest-8.3.1 into combined-prs-branch
github-actions[bot] Jul 22, 2024
e054bbf
Merge dependabot/pip/sqlparse-0.5.1 into combined-prs-branch
github-actions[bot] Jul 22, 2024
d12f880
Merge dependabot/pip/django-crispy-forms-2.3 into combined-prs-branch
github-actions[bot] Jul 22, 2024
4a86392
Merge dependabot/pip/ruff-0.5.4 into combined-prs-branch
github-actions[bot] Jul 22, 2024
19c2dc7
Merge dependabot/pip/mypy-1.11.0 into combined-prs-branch
github-actions[bot] Jul 22, 2024
1814c60
Merge dependabot/pip/django-debug-toolbar-4.4.6 into combined-prs-branch
github-actions[bot] Jul 22, 2024
73bc3a2
Merge dependabot/pip/jsonschema-4.23.0 into combined-prs-branch
github-actions[bot] Jul 22, 2024
7d89779
Merge dependabot/pip/types-requests-2.32.0.20240712 into combined-prs…
github-actions[bot] Jul 22, 2024
a63916d
Merge branch 'main' into combined-prs-branch
github-actions[bot] Jul 22, 2024
3155909
Merge pull request #665 from UW-GAC/combined-prs-branch
amstilp Jul 22, 2024
e813e0d
Update certifi version in requirements file
amstilp Jul 22, 2024
3e4ad4b
Update zipp version in requirements file
amstilp Jul 22, 2024
8ada7c9
Remove temporary pinned versions from requirements.in file
amstilp Jul 22, 2024
4c16f3d
Manually update .txt files
amstilp Jul 22, 2024
1ac0bff
Remove explicit permissions in workflow
amstilp Jul 22, 2024
7257657
More manual updates to requirements file
amstilp Jul 22, 2024
4b73b78
Merge pull request #666 from UW-GAC/maint/security-updates
amstilp Jul 23, 2024
173e301
Merge pull request #653 from UW-GAC/maint/add-crontab-file-to-activat…
amstilp Jul 23, 2024
eff28da
Update CI for ubuntu-22.04 upgrade
amstilp Jul 23, 2024
87bef0c
Add quotes around 3.10 in CI
amstilp Jul 23, 2024
1f368e7
Compile requirements files
amstilp Jul 23, 2024
2a9d38b
Merge pull request #670 from UW-GAC/pip-tools/update-requirements-fil…
amstilp Jul 23, 2024
3fc1bf1
Fix badge for consortium members with data access
amstilp Jul 26, 2024
8cd1f94
Merge pull request #671 from UW-GAC/bugfix/fix-study-site-members-wit…
amstilp Jul 26, 2024
c4d34ad
Only show active users in UserAutocomplete
amstilp Jul 26, 2024
a26892f
Use only active users for UserLookupForm queryset
amstilp Jul 26, 2024
8879b32
Show an alert on the User profile page if user is inactive
amstilp Jul 26, 2024
e62adf5
Show an alert if a user's AnVIL account is inactive
amstilp Jul 26, 2024
6b3c542
Change inactive alerts to have a "danger" background
amstilp Jul 26, 2024
25bda17
Make the account link alert dismissable
amstilp Jul 26, 2024
8002b2c
Merge pull request #674 from UW-GAC/feature/better-behavior-for-inact…
amstilp Jul 26, 2024
efe29e5
Try adding a test to capture inventory inputs bug
amstilp Jul 26, 2024
e6465b8
Try modifying the test to catch the bug
amstilp Jul 29, 2024
68dc849
Try ordering workspaces differently in the test
amstilp Jul 29, 2024
34cdadb
Try rewriting test again
amstilp Jul 29, 2024
d34bff2
Add tests to check ordering of results
amstilp Jul 29, 2024
fdca4df
Fix comments in tests
amstilp Jul 29, 2024
7f60a52
Sort workspaces before concatenating study names
amstilp Jul 29, 2024
8126df7
Rename phenotype inventory to just "inventory"
amstilp Jul 29, 2024
fdbd48f
Merge pull request #675 from UW-GAC/bugfix/inventory-inputs-for-multi…
amstilp Jul 30, 2024
c33a3dc
Merge pull request #669 from UW-GAC/maint/ubuntu-22.04
amstilp Jul 30, 2024
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
8 changes: 2 additions & 6 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,10 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: [3.8]
python-version: ["3.10"]
backend: ["sqlite", "mariadb"]
mariadb-version: ["10.4"]
mariadb-version: ["10.6"]
include:
- python-version: "3.10" # Future ubuntu 22.04 upgrade.
backend: "mariadb"
mariadb-version: "10.6"
pip-recompile: true
- python-version: 3.12 # Future ubuntu 24.04.01 upgrade.
backend: "mariadb"
mariadb-version: "10.11"
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/combine-prs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ jobs:
steps:
- name: combine-prs
id: combine-prs
uses: github/combine-prs@v5.0.0
uses: github/combine-prs@v5.1.0
with:
labels: combined-pr # Optional: add a label to the combined PR
ci_required: true # require all checks to pass before combining
Expand Down
6 changes: 2 additions & 4 deletions .github/workflows/pip-compile.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@ on:

jobs:
update-requirements-files:
permissions:
pull-requests: write
runs-on: ubuntu-latest

steps:
Expand All @@ -16,10 +14,10 @@ jobs:
with:
ref: ${{ github.head_ref }}

- name: Set up Python 3.8
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: 3.8
python-version: "3.10"

- name: Update requirements files
uses: UW-GAC/pip-tools-actions/[email protected]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Temporary script to create some test data.
# Run with: python manage.py shell < add_phenotype_inventory_input_example_data.py
# Run with: python manage.py shell < add_inventory_input_example_data.py

from anvil_consortium_manager.tests.factories import (
ManagedGroupFactory,
Expand Down
1 change: 1 addition & 0 deletions primed-apps-activate.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ export DJANGO_SITE_DIR=/var/www/django/primed_apps/
export DJANGO_SITE_USER=primedweb
export DJANGO_SETTINGS_MODULE=config.settings.apps
export DJANGO_WSGI_FILE=config/primed_apps_wsgi.py
export DJANGO_CRONTAB=primed_apps.cron
export GAC_ENV=primed_apps
cd $DJANGO_SITE_DIR
. venv/bin/activate
1 change: 1 addition & 0 deletions primed-apps-dev-activate.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ export DJANGO_SITE_DIR=/var/www/django/primed_apps_dev/
export DJANGO_SITE_USER=primedweb
export DJANGO_SETTINGS_MODULE=config.settings.apps_dev
export DJANGO_WSGI_FILE=config/primed_apps_dev_wsgi.py
export DJANGO_CRONTAB=primed_apps_dev.cron
export GAC_ENV=primed_apps_dev
cd $DJANGO_SITE_DIR
. venv/bin/activate
4 changes: 3 additions & 1 deletion primed/dbgap/tests/test_forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -857,7 +857,9 @@ def test_dbgap_dar_data_missing_DAC_abbrev(self):
def test_dbgap_project_id_does_not_match(self):
"""Form is not valid when the dbgap_project_id does not match."""
form_data = {
"dbgap_dar_data": json.dumps([factories.dbGaPJSONProjectFactory(Project_id=2)]),
"dbgap_dar_data": json.dumps(
[factories.dbGaPJSONProjectFactory(Project_id=self.dbgap_application.dbgap_project_id + 1)]
),
"dbgap_application": self.dbgap_application,
}
form = self.form_class(data=form_data)
Expand Down
7 changes: 4 additions & 3 deletions primed/primed_anvil/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -130,12 +130,12 @@ def get_summary_table_data():
return data


def get_workspaces_for_phenotype_inventory():
def get_workspaces_for_inventory():
"""Get input to the primed-phenotype-inventory workflow.

This function generates the input for the "workspaces" field of the primed-phenotype-inventory workflow. Only
workspaces that have been shared with the consortium are included.
See dockstore link: https://dockstore.org/workflows/github.com/UW-GAC/primed-inventory-workflows/primed_phenotype_inventory:main?tab=info
See dockstore link: https://dockstore.org/workflows/github.com/UW-GAC/primed-inventory-workflows/primed_inventory:main?tab=info

The "workspaces" field has the format:
{
Expand Down Expand Up @@ -212,7 +212,8 @@ def get_workspaces_for_phenotype_inventory():

# Combine all querysets and process into the expected output for the AnVIL workflow.
workspaces = dbgap_workspaces.union(cdsa_workspaces).union(open_access_workspaces)

# Sort by workspace_name so that itertools.groupby works as expected.
workspaces = sorted(workspaces, key=lambda x: x["workspace_name"])
json = {}
for key, group in groupby(workspaces, lambda x: x["workspace_name"]):
study_names = [x["study_names"] if x["study_names"] else "" for x in group]
Expand Down
198 changes: 169 additions & 29 deletions primed/primed_anvil/tests/test_helpers.py

Large diffs are not rendered by default.

21 changes: 17 additions & 4 deletions primed/primed_anvil/tests/test_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -910,6 +910,19 @@ def test_site_user_table_when_member_group_is_set(self):
self.assertIsInstance(table, tables.UserAccountSingleGroupMembershipTable)
self.assertEqual(table.managed_group, member_group)

def test_site_user_table_does_not_include_inactive_users(self):
"""Site user table does not include inactive users."""
obj = self.model_factory.create()
inactive_site_user = UserFactory.create()
inactive_site_user.study_sites.set([obj])
inactive_site_user.is_active = False
inactive_site_user.save()
self.client.force_login(self.user)
response = self.client.get(self.get_url(obj.pk))
table = response.context_data["tables"][0]
self.assertEqual(len(table.rows), 0)
self.assertNotIn(inactive_site_user, table.data)

def test_member_group_table(self):
member_group = ManagedGroupFactory.create()
obj = self.model_factory.create(member_group=member_group)
Expand Down Expand Up @@ -1234,8 +1247,8 @@ def test_includes_cdsa_workspaces(self):
self.assertEqual(len(response.context_data["summary_table"].rows), 1)


class PhenotypeInventoryInputsViewTest(TestCase):
"""Tests for the PhenotypeInventoryInputsView view."""
class InventoryInputsViewTest(TestCase):
"""Tests for the InventoryInputsView view."""

def setUp(self):
"""Set up test class."""
Expand All @@ -1249,11 +1262,11 @@ def setUp(self):

def get_url(self, *args):
"""Get the url for the view being tested."""
return reverse("primed_anvil:utilities:phenotype_inventory_inputs", args=args)
return reverse("primed_anvil:utilities:inventory_inputs", args=args)

def get_view(self):
"""Return the view being tested."""
return views.PhenotypeInventoryInputsView.as_view()
return views.InventoryInputsView.as_view()

def test_view_redirect_not_logged_in(self):
"View redirects to login view when user is not logged in."
Expand Down
6 changes: 3 additions & 3 deletions primed/primed_anvil/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,9 @@
utilities_patterns = (
[
path(
"phenotype_inventory_inputs/",
views.PhenotypeInventoryInputsView.as_view(),
name="phenotype_inventory_inputs",
"inventory_inputs/",
views.InventoryInputsView.as_view(),
name="inventory_inputs",
),
],
"utilities",
Expand Down
8 changes: 4 additions & 4 deletions primed/primed_anvil/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ class StudySiteDetail(AnVILConsortiumManagerStaffViewRequired, MultiTableMixin,
model = models.StudySite

def get_tables(self):
user_qs = User.objects.filter(study_sites=self.object)
user_qs = User.objects.filter(is_active=True, study_sites=self.object)
if self.object.member_group:
user_table = tables.UserAccountSingleGroupMembershipTable(user_qs, managed_group=self.object.member_group)
else:
Expand Down Expand Up @@ -180,10 +180,10 @@ def get_context_data(self, **kwargs):
return context


class PhenotypeInventoryInputsView(AnVILConsortiumManagerStaffViewRequired, TemplateView):
template_name = "primed_anvil/phenotype_inventory_inputs.html"
class InventoryInputsView(AnVILConsortiumManagerStaffViewRequired, TemplateView):
template_name = "primed_anvil/inventory_inputs.html"

def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context["workspaces_input"] = json.dumps(helpers.get_workspaces_for_phenotype_inventory(), indent=2)
context["workspaces_input"] = json.dumps(helpers.get_workspaces_for_inventory(), indent=2)
return context
2 changes: 1 addition & 1 deletion primed/templates/anvil_consortium_manager/navbar.html
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@

<li><hr class="dropdown-divider"></li>
<li>
<a class="dropdown-item" href="{% url 'primed_anvil:utilities:phenotype_inventory_inputs' %}">Phenotype inventory</a>
<a class="dropdown-item" href="{% url 'primed_anvil:utilities:inventory_inputs' %}">Inventory inputs</a>
</li>

<li><hr class="dropdown-divider"></li>
Expand Down
5 changes: 3 additions & 2 deletions primed/templates/base.html
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@
{# Placed at the top of the document so pages load faster with defer #}
{% block javascript %}
<!-- Bootstrap JS and its dependencies-->
<script src="https://code.jquery.com/jquery-3.6.0.min.js" integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js" integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p" crossorigin="anonymous"></script>
<script src="https://code.jquery.com/jquery-3.6.0.min.js" integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script>
<script src="https://unpkg.com/[email protected]" integrity="sha384-D1Kt99CQMDuVetoL1lrYwg5t+9QdHe7NLX/SoJYkXDFfX37iInKRy5xLSi8nO7UC" crossorigin="anonymous"></script>

<!-- Your stuff: Third-party javascript libraries go here -->
Expand Down Expand Up @@ -119,9 +119,10 @@
{% endif %}

{% if request.user.is_authenticated and not request.user.account %}
<div class="alert alert-warning" role="alert">
<div class="alert alert-warning alert-dismissible fade show" role="alert">
<i class="bi bi-exclamation-triangle-fill me-1"></i>
You must <a href="{% url 'anvil_consortium_manager:accounts:link' %}">link your AnVIL account</a> before you can access any data on AnVIL.
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
</div>
{% endif %}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ <h2>Phenotype inventory workflow</h2>

<p>
This page creates the input for the "workspaces" field in the
<a href="https://dockstore.org/workflows/github.com/UW-GAC/primed-inventory-workflows/primed_phenotype_inventory:main?tab=info">PRIMED phenotype inventory workflow</a>.
<a href="https://dockstore.org/workflows/github.com/UW-GAC/primed-inventory-workflows/primed_inventory:main?tab=info">PRIMED phenotype inventory workflow</a>.
Copy the text in the box below and paste it into the "workspaces" field when running the workflow on AnVIL.
</p>

Expand Down
2 changes: 1 addition & 1 deletion primed/templates/primed_anvil/studysite_detail.html
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ <h2 class="accordion-header" id="headingMembersOne">
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#collapseMembersOne" aria-expanded="false" aria-controls="collapseMembersOne">
<span class="fa-solid fa-cloud-arrow-down mx-2"></span>
View consortium members with data access
<span class="badge mx-2 bg-secondary pill"> {{ tables.1.rows|length }}</span>
<span class="badge mx-2 bg-secondary pill"> {{ tables.3.rows|length }}</span>
</button>
</h2>
<div id="collapseMembersOne" class="accordion-collapse collapse" aria-labelledby="headingMembersOne" data-bs-parent="#accordionMembers">
Expand Down
17 changes: 17 additions & 0 deletions primed/templates/users/user_detail.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,15 @@
{% block content %}
<div class="container">

{% if not object.is_active %}

<p class='alert alert-danger mt-3'>
<i class="bi bi-exclamation-triangle-fill"></i>
This user is inactive.
</p>

{% endif %}

<div class="row row-cols-1 rows-cols-sm-2 row-cols-md-2 g-2 mt-3">
<div class="col">
<div class='card card-shadow-sm'>
Expand Down Expand Up @@ -57,6 +66,14 @@ <h3><i class="bi bi-link-45deg"></i> {% if object == request.user %}My{% else %}
<div class='card-body'>
{% if object.account %}
<p><i class="bi bi-check-circle-fill text-success"></i> Profile has a linked AnVIL account established</p>

{% if not object.account.status %}
<p class='alert alert-danger mt-3'>
<i class="bi bi-exclamation-triangle-fill"></i>
This account is inactive.
</p>
{% endif %}

<ul class='list-group'>
<li class='list-group-item'>
<h5>Account Email</h5>
Expand Down
2 changes: 1 addition & 1 deletion primed/users/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ class UserLookupForm(Bootstrap5MediaFormMixin, forms.Form):
"""Form for the user lookup"""

user = forms.ModelChoiceField(
queryset=User.objects.all(),
queryset=User.objects.filter(is_active=True),
widget=autocomplete.ModelSelect2(
url="users:autocomplete",
attrs={"data-theme": "bootstrap-5"},
Expand Down
13 changes: 13 additions & 0 deletions primed/users/tests/test_forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,3 +63,16 @@ def test_invalid_missing_name(self):
self.assertIn("user", form.errors)
self.assertEqual(len(form.errors["user"]), 1)
self.assertIn("required", form.errors["user"][0])

def test_inactive_user(self):
"""Form is invalid when user is inactive."""
user_obj = UserFactory.create(is_active=False)
form_data = {
"user": user_obj,
}
form = self.form_class(data=form_data)
self.assertFalse(form.is_valid())
self.assertEqual(len(form.errors), 1)
self.assertIn("user", form.errors)
self.assertEqual(len(form.errors["user"]), 1)
self.assertIn("valid choice", form.errors["user"][0])
62 changes: 62 additions & 0 deletions primed/users/tests/test_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -574,6 +574,39 @@ def test_acm_staff_view(self):
self.assertIn(agreement_1.signed_agreement, response.context["signed_agreements"])
self.assertIn(agreement_2.signed_agreement, response.context["signed_agreements"])

def test_inactive_user_inactive_message(self):
"""Inactive user alert is shown for an inactive user."""
user = UserFactory.create(is_active=False)
self.client.force_login(self.user)
response = self.client.get(user.get_absolute_url())
self.assertEqual(response.status_code, 200)
self.assertContains(response, "This user is inactive.")

def test_active_user_no_inactive_message(self):
"""Inactive user alert is not shown for an active user."""
self.client.force_login(self.user)
response = self.client.get(self.user.get_absolute_url())
self.assertEqual(response.status_code, 200)
self.assertNotContains(response, "This user is inactive.")

def test_inactive_anvil_account_alert_is_inactive(self):
"""Alert is shown when AnVIL account is inactive."""
account = AccountFactory.create(email="[email protected]", user=self.user, verified=True)
account.status = account.INACTIVE_STATUS
account.save()
self.client.force_login(self.user)
response = self.client.get(self.user.get_absolute_url())
self.assertEqual(response.status_code, 200)
self.assertContains(response, "This account is inactive.")

def test_inactive_anvil_account_alert_is_active(self):
"""Alert is not shown when AnVIL account is active."""
AccountFactory.create(email="[email protected]", user=self.user, verified=True)
self.client.force_login(self.user)
response = self.client.get(self.user.get_absolute_url())
self.assertEqual(response.status_code, 200)
self.assertNotContains(response, "This account is inactive.")


class UserAutocompleteTest(TestCase):
def setUp(self):
Expand Down Expand Up @@ -723,6 +756,17 @@ def test_get_selected_result_label(self):
view.setup(request)
self.assertEqual(view.get_selected_result_label(instance), "First Last ([email protected])")

def test_excludes_inactive_users(self):
"""Queryset excludes excludes inactive users."""
UserFactory.create(is_active=False)
request = self.factory.get(self.get_url())
request.user = self.user
response = self.get_view()(request)
returned_ids = [int(x["id"]) for x in json.loads(response.content.decode("utf-8"))["results"]]
# Only test user.
self.assertEqual(len(returned_ids), 1)
self.assertEqual(returned_ids, [self.user.pk])


class UserLookup(TestCase):
"""Test for UserLookup view"""
Expand Down Expand Up @@ -799,3 +843,21 @@ def test_blank_user(self):
self.assertIn("user", form.errors.keys())
self.assertEqual(len(form.errors["user"]), 1)
self.assertIn("required", form.errors["user"][0])

def test_invalid_inactive_user(self):
"""Form is invalid with an inactive user."""
object = UserFactory.create(
username="user1",
password="passwd",
email="[email protected]",
is_active=False,
)
self.client.force_login(self.user)
response = self.client.post(self.get_url(), {"user": object.pk})
self.assertEqual(response.status_code, 200)
form = response.context_data["form"]
self.assertFalse(form.is_valid())
self.assertEqual(len(form.errors), 1)
self.assertIn("user", form.errors)
self.assertEqual(len(form.errors["user"]), 1)
self.assertIn("valid choice", form.errors["user"][0])
4 changes: 3 additions & 1 deletion primed/users/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,9 @@ def get_result_label(self, result):

def get_queryset(self):
"""Filter to users matching the query."""
qs = User.objects.all().order_by("username")
qs = User.objects.filter(
is_active=True,
).order_by("username")

if self.q:
# Filter to users whose name or email matches the query.
Expand Down
Loading