Commit 62d07c91 by Renzo Lucioni

Merge pull request #11541 from edx/renzo/manual-cert-trigger

Add API endpoint for issuing programs certificates
parents 922269f0 619420bb
# pylint: disable=missing-docstring
from django.core.urlresolvers import reverse
from django.test import TestCase
import mock
from oauth2_provider.tests.factories import AccessTokenFactory, ClientFactory
from openedx.core.djangoapps.programs.tests.mixins import ProgramsApiConfigMixin
from student.tests.factories import UserFactory
class IssueProgramCertificatesViewTests(TestCase, ProgramsApiConfigMixin):
password = 'password'
def setUp(self):
super(IssueProgramCertificatesViewTests, self).setUp()
self.create_programs_config()
self.path = reverse('support:programs-certify')
self.user = UserFactory(password=self.password, is_staff=True)
self.data = {'username': self.user.username}
self.headers = {}
self.client.login(username=self.user.username, password=self.password)
def _verify_response(self, status_code):
"""Verify that the endpoint returns the provided status code and enqueues the task if appropriate."""
with mock.patch('lms.djangoapps.support.views.programs.award_program_certificates.delay') as mock_task:
response = self.client.post(self.path, self.data, **self.headers)
self.assertEqual(response.status_code, status_code)
self.assertEqual(status_code == 200, mock_task.called)
def test_authentication_required(self):
"""Verify that the endpoint requires authentication."""
self.client.logout()
self._verify_response(403)
def test_session_auth(self):
"""Verify that the endpoint supports session auth."""
self._verify_response(200)
def test_oauth(self):
"""Verify that the endpoint supports OAuth 2.0."""
access_token = AccessTokenFactory(user=self.user, client=ClientFactory()).token # pylint: disable=no-member
self.headers['HTTP_AUTHORIZATION'] = 'Bearer ' + access_token
self.client.logout()
self._verify_response(200)
def test_staff_permissions_required(self):
"""Verify that staff permissions are required to access the endpoint."""
self.user.is_staff = False
self.user.save() # pylint: disable=no-member
self._verify_response(403)
def test_certification_disabled(self):
"""Verify that the endpoint returns a 400 when program certification is disabled."""
self.create_programs_config(enable_certification=False)
self._verify_response(400)
def test_username_required(self):
"""Verify that the endpoint returns a 400 when a username isn't provided."""
self.data.pop('username')
self._verify_response(400)
......@@ -16,4 +16,5 @@ urlpatterns = patterns(
views.EnrollmentSupportListView.as_view(),
name="enrollment_list"
),
url(r'^programs/certify/$', views.IssueProgramCertificatesView.as_view(), name='programs-certify'),
)
......@@ -6,3 +6,4 @@ from .index import *
from .certificate import *
from .enrollments import *
from .refund import *
from .programs import IssueProgramCertificatesView
# pylint: disable=missing-docstring
import logging
from rest_framework import permissions, status, views
from rest_framework.authentication import SessionAuthentication
from rest_framework.response import Response
from rest_framework_oauth.authentication import OAuth2Authentication
from openedx.core.djangoapps.programs.models import ProgramsApiConfig
from openedx.core.djangoapps.programs.tasks.v1.tasks import award_program_certificates
log = logging.getLogger(__name__)
class IssueProgramCertificatesView(views.APIView):
"""
**Use Cases**
Trigger the task responsible for awarding program certificates on behalf
of the user with the provided username.
**Example Requests**
POST /support/programs/certify/
{
'username': 'foo'
}
**Returns**
* 200 on success.
* 400 if program certification is disabled or a username is not provided.
* 401 if the request is not authenticated.
* 403 if the authenticated user does not have staff permissions.
"""
authentication_classes = (SessionAuthentication, OAuth2Authentication)
permission_classes = (permissions.IsAuthenticated, permissions.IsAdminUser,)
def post(self, request):
if not ProgramsApiConfig.current().is_certification_enabled:
return Response(
{'error': 'Program certification is disabled.'},
status=status.HTTP_400_BAD_REQUEST
)
username = request.data.get('username')
if username:
log.info('Enqueuing program certification task for user [%s]', username)
award_program_certificates.delay(username)
return Response()
else:
return Response(
{'error': 'A username is required in order to issue program certificates.'},
status=status.HTTP_400_BAD_REQUEST
)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment