def test_get_badge_class_course_disabled(self): """ Verify attempting to fetch a badge class for a course which does not issue badges raises an exception. """ course_key = CourseFactory.create(metadata={'issue_badges': False}).location.course_key with self.assertRaises(CourseBadgesDisabledError): BadgeClass.get_badge_class( slug='test_slug', issuing_component='test_component', description='Attempted override', criteria='test', display_name='Testola', image_file_handle=get_image('good'), course_id=course_key, )
def test_get_badge_class_nocreate(self): """ Test returns None if the badge class does not exist. """ badge_class = BadgeClass.get_badge_class( slug='new_slug', issuing_component='new_component', create=False ) self.assertIsNone(badge_class) # Run this twice to verify there wasn't a background creation of the badge. badge_class = BadgeClass.get_badge_class( slug='new_slug', issuing_component='new_component', description=None, criteria=None, display_name=None, image_file_handle=None, create=False ) self.assertIsNone(badge_class)
def course_group_check(user, course_key): """ Awards a badge if a user has completed every course in a defined set. """ from lms.djangoapps.certificates.models import CertificateStatuses config = CourseEventBadgesConfiguration.current().course_group_settings awards = [] for slug, keys in config.items(): if course_key in keys: certs = user.generatedcertificate_set.filter( status__in=CertificateStatuses.PASSED_STATUSES, course_id__in=keys, ) if len(certs) == len(keys): # course_complete Assertions are not working correctly # yet with Badgr.io, while course group is working. # so we use course groups with a single course, # in which case we can provide an evidence URL # to the HTML cert for the one coursee if len(keys) == 1: evidence = evidence_url(user.id, course_key) awards.append((slug, evidence)) else: awards.append((slug,)) for award in awards: badge_class = BadgeClass.get_badge_class( slug=slug, create=False, ) if badge_class and not badge_class.get_for_user(user): try: badge_class.award(user, evidence_url=award[1]) except IndexError: badge_class.award(user)
def get_completion_badge(course_id, user): """ Given a course key and a user, find the user's enrollment mode and get the Course Completion badge. """ from student.models import CourseEnrollment badge_classes = CourseEnrollment.objects.filter( user=user, course_id=course_id ).order_by('-is_active') if not badge_classes: return None mode = badge_classes[0].mode course = modulestore().get_course(course_id) if not course.issue_badges: return None return BadgeClass.get_badge_class( slug=course_slug(course_id, mode), issuing_component='', criteria=criteria(course_id), description=badge_description(course, mode), course_id=course_id, mode=mode, display_name=course.display_name, image_file_handle=CourseCompleteImageConfiguration.image_for_mode(mode) )
def get_completion_badge(course_id, user, preview_mode=None): """ Given a course key and a user, find the user's enrollment mode and get the Course Completion badge. """ from student.models import CourseEnrollment if user.is_staff: mode = 'honor' if preview_mode: mode = preview_mode else: badge_classes = CourseEnrollment.objects.filter( user=user, course_id=course_id).order_by('-is_active') if not badge_classes: return None mode = badge_classes[0].mode course = modulestore().get_course(course_id) if not course.issue_badges: return None return BadgeClass.get_badge_class( slug=course_slug(course_id, mode), issuing_component='', criteria=criteria(course_id), description=badge_description(course, mode), course_id=course_id, mode=mode, display_name=course.display_name, image_file_handle=CourseCompleteImageConfiguration.image_for_mode( mode))
def test_unique_for_course(self): """ Verify that the course_id is used in fetching existing badges or creating new ones. """ course_key = CourseFactory.create().location.course_key premade_badge_class = BadgeClassFactory.create(course_id=course_key) badge_class = BadgeClass.get_badge_class( slug='test_slug', issuing_component='test_component', description='Attempted override', criteria='test', display_name='Testola', image_file_handle=get_image('good') ) course_badge_class = BadgeClass.get_badge_class( slug='test_slug', issuing_component='test_component', description='Attempted override', criteria='test', display_name='Testola', image_file_handle=get_image('good'), course_id=course_key, ) self.assertNotEqual(badge_class.id, course_badge_class.id) self.assertEqual(course_badge_class.id, premade_badge_class.id)
def test_runs_validator(self): """ Verify that the image validator is triggered when cleaning the model. """ self.assertRaises( ValidationError, BadgeClass( slug='test', issuing_component='test2', criteria='test3', description='test4', image=get_image('unbalanced') ).full_clean )
def test_get_badge_class_preexisting(self): """ Verify fetching a badge first grabs existing badges. """ premade_badge_class = BadgeClassFactory.create() # Ignore additional parameters. This class already exists. badge_class = BadgeClass.get_badge_class( slug='test_slug', issuing_component='test_component', description='Attempted override', criteria='test', display_name='Testola', image_file_handle=get_image('good') ) # These defaults are set on the factory. self.assertEqual(badge_class.criteria, 'https://example.com/syllabus') self.assertEqual(badge_class.display_name, 'Test Badge') self.assertEqual(badge_class.description, "Yay! It's a test badge.") # File name won't always be the same. self.assertEqual(badge_class.image.path, premade_badge_class.image.path)
def test_get_badge_class_create(self): """ Verify fetching a badge creates it if it doesn't yet exist. """ badge_class = BadgeClass.get_badge_class( slug='new_slug', issuing_component='new_component', description='This is a test', criteria='https://example.com/test_criteria', display_name='Super Badge', image_file_handle=get_image('good') ) # This should have been saved before being passed back. self.assertTrue(badge_class.id) self.assertEqual(badge_class.slug, 'new_slug') self.assertEqual(badge_class.issuing_component, 'new_component') self.assertEqual(badge_class.description, 'This is a test') self.assertEqual(badge_class.criteria, 'https://example.com/test_criteria') self.assertEqual(badge_class.display_name, 'Super Badge') self.assertTrue('good' in badge_class.image.name.rsplit('/', 1)[-1])
def test_unique_by_course_id_plus_mode(self): """ Verify that validation error is triggered when creating a BadgeClass w/ same course_id and mode as existing. """ course_key = CourseFactory.create().location.course_key badge_class = BadgeClassFactory.create(course_id=course_key, mode='honor') self.assertRaises( ValidationError, BadgeClass( course_id=course_key, mode='honor', slug='test', issuing_component='test2', criteria='test3', description='test4', image=get_image('unbalanced'), ).full_clean)
def award_badge(config, count, user): """ Given one of the configurations for enrollments or completions, award the appropriate badge if one is configured. config is a dictionary with integer keys and course keys as values. count is the key to retrieve from this dictionary. user is the user to award the badge to. Example config: {3: 'slug_for_badge_for_three_enrollments', 5: 'slug_for_badge_with_five_enrollments'} """ slug = config.get(count) if not slug: return badge_class = BadgeClass.get_badge_class( slug=slug, create=False, ) if not badge_class: return if not badge_class.get_for_user(user): badge_class.award(user)
def course_group_check(user, course_key): """ Awards a badge if a user has completed every course in a defined set. """ from certificates.models import CertificateStatuses config = CourseEventBadgesConfiguration.current().course_group_settings awards = [] for slug, keys in config.items(): if course_key in keys: certs = user.generatedcertificate_set.filter( status__in=CertificateStatuses.PASSED_STATUSES, course_id__in=keys, ) if len(certs) == len(keys): awards.append(slug) for slug in awards: badge_class = BadgeClass.get_badge_class( slug=slug, issuing_component='openedx__course', create=False, ) if badge_class and not badge_class.get_for_user(user): badge_class.award(user)
def award_badge(config, count, user): """ Given one of the configurations for enrollments or completions, award the appropriate badge if one is configured. config is a dictionary with integer keys and course keys as values. count is the key to retrieve from this dictionary. user is the user to award the badge to. Example config: {3: 'slug_for_badge_for_three_enrollments', 5: 'slug_for_badge_with_five_enrollments'} """ slug = config.get(count) if not slug: return badge_class = BadgeClass.get_badge_class( slug=slug, issuing_component='openedx__course', create=False, ) if not badge_class: return if not badge_class.get_for_user(user): badge_class.award(user)
def course_group_check(user, course_key): """ Awards a badge if a user has completed every course in a defined set. """ from lms.djangoapps.certificates.models import CertificateStatuses config = CourseEventBadgesConfiguration.current().course_group_settings awards = [] for slug, keys in config.items(): if course_key in keys: certs = user.generatedcertificate_set.filter( status__in=CertificateStatuses.PASSED_STATUSES, course_id__in=keys, ) if len(certs) == len(keys): awards.append(slug) for slug in awards: badge_class = BadgeClass.get_badge_class( slug=slug, issuing_component='openedx__course', create=False, ) if badge_class and not badge_class.get_for_user(user): badge_class.award(user)
def test_backend(self): """ Verify the BadgeClass fetches the backend properly. """ self.assertIsInstance(BadgeClass().backend, DummyBackend)