From 58bab756ca0430da04b9838e63028475ee5b25bf Mon Sep 17 00:00:00 2001 From: jofeinstein Date: Fri, 25 Feb 2022 17:03:29 -0500 Subject: [PATCH 01/85] initial request hub commit --- .../templates/request_hub/request_hub.html | 261 ++++++++++++++++++ .../core/user/views_/request_hub_views.py | 115 ++++++++ 2 files changed, 376 insertions(+) create mode 100644 coldfront/core/user/templates/request_hub/request_hub.html create mode 100644 coldfront/core/user/views_/request_hub_views.py diff --git a/coldfront/core/user/templates/request_hub/request_hub.html b/coldfront/core/user/templates/request_hub/request_hub.html new file mode 100644 index 000000000..46a5afe3f --- /dev/null +++ b/coldfront/core/user/templates/request_hub/request_hub.html @@ -0,0 +1,261 @@ +{% extends "common/base.html" %} {% load common_tags %} {% block content %} + +
+
+

Request Hub

+
+ +

Below are all your active requests. To view your completed requests, click to view completed requests in the appropriate section

+
+
+ + +
+
+ +
+
+ +
+
+ {% if cluster_account_list_active %} + +
+
+
Active Cluster Account Requests
+
+ + + + + + + + + + + + + + {% for cluster_account in cluster_account_list_active %} + + + + + + + + + + {% endfor %} + +
+ # + + + + Date Requested/
Last Modified + + +
+ User Email + + + + Cluster Username + + + + Project + + + + Allocation + + Status +
{{ cluster_account.pk }}{{ cluster_account.modified|date:"M. d, Y" }}{{ cluster_account.allocation_user.user.email }} + {% if cluster_account.allocation_user.user.userprofile.cluster_uid %} + {{ cluster_account.allocation_user.user.username }} + {% else %} + + No cluster account. + + {% endif %} + + + {{ cluster_account.allocation.project.name }} + + + + Allocation {{ allocation.pk }} + {{ cluster_account.allocation.pk }} + + + {% with status=cluster_account.value %} + {% if status == "Pending - Add" %} + Pending + {% elif status == "Processing" %} + {{ status }} + {% elif status == "Active" %} + {{ status }} + {% elif status == "Denied" %} + {{ status }} + {% endif %} + {% endwith %} +
+ + Page {{ cluster_account_list_active.number }} of {{ cluster_account_list_active.paginator.num_pages }} +
    + {% if cluster_account_list_active.has_previous %} +
  • Previous
  • + {% else %} +
  • Previous
  • + {% endif %} + {% if cluster_account_list_active.has_next %} +
  • Next
  • + {% else %} +
  • Next
  • + {% endif %} +
+
+
+
+ + {% else %} +
+ No active cluster account requests! +
+ {% endif %} +
+
+

+
+
+ {% if cluster_account_list_complete %} +
+
+
Completed Cluster Account Requests
+
+ + + + + + + + + + + + + + {% for cluster_account in cluster_account_list_complete %} + + + + + + + + + + {% endfor %} + +
+ # + + + + Date Requested/
Last Modified + + +
+ User Email + + + + Cluster Username + + + + Project + + + + Allocation + + Status +
{{ cluster_account.pk }}{{ cluster_account.modified|date:"M. d, Y" }}{{ cluster_account.allocation_user.user.email }} + {% if cluster_account.allocation_user.user.userprofile.cluster_uid %} + {{ cluster_account.allocation_user.user.username }} + {% else %} + + No cluster account. + + {% endif %} + + + {{ cluster_account.allocation.project.name }} + + + + Allocation {{ allocation.pk }} + {{ cluster_account.allocation.pk }} + + + {% with status=cluster_account.value %} + {% if status == "Pending - Add" %} + Pending + {% elif status == "Processing" %} + {{ status }} + {% elif status == "Active" %} + {{ status }} + {% elif status == "Denied" %} + {{ status }} + {% endif %} + {% endwith %} +
+ + Page {{ cluster_account_list_complete.number }} of {{ cluster_account_list_complete.paginator.num_pages }} +
    + {% if cluster_account_list_complete.has_previous %} +
  • Previous
  • + {% else %} +
  • Previous
  • + {% endif %} + {% if cluster_account_list_complete.has_next %} +
  • Next
  • + {% else %} +
  • Next
  • + {% endif %} +
