Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 36 additions & 27 deletions admin/nodes/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from django.contrib import messages
from django.contrib.auth.mixins import PermissionRequiredMixin
from django.core.exceptions import PermissionDenied, ValidationError
from django.db.models import F, Case, When, IntegerField
from django.db.models import F, Case, When, IntegerField, Prefetch
from django.http import HttpResponse
from django.shortcuts import redirect, reverse, get_object_or_404
from django.urls import NoReverseMatch
Expand Down Expand Up @@ -487,42 +487,51 @@ class EmbargoReportView(PermissionRequiredMixin, TemplateView):
- active embargoes that are past their end date
- upcoming active embargoes
"""
EMBARGO_REPORT_PAGE_SIZE = 10
Comment thread
cslzchen marked this conversation as resolved.
Outdated

template_name = 'nodes/embargo_report.html'
permission_required = 'osf.view_registration'
raise_exception = True

def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
pending_embargoes = Embargo.objects.pending_embargoes().select_related('initiated_by')
active_embargoes = Embargo.objects.active_embargoes().select_related('initiated_by')

pending_overdue_embargoes = [
embargo for embargo in pending_embargoes
if embargo.should_be_embargoed
]

overdue_embargoes = [
embargo for embargo in active_embargoes
if embargo.should_be_completed
]

upcoming_queryset = active_embargoes.filter(
end_date__gte=timezone.now(),
).order_by('end_date')
def _embargo_report_queryset(self, queryset):
return queryset.select_related('initiated_by').prefetch_related(
Prefetch(
'registrations',
queryset=Registration.objects.filter(is_deleted=False).prefetch_related(
'guids',
).only('id', 'title', 'is_public', 'embargo_id'),
),
)

page_number = self.request.GET.get('page') or 1
paginator = Paginator(upcoming_queryset, 10)
def paginate_embargo_report(self, request, queryset, page_param):
paginator = Paginator(queryset, self.EMBARGO_REPORT_PAGE_SIZE)
page_number = request.GET.get(page_param) or 1
try:
upcoming_page = paginator.page(page_number)
return paginator.page(page_number)
except InvalidPage:
upcoming_page = paginator.page(1)
return paginator.page(1)

def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
request = self.request

context.update({
'now': timezone.now(),
'pending_overdue_embargoes': pending_overdue_embargoes,
'overdue_embargoes': overdue_embargoes,
'upcoming_embargoes': upcoming_page.object_list,
'upcoming_page': upcoming_page,
'upcoming_page': self.paginate_embargo_report(
request,
self._embargo_report_queryset(Embargo.objects.active_upcoming()),
'upcoming_page',
),
'pending_page': self.paginate_embargo_report(
request,
self._embargo_report_queryset(Embargo.objects.pending_past_activation_window()),
'pending_page',
),
'overdue_page': self.paginate_embargo_report(
request,
self._embargo_report_queryset(Embargo.objects.active_past_end_date()),
'overdue_page',
),
})
return context

Expand Down
23 changes: 15 additions & 8 deletions admin/templates/nodes/embargo_report.html
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,12 @@ <h2>Upcoming Active Embargoes</h2>
<th>Initiated By</th>
</tr>
</thead>
{% include "util/pagination.html" with items=upcoming_page status='' pagin=False order='' %}
{% if upcoming_page.paginator.num_pages > 1 %}
{% include "util/pagination.html" with items=upcoming_page page_param="upcoming_page" status='' pagin=False order='' %}
{% endif %}
<tbody>
{% for embargo in upcoming_embargoes %}
{% with registration=embargo.registrations.first %}
{% for embargo in upcoming_page %}
{% with registration=embargo.registrations.all.0 %}
{% if registration %}
<tr>
<td>
Expand Down Expand Up @@ -66,9 +68,12 @@ <h2>Pending Embargoes Past Pending Window</h2>
<th>Initiated By</th>
</tr>
</thead>
{% if pending_page.paginator.num_pages > 1 %}
{% include "util/pagination.html" with items=pending_page page_param="pending_page" status='' pagin=False order='' %}
{% endif %}
<tbody>
{% for embargo in pending_overdue_embargoes %}
{% with registration=embargo.registrations.first %}
{% for embargo in pending_page %}
{% with registration=embargo.registrations.all.0 %}
{% if registration %}
<tr>
<td>
Expand Down Expand Up @@ -113,9 +118,12 @@ <h2>Active Embargoes Past Pending Window</h2>
<th>Initiated By</th>
</tr>
</thead>
{% if overdue_page.paginator.num_pages > 1 %}
{% include "util/pagination.html" with items=overdue_page page_param="overdue_page" status='' pagin=False order='' %}
{% endif %}
<tbody>
{% for embargo in overdue_embargoes %}
{% with registration=embargo.registrations.first %}
{% for embargo in overdue_page %}
{% with registration=embargo.registrations.all.0 %}
{% if registration %}
<tr>
<td>
Expand Down Expand Up @@ -154,4 +162,3 @@ <h2>Active Embargoes Past Pending Window</h2>
</table>

{% endblock %}

8 changes: 4 additions & 4 deletions admin/templates/util/pagination.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@
<div class="pagination pagination-lg">
<span>
{% if items.has_previous %}
<a href="?page=1&amp;status={{ status }}&amp;p={{ pagin }}&amp;order_by={{ order }}{{ extra_query_params }}"
<a href="?{{ page_param|default:"page" }}=1&amp;status={{ status }}&amp;p={{ pagin }}&amp;order_by={{ order }}{{ extra_query_params }}"
class="btn btn-primary">
|
</a>
<a href="?page={{ items.previous_page_number }}&amp;status={{ status }}&amp;p={{ pagin }}&amp;order_by={{ order }}{{ extra_query_params }}"
<a href="?{{ page_param|default:"page" }}={{ items.previous_page_number }}&amp;status={{ status }}&amp;p={{ pagin }}&amp;order_by={{ order }}{{ extra_query_params }}"
class="btn btn-primary">
<i class="fa fa-angle-left"></i>
</a>
Expand All @@ -25,11 +25,11 @@
</span>

{% if items.has_next %}
<a href="?page={{ items.next_page_number }}&amp;status={{ status }}&amp;p={{ pagin }}&amp;order_by={{ order }}{{ extra_query_params }}"
<a href="?{{ page_param|default:"page" }}={{ items.next_page_number }}&amp;status={{ status }}&amp;p={{ pagin }}&amp;order_by={{ order }}{{ extra_query_params }}"
class="btn btn-primary">
<i class="fa fa-angle-right"></i>
</a>
<a href="?page={{ items.paginator.num_pages }}&amp;status={{ status }}&amp;p={{ pagin }}&amp;order_by={{ order }}{{ extra_query_params }}"
<a href="?{{ page_param|default:"page" }}={{ items.paginator.num_pages }}&amp;status={{ status }}&amp;p={{ pagin }}&amp;order_by={{ order }}{{ extra_query_params }}"
class="btn btn-primary">
|
</a>
Expand Down
67 changes: 65 additions & 2 deletions admin_tests/nodes/test_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
AbstractNode,
RegistrationApproval,
Embargo,
Sanction,
SchemaResponse,
DraftRegistration,
)
Expand All @@ -39,7 +40,8 @@
CheckArchiveStatusRegistrationsView,
ForceArchiveRegistrationsView,
ApprovalBacklogListView,
ConfirmApproveBacklogView
ConfirmApproveBacklogView,
EmbargoReportView,
)
from admin_tests.utilities import setup_log_view, setup_view, handle_post_view_request
from api_tests.share._utils import mock_update_share
Expand All @@ -57,14 +59,15 @@
RegistrationApprovalFactory,
RegistrationProviderFactory,
DraftRegistrationFactory,
EmbargoFactory,
get_default_metaschema
)
from osf.utils.workflows import ApprovalStates, RegistrationModerationStates
from osf.utils import permissions
from osf.exceptions import NodeStateError


from website.settings import REGISTRATION_APPROVAL_TIME
from website.settings import REGISTRATION_APPROVAL_TIME, EMBARGO_PENDING_TIME


def patch_messages(request):
Expand Down Expand Up @@ -1069,3 +1072,63 @@ def test_file_is_removed_from_registration_osfstorage(self):
name=registration_osfstorage.archive_folder_name
).children.exists()
assert not self.registration_registered_from.files.exists()


class TestEmbargoReportView(AdminTestCase):

def setUp(self):
super().setUp()
self.request = RequestFactory().get('/nodes/embargo_report/')
self.view = setup_log_view(EmbargoReportView(), self.request)

def test_pending_past_activation_window_in_report(self):
embargo = EmbargoFactory(approve=False)
embargo.initiation_date = timezone.now() - EMBARGO_PENDING_TIME - timezone.timedelta(days=1)
embargo.save()

context = self.view.get_context_data()
assert embargo in context['pending_page']

def test_recent_pending_embargo_excluded(self):
embargo = EmbargoFactory(approve=False)
embargo.initiation_date = timezone.now()
embargo.save()

context = self.view.get_context_data()
assert embargo not in context['pending_page']

def test_active_past_end_date_in_report(self):
embargo = EmbargoFactory(
approve=True,
end_date=timezone.now() - timezone.timedelta(days=1),
)
embargo.state = Sanction.APPROVED
embargo.save()

context = self.view.get_context_data()
assert embargo in context['overdue_page']

def test_active_upcoming_in_report(self):
embargo = EmbargoFactory(
approve=True,
end_date=timezone.now() + timezone.timedelta(days=30),
)
embargo.state = Sanction.APPROVED
embargo.save()

context = self.view.get_context_data()
assert embargo in context['upcoming_page']

def test_deleted_registration_embargo_excluded(self):
embargo = EmbargoFactory(
approve=True,
end_date=timezone.now() - timezone.timedelta(days=1),
)
embargo.state = Sanction.APPROVED
embargo.save()
registration = embargo.registrations.first()
registration.is_deleted = True
registration.save()

context = self.view.get_context_data()
assert embargo not in context['overdue_page']
35 changes: 35 additions & 0 deletions osf/models/sanctions.py
Original file line number Diff line number Diff line change
Expand Up @@ -456,8 +456,17 @@ def _email_template_context(self, user, node, is_authorizer=False, urls=None):
return {}


class EmbargoQuerySet(models.QuerySet):

def non_deleted_registations(self):
return self.filter(registrations__is_deleted=False).distinct()
Comment thread
cslzchen marked this conversation as resolved.
Outdated


class EmbargoManager(models.Manager):

def get_queryset(self):
return EmbargoQuerySet(self.model, using=self._db)

def pending_embargoes(self):
"""Embargoes that are still awaiting admin approval."""
return self.filter(state=self.model.UNAPPROVED)
Expand All @@ -466,6 +475,32 @@ def active_embargoes(self):
"""Embargoes that have been approved and are currently in effect."""
return self.filter(state=self.model.APPROVED)

def pending_past_activation_window(self):
"""Pending embargoes that should have been activated (matches should_be_embargoed)."""
cutoff = timezone.now() - osf_settings.EMBARGO_PENDING_TIME
return (
self.pending_embargoes()
.filter(initiation_date__lte=cutoff)
.non_deleted_registations()
Comment thread
cslzchen marked this conversation as resolved.
Outdated
Comment thread
cslzchen marked this conversation as resolved.
Outdated
Comment thread
cslzchen marked this conversation as resolved.
Outdated
)

def active_past_end_date(self):
"""Active embargoes past end date (matches should_be_completed)."""
return (
self.active_embargoes()
.filter(end_date__lt=timezone.now())
.non_deleted_registations()
)

def active_upcoming(self):
"""Active embargoes with a future end date."""
return (
self.active_embargoes()
.filter(end_date__gte=timezone.now())
.non_deleted_registations()
.order_by('end_date')
)
Comment thread
cslzchen marked this conversation as resolved.


class Embargo(SanctionCallbackMixin, EmailApprovableSanction):
"""Embargo object for registrations waiting to go public."""
Expand Down