Skip to content

Commit

Permalink
Merge pull request #220 from UW-GAC/deploy/stage
Browse files Browse the repository at this point in the history
Deploy to prod
  • Loading branch information
amstilp authored Jul 11, 2023
2 parents c11e9ab + 39e092b commit 0503f04
Show file tree
Hide file tree
Showing 11 changed files with 2,912 additions and 958 deletions.
3,601 changes: 2,649 additions & 952 deletions primed/static/css/project.css

Large diffs are not rendered by default.

93 changes: 92 additions & 1 deletion primed/static/css/project.css.map

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion primed/static/sass/project.scss
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ li.nav-item a:focus {
}

.alert-error {
background-color: $pink;
background-color: $pink-100;
border-color: $dark-pink;
color: $red;
}
5 changes: 4 additions & 1 deletion primed/templates/anvil_consortium_manager/navbar.html
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,10 @@
<li>
<a class="dropdown-item" href="{% url 'duo:data_use_modifiers:list' %}">List DUO modifiers</a>
</li>

<li><hr class="dropdown-divider"></li>
<li>
<a class="dropdown-item" href="{% url 'users:lookup' %}">Look up a user</a>
</li>

</ul>
</li>
Expand Down
20 changes: 20 additions & 0 deletions primed/templates/users/userlookup_form.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{% extends "base.html" %}
{% load static %}
{% load crispy_forms_tags %}

{% block title %}User lookup{% endblock title %}

{% block content %}

<h2>User lookup</h2>

<form method="post">
{% csrf_token %}
{{ form|crispy }}
<button type="submit" class="btn btn-success">Go to user profile</button>
</form>
{% endblock %}

{% block inline_javascript %}
{{ form.media }}
{% endblock inline_javascript %}
17 changes: 17 additions & 0 deletions primed/users/forms.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
from anvil_consortium_manager.forms import Bootstrap5MediaFormMixin
from dal import autocomplete
from django import forms
from django.contrib.auth import forms as admin_forms
from django.contrib.auth import get_user_model
from django.utils.translation import gettext_lazy as _
Expand All @@ -17,3 +20,17 @@ class Meta(admin_forms.UserCreationForm.Meta):
error_messages = {
"username": {"unique": _("This username has already been taken.")}
}


class UserLookupForm(Bootstrap5MediaFormMixin, forms.Form):
"""Form for the user lookup"""