+
+
+
+ + {% else %} +
+ No new or pending cluster account requests! +
+ {% endif %} +
+
+
+
+
+
+ +{% endblock %} diff --git a/coldfront/core/user/views_/request_hub_views.py b/coldfront/core/user/views_/request_hub_views.py new file mode 100644 index 000000000..ba0049cff --- /dev/null +++ b/coldfront/core/user/views_/request_hub_views.py @@ -0,0 +1,115 @@ +from itertools import chain + +from django.contrib import messages +from django.contrib.auth.mixins import LoginRequiredMixin, UserPassesTestMixin +from django.contrib.auth.models import User +from django.core.paginator import EmptyPage, PageNotAnInteger, Paginator +from django.db.models import Q +from django.http import HttpResponseRedirect +from django.shortcuts import get_object_or_404, render +from django.urls import reverse +from django.views.generic import ListView +from django.views.generic.base import TemplateView, View +from django.views.generic.edit import FormView + +from coldfront.core.allocation.models import (Allocation, + AllocationAttributeType, + AllocationUserStatusChoice, + AllocationUserAttribute) + +from coldfront.core.project.forms_.removal_forms import \ + (ProjectRemovalRequestSearchForm, + ProjectRemovalRequestUpdateStatusForm, + ProjectRemovalRequestCompletionForm) +from coldfront.core.project.models import (Project, + ProjectUserStatusChoice, + ProjectUserRemovalRequest, + ProjectUserRemovalRequestStatusChoice) +from coldfront.core.project.utils_.removal_utils import ProjectRemovalRequestRunner +from coldfront.core.utils.common import (import_from_settings, + utc_now_offset_aware) +from coldfront.core.utils.mail import send_email_template + +import logging + +EMAIL_ENABLED = import_from_settings('EMAIL_ENABLED', False) + +if EMAIL_ENABLED: + EMAIL_SENDER = import_from_settings('EMAIL_SENDER') + EMAIL_SIGNATURE = import_from_settings('EMAIL_SIGNATURE') + SUPPORT_EMAIL = import_from_settings('CENTER_HELP_EMAIL') + +logger = logging.getLogger(__name__) + + +class RequestHub(LoginRequiredMixin, + UserPassesTestMixin, + TemplateView): + template_name = 'request_hub/request_hub.html' + paginate_by = 2 + paginators = 0 + + def get_cluster_account_requests(self): + user = self.request.user + + cluster_account_status = AllocationAttributeType.objects.get( + name='Cluster Account Status') + + cluster_account_list_complete = AllocationUserAttribute.objects.filter( + allocation_attribute_type=cluster_account_status, + value__in=['Denied', 'Active'], + allocation_user__user=user) + + cluster_account_list_active = AllocationUserAttribute.objects.filter( + allocation_attribute_type=cluster_account_status, + value__in=['Pending - Add', 'Processing'], + allocation_user__user=user) + + return cluster_account_list_active, cluster_account_list_complete + + def test_func(self): + """UserPassesTestMixin tests.""" + if self.request.user.is_superuser: + return True + + if self.request.user.has_perm('project.view_projectuserremovalrequest'): + return True + # + # message = ( + # 'You do not have permission to review project removal requests.') + # messages.error(self.request, message) + + return True + + def get_context_data(self, **kwargs): + def create_paginator(queryset, context_name): + """ + Creates a paginator object for the given queryset + and updates the context with the created object. + """ + paginator = Paginator(queryset, self.paginate_by) + page = self.request.GET.get(f'page{self.paginators}') + try: + queryset = paginator.page(page) + except PageNotAnInteger: + queryset = paginator.page(1) + except EmptyPage: + queryset = paginator.page(paginator.num_pages) + + context[context_name] = queryset + + self.paginators += 1 + + context = super().get_context_data(**kwargs) + + cluster_account_list_active, cluster_account_list_complete = \ + self.get_cluster_account_requests() + + create_paginator(cluster_account_list_active, + 'cluster_account_list_active') + context['num_active_cluster_account_requests'] = len(cluster_account_list_active) + + create_paginator(cluster_account_list_complete, + 'cluster_account_list_complete') + + return context \ No newline at end of file From fe3871a73af9a6bf94bd727b20fc75513a60acc2 Mon Sep 17 00:00:00 2001 From: jofeinstein Date: Fri, 25 Feb 2022 17:03:48 -0500 Subject: [PATCH 02/85] added path for request hub --- coldfront/core/user/urls.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/coldfront/core/user/urls.py b/coldfront/core/user/urls.py index c48520c12..a50278965 100644 --- a/coldfront/core/user/urls.py +++ b/coldfront/core/user/urls.py @@ -7,6 +7,7 @@ from django.urls import path, reverse_lazy import coldfront.core.user.views as user_views +import coldfront.core.user.views_.request_hub_views as request_hub_views from coldfront.core.user.forms import VerifiedEmailAddressPasswordResetForm from coldfront.core.user.forms import UserLoginForm @@ -113,4 +114,9 @@ path('identity-linking-request', user_views.IdentityLinkingRequestView.as_view(), name='identity-linking-request'), + + # Request Hub + path('request-hub', + request_hub_views.RequestHub.as_view(), + name='request-hub'), ] From a87f65a14dc3e0f89db1037e2711eb3eb7edf60e Mon Sep 17 00:00:00 2001 From: jofeinstein Date: Fri, 25 Feb 2022 17:04:11 -0500 Subject: [PATCH 03/85] added request hub to navbar --- coldfront/templates/common/authorized_navbar.html | 3 +++ 1 file changed, 3 insertions(+) diff --git a/coldfront/templates/common/authorized_navbar.html b/coldfront/templates/common/authorized_navbar.html index 854ffca5e..066c6dad7 100644 --- a/coldfront/templates/common/authorized_navbar.html +++ b/coldfront/templates/common/authorized_navbar.html @@ -30,6 +30,9 @@ +
  • + Request Hub +
  • {% if request.user.is_superuser %} {% include 'common/navbar_admin.html' %} {% elif request.user.is_staff %} From 1e282ec7dc3e844c4019dbe24b483dcd1c9fee63 Mon Sep 17 00:00:00 2001 From: jofeinstein Date: Fri, 25 Feb 2022 17:14:46 -0500 Subject: [PATCH 04/85] changed icons and spacing --- .../user/templates/request_hub/request_hub.html | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/coldfront/core/user/templates/request_hub/request_hub.html b/coldfront/core/user/templates/request_hub/request_hub.html index 46a5afe3f..4046a5e9a 100644 --- a/coldfront/core/user/templates/request_hub/request_hub.html +++ b/coldfront/core/user/templates/request_hub/request_hub.html @@ -19,7 +19,10 @@

    Request Hub

    Cluster Account Requests {% if num_active_cluster_account_requests %} - {{ num_active_cluster_account_requests }} active requests + + + + {{ num_active_cluster_account_requests }} active requests {% endif %} @@ -141,7 +144,7 @@
    Active Cluster Account Requests
    {% endif %} -

    +
    {% if cluster_account_list_complete %} @@ -248,9 +251,17 @@
    Completed Cluster Account Requests
    {% else %}
    - No new or pending cluster account requests! + No completed cluster account requests!
    {% endif %} + + {% if user.is_superuser %} +

    + + + Go To Cluster Account Requests Main Page + + {% endif %}
    From d06800ffe4386c81473a7ec22fd07ff79288fa67 Mon Sep 17 00:00:00 2001 From: jofeinstein Date: Fri, 25 Feb 2022 18:20:59 -0500 Subject: [PATCH 05/85] moved cluster request table to separate html file --- .../core/user/views_/request_hub_views.py | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/coldfront/core/user/views_/request_hub_views.py b/coldfront/core/user/views_/request_hub_views.py index ba0049cff..3a22cf551 100644 --- a/coldfront/core/user/views_/request_hub_views.py +++ b/coldfront/core/user/views_/request_hub_views.py @@ -67,6 +67,22 @@ def get_cluster_account_requests(self): return cluster_account_list_active, cluster_account_list_complete + def get_removal_requests(self): + user = self.request.user + + project_user_cond = Q(project_user__user=self.request.user) + requester_cond = Q(requester=self.request.user) + + removal_request_active = ProjectUserRemovalRequest.objects.filter( + status__name__in=['Pending', 'Processing']).\ + filter(project_user_cond | requester_cond) + + removal_request_complete = ProjectUserRemovalRequest.objects.filter( + status__name='Complete').\ + filter(project_user_cond | requester_cond) + + return removal_request_active, removal_request_complete + def test_func(self): """UserPassesTestMixin tests.""" if self.request.user.is_superuser: @@ -112,4 +128,14 @@ def create_paginator(queryset, context_name): create_paginator(cluster_account_list_complete, 'cluster_account_list_complete') + removal_request_active, removal_request_complete = \ + self.get_removal_requests() + + create_paginator(removal_request_active, + 'removal_request_active') + context['num_removal_request_active'] = len(removal_request_active) + + create_paginator(removal_request_complete, + 'removal_request_complete') + return context \ No newline at end of file From 2b8805ac0ce3b0f8e8b3849ef797e78599446415 Mon Sep 17 00:00:00 2001 From: jofeinstein Date: Fri, 25 Feb 2022 18:23:53 -0500 Subject: [PATCH 06/85] moved cluster request table to separate html file --- .../request_hub/cluster_account_list.html | 112 +++++++++ .../templates/request_hub/request_hub.html | 232 +----------------- 2 files changed, 120 insertions(+), 224 deletions(-) create mode 100644 coldfront/core/user/templates/request_hub/cluster_account_list.html diff --git a/coldfront/core/user/templates/request_hub/cluster_account_list.html b/coldfront/core/user/templates/request_hub/cluster_account_list.html new file mode 100644 index 000000000..c7c699c51 --- /dev/null +++ b/coldfront/core/user/templates/request_hub/cluster_account_list.html @@ -0,0 +1,112 @@ +
    +
    + {% if queryset %} + +
    +
    +
    {{ adj }} Cluster Account Requests
    +
    + + + + + + + + + + + + + + {% for cluster_account in queryset %} + + + + + + + + + + {% endfor %} + +
    + # + + + + Date Requested/
    Last Modified + + +
    + User Email + + + + Cluster Username + + + + Project + + + + Allocation + + Status +
    {{ cluster_account.pk }}{{ cluster_account.modified|date:"M. d, Y" }}{{ cluster_account.allocation_user.user.email }} + {% if cluster_account.allocation_user.user.userprofile.cluster_uid %} + {{ cluster_account.allocation_user.user.username }} + {% else %} + + No cluster account. + + {% endif %} + + + {{ cluster_account.allocation.project.name }} + + + + Allocation {{ allocation.pk }} + {{ cluster_account.allocation.pk }} + + + {% with status=cluster_account.value %} + {% if status == "Pending - Add" %} + Pending + {% elif status == "Processing" %} + {{ status }} + {% elif status == "Active" %} + {{ status }} + {% elif status == "Denied" %} + {{ status }} + {% endif %} + {% endwith %} +
    + + Page {{ queryset.number }} of {{ queryset.paginator.num_pages }} +
      + {% if queryset.has_previous %} +
    • Previous
    • + {% else %} +
    • Previous
    • + {% endif %} + {% if queryset.has_next %} +
    • Next
    • + {% else %} +
    • Next
    • + {% endif %} +
    +
    +
    +
    + + {% else %} +
    + No {{ adj }} cluster account requests! +
    + {% endif %} +
    +
    diff --git a/coldfront/core/user/templates/request_hub/request_hub.html b/coldfront/core/user/templates/request_hub/request_hub.html index 4046a5e9a..f64077267 100644 --- a/coldfront/core/user/templates/request_hub/request_hub.html +++ b/coldfront/core/user/templates/request_hub/request_hub.html @@ -32,241 +32,25 @@

    Request Hub

    -
    -
    - {% if cluster_account_list_active %} + {% with queryset=cluster_account_list_active adj='active' page_num='0' %} + {% include 'request_hub/cluster_account_list.html' %} + {% endwith %} -
    -
    -
    Active Cluster Account Requests
    -
    - - - - - - - - - - - - - - {% for cluster_account in cluster_account_list_active %} - - - - - - - - - - {% endfor %} - -
    - # - - - - Date Requested/
    Last Modified - - -
    - User Email - - - - Cluster Username - - - - Project - - - - Allocation - - Status -
    {{ cluster_account.pk }}{{ cluster_account.modified|date:"M. d, Y" }}{{ cluster_account.allocation_user.user.email }} - {% if cluster_account.allocation_user.user.userprofile.cluster_uid %} - {{ cluster_account.allocation_user.user.username }} - {% else %} - - No cluster account. - - {% endif %} - - - {{ cluster_account.allocation.project.name }} - - - - Allocation {{ allocation.pk }} - {{ cluster_account.allocation.pk }} - - - {% with status=cluster_account.value %} - {% if status == "Pending - Add" %} - Pending - {% elif status == "Processing" %} - {{ status }} - {% elif status == "Active" %} - {{ status }} - {% elif status == "Denied" %} - {{ status }} - {% endif %} - {% endwith %} -
    - - Page {{ cluster_account_list_active.number }} of {{ cluster_account_list_active.paginator.num_pages }} -
      - {% if cluster_account_list_active.has_previous %} -
    • Previous
    • - {% else %} -
    • Previous
    • - {% endif %} - {% if cluster_account_list_active.has_next %} -
    • Next
    • - {% else %} -
    • Next
    • - {% endif %} -
    -
    -
    -
    - - {% else %} -
    - No active cluster account requests! -
    - {% endif %} -
    -
    - -
    -
    - {% if cluster_account_list_complete %} -
    -
    -
    Completed Cluster Account Requests
    -
    - - - - - - - - - - - - - - {% for cluster_account in cluster_account_list_complete %} - - - - - - - - - - {% endfor %} - -
    - # - - - - Date Requested/
    Last Modified - - -
    - User Email - - - - Cluster Username - - - - Project - - - - Allocation - - Status -
    {{ cluster_account.pk }}{{ cluster_account.modified|date:"M. d, Y" }}{{ cluster_account.allocation_user.user.email }} - {% if cluster_account.allocation_user.user.userprofile.cluster_uid %} - {{ cluster_account.allocation_user.user.username }} - {% else %} - - No cluster account. - - {% endif %} - - - {{ cluster_account.allocation.project.name }} - - - - Allocation {{ allocation.pk }} - {{ cluster_account.allocation.pk }} - - - {% with status=cluster_account.value %} - {% if status == "Pending - Add" %} - Pending - {% elif status == "Processing" %} - {{ status }} - {% elif status == "Active" %} - {{ status }} - {% elif status == "Denied" %} - {{ status }} - {% endif %} - {% endwith %} -
    - - Page {{ cluster_account_list_complete.number }} of {{ cluster_account_list_complete.paginator.num_pages }} -
      - {% if cluster_account_list_complete.has_previous %} -
    • Previous
    • - {% else %} -
    • Previous
    • - {% endif %} - {% if cluster_account_list_complete.has_next %} -
    • Next
    • - {% else %} -
    • Next
    • - {% endif %} -
    -
    -
    -
    - - {% else %} -
    - No completed cluster account requests! -
    - {% endif %} + {% with queryset=cluster_account_list_complete adj='complete' page_num='1' %} + {% include 'request_hub/cluster_account_list.html' %} + {% endwith %} {% if user.is_superuser %} -

    + {% endif %}
    - - {% endblock %} From 4d5d00dedba563a68e72d5bddba4cc2359da042d Mon Sep 17 00:00:00 2001 From: jofeinstein Date: Fri, 25 Feb 2022 20:41:58 -0500 Subject: [PATCH 07/85] added removal requests --- coldfront/core/user/views_/request_hub_views.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/coldfront/core/user/views_/request_hub_views.py b/coldfront/core/user/views_/request_hub_views.py index 3a22cf551..00c8ac387 100644 --- a/coldfront/core/user/views_/request_hub_views.py +++ b/coldfront/core/user/views_/request_hub_views.py @@ -48,6 +48,7 @@ class RequestHub(LoginRequiredMixin, template_name = 'request_hub/request_hub.html' paginate_by = 2 paginators = 0 + show_all_requests = False def get_cluster_account_requests(self): user = self.request.user @@ -138,4 +139,8 @@ def create_paginator(queryset, context_name): create_paginator(removal_request_complete, 'removal_request_complete') + context['show_all'] = (self.request.user.is_superuser or + self.request.user.is_staff) and \ + self.show_all_requests + return context \ No newline at end of file From 07299c6eeef84f3e55f9c6f465730eb45d86aaff Mon Sep 17 00:00:00 2001 From: jofeinstein Date: Fri, 25 Feb 2022 20:42:24 -0500 Subject: [PATCH 08/85] added removal requests --- .../request_hub/removal_request_list.html | 107 ++++++++++++++++++ .../templates/request_hub/request_hub.html | 51 ++++++++- 2 files changed, 154 insertions(+), 4 deletions(-) create mode 100644 coldfront/core/user/templates/request_hub/removal_request_list.html diff --git a/coldfront/core/user/templates/request_hub/removal_request_list.html b/coldfront/core/user/templates/request_hub/removal_request_list.html new file mode 100644 index 000000000..e031b1111 --- /dev/null +++ b/coldfront/core/user/templates/request_hub/removal_request_list.html @@ -0,0 +1,107 @@ +
    +
    + {% if queryset %} +
    +
    +
    {{ adj }} Project Removal Requests
    +
    + + + + + + + + + + + + + + {% for removal_request in queryset %} + + {% if show_all %} + + {% else %} + + {% endif %} + {% if adj == 'active' %} + + {% else %} + + {% endif %} + + + + + + + + {% endfor %} + +
    + # + + + + {% if adj == 'active' %} + Date Requested + {% else %} + Date Completed + {% endif %} + + + + User Email + + + + User + + + + Requester + + + + Project + + + + Status +
    {{ removal_request.pk }}{{ forloop.counter }}{{ removal_request.request_time|date:"M. d, Y" }}{{ removal_request.completion_time|date:"M. d, Y" }}{{ removal_request.project_user.user.email }}{{ removal_request.project_user.user.username }}{{ removal_request.requester.username }} + + {{ removal_request.project_user.project.name }} + + + {% with status=removal_request.status.name %} + {% if status == "Pending" %} + {{ status }} + {% elif status == "Processing" %} + {{ status }} + {% elif status == "Complete" %} + {{ status }} + {% endif %} + {% endwith %} +
    + + {% with pag_obj=queryset %} + {% include 'common/pagination.html' %} + {% endwith %} + +
    +
    +
    + {% else %} + {% if adj == 'active' %} +
    + No active project removal requests! +
    + {% else %} +
    + No completed project removal requests! +
    + {% endif %} + {% endif %} +
    +
    \ No newline at end of file diff --git a/coldfront/core/user/templates/request_hub/request_hub.html b/coldfront/core/user/templates/request_hub/request_hub.html index f64077267..b63ead754 100644 --- a/coldfront/core/user/templates/request_hub/request_hub.html +++ b/coldfront/core/user/templates/request_hub/request_hub.html @@ -10,10 +10,10 @@

    Request Hub

    -
    +
    - + -
    +
    {% with queryset=cluster_account_list_active adj='active' page_num='0' %} {% include 'request_hub/cluster_account_list.html' %} {% endwith %} - {% with queryset=cluster_account_list_complete adj='complete' page_num='1' %} + {% with queryset=cluster_account_list_complete adj='completed' page_num='1' %} {% include 'request_hub/cluster_account_list.html' %} {% endwith %} @@ -53,4 +53,47 @@

    Request Hub

    +
    +
    + +
    +
    + + {% with queryset=removal_request_active adj='active' page_num='2'%} + {% include 'request_hub/removal_request_list.html' %} + {% endwith %} + + {% with queryset=removal_request_complete adj='completed' page_num='3' %} + {% include 'request_hub/removal_request_list.html' %} + {% endwith %} + + {% if user.is_superuser %} + + {% endif %} +
    +
    +
    +
    + {% endblock %} From a60bec5925788874e516aa44caf6a11e3bf10137 Mon Sep 17 00:00:00 2001 From: jofeinstein Date: Fri, 25 Feb 2022 20:42:42 -0500 Subject: [PATCH 09/85] exported pagination code to separate html --- coldfront/templates/common/pagination.html | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 coldfront/templates/common/pagination.html diff --git a/coldfront/templates/common/pagination.html b/coldfront/templates/common/pagination.html new file mode 100644 index 000000000..8dc73231a --- /dev/null +++ b/coldfront/templates/common/pagination.html @@ -0,0 +1,13 @@ +Page {{ pag_obj.number }} of {{ pag_obj.paginator.num_pages }} +
      + {% if pag_obj.has_previous %} +
    • Previous
    • + {% else %} +
    • Previous
    • + {% endif %} + {% if pag_obj.has_next %} +
    • Next
    • + {% else %} +
    • Next
    • + {% endif %} +
    From 64302ad236627e202c64db77d62d0f5e25816033 Mon Sep 17 00:00:00 2001 From: jofeinstein Date: Fri, 25 Feb 2022 20:43:17 -0500 Subject: [PATCH 10/85] show forloop counter instead of pk if not superuser --- .../request_hub/cluster_account_list.html | 23 +++++++------------ 1 file changed, 8 insertions(+), 15 deletions(-) diff --git a/coldfront/core/user/templates/request_hub/cluster_account_list.html b/coldfront/core/user/templates/request_hub/cluster_account_list.html index c7c699c51..434de22b1 100644 --- a/coldfront/core/user/templates/request_hub/cluster_account_list.html +++ b/coldfront/core/user/templates/request_hub/cluster_account_list.html @@ -45,7 +45,11 @@
    {{ adj }} Cluste {% for cluster_account in queryset %} - {{ cluster_account.pk }} + {% if show_all %} + {{ cluster_account.pk }} + {% else %} + {{ forloop.counter }} + {% endif %} {{ cluster_account.modified|date:"M. d, Y" }} {{ cluster_account.allocation_user.user.email }} @@ -85,20 +89,9 @@
    {{ adj }} Cluste {% endfor %} - - Page {{ queryset.number }} of {{ queryset.paginator.num_pages }} -
      - {% if queryset.has_previous %} -
    • Previous
    • - {% else %} -
    • Previous
    • - {% endif %} - {% if queryset.has_next %} -
    • Next
    • - {% else %} -
    • Next
    • - {% endif %} -
    + {% with pag_obj=queryset %} + {% include 'common/pagination.html' %} + {% endwith %}
    From 910dbc4128d349c35f9ff927b419300a629a37fd Mon Sep 17 00:00:00 2001 From: jofeinstein Date: Sat, 26 Feb 2022 00:08:19 -0500 Subject: [PATCH 11/85] added script to maintain scroll position --- .../templates/request_hub/request_hub.html | 104 ++++-------------- 1 file changed, 19 insertions(+), 85 deletions(-) diff --git a/coldfront/core/user/templates/request_hub/request_hub.html b/coldfront/core/user/templates/request_hub/request_hub.html index b63ead754..9c6c163a0 100644 --- a/coldfront/core/user/templates/request_hub/request_hub.html +++ b/coldfront/core/user/templates/request_hub/request_hub.html @@ -10,90 +10,24 @@

    Request Hub

    -
    -
    - -
    -
    - - {% with queryset=cluster_account_list_active adj='active' page_num='0' %} - {% include 'request_hub/cluster_account_list.html' %} - {% endwith %} - - {% with queryset=cluster_account_list_complete adj='completed' page_num='1' %} - {% include 'request_hub/cluster_account_list.html' %} - {% endwith %} - - {% if user.is_superuser %} - - {% endif %} -
    -
    -
    -
    - -
    -
    - -
    -
    - - {% with queryset=removal_request_active adj='active' page_num='2'%} - {% include 'request_hub/removal_request_list.html' %} - {% endwith %} - - {% with queryset=removal_request_complete adj='completed' page_num='3' %} - {% include 'request_hub/removal_request_list.html' %} - {% endwith %} - - {% if user.is_superuser %} - - {% endif %} -
    -
    -
    -
    + {% with num=0 title='Cluster Account Requests' num_active=num_active_cluster_account_requests list_template='request_hub/cluster_account_list.html' active_queryset=cluster_account_list_active complete_queryset=cluster_account_list_complete button_path='allocation-cluster-account-request-list' button_text='Go To Cluster Account Requests Main Page' %} + {% include 'request_hub/request_section.html' %} + {% endwith %} + + {% with num=2 title='Project Removal Requests' num_active=num_removal_request_active list_template='request_hub/removal_request_list.html' active_queryset=removal_request_active complete_queryset=removal_request_complete button_path='project-removal-request-list' button_text='Go To Project Removal Requests Main Page' %} + {% include 'request_hub/request_section.html' %} + {% endwith %} + + {% endblock %} From d8fcac4520e840208994a2cf229df095bbcacb77 Mon Sep 17 00:00:00 2001 From: jofeinstein Date: Sat, 26 Feb 2022 00:08:45 -0500 Subject: [PATCH 12/85] initial commit --- .../request_hub/request_section.html | 64 +++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 coldfront/core/user/templates/request_hub/request_section.html diff --git a/coldfront/core/user/templates/request_hub/request_section.html b/coldfront/core/user/templates/request_hub/request_section.html new file mode 100644 index 000000000..87d8161b0 --- /dev/null +++ b/coldfront/core/user/templates/request_hub/request_section.html @@ -0,0 +1,64 @@ +
    +
    + +
    +
    + + {% with queryset=active_queryset adj='active' page_num=num %} + {% include list_template %} + {% endwith %} + + {% with queryset=complete_queryset adj='completed' page_num=num|add:1 %} + {% include list_template %} + {% endwith %} + + {% if user.is_superuser %} + + {% endif %} +
    +
    +
    +
    + + From a6944e5a841aa09c76f2fd297b712baafc97a15b Mon Sep 17 00:00:00 2001 From: jofeinstein Date: Sat, 26 Feb 2022 10:32:39 -0500 Subject: [PATCH 13/85] created obj to store values used in templates --- .../templates/request_hub/request_hub.html | 8 +- .../request_hub/request_section.html | 24 +-- .../core/user/views_/request_hub_views.py | 154 ++++++++++-------- 3 files changed, 99 insertions(+), 87 deletions(-) diff --git a/coldfront/core/user/templates/request_hub/request_hub.html b/coldfront/core/user/templates/request_hub/request_hub.html index 9c6c163a0..7437dd74a 100644 --- a/coldfront/core/user/templates/request_hub/request_hub.html +++ b/coldfront/core/user/templates/request_hub/request_hub.html @@ -10,13 +10,13 @@

    Request Hub

    - {% with num=0 title='Cluster Account Requests' num_active=num_active_cluster_account_requests list_template='request_hub/cluster_account_list.html' active_queryset=cluster_account_list_active complete_queryset=cluster_account_list_complete button_path='allocation-cluster-account-request-list' button_text='Go To Cluster Account Requests Main Page' %} + {% with request_obj=cluster_account_request_obj %} {% include 'request_hub/request_section.html' %} {% endwith %} - {% with num=2 title='Project Removal Requests' num_active=num_removal_request_active list_template='request_hub/removal_request_list.html' active_queryset=removal_request_active complete_queryset=removal_request_complete button_path='project-removal-request-list' button_text='Go To Project Removal Requests Main Page' %} - {% include 'request_hub/request_section.html' %} - {% endwith %} +{# {% with num=2 title='Project Removal Requests' num_active=num_active_removal_request list_template='request_hub/removal_request_list.html' active_queryset=removal_request_active complete_queryset=removal_request_complete button_path='project-removal-request-list' button_text='Go To Project Removal Requests Main Page' %}#} +{# {% include 'request_hub/request_section.html' %}#} +{# {% endwith %}#} {% endblock %} diff --git a/coldfront/templates/common/authorized_navbar.html b/coldfront/templates/common/authorized_navbar.html index fb18dafea..3a486beb8 100644 --- a/coldfront/templates/common/authorized_navbar.html +++ b/coldfront/templates/common/authorized_navbar.html @@ -30,7 +30,7 @@ -
  • +
  • {% if request.user.is_superuser %} From f2da3322c6f1adb51fdd74f7bd088b7183cd3dff Mon Sep 17 00:00:00 2001 From: jofeinstein Date: Sat, 26 Feb 2022 11:19:28 -0500 Subject: [PATCH 17/85] removed sorting options, added title to list template include --- .../request_hub/cluster_account_list.html | 10 ------- .../request_hub/removal_request_list.html | 26 +++---------------- 2 files changed, 4 insertions(+), 32 deletions(-) diff --git a/coldfront/core/user/templates/request_hub/cluster_account_list.html b/coldfront/core/user/templates/request_hub/cluster_account_list.html index 434de22b1..9761e2700 100644 --- a/coldfront/core/user/templates/request_hub/cluster_account_list.html +++ b/coldfront/core/user/templates/request_hub/cluster_account_list.html @@ -11,28 +11,18 @@
    {{ adj }} Cluste # - - Date Requested/
    Last Modified - - User Email - - Cluster Username - - Project - - Allocation diff --git a/coldfront/core/user/templates/request_hub/removal_request_list.html b/coldfront/core/user/templates/request_hub/removal_request_list.html index e031b1111..aefd47bed 100644 --- a/coldfront/core/user/templates/request_hub/removal_request_list.html +++ b/coldfront/core/user/templates/request_hub/removal_request_list.html @@ -3,15 +3,13 @@ {% if queryset %}
    -
    {{ adj }} Project Removal Requests
    +
    {{ adj }} {{ title }}
    - - -
    # - - {% if adj == 'active' %} @@ -19,28 +17,18 @@
    {{ adj }} Projec {% else %} Date Completed {% endif %} - -
    User Email - - User - - Requester - - Project - - Status @@ -93,15 +81,9 @@
    {{ adj }} Projec {% else %} - {% if adj == 'active' %} -
    - No active project removal requests! -
    - {% else %} -
    - No completed project removal requests! -
    - {% endif %} +
    + No {{ adj }} project removal requests! +
    {% endif %} \ No newline at end of file From 3f7b881f2756fcbbdf063149f932f3cdb8d7433a Mon Sep 17 00:00:00 2001 From: jofeinstein Date: Sat, 26 Feb 2022 11:19:50 -0500 Subject: [PATCH 18/85] adding savio project requests --- .../savio_project_request_list.html | 78 +++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100644 coldfront/core/user/templates/request_hub/savio_project_request_list.html diff --git a/coldfront/core/user/templates/request_hub/savio_project_request_list.html b/coldfront/core/user/templates/request_hub/savio_project_request_list.html new file mode 100644 index 000000000..87b4527c8 --- /dev/null +++ b/coldfront/core/user/templates/request_hub/savio_project_request_list.html @@ -0,0 +1,78 @@ +
    +
    + {% if queryset %} +
    +
    +
    {{ adj }} Savio Project Requests
    +
    + + + + + + + + + + + + + + + {% for savio_project_request in queryset %} + + + + + + + + + + + {% endfor %} + +
    + # + + Date Requested/
    Last Modified +
    + Requester Email + + Project + + Allocation Type + Pooling? + PI + Status
    + + Project {{ savio_project_request.pk }} + {{ savio_project_request.pk }} + + {{ savio_project_request.modified|date:"M. d, Y" }}{{ savio_project_request.requester.email }}{{ savio_project_request.project.name }}{{ savio_project_request.allocation_type }}{{ savio_project_request.pool }}{{ savio_project_request.pi.email }} + {% with status=savio_project_request.status.name %} + {% if status == 'Under Review' %} + {{ status }} + {% elif status == 'Approved - Processing' %} + {{ status }} + {% elif status == 'Approved - Complete' %} + {{ status }} + {% else %} + {{ status }} + {% endif %} + {% endwith %} +
    + + {% with pag_obj=queryset %} + {% include 'common/pagination.html' %} + {% endwith %} +
    +
    +
    + {% else %} +
    + No {{ adj }} Savio project requests! +
    + {% endif %} +
    +
    \ No newline at end of file From 8608b62331a4b0ee76f4fa0f665d5e6b48745c26 Mon Sep 17 00:00:00 2001 From: jofeinstein Date: Sat, 26 Feb 2022 11:20:06 -0500 Subject: [PATCH 19/85] adding savio project requests --- .../core/user/views_/request_hub_views.py | 64 +++++++++++++------ 1 file changed, 45 insertions(+), 19 deletions(-) diff --git a/coldfront/core/user/views_/request_hub_views.py b/coldfront/core/user/views_/request_hub_views.py index a143bdd4b..ef291d2e0 100644 --- a/coldfront/core/user/views_/request_hub_views.py +++ b/coldfront/core/user/views_/request_hub_views.py @@ -24,7 +24,8 @@ from coldfront.core.project.models import (Project, ProjectUserStatusChoice, ProjectUserRemovalRequest, - ProjectUserRemovalRequestStatusChoice) + ProjectUserRemovalRequestStatusChoice, + SavioProjectAllocationRequest) from coldfront.core.project.utils_.removal_utils import ProjectRemovalRequestRunner from coldfront.core.utils.common import (import_from_settings, utc_now_offset_aware) @@ -60,7 +61,6 @@ class RequestHub(LoginRequiredMixin, paginate_by = 5 paginators = 0 show_all_requests = False - cur_num = 0 def create_paginator(self, queryset): """ @@ -88,17 +88,16 @@ def get_cluster_account_request(self): cluster_account_status = AllocationAttributeType.objects.get( name='Cluster Account Status') + kwargs = {'allocation_user__user': user, + 'allocation_attribute_type': cluster_account_status} cluster_account_list_complete = AllocationUserAttribute.objects.filter( - allocation_attribute_type=cluster_account_status, - value__in=['Denied', 'Active'], - allocation_user__user=user) + value__in=['Denied', 'Active'], **kwargs) cluster_account_list_active = AllocationUserAttribute.objects.filter( - allocation_attribute_type=cluster_account_status, - value__in=['Pending - Add', 'Processing'], - allocation_user__user=user) + value__in=['Pending - Add', 'Processing'], **kwargs) + cluster_request_object.num = self.paginators cluster_request_object.active_queryset = \ self.create_paginator(cluster_account_list_active) @@ -114,8 +113,6 @@ def get_cluster_account_request(self): 'allocation-cluster-account-request-list' cluster_request_object.button_text = \ 'Go To Cluster Account Requests Main Page' - cluster_request_object.num = self.cur_num - self.cur_num += 2 return cluster_request_object @@ -124,17 +121,15 @@ def get_project_removal_request(self): removal_request_object = RequestListItem() user = self.request.user - project_user_cond = Q(project_user__user=user) - requester_cond = Q(requester=user) + args = [Q(project_user__user=user) | Q(requester=user)] removal_request_active = ProjectUserRemovalRequest.objects.filter( - status__name__in=['Pending', 'Processing']).\ - filter(project_user_cond | requester_cond) + status__name__in=['Pending', 'Processing'], *args) removal_request_complete = ProjectUserRemovalRequest.objects.filter( - status__name='Complete').\ - filter(project_user_cond | requester_cond) + status__name='Complete', *args) + removal_request_object.num = self.paginators removal_request_object.active_queryset = \ self.create_paginator(removal_request_active) @@ -150,16 +145,47 @@ def get_project_removal_request(self): 'project-removal-request-list' removal_request_object.button_text = \ 'Go To Project Removal Requests Main Page' - removal_request_object.num = self.cur_num - self.cur_num += 2 return removal_request_object + def get_savio_project_request(self): + """Populates a RequestListItem with data for savio project requests""" + savio_proj_request_object = RequestListItem() + user = self.request.user + + args = [Q(pi=user) | Q(requester=user)] + + project_request_active = SavioProjectAllocationRequest.objects.filter( + status__name__in=['Under Review', 'Approved - Processing'], *args) + + project_request_complete = SavioProjectAllocationRequest.objects.filter( + status__name__in=['Approved - Complete', 'Denied'], *args) + + savio_proj_request_object.num = self.paginators + savio_proj_request_object.active_queryset = \ + self.create_paginator(project_request_active) + + savio_proj_request_object.complete_queryset = \ + self.create_paginator(project_request_complete) + + savio_proj_request_object.num_active = project_request_active.count() + + savio_proj_request_object.title = 'Savio Project Requests' + savio_proj_request_object.list_template = \ + 'request_hub/savio_project_request_list.html' + savio_proj_request_object.button_path = \ + 'savio-project-pending-request-list' + savio_proj_request_object.button_text = \ + 'Go To Savio Project Requests Main Page' + + return savio_proj_request_object + def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) requests = ['cluster_account_request', - 'project_removal_request'] + 'project_removal_request', + 'savio_project_request'] for request in requests: context[f'{request}_obj'] = eval(f'self.get_{request}()') From 81893d05f6eacce5d5c6101b6c23628f24e245d2 Mon Sep 17 00:00:00 2001 From: jofeinstein Date: Sat, 26 Feb 2022 11:21:39 -0500 Subject: [PATCH 20/85] added title vairable to list template --- .../core/user/templates/request_hub/request_section.html | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/coldfront/core/user/templates/request_hub/request_section.html b/coldfront/core/user/templates/request_hub/request_section.html index bb087c8e1..ec2576957 100644 --- a/coldfront/core/user/templates/request_hub/request_section.html +++ b/coldfront/core/user/templates/request_hub/request_section.html @@ -17,14 +17,14 @@ -
    +
    - {% with queryset=request_obj.active_queryset adj='active' page_num=request_obj.num %} + {% with queryset=request_obj.active_queryset adj='active' page_num=request_obj.num title=request_obj.title %} {% include request_obj.list_template %} {% endwith %} - {% with queryset=request_obj.complete_queryset adj='completed' page_num=request_obj.num|add:1 %} + {% with queryset=request_obj.complete_queryset adj='completed' page_num=request_obj.num|add:1 title=request_obj.title %} {% include request_obj.list_template %} {% endwith %} From 5734fba7d1d3b7721450b2bbcb90a70a4a40ef2b Mon Sep 17 00:00:00 2001 From: jofeinstein Date: Sat, 26 Feb 2022 11:22:02 -0500 Subject: [PATCH 21/85] adding savio project requests --- coldfront/core/user/templates/request_hub/request_hub.html | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/coldfront/core/user/templates/request_hub/request_hub.html b/coldfront/core/user/templates/request_hub/request_hub.html index 59aafcef0..bac2c11f9 100644 --- a/coldfront/core/user/templates/request_hub/request_hub.html +++ b/coldfront/core/user/templates/request_hub/request_hub.html @@ -18,6 +18,10 @@

    Request Hub

    {% include 'request_hub/request_section.html' %} {% endwith %} + {% with request_obj=savio_project_request_obj %} + {% include 'request_hub/request_section.html' %} + {% endwith %} + {% endblock %} From f833049bb72ff9a5e3438fd7ac1e9cf54d3f3e5e Mon Sep 17 00:00:00 2001 From: jofeinstein Date: Sat, 26 Feb 2022 16:32:16 -0500 Subject: [PATCH 25/85] moved collapse script to request_hub.html --- .../request_hub/request_section.html | 21 ------------------- 1 file changed, 21 deletions(-) diff --git a/coldfront/core/user/templates/request_hub/request_section.html b/coldfront/core/user/templates/request_hub/request_section.html index ec2576957..ea85484c4 100644 --- a/coldfront/core/user/templates/request_hub/request_section.html +++ b/coldfront/core/user/templates/request_hub/request_section.html @@ -41,24 +41,3 @@
    - From d27c75a0941588069ea0407ad502f46881952bff Mon Sep 17 00:00:00 2001 From: jofeinstein Date: Sat, 26 Feb 2022 16:32:52 -0500 Subject: [PATCH 26/85] added request hub to admin dropdown --- coldfront/templates/common/navbar_admin.html | 3 +++ 1 file changed, 3 insertions(+) diff --git a/coldfront/templates/common/navbar_admin.html b/coldfront/templates/common/navbar_admin.html index 114185bea..a8b729388 100644 --- a/coldfront/templates/common/navbar_admin.html +++ b/coldfront/templates/common/navbar_admin.html @@ -13,6 +13,9 @@
  • -
    +
    {% with queryset=request_obj.active_queryset adj='active' page_num=request_obj.num title=request_obj.title %} From 3a586a6ea57c150159f5ebdb3bd9cc927e6bf803 Mon Sep 17 00:00:00 2001 From: jofeinstein Date: Sat, 26 Feb 2022 23:21:41 -0500 Subject: [PATCH 48/85] added order_by to all queries --- .../core/user/views_/request_hub_views.py | 107 +++++++++++------- 1 file changed, 67 insertions(+), 40 deletions(-) diff --git a/coldfront/core/user/views_/request_hub_views.py b/coldfront/core/user/views_/request_hub_views.py index dcbdd2d16..0442a3d11 100644 --- a/coldfront/core/user/views_/request_hub_views.py +++ b/coldfront/core/user/views_/request_hub_views.py @@ -69,11 +69,15 @@ def get_cluster_account_request(self): if not self.show_all_requests: kwargs['allocation_user__user'] = user - cluster_account_list_complete = AllocationUserAttribute.objects.filter( - value__in=['Denied', 'Active'], **kwargs) + cluster_account_list_complete = \ + AllocationUserAttribute.objects.filter( + value__in=['Denied', 'Active'], **kwargs).order_by( + 'modified') - cluster_account_list_active = AllocationUserAttribute.objects.filter( - value__in=['Pending - Add', 'Processing'], **kwargs) + cluster_account_list_active = \ + AllocationUserAttribute.objects.filter( + value__in=['Pending - Add', 'Processing'], **kwargs).order_by( + 'modified') cluster_request_object.num = self.paginators cluster_request_object.active_queryset = \ @@ -103,11 +107,15 @@ def get_project_removal_request(self): if not self.show_all_requests: args.append(Q(project_user__user=user) | Q(requester=user)) - removal_request_active = ProjectUserRemovalRequest.objects.filter( - status__name__in=['Pending', 'Processing'], *args) + removal_request_active = \ + ProjectUserRemovalRequest.objects.filter( + status__name__in=['Pending', 'Processing'], *args).order_by( + 'modified') - removal_request_complete = ProjectUserRemovalRequest.objects.filter( - status__name='Complete', *args) + removal_request_complete = \ + ProjectUserRemovalRequest.objects.filter( + status__name='Complete', *args).order_by( + 'modified') removal_request_object.num = self.paginators removal_request_object.active_queryset = \ @@ -137,11 +145,17 @@ def get_savio_project_request(self): if not self.show_all_requests: args.append(Q(pi=user) | Q(requester=user)) - project_request_active = SavioProjectAllocationRequest.objects.filter( - status__name__in=['Under Review', 'Approved - Processing'], *args) + project_request_active = \ + SavioProjectAllocationRequest.objects.filter( + status__name__in=['Under Review', 'Approved - Processing'], + *args).order_by( + 'modified') - project_request_complete = SavioProjectAllocationRequest.objects.filter( - status__name__in=['Approved - Complete', 'Denied'], *args) + project_request_complete = \ + SavioProjectAllocationRequest.objects.filter( + status__name__in=['Approved - Complete', 'Denied'], + *args).order_by( + 'modified') savio_proj_request_object.num = self.paginators savio_proj_request_object.active_queryset = \ @@ -171,11 +185,17 @@ def get_vector_project_request(self): if not self.show_all_requests: args.append(Q(pi=user) | Q(requester=user)) - project_request_active = VectorProjectAllocationRequest.objects.filter( - status__name__in=['Under Review', 'Approved - Processing'], *args) + project_request_active = \ + VectorProjectAllocationRequest.objects.filter( + status__name__in=['Under Review', 'Approved - Processing'], + *args).order_by( + 'modified') - project_request_complete = VectorProjectAllocationRequest.objects.filter( - status__name__in=['Approved - Complete', 'Denied'], *args) + project_request_complete = \ + VectorProjectAllocationRequest.objects.filter( + status__name__in=['Approved - Complete', 'Denied'], + *args).order_by( + 'modified') vector_proj_request_object.num = self.paginators vector_proj_request_object.active_queryset = \ @@ -205,11 +225,16 @@ def get_project_join_request(self): if not self.show_all_requests: args.append(Q(project_user__user=user)) - project_join_request_active = ProjectUserJoinRequest.objects.filter( - project_user__status__name='Pending - Add', *args) + project_join_request_active = \ + ProjectUserJoinRequest.objects.filter( + project_user__status__name='Pending - Add', *args).order_by( + 'modified') - project_join_request_complete = ProjectUserJoinRequest.objects.filter( - project_user__status__name__in=['Active', 'Denied'], *args) + project_join_request_complete = \ + ProjectUserJoinRequest.objects.filter( + project_user__status__name__in=['Active', 'Denied'], + *args).order_by( + 'modified') proj_join_request_object.num = self.paginators proj_join_request_object.active_queryset = \ @@ -239,11 +264,15 @@ def get_project_renewal_request(self): if not self.show_all_requests: args.append(Q(requester=user) | Q(pi=user)) - project_renewal_request_active = AllocationRenewalRequest.objects.filter( - status__name__in=['Approved', 'Under Review'], *args) + project_renewal_request_active = \ + AllocationRenewalRequest.objects.filter( + status__name__in=['Approved', 'Under Review'], *args).order_by( + 'modified') - project_renewal_request_complete = AllocationRenewalRequest.objects.filter( - status__name__in=['Complete', 'Denied'], *args) + project_renewal_request_complete = \ + AllocationRenewalRequest.objects.filter( + status__name__in=['Complete', 'Denied'], *args).order_by( + 'modified') proj_renewal_request_object.num = self.paginators proj_renewal_request_object.active_queryset = \ @@ -269,33 +298,33 @@ def get_su_purchase_request(self): su_pruchase_request_object = RequestListItem() user = self.request.user - su_pruchase_request_active = AllocationAdditionRequest.objects.filter( - status__name__in=['Under Review']) + su_purchase_request_active = AllocationAdditionRequest.objects.filter( + status__name__in=['Under Review']).order_by('modified') - su_pruchase_request_complete = AllocationAdditionRequest.objects.filter( - status__name__in=['Complete', 'Denied']) + su_purchase_request_complete = AllocationAdditionRequest.objects.filter( + status__name__in=['Complete', 'Denied']).order_by('modified') if not self.show_all_requests: request_ids = [ - r.id for r in su_pruchase_request_active + r.id for r in su_purchase_request_active if is_user_manager_or_pi_of_project(user, r.project)] - su_pruchase_request_active = \ - su_pruchase_request_active.filter(id__in=request_ids) + su_purchase_request_active = \ + su_purchase_request_active.filter(id__in=request_ids) request_ids = [ - r.id for r in su_pruchase_request_complete + r.id for r in su_purchase_request_complete if is_user_manager_or_pi_of_project(user, r.project)] - su_pruchase_request_complete = \ - su_pruchase_request_complete.filter(id__in=request_ids) + su_purchase_request_complete = \ + su_purchase_request_complete.filter(id__in=request_ids) su_pruchase_request_object.num = self.paginators su_pruchase_request_object.active_queryset = \ - self.create_paginator(su_pruchase_request_active) + self.create_paginator(su_purchase_request_active) su_pruchase_request_object.complete_queryset = \ - self.create_paginator(su_pruchase_request_complete) + self.create_paginator(su_purchase_request_complete) - su_pruchase_request_object.num_active = su_pruchase_request_active.count() + su_pruchase_request_object.num_active = su_purchase_request_active.count() su_pruchase_request_object.title = 'Service Unit Purchase Requests' su_pruchase_request_object.table = \ @@ -322,12 +351,10 @@ def get_context_data(self, **kwargs): context[f'{request}_obj'] = eval(f'self.get_{request}()') context['show_all'] = ((self.request.user.is_superuser or - self.request.user.is_staff) and + self.request.user.is_staff) and self.show_all_requests) context['admin_staff'] = (self.request.user.is_superuser or self.request.user.is_staff) - context['pi_manager'] = None - return context From 23341e670a0ad886c656e576c4a2145949969bc0 Mon Sep 17 00:00:00 2001 From: jofeinstein Date: Sat, 26 Feb 2022 23:35:25 -0500 Subject: [PATCH 49/85] moved buttons --- .../templates/request_hub/request_hub.html | 29 ++++++++++--------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/coldfront/core/user/templates/request_hub/request_hub.html b/coldfront/core/user/templates/request_hub/request_hub.html index 80abcca40..474d856d1 100644 --- a/coldfront/core/user/templates/request_hub/request_hub.html +++ b/coldfront/core/user/templates/request_hub/request_hub.html @@ -23,25 +23,26 @@

    Request Hub

    -
    - - -
    -
    +
    +
    +
    + + +
    +
    +
    + {% with request_obj=cluster_account_request_obj %} {% include 'request_hub/request_section.html' %} From 91609724d451348a21ba3c38cb88e0cbe47e0755 Mon Sep 17 00:00:00 2001 From: jofeinstein Date: Sat, 26 Feb 2022 23:35:46 -0500 Subject: [PATCH 50/85] fixed wrong href in button --- coldfront/core/user/templates/request_hub/request_section.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/coldfront/core/user/templates/request_hub/request_section.html b/coldfront/core/user/templates/request_hub/request_section.html index 9fca67180..b62aa99cd 100644 --- a/coldfront/core/user/templates/request_hub/request_section.html +++ b/coldfront/core/user/templates/request_hub/request_section.html @@ -1,7 +1,7 @@
    - +
    From 749ce698d9620d7445d07bbae632994b287a2437 Mon Sep 17 00:00:00 2001 From: jofeinstein Date: Sat, 26 Feb 2022 23:38:25 -0500 Subject: [PATCH 51/85] changed name of request hub --- coldfront/templates/common/navbar_admin.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/coldfront/templates/common/navbar_admin.html b/coldfront/templates/common/navbar_admin.html index a8b729388..4b3f539ac 100644 --- a/coldfront/templates/common/navbar_admin.html +++ b/coldfront/templates/common/navbar_admin.html @@ -14,7 +14,7 @@
    - From 65210ae97767cbce4a4194417e5096815e4fd09a Mon Sep 17 00:00:00 2001 From: jofeinstein Date: Sat, 26 Feb 2022 23:47:13 -0500 Subject: [PATCH 56/85] fixed newlines --- coldfront/core/user/templates/request_hub/request_hub.html | 3 --- 1 file changed, 3 deletions(-) diff --git a/coldfront/core/user/templates/request_hub/request_hub.html b/coldfront/core/user/templates/request_hub/request_hub.html index 474d856d1..f7c055696 100644 --- a/coldfront/core/user/templates/request_hub/request_hub.html +++ b/coldfront/core/user/templates/request_hub/request_hub.html @@ -20,14 +20,12 @@

    Request Hub

    Click
    here to view all requests in the myBRC Portal. {% endif %} {% endif %} -
    -
    @@ -43,7 +41,6 @@

    Request Hub

    - {% with request_obj=cluster_account_request_obj %} {% include 'request_hub/request_section.html' %} {% endwith %} From 34729f896003a010c9d9b206eef48fdbee5e0d7c Mon Sep 17 00:00:00 2001 From: jofeinstein Date: Sun, 27 Feb 2022 01:10:46 -0500 Subject: [PATCH 57/85] changed pag_obj to page_obj. added conditional to pagination.html --- .../user/templates/request_hub/request_section.html | 4 ++-- coldfront/templates/common/pagination.html | 11 ++++++----- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/coldfront/core/user/templates/request_hub/request_section.html b/coldfront/core/user/templates/request_hub/request_section.html index d59d37147..781ff4f4b 100644 --- a/coldfront/core/user/templates/request_hub/request_section.html +++ b/coldfront/core/user/templates/request_hub/request_section.html @@ -25,7 +25,7 @@
    {{ adj }} {{ title }}
    {% include request_obj.table %} - {% with pag_obj=queryset %} + {% with page_obj=queryset %} {% include 'common/pagination.html' %} {% endwith %}
    @@ -48,7 +48,7 @@
    {{ adj }} {{ tit
    {{ adj }} {{ title }}
    {% include request_obj.table %} - {% with pag_obj=queryset %} + {% with page_obj=queryset %} {% include 'common/pagination.html' %} {% endwith %}
    diff --git a/coldfront/templates/common/pagination.html b/coldfront/templates/common/pagination.html index 8dc73231a..00d7cbc83 100644 --- a/coldfront/templates/common/pagination.html +++ b/coldfront/templates/common/pagination.html @@ -1,13 +1,14 @@ -Page {{ pag_obj.number }} of {{ pag_obj.paginator.num_pages }} +{% if is_paginated %} Page {{ page_obj.number }} of {{ page_obj.paginator.num_pages }}
      - {% if pag_obj.has_previous %} -
    • Previous
    • + {% if page_obj.has_previous %} +
    • Previous
    • {% else %}
    • Previous
    • {% endif %} - {% if pag_obj.has_next %} -
    • Next
    • + {% if page_obj.has_next %} +
    • Next
    • {% else %}
    • Next
    • {% endif %}
    +{% endif %} From 2202c0efe9d402cce7734acf0c793d6411861f72 Mon Sep 17 00:00:00 2001 From: JoJo Feinstein Date: Mon, 28 Feb 2022 10:00:32 -0500 Subject: [PATCH 58/85] removed if paginated as it didnt work in request hub --- coldfront/templates/common/pagination.html | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/coldfront/templates/common/pagination.html b/coldfront/templates/common/pagination.html index 00d7cbc83..39294c611 100644 --- a/coldfront/templates/common/pagination.html +++ b/coldfront/templates/common/pagination.html @@ -1,4 +1,4 @@ -{% if is_paginated %} Page {{ page_obj.number }} of {{ page_obj.paginator.num_pages }} +Page {{ page_obj.number }} of {{ page_obj.paginator.num_pages }}
      {% if page_obj.has_previous %}
    • Previous
    • @@ -11,4 +11,3 @@
    • Next
    • {% endif %}
    -{% endif %} From 4fc20b1fb6131b6a1c4f824b01344aa2d4c7ed53 Mon Sep 17 00:00:00 2001 From: JoJo Feinstein Date: Mon, 28 Feb 2022 10:00:56 -0500 Subject: [PATCH 59/85] refactored expand/collapse all scripts --- .../core/user/templates/request_hub/request_hub.html | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/coldfront/core/user/templates/request_hub/request_hub.html b/coldfront/core/user/templates/request_hub/request_hub.html index f7c055696..ef17e6cfc 100644 --- a/coldfront/core/user/templates/request_hub/request_hub.html +++ b/coldfront/core/user/templates/request_hub/request_hub.html @@ -1,4 +1,6 @@ -{% extends "common/base.html" %} {% load common_tags %} {% block content %} +{% extends "common/base.html" %} +{% load common_tags %} +{% block content %}

    Request Hub

    @@ -104,15 +106,13 @@

    Request Hub

    if (scrollpos && resetpos) window.scrollTo(0, scrollpos); $(document).on('click', '#expand_all_button', function() { - var matches = document.querySelectorAll("[id^='collapse-']"); - matches.forEach(function (item, index) { + document.querySelectorAll("[id^='collapse-']").forEach(function (item, index) { $(item).collapse("show"); }); }); $(document).on('click', '#collapse_all_button', function() { - var matches = document.querySelectorAll("[id^='collapse-']"); - matches.forEach(function (item, index) { + document.querySelectorAll("[id^='collapse-']").forEach(function (item, index) { $(item).collapse("hide"); }); }); From dbe07749c686b93bc4b9223811a26ac757e34381 Mon Sep 17 00:00:00 2001 From: jofeinstein Date: Mon, 28 Feb 2022 13:18:27 -0500 Subject: [PATCH 60/85] changed active to pending --- .../request_hub/request_section.html | 6 +- .../core/user/views_/request_hub_views.py | 78 +++++++++---------- 2 files changed, 42 insertions(+), 42 deletions(-) diff --git a/coldfront/core/user/templates/request_hub/request_section.html b/coldfront/core/user/templates/request_hub/request_section.html index 781ff4f4b..77442d756 100644 --- a/coldfront/core/user/templates/request_hub/request_section.html +++ b/coldfront/core/user/templates/request_hub/request_section.html @@ -5,10 +5,10 @@
    {{ request_obj.title}} - {% if request_obj.num_active %} + {% if request_obj.num_pending %} - {{ request_obj.num_active }} active requests + {{ request_obj.num_pending }} pending requests {% endif %}
    @@ -16,7 +16,7 @@
    - {% with queryset=request_obj.active_queryset adj='active' page_num=request_obj.num title=request_obj.title %} + {% with queryset=request_obj.pending_queryset adj='pending' page_num=request_obj.num title=request_obj.title %}
    {% if queryset %} diff --git a/coldfront/core/user/views_/request_hub_views.py b/coldfront/core/user/views_/request_hub_views.py index 021f54ebb..5c050f412 100644 --- a/coldfront/core/user/views_/request_hub_views.py +++ b/coldfront/core/user/views_/request_hub_views.py @@ -21,16 +21,16 @@ class RequestListItem: in the request hub """ - __slots__ = ['num', 'title', 'num_active', 'table', - 'active_queryset', 'complete_queryset', + __slots__ = ['num', 'title', 'num_pending', 'table', + 'pending_queryset', 'complete_queryset', 'button_path', 'button_text'] def __init__(self): num = None title = None - num_active = None + num_pending = None table = None - active_queryset = None + pending_queryset = None complete_queryset = None button_path = None button_text = None @@ -79,19 +79,19 @@ def get_cluster_account_request(self): value__in=['Denied', 'Active'], **kwargs).order_by( 'modified') - cluster_account_list_active = \ + cluster_account_list_pending = \ AllocationUserAttribute.objects.filter( value__in=['Pending - Add', 'Processing'], **kwargs).order_by( 'modified') cluster_request_object.num = self.paginators - cluster_request_object.active_queryset = \ - self.create_paginator(cluster_account_list_active) + cluster_request_object.pending_queryset = \ + self.create_paginator(cluster_account_list_pending) cluster_request_object.complete_queryset = \ self.create_paginator(cluster_account_list_complete) - cluster_request_object.num_active = cluster_account_list_active.count() + cluster_request_object.num_pending = cluster_account_list_pending.count() cluster_request_object.title = 'Cluster Account Requests' cluster_request_object.table = \ @@ -112,7 +112,7 @@ def get_project_removal_request(self): if not self.show_all_requests: args.append(Q(project_user__user=user) | Q(requester=user)) - removal_request_active = \ + removal_request_pending = \ ProjectUserRemovalRequest.objects.filter( status__name__in=['Pending', 'Processing'], *args).order_by( 'modified') @@ -123,13 +123,13 @@ def get_project_removal_request(self): 'modified') removal_request_object.num = self.paginators - removal_request_object.active_queryset = \ - self.create_paginator(removal_request_active) + removal_request_object.pending_queryset = \ + self.create_paginator(removal_request_pending) removal_request_object.complete_queryset = \ self.create_paginator(removal_request_complete) - removal_request_object.num_active = removal_request_active.count() + removal_request_object.num_pending = removal_request_pending.count() removal_request_object.title = 'Project Removal Requests' removal_request_object.table = \ @@ -150,7 +150,7 @@ def get_savio_project_request(self): if not self.show_all_requests: args.append(Q(pi=user) | Q(requester=user)) - project_request_active = \ + project_request_pending = \ SavioProjectAllocationRequest.objects.filter( status__name__in=['Under Review', 'Approved - Processing'], *args).order_by( @@ -163,13 +163,13 @@ def get_savio_project_request(self): 'modified') savio_proj_request_object.num = self.paginators - savio_proj_request_object.active_queryset = \ - self.create_paginator(project_request_active) + savio_proj_request_object.pending_queryset = \ + self.create_paginator(project_request_pending) savio_proj_request_object.complete_queryset = \ self.create_paginator(project_request_complete) - savio_proj_request_object.num_active = project_request_active.count() + savio_proj_request_object.num_pending = project_request_pending.count() savio_proj_request_object.title = 'Savio Project Requests' savio_proj_request_object.table = \ @@ -190,7 +190,7 @@ def get_vector_project_request(self): if not self.show_all_requests: args.append(Q(pi=user) | Q(requester=user)) - project_request_active = \ + project_request_pending = \ VectorProjectAllocationRequest.objects.filter( status__name__in=['Under Review', 'Approved - Processing'], *args).order_by( @@ -203,13 +203,13 @@ def get_vector_project_request(self): 'modified') vector_proj_request_object.num = self.paginators - vector_proj_request_object.active_queryset = \ - self.create_paginator(project_request_active) + vector_proj_request_object.pending_queryset = \ + self.create_paginator(project_request_pending) vector_proj_request_object.complete_queryset = \ self.create_paginator(project_request_complete) - vector_proj_request_object.num_active = project_request_active.count() + vector_proj_request_object.num_pending = project_request_pending.count() vector_proj_request_object.title = 'Vector Project Requests' vector_proj_request_object.table = \ @@ -230,26 +230,26 @@ def get_project_join_request(self): if not self.show_all_requests: args.append(Q(project_user__user=user)) - project_join_request_active = \ + project_join_request_pending = \ ProjectUserJoinRequest.objects.filter( project_user__status__name='Pending - Add', *args).order_by( 'modified') project_join_request_complete = \ ProjectUserJoinRequest.objects.filter( - project_user__status__name__in=['Active', 'Denied'], + project_user__status__name__in=['pending', 'Denied'], *args).order_by( 'modified') proj_join_request_object.num = self.paginators - proj_join_request_object.active_queryset = \ - self.create_paginator(project_join_request_active) + proj_join_request_object.pending_queryset = \ + self.create_paginator(project_join_request_pending) proj_join_request_object.complete_queryset = \ self.create_paginator(project_join_request_complete) - proj_join_request_object.num_active = \ - project_join_request_active.count() + proj_join_request_object.num_pending = \ + project_join_request_pending.count() proj_join_request_object.title = 'Project Join Requests' proj_join_request_object.table = \ @@ -270,7 +270,7 @@ def get_project_renewal_request(self): if not self.show_all_requests: args.append(Q(requester=user) | Q(pi=user)) - project_renewal_request_active = \ + project_renewal_request_pending = \ AllocationRenewalRequest.objects.filter( status__name__in=['Approved', 'Under Review'], *args).order_by( 'modified') @@ -281,14 +281,14 @@ def get_project_renewal_request(self): 'modified') proj_renewal_request_object.num = self.paginators - proj_renewal_request_object.active_queryset = \ - self.create_paginator(project_renewal_request_active) + proj_renewal_request_object.pending_queryset = \ + self.create_paginator(project_renewal_request_pending) proj_renewal_request_object.complete_queryset = \ self.create_paginator(project_renewal_request_complete) - proj_renewal_request_object.num_active = \ - project_renewal_request_active.count() + proj_renewal_request_object.num_pending = \ + project_renewal_request_pending.count() proj_renewal_request_object.title = 'Project Renewal Requests' proj_renewal_request_object.table = \ @@ -305,7 +305,7 @@ def get_su_purchase_request(self): su_purchase_request_object = RequestListItem() user = self.request.user - su_purchase_request_active = AllocationAdditionRequest.objects.filter( + su_purchase_request_pending = AllocationAdditionRequest.objects.filter( status__name__in=['Under Review']).order_by('modified') su_purchase_request_complete = AllocationAdditionRequest.objects.filter( @@ -313,10 +313,10 @@ def get_su_purchase_request(self): if not self.show_all_requests: request_ids = [ - r.id for r in su_purchase_request_active + r.id for r in su_purchase_request_pending if is_user_manager_or_pi_of_project(user, r.project)] - su_purchase_request_active = \ - su_purchase_request_active.filter(id__in=request_ids) + su_purchase_request_pending = \ + su_purchase_request_pending.filter(id__in=request_ids) request_ids = [ r.id for r in su_purchase_request_complete @@ -325,14 +325,14 @@ def get_su_purchase_request(self): su_purchase_request_complete.filter(id__in=request_ids) su_purchase_request_object.num = self.paginators - su_purchase_request_object.active_queryset = \ - self.create_paginator(su_purchase_request_active) + su_purchase_request_object.pending_queryset = \ + self.create_paginator(su_purchase_request_pending) su_purchase_request_object.complete_queryset = \ self.create_paginator(su_purchase_request_complete) - su_purchase_request_object.num_active = \ - su_purchase_request_active.count() + su_purchase_request_object.num_pending = \ + su_purchase_request_pending.count() su_purchase_request_object.title = 'Service Unit Purchase Requests' su_purchase_request_object.table = \ From dc427c94c2beaf8bf9e7834a621d53396e55d7ac Mon Sep 17 00:00:00 2001 From: jofeinstein Date: Wed, 2 Mar 2022 09:58:33 -0500 Subject: [PATCH 61/85] added userpassestestmixin --- coldfront/core/user/views_/request_hub_views.py | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/coldfront/core/user/views_/request_hub_views.py b/coldfront/core/user/views_/request_hub_views.py index 5c050f412..a6bda4713 100644 --- a/coldfront/core/user/views_/request_hub_views.py +++ b/coldfront/core/user/views_/request_hub_views.py @@ -1,4 +1,5 @@ -from django.contrib.auth.mixins import LoginRequiredMixin +from django.contrib import messages +from django.contrib.auth.mixins import LoginRequiredMixin, UserPassesTestMixin from django.core.paginator import EmptyPage, PageNotAnInteger, Paginator from django.db.models import Q from django.views.generic.base import TemplateView @@ -37,12 +38,23 @@ def __init__(self): class RequestHub(LoginRequiredMixin, + UserPassesTestMixin, TemplateView): template_name = 'request_hub/request_hub.html' paginate_by = 10 paginators = 0 show_all_requests = False + def test_func(self): + """ UserPassesTestMixin Tests""" + if self.show_all_requests: + if self.request.user.is_superuser or self.request.user.is_staff: + return True + else: + return True + + return False + def create_paginator(self, queryset): """ Creates a paginator object for the given queryset From 5de44c1dbafde1c246d15fc208c8694f912d1ee3 Mon Sep 17 00:00:00 2001 From: jofeinstein Date: Wed, 2 Mar 2022 10:01:54 -0500 Subject: [PATCH 62/85] changed name of view --- coldfront/core/user/urls.py | 4 ++-- coldfront/core/user/views_/request_hub_views.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/coldfront/core/user/urls.py b/coldfront/core/user/urls.py index d03f298f7..6d852cbbf 100644 --- a/coldfront/core/user/urls.py +++ b/coldfront/core/user/urls.py @@ -117,10 +117,10 @@ # Request Hub path('request-hub', - request_hub_views.RequestHub.as_view(show_all_requests=False), + request_hub_views.RequestHubView.as_view(show_all_requests=False), name='request-hub'), path('request-hub-admin', - request_hub_views.RequestHub.as_view(show_all_requests=True), + request_hub_views.RequestHubView.as_view(show_all_requests=True), name='request-hub-admin'), ] diff --git a/coldfront/core/user/views_/request_hub_views.py b/coldfront/core/user/views_/request_hub_views.py index a6bda4713..8595eef9a 100644 --- a/coldfront/core/user/views_/request_hub_views.py +++ b/coldfront/core/user/views_/request_hub_views.py @@ -37,7 +37,7 @@ def __init__(self): button_text = None -class RequestHub(LoginRequiredMixin, +class RequestHubView(LoginRequiredMixin, UserPassesTestMixin, TemplateView): template_name = 'request_hub/request_hub.html' From cb7384360ac334ec6063b41893cf34086b9f80bf Mon Sep 17 00:00:00 2001 From: jofeinstein Date: Wed, 2 Mar 2022 10:02:24 -0500 Subject: [PATCH 63/85] initial commit --- .../tests/test_views/test_request_hub_view.py | 118 ++++++++++++++++++ 1 file changed, 118 insertions(+) create mode 100644 coldfront/core/user/tests/test_views/test_request_hub_view.py diff --git a/coldfront/core/user/tests/test_views/test_request_hub_view.py b/coldfront/core/user/tests/test_views/test_request_hub_view.py new file mode 100644 index 000000000..4087e5fc4 --- /dev/null +++ b/coldfront/core/user/tests/test_views/test_request_hub_view.py @@ -0,0 +1,118 @@ +import os +import sys +from decimal import Decimal +from http import HTTPStatus +from io import StringIO + +from django.core.management import call_command +from django.test import TestCase + +from coldfront.api.statistics.utils import create_project_allocation, \ + create_user_project_allocation +from coldfront.core.project.models import ProjectStatusChoice, \ + ProjectUserStatusChoice, ProjectUserRoleChoice, Project, ProjectUser +from coldfront.core.user.models import EmailAddress, UserProfile +from coldfront.core.user.tests.utils import TestUserBase +from coldfront.core.user.utils import account_activation_url +from django.contrib.auth.models import User +from django.contrib.messages import get_messages +from django.test import Client +from django.urls import reverse + + +class TestRequestHubView(TestCase): + """A class for testing the view for activating a user's account.""" + + password = 'test1234' + + def setUp(self): + """Set up test data.""" + out, err = StringIO(), StringIO() + commands = [ + 'add_resource_defaults', + 'add_allocation_defaults', + 'import_field_of_science_data', + 'add_default_project_choices', + 'create_staff_group', + ] + sys.stdout = open(os.devnull, 'w') + for command in commands: + call_command(command, stdout=out, stderr=err) + sys.stdout = sys.__stdout__ + + self.password = 'password' + + self.pi = User.objects.create( + username='pi0', email='pi0@nonexistent.com') + user_profile = UserProfile.objects.get(user=self.pi) + user_profile.is_pi = True + user_profile.save() + + self.admin = User.objects.create( + username='admin', email='admin@nonexistent.com') + user_profile = UserProfile.objects.get(user=self.admin) + user_profile.is_superuser = True + user_profile.save() + + self.staff = User.objects.create( + username='staff', email='staff@nonexistent.com') + user_profile = UserProfile.objects.get(user=self.staff) + user_profile.is_staff = True + user_profile.save() + + # Create two Users. + for i in range(2): + user = User.objects.create( + username=f'user{i}', email=f'user{i}@nonexistent.com') + user_profile = UserProfile.objects.get(user=user) + user_profile.cluster_uid = f'{i}' + user_profile.save() + setattr(self, f'user{i}', user) + setattr(self, f'user_profile{i}', user_profile) + + # Create Projects and associate Users with them. + project_status = ProjectStatusChoice.objects.get(name='Active') + project_user_status = ProjectUserStatusChoice.objects.get( + name='Active') + user_role = ProjectUserRoleChoice.objects.get(name='User') + manager_role = ProjectUserRoleChoice.objects.get(name='Manager') + for i in range(2): + # Create a Project and ProjectUsers. + project = Project.objects.create( + name=f'project{i}', status=project_status) + setattr(self, f'project{i}', project) + ProjectUser.objects.create( + user=getattr(self, 'user0'), project=project, + role=user_role, status=project_user_status) + ProjectUser.objects.create( + user=self.pi, project=project, role=manager_role, + status=project_user_status) + + # Create a compute allocation for the Project. + allocation = Decimal(f'{i + 1}000.00') + create_project_allocation(project, allocation) + + # Create a compute allocation for each User on the Project. + for j in range(2): + create_user_project_allocation( + getattr(self, f'user{j}'), project, allocation / 2) + + for user in User.objects.all(): + user.set_password(self.password) + + self.url = reverse('request-hub') + self.admin_url = reverse('request-hub-admin') + + def assert_has_access(self, user, url, has_access): + self.client.login(username=user.username, password=self.password) + response = self.client.get(url) + status_code = HTTPStatus.OK if has_access else HTTPStatus.FORBIDDEN + self.assertEqual(response.status_code, status_code) + self.client.logout() + + def get_response(self, user, url): + self.client.login(username=user.username, password=self.password) + return self.client.get(url) + + def test_access(self): + """Testing access to RequestHubView""" From 3550f288893ae5244c9548f6ba4000f2630adaba Mon Sep 17 00:00:00 2001 From: jofeinstein Date: Wed, 2 Mar 2022 17:58:19 -0500 Subject: [PATCH 64/85] added tests for request_hub views --- .../tests/test_views/test_request_hub_view.py | 359 ++++++++++++++++-- 1 file changed, 330 insertions(+), 29 deletions(-) diff --git a/coldfront/core/user/tests/test_views/test_request_hub_view.py b/coldfront/core/user/tests/test_views/test_request_hub_view.py index 4087e5fc4..9c69edf5d 100644 --- a/coldfront/core/user/tests/test_views/test_request_hub_view.py +++ b/coldfront/core/user/tests/test_views/test_request_hub_view.py @@ -1,16 +1,25 @@ import os import sys +import datetime from decimal import Decimal from http import HTTPStatus from io import StringIO +from bs4 import BeautifulSoup + from django.core.management import call_command from django.test import TestCase from coldfront.api.statistics.utils import create_project_allocation, \ - create_user_project_allocation + create_user_project_allocation, get_accounting_allocation_objects +from coldfront.core.allocation.models import AllocationUserAttribute, \ + AllocationAttributeType, Allocation from coldfront.core.project.models import ProjectStatusChoice, \ - ProjectUserStatusChoice, ProjectUserRoleChoice, Project, ProjectUser + ProjectUserStatusChoice, ProjectUserRoleChoice, Project, ProjectUser, \ + ProjectUserRemovalRequestStatusChoice, ProjectUserRemovalRequest, \ + SavioProjectAllocationRequest, ProjectAllocationRequestStatusChoice, \ + savio_project_request_state_schema, vector_project_request_state_schema, \ + VectorProjectAllocationRequest, ProjectUserJoinRequest from coldfront.core.user.models import EmailAddress, UserProfile from coldfront.core.user.tests.utils import TestUserBase from coldfront.core.user.utils import account_activation_url @@ -21,23 +30,17 @@ class TestRequestHubView(TestCase): - """A class for testing the view for activating a user's account.""" - - password = 'test1234' + """A class for testing RequestHubView.""" def setUp(self): """Set up test data.""" - out, err = StringIO(), StringIO() - commands = [ - 'add_resource_defaults', - 'add_allocation_defaults', - 'import_field_of_science_data', - 'add_default_project_choices', - 'create_staff_group', - ] sys.stdout = open(os.devnull, 'w') - for command in commands: - call_command(command, stdout=out, stderr=err) + call_command('import_field_of_science_data') + call_command('add_default_project_choices') + call_command('add_resource_defaults') + call_command('add_allocation_defaults') + call_command('add_brc_accounting_defaults') + call_command('create_staff_group') sys.stdout = sys.__stdout__ self.password = 'password' @@ -48,17 +51,12 @@ def setUp(self): user_profile.is_pi = True user_profile.save() + # create staff and admin users self.admin = User.objects.create( - username='admin', email='admin@nonexistent.com') - user_profile = UserProfile.objects.get(user=self.admin) - user_profile.is_superuser = True - user_profile.save() + username='admin', email='admin@nonexistent.com', is_superuser=True) self.staff = User.objects.create( - username='staff', email='staff@nonexistent.com') - user_profile = UserProfile.objects.get(user=self.staff) - user_profile.is_staff = True - user_profile.save() + username='staff', email='staff@nonexistent.com', is_staff=True) # Create two Users. for i in range(2): @@ -81,28 +79,39 @@ def setUp(self): project = Project.objects.create( name=f'project{i}', status=project_status) setattr(self, f'project{i}', project) - ProjectUser.objects.create( - user=getattr(self, 'user0'), project=project, + proj_user = ProjectUser.objects.create( + user=self.user0, project=project, role=user_role, status=project_user_status) - ProjectUser.objects.create( + setattr(self, f'project{i}_user0', proj_user) + pi_proj_user = ProjectUser.objects.create( user=self.pi, project=project, role=manager_role, status=project_user_status) + setattr(self, f'project{i}_pi', pi_proj_user) # Create a compute allocation for the Project. allocation = Decimal(f'{i + 1}000.00') create_project_allocation(project, allocation) # Create a compute allocation for each User on the Project. - for j in range(2): - create_user_project_allocation( - getattr(self, f'user{j}'), project, allocation / 2) + create_user_project_allocation( + self.user0, project, allocation / 2) + # set passwords for user in User.objects.all(): user.set_password(self.password) + user.save() self.url = reverse('request-hub') self.admin_url = reverse('request-hub-admin') + self.requests = ['cluster account request', + 'project removal request', + 'savio project request', + 'vector project request', + 'project join request', + 'project renewal request', + 'service unit purchase request'] + def assert_has_access(self, user, url, has_access): self.client.login(username=user.username, password=self.password) response = self.client.get(url) @@ -114,5 +123,297 @@ def get_response(self, user, url): self.client.login(username=user.username, password=self.password) return self.client.get(url) + def assert_no_requests(self, user, url): + response = self.get_response(user, url) + soup = BeautifulSoup(response.content, 'html.parser') + for request in self.requests: + divs = soup.find(id=f'{request.replace(" ", "_")}_section'). \ + find_all('div', {'class': 'alert alert-info'}) + self.assertEqual(len(divs), 2) + for i, div in enumerate(divs): + self.assertIn(request.title(), str(div)) + self.assertIn('No pending' if i == 0 else 'No completed', + str(div)) + def test_access(self): """Testing access to RequestHubView""" + + # all users should have access to the normal view + for user in User.objects.all(): + self.assert_has_access(user, self.url, True) + + # only staff/admin should have access to request-hub-admin + self.assert_has_access(self.admin, self.admin_url, True) + self.assert_has_access(self.staff, self.admin_url, True) + self.assert_has_access(self.pi, self.admin_url, False) + self.assert_has_access(self.user0, self.admin_url, False) + self.assert_has_access(self.user1, self.admin_url, False) + + def test_admin_buttons(self): + """Test that 'Go to main request page' buttons only appear for + admin/staff""" + + def assert_button_displayed(user, displayed): + """Assert that the relevant button appears if the + given boolean is True; otherwise, assert that they do not + appear.""" + button_list = [f'Go To {request.title()}s Main Page' + for request in self.requests] + response = self.get_response(user, self.url) + html = response.content.decode('utf-8') + func = self.assertIn if displayed else self.assertNotIn + + for button in button_list: + func(button, html) + + assert_button_displayed(self.user0, False) + assert_button_displayed(self.admin, True) + assert_button_displayed(self.staff, True) + + def test_no_requests(self): + """Testing that the correct message is displayed when + there are no requests""" + + self.assert_no_requests(self.user0, self.url) + self.assert_no_requests(self.user1, self.url) + self.assert_no_requests(self.pi, self.url) + self.assert_no_requests(self.admin, self.url) + self.assert_no_requests(self.staff, self.url) + self.assert_no_requests(self.admin, self.admin_url) + self.assert_no_requests(self.staff, self.admin_url) + + def test_cluster_account_requests(self): + """Testing that cluster account requests appear""" + + def assert_request_shown(user, url): + response = self.get_response(user, url) + soup = BeautifulSoup(response.content, 'html.parser') + + pending_div = str( + soup.find(id=f'cluster_account_request_section_pending')) + self.assertIn(str(pending_req.pk), pending_div) + self.assertIn(pending_req.allocation_user.user.email, pending_div) + self.assertIn(pending_req.value, pending_div) + + completed_div = str( + soup.find(id=f'cluster_account_request_section_completed')) + self.assertIn(str(completed_req.pk), completed_div) + self.assertIn(completed_req.allocation_user.user.email, + completed_div) + self.assertIn(completed_req.value, completed_div) + + # creating two cluster account requests for user0 + allocation_obj = \ + get_accounting_allocation_objects(self.project0) + allocation_user_obj = \ + get_accounting_allocation_objects(self.project0, self.user0) + + cluster_account_status = AllocationAttributeType.objects.get( + name='Cluster Account Status') + + kwargs = { + 'allocation_attribute_type': cluster_account_status, + 'allocation': allocation_obj.allocation, + 'allocation_user': allocation_user_obj.allocation_user, + } + + pending_req = \ + AllocationUserAttribute.objects.create(value='Processing', **kwargs) + + completed_req = \ + AllocationUserAttribute.objects.create(value='Denied', **kwargs) + + assert_request_shown(self.user0, self.url) + assert_request_shown(self.admin, self.admin_url) + assert_request_shown(self.staff, self.admin_url) + + def test_project_removal_requests(self): + """Testing that project removal requests appear""" + def assert_request_shown(user, url): + response = self.get_response(user, url) + soup = BeautifulSoup(response.content, 'html.parser') + + pending_div = str( + soup.find(id=f'project_removal_request_section_pending')) + self.assertIn(str(pending_req.pk), pending_div) + self.assertIn(pending_req.project_user.user.username, pending_div) + self.assertIn(pending_req.requester.username, pending_div) + self.assertIn(pending_req.request_time.strftime("%b. %d, %Y"), pending_div) + self.assertIn(pending_req.status.name, pending_div) + + completed_div = str( + soup.find(id=f'project_removal_request_section_completed')) + self.assertIn(str(completed_req.pk), pending_div) + self.assertIn(completed_req.project_user.user.username, completed_div) + self.assertIn(completed_req.requester.username, completed_div) + self.assertIn(completed_req.completion_time.strftime("%b. %d, %Y"), completed_div) + self.assertIn(completed_req.status.name, completed_div) + + processing_status = \ + ProjectUserRemovalRequestStatusChoice.objects.get(name='Processing') + complete_status = \ + ProjectUserRemovalRequestStatusChoice.objects.get(name='Complete') + current_time = datetime.datetime.now() + + kwargs = { + 'project_user': self.project0_user0, + 'requester': self.project0_pi.user, + 'request_time': current_time, + } + pending_req = ProjectUserRemovalRequest.objects.create( + status=processing_status, **kwargs) + completed_req = ProjectUserRemovalRequest.objects.create( + status=complete_status, + completion_time=current_time + datetime.timedelta(days=4), + **kwargs + ) + + assert_request_shown(self.user0, self.url) + assert_request_shown(self.pi, self.url) + assert_request_shown(self.admin, self.admin_url) + assert_request_shown(self.staff, self.admin_url) + + def test_savio_project_requests(self): + """Testing that savio project requests appear""" + + def assert_request_shown(user, url): + response = self.get_response(user, url) + soup = BeautifulSoup(response.content, 'html.parser') + + pending_div = str( + soup.find(id=f'savio_project_request_section_pending')) + self.assertIn(str(pending_req.pk), pending_div) + self.assertIn(pending_req.requester.email, pending_div) + self.assertIn(pending_req.pi.email, pending_div) + self.assertIn(pending_req.modified.strftime("%b. %d, %Y"), pending_div) + self.assertIn(pending_req.status.name, pending_div) + + completed_div = str( + soup.find(id=f'savio_project_request_section_completed')) + self.assertIn(str(completed_req.pk), completed_div) + self.assertIn(completed_req.requester.email, completed_div) + self.assertIn(completed_req.pi.email, completed_div) + self.assertIn(completed_req.modified.strftime("%b. %d, %Y"), completed_div) + self.assertIn(completed_req.status.name, completed_div) + + kwargs = { + 'requester': self.user0, + 'allocation_type': 'FCA', + 'pi': self.pi, + 'project': self.project0, + 'pool': False, + 'survey_answers': savio_project_request_state_schema() + } + + processing_status = \ + ProjectAllocationRequestStatusChoice.objects.get( + name='Approved - Processing') + complete_status = \ + ProjectAllocationRequestStatusChoice.objects.get( + name='Approved - Complete') + + pending_req = SavioProjectAllocationRequest.objects.create( + status=processing_status, **kwargs) + completed_req = SavioProjectAllocationRequest.objects.create( + status=complete_status, **kwargs) + + assert_request_shown(self.user0, self.url) + assert_request_shown(self.pi, self.url) + assert_request_shown(self.admin, self.admin_url) + assert_request_shown(self.staff, self.admin_url) + + def test_vector_project_requests(self): + """Testing that vector project requests appear""" + def assert_request_shown(user, url): + response = self.get_response(user, url) + soup = BeautifulSoup(response.content, 'html.parser') + + pending_div = str( + soup.find(id=f'vector_project_request_section_pending')) + self.assertIn(str(pending_req.pk), pending_div) + self.assertIn(pending_req.requester.email, pending_div) + self.assertIn(pending_req.pi.email, pending_div) + self.assertIn(pending_req.modified.strftime("%b. %d, %Y"), pending_div) + self.assertIn(pending_req.status.name, pending_div) + + completed_div = str( + soup.find(id=f'vector_project_request_section_completed')) + self.assertIn(str(completed_req.pk), completed_div) + self.assertIn(completed_req.requester.email, completed_div) + self.assertIn(completed_req.pi.email, completed_div) + self.assertIn(completed_req.modified.strftime("%b. %d, %Y"), completed_div) + self.assertIn(completed_req.status.name, completed_div) + + kwargs = { + 'requester': self.user0, + 'pi': self.pi, + 'project': self.project0, + 'state': vector_project_request_state_schema() + } + + processing_status = \ + ProjectAllocationRequestStatusChoice.objects.get( + name='Approved - Processing') + complete_status = \ + ProjectAllocationRequestStatusChoice.objects.get( + name='Approved - Complete') + + pending_req = VectorProjectAllocationRequest.objects.create( + status=processing_status, **kwargs) + completed_req = VectorProjectAllocationRequest.objects.create( + status=complete_status, **kwargs) + + assert_request_shown(self.user0, self.url) + assert_request_shown(self.pi, self.url) + assert_request_shown(self.admin, self.admin_url) + assert_request_shown(self.staff, self.admin_url) + + def test_project_join_requests(self): + """Testing that project join requests appear correctly""" + + def assert_request_shown(user, url, section): + response = self.get_response(user, url) + soup = BeautifulSoup(response.content, 'html.parser') + + if section == 'both' or section == 'pending': + pending_div = str( + soup.find(id=f'project_join_request_section_pending')) + self.assertIn(str(pending_req.pk), pending_div) + self.assertIn(pending_req.project_user.user.username, pending_div) + self.assertIn(pending_req.project_user.project.name, pending_div) + self.assertIn(pending_req.created.strftime("%b. %d, %Y"), pending_div) + self.assertIn(pending_req.reason, pending_div) + + if section == 'both' or section == 'completed': + completed_div = str( + soup.find(id=f'project_join_request_section_completed')) + self.assertIn(str(completed_req.pk), completed_div) + self.assertIn(completed_req.project_user.user.username, completed_div) + self.assertIn(completed_req.project_user.project.name, completed_div) + self.assertIn(completed_req.created.strftime("%b. %d, %Y"), completed_div) + self.assertIn(completed_req.reason, completed_div) + + project_user_status = ProjectUserStatusChoice.objects.get( + name='Pending - Add') + user_role = ProjectUserRoleChoice.objects.get(name='User') + pending_proj_user = ProjectUser.objects.create( + user=self.user1, project=self.project0, + role=user_role, status=project_user_status) + + pending_req = ProjectUserJoinRequest.objects.create( + project_user=pending_proj_user, + reason='Request hub testing.') + completed_req = ProjectUserJoinRequest.objects.create( + project_user=self.project0_user0, + reason='Request hub testing.') + + assert_request_shown(self.user0, self.url, 'completed') + assert_request_shown(self.user1, self.url, 'pending') + assert_request_shown(self.pi, self.url, 'both') + assert_request_shown(self.admin, self.admin_url, 'both') + assert_request_shown(self.staff, self.admin_url, 'both') + + # def test_project_renewal_requests(self): + # """Testing that project renewal requests appear correctly""" + # + # AllocationRenewalRequest \ No newline at end of file From 04d890cdafd18e62b6b16ee7feaa6b4a701c2f4a Mon Sep 17 00:00:00 2001 From: jofeinstein Date: Wed, 2 Mar 2022 17:59:26 -0500 Subject: [PATCH 65/85] added ids to div sections --- .../core/user/templates/request_hub/request_section.html | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/coldfront/core/user/templates/request_hub/request_section.html b/coldfront/core/user/templates/request_hub/request_section.html index 77442d756..bd11f5d51 100644 --- a/coldfront/core/user/templates/request_hub/request_section.html +++ b/coldfront/core/user/templates/request_hub/request_section.html @@ -1,5 +1,5 @@
    -
    +
    @@ -17,7 +17,7 @@
    {% with queryset=request_obj.pending_queryset adj='pending' page_num=request_obj.num title=request_obj.title %} -
    +
    {% if queryset %}
    @@ -40,7 +40,7 @@
    {{ adj }} {{ tit
    {% endwith %} {% with queryset=request_obj.complete_queryset adj='completed' page_num=request_obj.num|add:1 title=request_obj.title %} -
    +
    {% if queryset %}
    @@ -62,7 +62,7 @@
    {{ adj }} {{ tit
    {% endwith %} - {% if user.is_superuser %} + {% if admin_staff %}
    From 873a349f59ebc78860822f60a5ad22294b5e3f2e Mon Sep 17 00:00:00 2001 From: jofeinstein Date: Wed, 2 Mar 2022 18:00:01 -0500 Subject: [PATCH 66/85] added adj variable to make it compatible with request hub --- .../project_removal/project_removal_request_list_table.html | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/coldfront/core/project/templates/project/project_removal/project_removal_request_list_table.html b/coldfront/core/project/templates/project/project_removal/project_removal_request_list_table.html index db4b230ec..927f0b57e 100644 --- a/coldfront/core/project/templates/project/project_removal/project_removal_request_list_table.html +++ b/coldfront/core/project/templates/project/project_removal/project_removal_request_list_table.html @@ -7,7 +7,7 @@ - {% if request_filter == 'pending' %} + {% if request_filter == 'pending' or adj == 'pending' %} Date Requested {% else %} Date Completed @@ -38,7 +38,7 @@ Status - {% if user.is_superuser and request_filter == 'pending' %} + {% if user.is_superuser and request_filter == 'pending'%} Actions @@ -49,7 +49,7 @@ {% for removal_request in queryset %} {{ removal_request.pk }} - {% if request_filter == 'pending' or adj == 'active' %} + {% if request_filter == 'pending' or adj == 'pending' %} {{ removal_request.request_time|date:"M. d, Y" }} {% else %} {{ removal_request.completion_time|date:"M. d, Y" }} From aa454c4695ebd8b35630f38e2688a53b25b3cabc Mon Sep 17 00:00:00 2001 From: jofeinstein Date: Wed, 2 Mar 2022 18:00:54 -0500 Subject: [PATCH 67/85] added id field to RequestListItem. PI/managers can now see proj join requests for their projects --- .../core/user/views_/request_hub_views.py | 40 +++++++++++++------ 1 file changed, 28 insertions(+), 12 deletions(-) diff --git a/coldfront/core/user/views_/request_hub_views.py b/coldfront/core/user/views_/request_hub_views.py index 8595eef9a..2d7f206a2 100644 --- a/coldfront/core/user/views_/request_hub_views.py +++ b/coldfront/core/user/views_/request_hub_views.py @@ -11,7 +11,7 @@ from coldfront.core.project.models import (ProjectUserRemovalRequest, SavioProjectAllocationRequest, VectorProjectAllocationRequest, - ProjectUserJoinRequest) + ProjectUserJoinRequest, Project) from coldfront.core.project.utils_.permissions_utils import \ is_user_manager_or_pi_of_project @@ -24,7 +24,7 @@ class RequestListItem: __slots__ = ['num', 'title', 'num_pending', 'table', 'pending_queryset', 'complete_queryset', - 'button_path', 'button_text'] + 'button_path', 'button_text', 'id'] def __init__(self): num = None @@ -35,11 +35,12 @@ def __init__(self): complete_queryset = None button_path = None button_text = None + id = None class RequestHubView(LoginRequiredMixin, - UserPassesTestMixin, - TemplateView): + UserPassesTestMixin, + TemplateView): template_name = 'request_hub/request_hub.html' paginate_by = 10 paginators = 0 @@ -53,8 +54,6 @@ def test_func(self): else: return True - return False - def create_paginator(self, queryset): """ Creates a paginator object for the given queryset @@ -112,6 +111,7 @@ def get_cluster_account_request(self): 'allocation-cluster-account-request-list' cluster_request_object.button_text = \ 'Go To Cluster Account Requests Main Page' + cluster_request_object.id = 'cluster_account_request_section' return cluster_request_object @@ -150,6 +150,7 @@ def get_project_removal_request(self): 'project-removal-request-list' removal_request_object.button_text = \ 'Go To Project Removal Requests Main Page' + removal_request_object.id = 'project_removal_request_section' return removal_request_object @@ -190,6 +191,7 @@ def get_savio_project_request(self): 'savio-project-pending-request-list' savio_proj_request_object.button_text = \ 'Go To Savio Project Requests Main Page' + savio_proj_request_object.id = 'savio_project_request_section' return savio_proj_request_object @@ -230,6 +232,7 @@ def get_vector_project_request(self): 'vector-project-pending-request-list' vector_proj_request_object.button_text = \ 'Go To Vector Project Requests Main Page' + vector_proj_request_object.id = 'vector_project_request_section' return vector_proj_request_object @@ -240,18 +243,28 @@ def get_project_join_request(self): args = [] if not self.show_all_requests: - args.append(Q(project_user__user=user)) + project_set = set() + for project in Project.objects.all(): + pi_condition = Q( + role__name='Principal Investigator') + manager_condition = Q(role__name='Manager') + + if project.projectuser_set.filter(user=user, + status__name='Active').filter( + Q(pi_condition | manager_condition)).count() > 0: + project_set.add(project) + + args.append(Q(project_user__user=user) | Q(project_user__project__in=project_set)) project_join_request_pending = \ ProjectUserJoinRequest.objects.filter( - project_user__status__name='Pending - Add', *args).order_by( - 'modified') + project_user__status__name='Pending - Add', + *args).order_by('modified') project_join_request_complete = \ ProjectUserJoinRequest.objects.filter( - project_user__status__name__in=['pending', 'Denied'], - *args).order_by( - 'modified') + project_user__status__name__in=['Active', 'Denied'], + *args).order_by('modified') proj_join_request_object.num = self.paginators proj_join_request_object.pending_queryset = \ @@ -270,6 +283,7 @@ def get_project_join_request(self): 'project-join-request-list' proj_join_request_object.button_text = \ 'Go To Project Join Requests Main Page' + proj_join_request_object.id = 'project_join_request_section' return proj_join_request_object @@ -309,6 +323,7 @@ def get_project_renewal_request(self): 'pi-allocation-renewal-pending-request-list' proj_renewal_request_object.button_text = \ 'Go To Project Renewal Requests Main Page' + proj_renewal_request_object.id = 'project_renewal_request_section' return proj_renewal_request_object @@ -353,6 +368,7 @@ def get_su_purchase_request(self): 'service-units-purchase-pending-request-list' su_purchase_request_object.button_text = \ 'Go To Service Unit Purchase Requests Main Page' + su_purchase_request_object.id = 'service_unit_purchase_request_section' return su_purchase_request_object From fc822548c7eb279ed5e69c32d270696dbe29a693 Mon Sep 17 00:00:00 2001 From: jofeinstein Date: Thu, 3 Mar 2022 09:22:27 -0500 Subject: [PATCH 68/85] removed imports --- coldfront/core/user/views_/request_hub_views.py | 1 - 1 file changed, 1 deletion(-) diff --git a/coldfront/core/user/views_/request_hub_views.py b/coldfront/core/user/views_/request_hub_views.py index 2d7f206a2..74fb0f0f2 100644 --- a/coldfront/core/user/views_/request_hub_views.py +++ b/coldfront/core/user/views_/request_hub_views.py @@ -1,4 +1,3 @@ -from django.contrib import messages from django.contrib.auth.mixins import LoginRequiredMixin, UserPassesTestMixin from django.core.paginator import EmptyPage, PageNotAnInteger, Paginator from django.db.models import Q From 814143ac97a10ab9e4cc684f71094e6e684d184c Mon Sep 17 00:00:00 2001 From: jofeinstein Date: Thu, 3 Mar 2022 09:22:44 -0500 Subject: [PATCH 69/85] added tests for each request type --- .../tests/test_views/test_request_hub_view.py | 211 ++++++++++++++++-- 1 file changed, 195 insertions(+), 16 deletions(-) diff --git a/coldfront/core/user/tests/test_views/test_request_hub_view.py b/coldfront/core/user/tests/test_views/test_request_hub_view.py index 9c69edf5d..2df4c1673 100644 --- a/coldfront/core/user/tests/test_views/test_request_hub_view.py +++ b/coldfront/core/user/tests/test_views/test_request_hub_view.py @@ -3,30 +3,29 @@ import datetime from decimal import Decimal from http import HTTPStatus -from io import StringIO - from bs4 import BeautifulSoup from django.core.management import call_command from django.test import TestCase +from django.contrib.auth.models import User +from django.urls import reverse from coldfront.api.statistics.utils import create_project_allocation, \ create_user_project_allocation, get_accounting_allocation_objects from coldfront.core.allocation.models import AllocationUserAttribute, \ - AllocationAttributeType, Allocation + AllocationAttributeType, \ + allocation_renewal_request_state_schema, AllocationPeriod, \ + AllocationRenewalRequestStatusChoice, AllocationRenewalRequest, \ + allocation_addition_request_state_schema, \ + AllocationAdditionRequestStatusChoice, AllocationAdditionRequest from coldfront.core.project.models import ProjectStatusChoice, \ ProjectUserStatusChoice, ProjectUserRoleChoice, Project, ProjectUser, \ ProjectUserRemovalRequestStatusChoice, ProjectUserRemovalRequest, \ SavioProjectAllocationRequest, ProjectAllocationRequestStatusChoice, \ savio_project_request_state_schema, vector_project_request_state_schema, \ VectorProjectAllocationRequest, ProjectUserJoinRequest -from coldfront.core.user.models import EmailAddress, UserProfile -from coldfront.core.user.tests.utils import TestUserBase -from coldfront.core.user.utils import account_activation_url -from django.contrib.auth.models import User -from django.contrib.messages import get_messages -from django.test import Client -from django.urls import reverse +from coldfront.core.user.models import UserProfile +from coldfront.core.utils.common import utc_now_offset_aware class TestRequestHubView(TestCase): @@ -41,6 +40,7 @@ def setUp(self): call_command('add_allocation_defaults') call_command('add_brc_accounting_defaults') call_command('create_staff_group') + call_command('create_allocation_periods') sys.stdout = sys.__stdout__ self.password = 'password' @@ -123,10 +123,12 @@ def get_response(self, user, url): self.client.login(username=user.username, password=self.password) return self.client.get(url) - def assert_no_requests(self, user, url): + def assert_no_requests(self, user, url, exclude=None): response = self.get_response(user, url) soup = BeautifulSoup(response.content, 'html.parser') for request in self.requests: + if request == exclude: + continue divs = soup.find(id=f'{request.replace(" ", "_")}_section'). \ find_all('div', {'class': 'alert alert-info'}) self.assertEqual(len(divs), 2) @@ -223,10 +225,22 @@ def assert_request_shown(user, url): completed_req = \ AllocationUserAttribute.objects.create(value='Denied', **kwargs) + # assert the correct requests are shown assert_request_shown(self.user0, self.url) assert_request_shown(self.admin, self.admin_url) assert_request_shown(self.staff, self.admin_url) + # other request sections should be empty + self.assert_no_requests(self.user0, self.url, exclude='cluster account request') + self.assert_no_requests(self.admin, self.admin_url, exclude='cluster account request') + self.assert_no_requests(self.staff, self.admin_url, exclude='cluster account request') + + # should not see any requests + self.assert_no_requests(self.user1, self.url) + self.assert_no_requests(self.pi, self.url) + self.assert_no_requests(self.staff, self.url) + self.assert_no_requests(self.admin, self.url) + def test_project_removal_requests(self): """Testing that project removal requests appear""" def assert_request_shown(user, url): @@ -253,7 +267,7 @@ def assert_request_shown(user, url): ProjectUserRemovalRequestStatusChoice.objects.get(name='Processing') complete_status = \ ProjectUserRemovalRequestStatusChoice.objects.get(name='Complete') - current_time = datetime.datetime.now() + current_time = utc_now_offset_aware() kwargs = { 'project_user': self.project0_user0, @@ -268,11 +282,23 @@ def assert_request_shown(user, url): **kwargs ) + # assert the correct requests are shown assert_request_shown(self.user0, self.url) assert_request_shown(self.pi, self.url) assert_request_shown(self.admin, self.admin_url) assert_request_shown(self.staff, self.admin_url) + # other request sections should be empty + self.assert_no_requests(self.user0, self.url, exclude='project removal request') + self.assert_no_requests(self.pi, self.url, exclude='project removal request') + self.assert_no_requests(self.admin, self.admin_url, exclude='project removal request') + self.assert_no_requests(self.staff, self.admin_url, exclude='project removal request') + + # should not see any requests + self.assert_no_requests(self.user1, self.url) + self.assert_no_requests(self.staff, self.url) + self.assert_no_requests(self.admin, self.url) + def test_savio_project_requests(self): """Testing that savio project requests appear""" @@ -317,11 +343,23 @@ def assert_request_shown(user, url): completed_req = SavioProjectAllocationRequest.objects.create( status=complete_status, **kwargs) + # assert the correct requests are shown assert_request_shown(self.user0, self.url) assert_request_shown(self.pi, self.url) assert_request_shown(self.admin, self.admin_url) assert_request_shown(self.staff, self.admin_url) + # other request sections should be empty + self.assert_no_requests(self.user0, self.url, exclude='savio project request') + self.assert_no_requests(self.pi, self.url, exclude='savio project request') + self.assert_no_requests(self.admin, self.admin_url, exclude='savio project request') + self.assert_no_requests(self.staff, self.admin_url, exclude='savio project request') + + # should not see any requests + self.assert_no_requests(self.user1, self.url) + self.assert_no_requests(self.staff, self.url) + self.assert_no_requests(self.admin, self.url) + def test_vector_project_requests(self): """Testing that vector project requests appear""" def assert_request_shown(user, url): @@ -363,11 +401,23 @@ def assert_request_shown(user, url): completed_req = VectorProjectAllocationRequest.objects.create( status=complete_status, **kwargs) + # assert the correct requests are shown assert_request_shown(self.user0, self.url) assert_request_shown(self.pi, self.url) assert_request_shown(self.admin, self.admin_url) assert_request_shown(self.staff, self.admin_url) + # other request sections should be empty + self.assert_no_requests(self.user0, self.url, exclude='vector project request') + self.assert_no_requests(self.pi, self.url, exclude='vector project request') + self.assert_no_requests(self.admin, self.admin_url, exclude='vector project request') + self.assert_no_requests(self.staff, self.admin_url, exclude='vector project request') + + # should not see any requests + self.assert_no_requests(self.user1, self.url) + self.assert_no_requests(self.staff, self.url) + self.assert_no_requests(self.admin, self.url) + def test_project_join_requests(self): """Testing that project join requests appear correctly""" @@ -407,13 +457,142 @@ def assert_request_shown(user, url, section): project_user=self.project0_user0, reason='Request hub testing.') + # assert the correct requests are shown assert_request_shown(self.user0, self.url, 'completed') assert_request_shown(self.user1, self.url, 'pending') assert_request_shown(self.pi, self.url, 'both') assert_request_shown(self.admin, self.admin_url, 'both') assert_request_shown(self.staff, self.admin_url, 'both') - # def test_project_renewal_requests(self): - # """Testing that project renewal requests appear correctly""" - # - # AllocationRenewalRequest \ No newline at end of file + # other request sections should be empty + self.assert_no_requests(self.user0, self.url, exclude='project join request') + self.assert_no_requests(self.user1, self.url, exclude='project join request') + self.assert_no_requests(self.pi, self.url, exclude='project join request') + self.assert_no_requests(self.admin, self.admin_url, exclude='project join request') + self.assert_no_requests(self.staff, self.admin_url, exclude='project join request') + + # should not see any requests + self.assert_no_requests(self.staff, self.url) + self.assert_no_requests(self.admin, self.url) + + def test_project_renewal_requests(self): + """Testing that project renewal requests appear correctly""" + + def assert_request_shown(user, url): + response = self.get_response(user, url) + soup = BeautifulSoup(response.content, 'html.parser') + + pending_div = str( + soup.find(id=f'project_renewal_request_section_pending')) + self.assertIn(str(pending_req.pk), pending_div) + self.assertIn(pending_req.requester.email, pending_div) + self.assertIn(pending_req.pre_project.name, pending_div) + self.assertIn(pending_req.post_project.name, pending_div) + self.assertIn(pending_req.modified.strftime("%b. %d, %Y"), pending_div) + self.assertIn(pending_req.status.name, pending_div) + + completed_div = str( + soup.find(id=f'project_renewal_request_section_completed')) + self.assertIn(str(completed_req.pk), completed_div) + self.assertIn(completed_req.requester.email, completed_div) + self.assertIn(completed_req.pre_project.name, completed_div) + self.assertIn(completed_req.post_project.name, completed_div) + self.assertIn(completed_req.modified.strftime("%b. %d, %Y"), completed_div) + self.assertIn(completed_req.status.name, completed_div) + + kwargs = { + 'pi': self.pi, + 'requester': self.user0, + 'allocation_period': AllocationPeriod.objects.get(name='AY21-22'), + 'pre_project': self.project0, + 'post_project': self.project0, + 'num_service_units': 1000, + 'request_time': utc_now_offset_aware(), + 'state': allocation_renewal_request_state_schema() + } + pending_status = AllocationRenewalRequestStatusChoice.objects.get( + name='Approved') + complete_status = AllocationRenewalRequestStatusChoice.objects.get( + name='Complete') + pending_req = AllocationRenewalRequest.objects.create( + status=pending_status, **kwargs) + completed_req = AllocationRenewalRequest.objects.create( + status=complete_status, **kwargs) + + # assert the correct requests are shown + assert_request_shown(self.user0, self.url) + assert_request_shown(self.pi, self.url) + assert_request_shown(self.admin, self.admin_url) + assert_request_shown(self.staff, self.admin_url) + + # other request sections should be empty + self.assert_no_requests(self.user0, self.url, exclude='project renewal request') + self.assert_no_requests(self.pi, self.url, exclude='project renewal request') + self.assert_no_requests(self.admin, self.admin_url, exclude='project renewal request') + self.assert_no_requests(self.staff, self.admin_url, exclude='project renewal request') + + # should not see any requests + self.assert_no_requests(self.user1, self.url) + self.assert_no_requests(self.staff, self.url) + self.assert_no_requests(self.admin, self.url) + + def test_su_purchase_requests(self): + """Testing that su purchase requests appear correctly""" + + def assert_request_shown(user, url): + response = self.get_response(user, url) + soup = BeautifulSoup(response.content, 'html.parser') + + pending_div = str( + soup.find(id=f'service_unit_purchase_request_section_pending')) + self.assertIn(str(pending_req.pk), pending_div) + self.assertIn(pending_req.requester.email, pending_div) + self.assertIn(pending_req.project.name, pending_div) + self.assertIn(str(pending_req.num_service_units), pending_div) + self.assertIn(pending_req.modified.strftime("%b. %d, %Y"), pending_div) + self.assertIn(pending_req.status.name, pending_div) + + completed_div = str( + soup.find(id=f'service_unit_purchase_request_section_completed')) + self.assertIn(str(completed_req.pk), completed_div) + self.assertIn(completed_req.requester.email, completed_div) + self.assertIn(completed_req.project.name, completed_div) + self.assertIn(str(completed_req.num_service_units), completed_div) + self.assertIn(completed_req.modified.strftime("%b. %d, %Y"), completed_div) + self.assertIn(completed_req.status.name, completed_div) + + current_time = utc_now_offset_aware() + kwargs = { + 'requester': self.pi, + 'project': self.project0, + 'num_service_units': 1000, + 'request_time': current_time, + 'state': allocation_addition_request_state_schema() + } + + pending_status = AllocationAdditionRequestStatusChoice.objects.get( + name='Under Review') + complete_status = AllocationAdditionRequestStatusChoice.objects.get( + name='Complete') + pending_req = AllocationAdditionRequest.objects.create( + status=pending_status, **kwargs) + completed_req = AllocationAdditionRequest.objects.create( + status=complete_status, + completion_time=current_time + datetime.timedelta(days=4), + **kwargs) + + # assert the correct requests are shown + assert_request_shown(self.pi, self.url) + assert_request_shown(self.admin, self.admin_url) + assert_request_shown(self.staff, self.admin_url) + + # other request sections should be empty + self.assert_no_requests(self.pi, self.url, exclude='service unit purchase request') + self.assert_no_requests(self.admin, self.admin_url, exclude='service unit purchase request') + self.assert_no_requests(self.staff, self.admin_url, exclude='service unit purchase request') + + # should not see any requests + self.assert_no_requests(self.user0, self.url) + self.assert_no_requests(self.user1, self.url) + self.assert_no_requests(self.staff, self.url) + self.assert_no_requests(self.admin, self.url) From 8ab2933be7c5cbbe46edebe4c22e1c6269f195e8 Mon Sep 17 00:00:00 2001 From: jofeinstein Date: Thu, 3 Mar 2022 09:41:35 -0500 Subject: [PATCH 70/85] added tests for pending notification badge --- .../tests/test_views/test_request_hub_view.py | 89 +++++++++++++++---- 1 file changed, 72 insertions(+), 17 deletions(-) diff --git a/coldfront/core/user/tests/test_views/test_request_hub_view.py b/coldfront/core/user/tests/test_views/test_request_hub_view.py index 2df4c1673..6388d9b3c 100644 --- a/coldfront/core/user/tests/test_views/test_request_hub_view.py +++ b/coldfront/core/user/tests/test_views/test_request_hub_view.py @@ -137,6 +137,13 @@ def assert_no_requests(self, user, url, exclude=None): self.assertIn('No pending' if i == 0 else 'No completed', str(div)) + def assert_pending_request_badge_shown(self, section, response, num_requests): + soup = BeautifulSoup(response.content, 'html.parser') + divs = soup.find(id=section) + notification = f'{num_requests} pending request' \ + f'{"s" if num_requests > 1 else ""}' + self.assertIn(notification, str(divs)) + def test_access(self): """Testing access to RequestHubView""" @@ -188,17 +195,24 @@ def test_cluster_account_requests(self): """Testing that cluster account requests appear""" def assert_request_shown(user, url): + section = 'cluster_account_request_section' response = self.get_response(user, url) soup = BeautifulSoup(response.content, 'html.parser') + # notification badge is shown + self.assert_pending_request_badge_shown( + section, response, 1) + + # pending request is shown pending_div = str( - soup.find(id=f'cluster_account_request_section_pending')) + soup.find(id=f'{section}_pending')) self.assertIn(str(pending_req.pk), pending_div) self.assertIn(pending_req.allocation_user.user.email, pending_div) self.assertIn(pending_req.value, pending_div) + # completed request is shown completed_div = str( - soup.find(id=f'cluster_account_request_section_completed')) + soup.find(id=f'{section}_completed')) self.assertIn(str(completed_req.pk), completed_div) self.assertIn(completed_req.allocation_user.user.email, completed_div) @@ -246,17 +260,24 @@ def test_project_removal_requests(self): def assert_request_shown(user, url): response = self.get_response(user, url) soup = BeautifulSoup(response.content, 'html.parser') + section = 'project_removal_request_section' + # notification badge is shown + self.assert_pending_request_badge_shown( + section, response, 1) + + # pending request is shown pending_div = str( - soup.find(id=f'project_removal_request_section_pending')) + soup.find(id=f'{section}_pending')) self.assertIn(str(pending_req.pk), pending_div) self.assertIn(pending_req.project_user.user.username, pending_div) self.assertIn(pending_req.requester.username, pending_div) self.assertIn(pending_req.request_time.strftime("%b. %d, %Y"), pending_div) self.assertIn(pending_req.status.name, pending_div) + # completed request is shown completed_div = str( - soup.find(id=f'project_removal_request_section_completed')) + soup.find(id=f'{section}_completed')) self.assertIn(str(completed_req.pk), pending_div) self.assertIn(completed_req.project_user.user.username, completed_div) self.assertIn(completed_req.requester.username, completed_div) @@ -305,17 +326,24 @@ def test_savio_project_requests(self): def assert_request_shown(user, url): response = self.get_response(user, url) soup = BeautifulSoup(response.content, 'html.parser') + section = 'savio_project_request_section' + + # notification badge is shown + self.assert_pending_request_badge_shown( + section, response, 1) + # pending request is shown pending_div = str( - soup.find(id=f'savio_project_request_section_pending')) + soup.find(id=f'{section}_pending')) self.assertIn(str(pending_req.pk), pending_div) self.assertIn(pending_req.requester.email, pending_div) self.assertIn(pending_req.pi.email, pending_div) self.assertIn(pending_req.modified.strftime("%b. %d, %Y"), pending_div) self.assertIn(pending_req.status.name, pending_div) + # completed request is shown completed_div = str( - soup.find(id=f'savio_project_request_section_completed')) + soup.find(id=f'{section}_completed')) self.assertIn(str(completed_req.pk), completed_div) self.assertIn(completed_req.requester.email, completed_div) self.assertIn(completed_req.pi.email, completed_div) @@ -365,17 +393,24 @@ def test_vector_project_requests(self): def assert_request_shown(user, url): response = self.get_response(user, url) soup = BeautifulSoup(response.content, 'html.parser') + section = 'vector_project_request_section' + # notification badge is shown + self.assert_pending_request_badge_shown( + section, response, 1) + + # pending request is shown pending_div = str( - soup.find(id=f'vector_project_request_section_pending')) + soup.find(id=f'{section}_pending')) self.assertIn(str(pending_req.pk), pending_div) self.assertIn(pending_req.requester.email, pending_div) self.assertIn(pending_req.pi.email, pending_div) self.assertIn(pending_req.modified.strftime("%b. %d, %Y"), pending_div) self.assertIn(pending_req.status.name, pending_div) + # completed request is shown completed_div = str( - soup.find(id=f'vector_project_request_section_completed')) + soup.find(id=f'{section}_completed')) self.assertIn(str(completed_req.pk), completed_div) self.assertIn(completed_req.requester.email, completed_div) self.assertIn(completed_req.pi.email, completed_div) @@ -421,22 +456,29 @@ def assert_request_shown(user, url): def test_project_join_requests(self): """Testing that project join requests appear correctly""" - def assert_request_shown(user, url, section): + def assert_request_shown(user, url, status): response = self.get_response(user, url) soup = BeautifulSoup(response.content, 'html.parser') + section = 'project_join_request_section' + + # pending request is shown + if status == 'both' or status == 'pending': + # notification badge is shown + self.assert_pending_request_badge_shown( + section, response, 1) - if section == 'both' or section == 'pending': pending_div = str( - soup.find(id=f'project_join_request_section_pending')) + soup.find(id=f'{section}_pending')) self.assertIn(str(pending_req.pk), pending_div) self.assertIn(pending_req.project_user.user.username, pending_div) self.assertIn(pending_req.project_user.project.name, pending_div) self.assertIn(pending_req.created.strftime("%b. %d, %Y"), pending_div) self.assertIn(pending_req.reason, pending_div) - if section == 'both' or section == 'completed': + # completed request is shown + if status == 'both' or status == 'completed': completed_div = str( - soup.find(id=f'project_join_request_section_completed')) + soup.find(id=f'{section}_completed')) self.assertIn(str(completed_req.pk), completed_div) self.assertIn(completed_req.project_user.user.username, completed_div) self.assertIn(completed_req.project_user.project.name, completed_div) @@ -481,9 +523,15 @@ def test_project_renewal_requests(self): def assert_request_shown(user, url): response = self.get_response(user, url) soup = BeautifulSoup(response.content, 'html.parser') + section = 'project_renewal_request_section' + # notification badge is shown + self.assert_pending_request_badge_shown( + section, response, 1) + + # pending request is shown pending_div = str( - soup.find(id=f'project_renewal_request_section_pending')) + soup.find(id=f'{section}_pending')) self.assertIn(str(pending_req.pk), pending_div) self.assertIn(pending_req.requester.email, pending_div) self.assertIn(pending_req.pre_project.name, pending_div) @@ -491,8 +539,9 @@ def assert_request_shown(user, url): self.assertIn(pending_req.modified.strftime("%b. %d, %Y"), pending_div) self.assertIn(pending_req.status.name, pending_div) + # completed request is shown completed_div = str( - soup.find(id=f'project_renewal_request_section_completed')) + soup.find(id=f'{section}_completed')) self.assertIn(str(completed_req.pk), completed_div) self.assertIn(completed_req.requester.email, completed_div) self.assertIn(completed_req.pre_project.name, completed_div) @@ -542,9 +591,15 @@ def test_su_purchase_requests(self): def assert_request_shown(user, url): response = self.get_response(user, url) soup = BeautifulSoup(response.content, 'html.parser') + section = 'service_unit_purchase_request_section' + + # notification badge is shown + self.assert_pending_request_badge_shown( + section, response, 1) + # pending request is shown pending_div = str( - soup.find(id=f'service_unit_purchase_request_section_pending')) + soup.find(id=f'{section}_pending')) self.assertIn(str(pending_req.pk), pending_div) self.assertIn(pending_req.requester.email, pending_div) self.assertIn(pending_req.project.name, pending_div) @@ -553,7 +608,7 @@ def assert_request_shown(user, url): self.assertIn(pending_req.status.name, pending_div) completed_div = str( - soup.find(id=f'service_unit_purchase_request_section_completed')) + soup.find(id=f'{section}_completed')) self.assertIn(str(completed_req.pk), completed_div) self.assertIn(completed_req.requester.email, completed_div) self.assertIn(completed_req.project.name, completed_div) From 2b2776abc44988861fc2c666d7f3b18af3900e90 Mon Sep 17 00:00:00 2001 From: jofeinstein Date: Thu, 3 Mar 2022 09:42:04 -0500 Subject: [PATCH 71/85] pending notification badge is plural when num_requests > 1 --- coldfront/core/user/templates/request_hub/request_section.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/coldfront/core/user/templates/request_hub/request_section.html b/coldfront/core/user/templates/request_hub/request_section.html index bd11f5d51..6fa24bcc0 100644 --- a/coldfront/core/user/templates/request_hub/request_section.html +++ b/coldfront/core/user/templates/request_hub/request_section.html @@ -8,7 +8,7 @@ {% if request_obj.num_pending %} - {{ request_obj.num_pending }} pending requests + {{ request_obj.num_pending }} pending request{% if request_obj.num_pending > 1 %}s{% endif %} {% endif %}
    From 98c85831f35f956743eea6b8807bf0885d367b0a Mon Sep 17 00:00:00 2001 From: jofeinstein Date: Thu, 3 Mar 2022 09:47:16 -0500 Subject: [PATCH 72/85] TestRequestHubView now inherits TestBase --- .../tests/test_views/test_request_hub_view.py | 37 +++++-------------- 1 file changed, 9 insertions(+), 28 deletions(-) diff --git a/coldfront/core/user/tests/test_views/test_request_hub_view.py b/coldfront/core/user/tests/test_views/test_request_hub_view.py index 6388d9b3c..86dbe1da5 100644 --- a/coldfront/core/user/tests/test_views/test_request_hub_view.py +++ b/coldfront/core/user/tests/test_views/test_request_hub_view.py @@ -1,12 +1,7 @@ -import os -import sys import datetime from decimal import Decimal -from http import HTTPStatus from bs4 import BeautifulSoup -from django.core.management import call_command -from django.test import TestCase from django.contrib.auth.models import User from django.urls import reverse @@ -26,22 +21,15 @@ VectorProjectAllocationRequest, ProjectUserJoinRequest from coldfront.core.user.models import UserProfile from coldfront.core.utils.common import utc_now_offset_aware +from coldfront.core.utils.tests.test_base import TestBase -class TestRequestHubView(TestCase): +class TestRequestHubView(TestBase): """A class for testing RequestHubView.""" def setUp(self): """Set up test data.""" - sys.stdout = open(os.devnull, 'w') - call_command('import_field_of_science_data') - call_command('add_default_project_choices') - call_command('add_resource_defaults') - call_command('add_allocation_defaults') - call_command('add_brc_accounting_defaults') - call_command('create_staff_group') - call_command('create_allocation_periods') - sys.stdout = sys.__stdout__ + super().setUp() self.password = 'password' @@ -112,13 +100,6 @@ def setUp(self): 'project renewal request', 'service unit purchase request'] - def assert_has_access(self, user, url, has_access): - self.client.login(username=user.username, password=self.password) - response = self.client.get(url) - status_code = HTTPStatus.OK if has_access else HTTPStatus.FORBIDDEN - self.assertEqual(response.status_code, status_code) - self.client.logout() - def get_response(self, user, url): self.client.login(username=user.username, password=self.password) return self.client.get(url) @@ -149,14 +130,14 @@ def test_access(self): # all users should have access to the normal view for user in User.objects.all(): - self.assert_has_access(user, self.url, True) + self.assert_has_access(self.url, user, True) # only staff/admin should have access to request-hub-admin - self.assert_has_access(self.admin, self.admin_url, True) - self.assert_has_access(self.staff, self.admin_url, True) - self.assert_has_access(self.pi, self.admin_url, False) - self.assert_has_access(self.user0, self.admin_url, False) - self.assert_has_access(self.user1, self.admin_url, False) + self.assert_has_access(self.admin_url, self.admin, True) + self.assert_has_access(self.admin_url, self.staff, True) + self.assert_has_access(self.admin_url, self.pi, False) + self.assert_has_access(self.admin_url, self.user0, False) + self.assert_has_access(self.admin_url, self.user1, False) def test_admin_buttons(self): """Test that 'Go to main request page' buttons only appear for From d268777e8279ce8d8ce6b27b0ce1a9c737eea0e9 Mon Sep 17 00:00:00 2001 From: jofeinstein Date: Fri, 4 Mar 2022 18:34:04 -0500 Subject: [PATCH 73/85] adding template for help text popover --- .../user/templates/request_hub/help_text_popover.html | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 coldfront/core/user/templates/request_hub/help_text_popover.html diff --git a/coldfront/core/user/templates/request_hub/help_text_popover.html b/coldfront/core/user/templates/request_hub/help_text_popover.html new file mode 100644 index 000000000..22a3f31ab --- /dev/null +++ b/coldfront/core/user/templates/request_hub/help_text_popover.html @@ -0,0 +1,11 @@ +
    + Help Text + + + + \ No newline at end of file From 4f9ea1d6cbfc575a6a8a459320561ca137e496d5 Mon Sep 17 00:00:00 2001 From: jofeinstein Date: Fri, 4 Mar 2022 18:35:33 -0500 Subject: [PATCH 74/85] changed alignment of buttons. changed help text --- coldfront/core/user/templates/request_hub/request_hub.html | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/coldfront/core/user/templates/request_hub/request_hub.html b/coldfront/core/user/templates/request_hub/request_hub.html index ef17e6cfc..e4b615923 100644 --- a/coldfront/core/user/templates/request_hub/request_hub.html +++ b/coldfront/core/user/templates/request_hub/request_hub.html @@ -10,12 +10,12 @@

    Request Hub

    {% if show_all %} - Below are all of the requests in the myBRC Portal. Click on a request + Below are all of the requests in MyBRC. Click on a request section to view requests of that type. To perform actions on a specific request, click the button to go to the request's main page and perform the actions there. Click here to view only your requests. {% else %} - Below are all of your requests in the myBRC Portal. Click on a request + Below are all of your requests in MyBRC. Click on a request section to view your requests of that type. {% if admin_staff %} @@ -30,7 +30,7 @@

    Request Hub

    -
    +