[MICROBA-676] Changes to the notify_credentials task to filter on username

This commit is contained in:
Albert (AJ) St. Aubin
2020-10-29 10:51:34 -04:00
parent 7d40793967
commit 72aa58406b
4 changed files with 65 additions and 10 deletions

View File

@@ -155,7 +155,7 @@ def get_certificates_for_user_by_course_keys(user, course_keys):
}
def get_recently_modified_certificates(course_keys=None, start_date=None, end_date=None):
def get_recently_modified_certificates(course_keys=None, start_date=None, end_date=None, username=None):
"""
Returns a QuerySet of GeneratedCertificate objects filtered by the input
parameters and ordered by modified_date.
@@ -171,6 +171,9 @@ def get_recently_modified_certificates(course_keys=None, start_date=None, end_da
if end_date:
cert_filter_args['modified_date__lte'] = end_date
if username:
cert_filter_args['user__username'] = username
return GeneratedCertificate.objects.filter(**cert_filter_args).order_by('modified_date')

View File

@@ -35,7 +35,7 @@ def clear_prefetched_course_and_subsection_grades(course_key):
_PersistentCourseGrade.clear_prefetched_data(course_key)
def get_recently_modified_grades(course_keys, start_date, end_date):
def get_recently_modified_grades(course_keys, start_date, end_date, user=None):
"""
Returns a QuerySet of PersistentCourseGrade objects filtered by the input
parameters and ordered by modified date.
@@ -47,6 +47,8 @@ def get_recently_modified_grades(course_keys, start_date, end_date):
grade_filter_args['modified__gte'] = start_date
if end_date:
grade_filter_args['modified__lte'] = end_date
if user:
grade_filter_args['user_id'] = user.id
return _PersistentCourseGrade.objects.filter(**grade_filter_args).order_by('modified')

View File

