Commit 14364dc7 by Gregory Martin Committed by GitHub

Merge pull request #15955 from edx/yro/update_mobile_api_certs

Update 'downloadable' status for mobile/other API
parents 6062e45e c1dcb54a
...@@ -234,8 +234,9 @@ def certificate_downloadable_status(student, course_key): ...@@ -234,8 +234,9 @@ def certificate_downloadable_status(student, course_key):
'download_url': None, 'download_url': None,
'uuid': None, 'uuid': None,
} }
may_view_certificate = CourseOverview.get_from_id(course_key).may_certify()
if current_status['status'] == CertificateStatuses.downloadable: if current_status['status'] == CertificateStatuses.downloadable and may_view_certificate:
response_data['is_downloadable'] = True response_data['is_downloadable'] = True
response_data['download_url'] = current_status['download_url'] or get_certificate_url(student.id, course_key) response_data['download_url'] = current_status['download_url'] or get_certificate_url(student.id, course_key)
response_data['uuid'] = current_status['uuid'] response_data['uuid'] = current_status['uuid']
......
...@@ -5,6 +5,7 @@ from functools import wraps ...@@ -5,6 +5,7 @@ from functools import wraps
import ddt import ddt
from datetime import datetime from datetime import datetime
from datetime import timedelta
from config_models.models import cache from config_models.models import cache
from django.conf import settings from django.conf import settings
from django.core.urlresolvers import reverse from django.core.urlresolvers import reverse
...@@ -15,6 +16,7 @@ from freezegun import freeze_time ...@@ -15,6 +16,7 @@ from freezegun import freeze_time
from mock import patch from mock import patch
from nose.plugins.attrib import attr from nose.plugins.attrib import attr
from opaque_keys.edx.locator import CourseLocator from opaque_keys.edx.locator import CourseLocator
import pytz
from certificates import api as certs_api from certificates import api as certs_api
from certificates.models import ( from certificates.models import (
...@@ -81,6 +83,7 @@ class WebCertificateTestMixin(object): ...@@ -81,6 +83,7 @@ class WebCertificateTestMixin(object):
@attr(shard=1) @attr(shard=1)
@ddt.ddt
class CertificateDownloadableStatusTests(WebCertificateTestMixin, ModuleStoreTestCase): class CertificateDownloadableStatusTests(WebCertificateTestMixin, ModuleStoreTestCase):
"""Tests for the `certificate_downloadable_status` helper function. """ """Tests for the `certificate_downloadable_status` helper function. """
ENABLED_SIGNALS = ['course_published'] ENABLED_SIGNALS = ['course_published']
...@@ -94,7 +97,9 @@ class CertificateDownloadableStatusTests(WebCertificateTestMixin, ModuleStoreTes ...@@ -94,7 +97,9 @@ class CertificateDownloadableStatusTests(WebCertificateTestMixin, ModuleStoreTes
org='edx', org='edx',
number='verified', number='verified',
display_name='Verified Course', display_name='Verified Course',
end=datetime.now() end=datetime.now(pytz.UTC),
self_paced=False,
certificate_available_date=datetime.now(pytz.UTC) - timedelta(days=2)
) )
self.request_factory = RequestFactory() self.request_factory = RequestFactory()
...@@ -201,6 +206,31 @@ class CertificateDownloadableStatusTests(WebCertificateTestMixin, ModuleStoreTes ...@@ -201,6 +206,31 @@ class CertificateDownloadableStatusTests(WebCertificateTestMixin, ModuleStoreTes
} }
) )
@ddt.data(
(False, datetime.now(pytz.UTC) + timedelta(days=2), False),
(False, datetime.now(pytz.UTC) - timedelta(days=2), True),
(True, datetime.now(pytz.UTC) + timedelta(days=2), True)
)
@ddt.unpack
@patch.dict(settings.FEATURES, {'CERTIFICATES_HTML_VIEW': True})
def test_cert_api_return(self, self_paced, cert_avail_date, cert_downloadable_status):
"""
Test 'downloadable status'
"""
self.course.self_paced = self_paced
self.course.certificate_available_date = cert_avail_date
self.course.save()
CourseEnrollment.enroll(self.student, self.course.id, mode='honor')
self._setup_course_certificate()
with mock_passing_grade():
certs_api.generate_user_certificates(self.student, self.course.id)
self.assertEqual(
certs_api.certificate_downloadable_status(self.student, self.course.id)['is_downloadable'],
cert_downloadable_status
)
@attr(shard=1) @attr(shard=1)
@ddt.ddt @ddt.ddt
......
...@@ -2075,7 +2075,8 @@ class GenerateUserCertTests(ModuleStoreTestCase): ...@@ -2075,7 +2075,8 @@ class GenerateUserCertTests(ModuleStoreTestCase):
number='verified', number='verified',
end=datetime.now(), end=datetime.now(),
display_name='Verified Course', display_name='Verified Course',
grade_cutoffs={'cutoff': 0.75, 'Pass': 0.5} grade_cutoffs={'cutoff': 0.75, 'Pass': 0.5},
self_paced=True
) )
self.enrollment = CourseEnrollment.enroll(self.student, self.course.id, mode='honor') self.enrollment = CourseEnrollment.enroll(self.student, self.course.id, mode='honor')
self.assertTrue(self.client.login(username=self.student, password='123456')) self.assertTrue(self.client.login(username=self.student, password='123456'))
......
...@@ -10,7 +10,6 @@ Test utilities for mobile API tests: ...@@ -10,7 +10,6 @@ Test utilities for mobile API tests:
MobileCourseAccessTestMixin - tests for APIs with mobile_course_access. MobileCourseAccessTestMixin - tests for APIs with mobile_course_access.
""" """
# pylint: disable=no-member # pylint: disable=no-member
from datetime import timedelta
import ddt import ddt
import datetime import datetime
...@@ -19,6 +18,7 @@ from django.core.urlresolvers import reverse ...@@ -19,6 +18,7 @@ from django.core.urlresolvers import reverse
from django.utils import timezone from django.utils import timezone
from mock import patch from mock import patch
from opaque_keys.edx.keys import CourseKey from opaque_keys.edx.keys import CourseKey
import pytz
from rest_framework.test import APITestCase from rest_framework.test import APITestCase
from courseware.access_response import MobileAvailabilityError, StartDateError, VisibilityError from courseware.access_response import MobileAvailabilityError, StartDateError, VisibilityError
...@@ -43,7 +43,9 @@ class MobileAPITestCase(ModuleStoreTestCase, APITestCase): ...@@ -43,7 +43,9 @@ class MobileAPITestCase(ModuleStoreTestCase, APITestCase):
self.course = CourseFactory.create( self.course = CourseFactory.create(
mobile_available=True, mobile_available=True,
static_asset_path="needed_for_split", static_asset_path="needed_for_split",
end=datetime.datetime.now()) end=datetime.datetime.now(pytz.UTC),
certificate_available_date=datetime.datetime.now(pytz.UTC)
)
self.user = UserFactory.create() self.user = UserFactory.create()
self.password = 'test' self.password = 'test'
self.username = self.user.username self.username = self.user.username
...@@ -176,7 +178,7 @@ class MobileCourseAccessTestMixin(MobileAPIMilestonesMixin): ...@@ -176,7 +178,7 @@ class MobileCourseAccessTestMixin(MobileAPIMilestonesMixin):
# pylint: disable=attribute-defined-outside-init # pylint: disable=attribute-defined-outside-init
self.course = CourseFactory.create(mobile_available=True, static_asset_path="needed_for_split") self.course = CourseFactory.create(mobile_available=True, static_asset_path="needed_for_split")
# pylint: disable=attribute-defined-outside-init # pylint: disable=attribute-defined-outside-init
self.course.start = timezone.now() + timedelta(days=365) self.course.start = timezone.now() + datetime.timedelta(days=365)
self.init_course_access() self.init_course_access()
self._verify_response(self.ALLOW_ACCESS_TO_UNRELEASED_COURSE, StartDateError(self.course.start)) self._verify_response(self.ALLOW_ACCESS_TO_UNRELEASED_COURSE, StartDateError(self.course.start))
......
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