Adds a waffle switch which gates access to the CourseEnrollmentAdmin views

This commit is contained in:
Jillian Vogel
2018-07-25 15:04:40 +09:30
parent 41848b8ff3
commit 7f0bbedba1
2 changed files with 88 additions and 8 deletions

View File

@@ -1,5 +1,6 @@
""" Django admin pages for student app """
from config_models.admin import ConfigurationModelAdmin
import waffle
from django import forms
from django.contrib import admin
from django.contrib.admin.sites import NotRegistered
@@ -165,13 +166,7 @@ class CourseEnrollmentForm(forms.ModelForm):
fields = '__all__'
# Page disabled because it makes DB quries that impact performance enough to
# cause a site outage. It may be re-enabled when it is updated to make more
# efficent DB queries
# https://openedx.atlassian.net/browse/OPS-2943
# Learner ticket to add functionality to /support
# https://openedx.atlassian.net/browse/LEARNER-4744
#@admin.register(CourseEnrollment)
@admin.register(CourseEnrollment)
class CourseEnrollmentAdmin(admin.ModelAdmin):
""" Admin interface for the CourseEnrollment model. """
list_display = ('id', 'course_id', 'mode', 'user', 'is_active',)
@@ -183,6 +178,43 @@ class CourseEnrollmentAdmin(admin.ModelAdmin):
def queryset(self, request):
return super(CourseEnrollmentAdmin, self).queryset(request).select_related('user')
def has_permission(self, request, method):
"""
Returns True if the given method is allowed.
Access to these admin views is restricted because it makes DB quries that impact performance enough to cause a
site outage, cf https://openedx.atlassian.net/browse/OPS-2943
Enable these views using the waffle switch: `student.coursenrollment.admin`
"""
if waffle.switch_is_active('student.coursenrollment.admin'):
return getattr(super(CourseEnrollmentAdmin, self), method)(request)
return False
def has_add_permission(self, request):
"""
Returns True if CourseEnrollment objects can be added via the admin view.
"""
return self.has_permission(request, 'has_add_permission')
def has_change_permission(self, request, obj=None):
"""
Returns True if CourseEnrollment objects can be modified via the admin view.
"""
return self.has_permission(request, 'has_change_permission')
def has_delete_permission(self, request, obj=None):
"""
Returns True if CourseEnrollment objects can be deleted via the admin view.
"""
return self.has_permission(request, 'has_delete_permission')
def has_module_permission(self, request):
"""
Returns True if links to the CourseEnrollment admin view can be displayed.
"""
return self.has_permission(request, 'has_module_permission')
class UserProfileInline(admin.StackedInline):
""" Inline admin interface for UserProfile model. """

View File

@@ -1,6 +1,8 @@
"""
Tests student admin.py
"""
import ddt
from waffle.testutils import override_switch
from django.contrib.admin.sites import AdminSite
from django.contrib.auth.models import User
from django.urls import reverse
@@ -8,7 +10,7 @@ from django.test import TestCase
from mock import Mock
from student.admin import UserAdmin
from student.tests.factories import UserFactory
from student.tests.factories import CourseEnrollmentFactory, UserFactory
from xmodule.modulestore.tests.django_utils import SharedModuleStoreTestCase
from xmodule.modulestore.tests.factories import CourseFactory
@@ -186,3 +188,49 @@ class AdminUserPageTest(TestCase):
request = Mock()
user = Mock()
self.assertIn('username', self.admin.get_readonly_fields(request, user))
@ddt.ddt
class CourseEnrollmentAdminTest(SharedModuleStoreTestCase):
"""
Unit tests for the CourseEnrollmentAdmin view.
"""
ADMIN_URLS = (
('get', reverse('admin:student_courseenrollment_add')),
('get', reverse('admin:student_courseenrollment_changelist')),
('get', reverse('admin:student_courseenrollment_change', args=(1,))),
('get', reverse('admin:student_courseenrollment_delete', args=(1,))),
('post', reverse('admin:student_courseenrollment_add')),
('post', reverse('admin:student_courseenrollment_changelist')),
('post', reverse('admin:student_courseenrollment_change', args=(1,))),
('post', reverse('admin:student_courseenrollment_delete', args=(1,))),
)
def setUp(self):
super(CourseEnrollmentAdminTest, self).setUp()
self.user = UserFactory.create(is_staff=True, is_superuser=True)
self.client.login(username=self.user.username, password='test')
CourseEnrollmentFactory(
user=self.user,
course_id=CourseFactory().id, # pylint: disable=no-member
)
@ddt.data(*ADMIN_URLS)
@ddt.unpack
def test_view_disabled(self, method, url):
"""
All CourseEnrollmentAdmin views are disabled by default.
"""
response = getattr(self.client, method)(url)
self.assertEqual(response.status_code, 403)
@override_switch('student.coursenrollment.admin', active=True)
@ddt.data(*ADMIN_URLS)
@ddt.unpack
def test_view_enabled(self, method, url):
"""
Ensure CourseEnrollmentAdmin views can be enabled with the waffle flag.
"""
self.client.login(username=self.user.username, password='test')
response = getattr(self.client, method)(url)
self.assertEqual(response.status_code, 200)