WL-1645 | Suppressing Error Alerts for WL Programs without Program Certificates.

This commit is contained in:
hasnain-naveed
2018-09-25 17:52:09 +05:00
parent a531953543
commit 282fe39337
2 changed files with 70 additions and 4 deletions

View File

@@ -16,6 +16,7 @@ from openedx.core.djangoapps.certificates.api import available_date_for_certific
from openedx.core.djangoapps.content.course_overviews.models import CourseOverview
from openedx.core.djangoapps.credentials.models import CredentialsApiConfig
from openedx.core.djangoapps.credentials.utils import get_credentials, get_credentials_api_client
from openedx.core.djangoapps.site_configuration import helpers as configuration_helpers
from openedx.core.djangoapps.programs.utils import ProgramProgressMeter
LOGGER = get_task_logger(__name__)
@@ -123,9 +124,13 @@ def award_program_certificates(self, username):
"""
LOGGER.info('Running task award_program_certificates for username %s', username)
programs_without_certificates = configuration_helpers.get_value('programs_without_certificates', [])
if programs_without_certificates:
if str(programs_without_certificates[0]).lower() == "all":
# this check will prevent unnecessary logging for partners without program certificates
return
countdown = 2 ** self.request.retries
# If the credentials config model is disabled for this
# feature, it may indicate a condition where processing of such tasks
# has been temporarily disabled. Since this is a recoverable situation,
@@ -156,6 +161,10 @@ def award_program_certificates(self, username):
# Determine which program certificates the user has already been awarded, if any.
existing_program_uuids = get_certified_programs(student)
# we will skip all the programs which have already been awarded and we want to skip the programs
# which are exit in site configuration in 'programs_without_certificates' list.
awarded_and_skipped_program_uuids = list(set(existing_program_uuids + list(programs_without_certificates)))
except Exception as exc:
LOGGER.exception('Failed to determine program certificates to be awarded for user %s', username)
raise self.retry(exc=exc, countdown=countdown, max_retries=MAX_RETRIES)
@@ -166,7 +175,7 @@ def award_program_certificates(self, username):
# This logic is important, because we will retry the whole task if awarding any particular program cert fails.
#
# N.B. the list is sorted to facilitate deterministic ordering, e.g. for tests.
new_program_uuids = sorted(list(set(completed_programs.keys()) - set(existing_program_uuids)))
new_program_uuids = sorted(list(set(completed_programs.keys()) - set(awarded_and_skipped_program_uuids)))
if new_program_uuids:
try:
credentials_client = get_credentials_api_client(

View File

@@ -2,6 +2,7 @@
Tests for programs celery tasks.
"""
import json
import logging
from datetime import datetime, timedelta
import ddt
import httpretty
@@ -21,10 +22,11 @@ from openedx.core.djangoapps.certificates.config import waffle
from openedx.core.djangoapps.content.course_overviews.tests.factories import CourseOverviewFactory
from openedx.core.djangoapps.credentials.tests.mixins import CredentialsApiConfigMixin
from openedx.core.djangoapps.programs.tasks.v1 import tasks
from openedx.core.djangoapps.site_configuration.tests.factories import SiteFactory
from openedx.core.djangoapps.site_configuration.tests.factories import SiteFactory, SiteConfigurationFactory
from openedx.core.djangolib.testing.utils import skip_unless_lms
from student.tests.factories import UserFactory
log = logging.getLogger(__name__)
CREDENTIALS_INTERNAL_SERVICE_URL = 'https://credentials.example.com'
TASKS_MODULE = 'openedx.core.djangoapps.programs.tasks.v1.tasks'
@@ -123,7 +125,7 @@ class AwardProgramCertificatesTestCase(CatalogIntegrationMixin, CredentialsApiCo
self.create_credentials_config()
self.student = UserFactory.create(username='test-student')
self.site = SiteFactory()
self.site_configuration = SiteConfigurationFactory(site=self.site)
self.catalog_integration = self.create_catalog_integration()
ClientFactory.create(name='credentials')
UserFactory.create(username=settings.CREDENTIALS_SERVICE_USERNAME)
@@ -170,6 +172,42 @@ class AwardProgramCertificatesTestCase(CatalogIntegrationMixin, CredentialsApiCo
actual_visible_dates = [call[0][3] for call in mock_award_program_certificate.call_args_list]
self.assertEqual(actual_visible_dates, expected_awarded_program_uuids) # program uuids are same as mock dates
@mock.patch('openedx.core.djangoapps.site_configuration.helpers.get_current_site_configuration')
def test_awarding_certs_with_skip_program_certificate(
self,
mocked_get_current_site_configuration,
mock_get_completed_programs,
mock_get_certified_programs,
mock_award_program_certificate,
):
"""
Checks that the Credentials API is used to award certificates for
the proper programs and those program will be skipped which are provided
by 'programs_without_certificates' list in site configuration.
"""
# all completed programs
mock_get_completed_programs.return_value = {1: 1, 2: 2, 3: 3, 4: 4}
# already awarded programs
mock_get_certified_programs.return_value = [1]
# programs to be skipped
self.site_configuration.values = {
"programs_without_certificates": [2]
}
self.site_configuration.save()
mocked_get_current_site_configuration.return_value = self.site_configuration
# programs which are expected to be awarded.
# (completed_programs - (already_awarded+programs + to_be_skipped_programs)
expected_awarded_program_uuids = [3, 4]
tasks.award_program_certificates.delay(self.student.username).get()
actual_program_uuids = [call[0][2] for call in mock_award_program_certificate.call_args_list]
self.assertEqual(actual_program_uuids, expected_awarded_program_uuids)
actual_visible_dates = [call[0][3] for call in mock_award_program_certificate.call_args_list]
self.assertEqual(actual_visible_dates, expected_awarded_program_uuids) # program uuids are same as mock dates
@ddt.data(
('credentials', 'enable_learner_issuance'),
)
@@ -219,6 +257,25 @@ class AwardProgramCertificatesTestCase(CatalogIntegrationMixin, CredentialsApiCo
self.assertFalse(mock_get_certified_programs.called)
self.assertFalse(mock_award_program_certificate.called)
@mock.patch('openedx.core.djangoapps.site_configuration.helpers.get_value')
def test_programs_without_certificates(
self,
mock_get_value,
mock_get_completed_programs,
mock_get_certified_programs,
mock_award_program_certificate
):
"""
Checks that the task will be aborted without further action if there exists a list
programs_without_certificates with ["ALL"] value in site configuration.
"""
mock_get_value.return_value = ["ALL"]
mock_get_completed_programs.return_value = {1: 1, 2: 2}
tasks.award_program_certificates.delay(self.student.username).get()
self.assertFalse(mock_get_completed_programs.called)
self.assertFalse(mock_get_certified_programs.called)
self.assertFalse(mock_award_program_certificate.called)
def _make_side_effect(self, side_effects):
"""
DRY helper. Returns a side effect function for use with mocks that