@@ -19,7 +19,7 @@ import time
from datetime import datetime, timedelta
import dateutil.parser
from django.contrib.auth.models import User
from django.contrib.auth import get_user_model
from django.core.management.base import BaseCommand, CommandError
from opaque_keys import InvalidKeyError
from opaque_keys.edx.keys import CourseKey
@@ -34,6 +34,7 @@ from openedx.core.djangoapps.credentials.signals import handle_cert_change, send
from openedx.core.djangoapps.programs.signals import handle_course_cert_changed, handle_course_cert_awarded
from openedx.core.djangoapps.site_configuration.models import SiteConfiguration
User = get_user_model()
log = logging.getLogger(__name__)
@@ -160,6 +161,11 @@ class Command(BaseCommand):
action='store_true',
help='Send program award notifications with course notification tasks',
)
parser.add_argument(
'--username',
default=None,
help='Run the command for a single user',
)
def get_args_from_database(self):
""" Returns an options dictionary from the current NotifyCredentialsConfig model. """
@@ -183,7 +189,7 @@ class Command(BaseCommand):
log.info(
u"notify_credentials starting, dry-run=%s, site=%s, delay=%d seconds, page_size=%d, "
u"from=%s, to=%s, notify_programs=%s, execution=%s",
u"from=%s, to=%s, notify_programs=%s, username=%s, execution=%s",
options['dry_run'],
options['site'],
options['delay'],
@@ -191,6 +197,7 @@ class Command(BaseCommand):
options['start_date'] if options['start_date'] else 'NA',
options['end_date'] if options['end_date'] else 'NA',
options['notify_programs'],
options['username'],
'auto' if options['auto'] else 'manual',
)
@@ -200,11 +207,19 @@ class Command(BaseCommand):
log.error(u'No site configuration found for site %s', options['site'])
course_keys = self.get_course_keys(options['courses'])
if not (course_keys or options['start_date'] or options['end_date']):
raise CommandError('You must specify a filter (e.g. --courses= or --start-date)')
if not (course_keys or options['start_date'] or options['end_date'] or options['username']):
raise CommandError('You must specify a filter (e.g. --courses= or --start-date or --username)')
certs = get_recently_modified_certificates(course_keys, options['start_date'], options['end_date'])
grades = get_recently_modified_grades(course_keys, options['start_date'], options['end_date'])
certs = get_recently_modified_certificates(
course_keys, options['start_date'], options['end_date'], options['username']
)
user = None
if options['username']:
user = User.objects.get(username=options['username'])
grades = get_recently_modified_grades(
course_keys, options['start_date'], options['end_date'], user
)
log.info('notify_credentials Sending notifications for {certs} certificates and {grades} grades'.format(
certs=certs.count(),

View File

@@ -33,6 +33,7 @@ class TestNotifyCredentials(TestCase):
def setUp(self):
super(TestNotifyCredentials, self).setUp()
self.user = UserFactory.create()
self.user2 = UserFactory.create()
with freeze_time(datetime(2017, 1, 1)):
self.cert1 = GeneratedCertificateFactory(user=self.user, course_id='course-v1:edX+Test+1')
@@ -42,7 +43,7 @@ class TestNotifyCredentials(TestCase):
self.cert3 = GeneratedCertificateFactory(user=self.user, course_id='course-v1:testX+Test+3')
with freeze_time(datetime(2017, 2, 1, 5)):
self.cert4 = GeneratedCertificateFactory(
user=self.user, course_id='course-v1:edX+Test+4', status=CertificateStatuses.downloadable
user=self.user2, course_id='course-v1:edX+Test+4', status=CertificateStatuses.downloadable
)
print(('self.cert1.modified_date', self.cert1.modified_date))
@@ -57,7 +58,7 @@ class TestNotifyCredentials(TestCase):
self.grade3 = PersistentCourseGrade.objects.create(user_id=self.user.id, course_id='course-v1:testX+Test+3',
percent_grade=1)
with freeze_time(datetime(2017, 2, 1, 5)):
self.grade4 = PersistentCourseGrade.objects.create(user_id=self.user.id, course_id='course-v1:edX+Test+4',
self.grade4 = PersistentCourseGrade.objects.create(user_id=self.user2.id, course_id='course-v1:edX+Test+4',
percent_grade=1)
print(('self.grade1.modified', self.grade1.modified))
@@ -122,6 +123,40 @@ class TestNotifyCredentials(TestCase):
self.assertListEqual(list(mock_send.call_args[0][0]), [self.cert2])
self.assertListEqual(list(mock_send.call_args[0][1]), [self.grade2])
@mock.patch(COMMAND_MODULE + '.Command.send_notifications')
def test_username_arg(self, mock_send):
call_command(
Command(), '--start-date', '2017-02-01', '--end-date', '2017-02-02', '--username', self.user2.username
)
self.assertTrue(mock_send.called)
self.assertListEqual(list(mock_send.call_args[0][0]), [self.cert4])
self.assertListEqual(list(mock_send.call_args[0][1]), [self.grade4])
mock_send.reset_mock()
call_command(
Command(), '--username', self.user2.username
)
self.assertTrue(mock_send.called)
self.assertListEqual(list(mock_send.call_args[0][0]), [self.cert4])
self.assertListEqual(list(mock_send.call_args[0][1]), [self.grade4])
mock_send.reset_mock()
call_command(
Command(), '--start-date', '2017-02-01', '--end-date', '2017-02-02', '--username', self.user.username
)
self.assertTrue(mock_send.called)
self.assertListEqual(list(mock_send.call_args[0][0]), [self.cert2])
self.assertListEqual(list(mock_send.call_args[0][1]), [self.grade2])
mock_send.reset_mock()
call_command(
Command(), '--username', self.user2.username
)
self.assertTrue(mock_send.called)
self.assertListEqual(list(mock_send.call_args[0][0]), [self.cert4])
self.assertListEqual(list(mock_send.call_args[0][1]), [self.grade4])
mock_send.reset_mock()
@mock.patch(COMMAND_MODULE + '.Command.send_notifications')
def test_no_args(self, mock_send):
with self.assertRaisesRegex(CommandError, 'You must specify a filter.*'):