user = forms.ModelChoiceField(
queryset=User.objects.all(),
widget=autocomplete.ModelSelect2(
url="users:autocomplete",
attrs={"data-theme": "bootstrap-5"},
),
required=True,
help_text="To lookup a user, enter either the name or username.",
)
28 changes: 27 additions & 1 deletion primed/users/tests/test_forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@
Module for all Form Tests.
"""
import pytest
from django.test import TestCase
from django.utils.translation import gettext_lazy as _

from primed.users.forms import UserCreationForm
from primed.users.forms import UserCreationForm, UserLookupForm
from primed.users.models import User
from primed.users.tests.factories import UserFactory

pytestmark = pytest.mark.django_db

Expand Down Expand Up @@ -37,3 +39,27 @@ def test_username_validation_error_msg(self, user: User):
assert len(form.errors) == 1
assert "username" in form.errors
assert form.errors["username"][0] == _("This username has already been taken.")


class UserLookupFormTest(TestCase):

form_class = UserLookupForm

def test_valid(self):
"""Form is valid with necessary input."""
user_obj = UserFactory.create()
form_data = {
"user": user_obj,
}
form = self.form_class(data=form_data)
self.assertTrue(form.is_valid())

def test_invalid_missing_name(self):
"""Form is invalid when missing name."""
form_data = {}
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("required", form.errors["user"][0])
80 changes: 80 additions & 0 deletions primed/users/tests/test_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
from primed.users.tests.factories import UserFactory
from primed.users.views import (
UserAutocompleteView,
UserLookupForm,
UserRedirectView,
UserUpdateView,
user_detail_view,
Expand Down Expand Up @@ -352,3 +353,82 @@ def test_get_selected_result_label(self):
self.assertEqual(
view.get_selected_result_label(instance), "First Last ([email protected])"
)


class UserLookup(TestCase):
"""Test for UserLookup view"""

def setUp(self):
"""Set up test class."""
self.factory = RequestFactory()
self.model_factory = UserFactory
# Create a user with both view and edit permission.
self.user = User.objects.create_user(username="test", password="test")

def get_url(self):
"""Get the url for the view being tested."""
return reverse("users:lookup")

def test_form_class(self):
"""The form class is as expected."""
self.client.force_login(self.user)
response = self.client.get(self.get_url())
self.assertIn("form", response.context_data)
self.assertIsInstance(response.context_data["form"], UserLookupForm)

def test_view_redirect_not_logged_in(self):
"View redirects to login view when user is not logged in."
response = self.client.get(self.get_url())
self.assertRedirects(
response, resolve_url(settings.LOGIN_URL) + "?next=" + self.get_url()
)

def test_status_code_with_user_permission(self):
"""Returns successful response code."""
self.client.force_login(self.user)
response = self.client.get(self.get_url())
self.assertEqual(response.status_code, 200)

def test_redirect_to_the_correct_profile_page(self):
"""The search view correctly redirect to the user profile page"""
object = UserFactory.create(
username="user1",
password="passwd",
email="[email protected]",
)
self.client.force_login(self.user)
response = self.client.post(self.get_url(), {"user": object.pk})
self.assertRedirects(
response,
resolve_url(reverse("users:detail", kwargs={"username": object.username})),
)

def test_invalid_input(self):
"""Posting invalid data re-renders the form with an error."""
self.client.force_login(self.user)
response = self.client.post(
self.get_url(),
{"user": -1},
)
self.assertEqual(response.status_code, 200)
form = response.context_data["form"]
self.assertFalse(form.is_valid())
self.assertEqual(len(form.errors.keys()), 1)
self.assertIn("user", form.errors.keys())
self.assertEqual(len(form.errors["user"]), 1)
self.assertIn("valid choice", form.errors["user"][0])

def test_blank_user(self):
"""Posting invalid data does not create an object."""
self.client.force_login(self.user)
response = self.client.post(
self.get_url(),
{},
)
self.assertEqual(response.status_code, 200)
form = response.context_data["form"]
self.assertFalse(form.is_valid())
self.assertEqual(len(form.errors.keys()), 1)
self.assertIn("user", form.errors.keys())
self.assertEqual(len(form.errors["user"]), 1)
self.assertIn("required", form.errors["user"][0])
2 changes: 2 additions & 0 deletions primed/users/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

from primed.users.views import (
UserAutocompleteView,
UserLookup,
user_detail_view,
user_redirect_view,
user_update_view,
Expand All @@ -12,5 +13,6 @@
path("~redirect/", view=user_redirect_view, name="redirect"),
path("~update/", view=user_update_view, name="update"),
path("autocomplete/", view=UserAutocompleteView.as_view(), name="autocomplete"),
path("lookup/", UserLookup.as_view(), name="lookup"),
path("<str:username>/", view=user_detail_view, name="detail"),
]
20 changes: 19 additions & 1 deletion primed/users/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@
from django.db.models import Q
from django.urls import reverse
from django.utils.translation import gettext_lazy as _
from django.views.generic import DetailView, RedirectView, UpdateView
from django.views.generic import DetailView, FormView, RedirectView, UpdateView

from .forms import UserLookupForm

User = get_user_model()

Expand Down Expand Up @@ -62,3 +64,19 @@ def get_queryset(self):
qs = qs.filter(Q(email__icontains=self.q) | Q(name__icontains=self.q))

return qs


class UserLookup(LoginRequiredMixin, FormView):
"""view to allow searching by user and redirect to the profile page of the selected user."""

template_name = "users/userlookup_form.html"
form_class = UserLookupForm

def form_valid(self, form):
self.user = form.cleaned_data["user"]
return super().form_valid(form)

def get_success_url(self):
"""Redirect to the user profile page after processing a valid form."""

return reverse("users:detail", kwargs={"username": self.user.username})
2 changes: 1 addition & 1 deletion requirements/base.txt
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ django-dbbackup==4.0.1 # https://github.com/jazzband/django-dbbackup
django-extensions==3.2.1 # https://github.com/django-extensions/django-extensions

# anvil_consortium_manager
git+https://github.com/UW-GAC/django-anvil-consortium-manager.git@v0.16.4
git+https://github.com/UW-GAC/django-anvil-consortium-manager.git@v0.17

# Simple history - model history tracking
django-simple-history==3.1.1
Expand Down

0 comments on commit 0503f04

Please sign in to comment.