def test_has_passing_certificate_fa(self): """ Assert that has_passing_certificate is true if user has a cert even if has_paid is false for FA programs """ mmtrack = MMTrack( user=self.user, program=self.program_financial_aid, edx_user_data=self.cached_edx_user_data ) key = self.crun_fa.edx_course_key assert mmtrack.has_passing_certificate(key) is False assert mmtrack.has_paid(key) is False cert_json = { "username": "******", "course_id": self.crun_fa.edx_course_key, "certificate_type": "verified", "status": "downloadable", "is_passing": True, "download_url": "http://www.example.com/demo.pdf", "grade": "0.98" } cached_edx_user_data = MagicMock( spec=CachedEdxUserData, enrollments=CachedEnrollment.deserialize_edx_data(self.enrollments_json), certificates=CachedCertificate.deserialize_edx_data(self.certificates_json + [cert_json]), current_grades=CachedCurrentGrade.deserialize_edx_data(self.current_grades_json), ) mmtrack = MMTrack( user=self.user, program=self.program_financial_aid, edx_user_data=cached_edx_user_data ) assert mmtrack.has_passing_certificate(key) is True assert mmtrack.has_paid(key) is False
def test_has_passing_certificate(self, certificate_type, is_passing, expected_result): """ Test for has_passing_certificate method with different type of certificates """ course_key = self.crun_fa.edx_course_key cert_json = { "username": "******", "course_id": course_key, "certificate_type": certificate_type, "is_passing": is_passing, "status": "downloadable", "download_url": "http://www.example.com/demo.pdf", "grade": "0.98" } cached_edx_user_data = MagicMock( spec=CachedEdxUserData, enrollments=CachedEnrollment.deserialize_edx_data(self.enrollments_json), certificates=CachedCertificate.deserialize_edx_data(self.certificates_json + [cert_json]), current_grades=CachedCurrentGrade.deserialize_edx_data(self.current_grades_json), ) mmtrack = MMTrack( user=self.user, program=self.program_financial_aid, edx_user_data=cached_edx_user_data ) assert mmtrack.has_passing_certificate(course_key) is expected_result
def handle(self, *args, **kwargs): # pylint: disable=unused-argument edx_course_key = kwargs.get('edx_course_key') try: run = CourseRun.objects.get(edx_course_key=edx_course_key) except CourseRun.DoesNotExist: raise CommandError('Course Run for course_id "{0}" does not exist'.format(edx_course_key)) con = get_redis_connection("redis") failed_users_count = con.llen(CACHE_KEY_FAILED_USERS_BASE_STR.format(edx_course_key)) if CourseRunGradingStatus.is_complete(run): self.stdout.write( self.style.SUCCESS( 'Final grades for course "{0}" are complete'.format(edx_course_key) ) ) elif CourseRunGradingStatus.is_pending(run): cache_id = CACHE_ID_BASE_STR.format(edx_course_key) group_results_id = cache_redis.get(cache_id) if group_results_id is not None: results = GroupResult.restore(group_results_id, app=app) if not results.ready(): self.stdout.write( self.style.WARNING( 'Final grades for course "{0}" are being processed'.format(edx_course_key) ) ) else: self.stdout.write( self.style.WARNING( 'Async task to freeze grade for course "{0}" ' 'are done, but course is not marked as complete.'.format(edx_course_key) ) ) else: self.stdout.write( self.style.ERROR( 'Final grades for course "{0}" are marked as they are being processed' ', but no task found.'.format(edx_course_key) ) ) else: self.stdout.write( self.style.WARNING( 'Final grades for course "{0}" are not being processed yet'.format(edx_course_key) ) ) message_detail = ', where {0} failed authentication'.format(failed_users_count) if failed_users_count else '' users_in_cache = set(CachedEnrollment.get_cached_users(run)).intersection( set(CachedCurrentGrade.get_cached_users(run)) ) self.stdout.write( self.style.SUCCESS( 'The students with a final grade are {0}/{1}{2}'.format( FinalGrade.objects.filter(course_run=run).count(), len(users_in_cache), message_detail ) ) )
def handle(self, *args, **kwargs): # pylint: disable=unused-argument edx_course_key = kwargs.get('edx_course_key') try: run = CourseRun.objects.get(edx_course_key=edx_course_key) except CourseRun.DoesNotExist: raise CommandError( 'Course Run for course_id "{0}" does not exist'.format( edx_course_key)) con = get_redis_connection("redis") failed_users_count = con.llen( CACHE_KEY_FAILED_USERS_BASE_STR.format(edx_course_key)) if CourseRunGradingStatus.is_complete(run): self.stdout.write( self.style.SUCCESS( 'Final grades for course "{0}" are complete'.format( edx_course_key))) elif CourseRunGradingStatus.is_pending(run): cache_id = CACHE_ID_BASE_STR.format(edx_course_key) group_results_id = cache_redis.get(cache_id) if group_results_id is not None: results = GroupResult.restore(group_results_id, app=app) if not results.ready(): self.stdout.write( self.style.WARNING( 'Final grades for course "{0}" are being processed' .format(edx_course_key))) else: self.stdout.write( self.style.WARNING( 'Async task to freeze grade for course "{0}" ' 'are done, but course is not marked as complete.'. format(edx_course_key))) else: self.stdout.write( self.style.ERROR( 'Final grades for course "{0}" are marked as they are being processed' ', but no task found.'.format(edx_course_key))) else: self.stdout.write( self.style.WARNING( 'Final grades for course "{0}" are not being processed yet' .format(edx_course_key))) message_detail = ', where {0} failed authentication'.format( failed_users_count) if failed_users_count else '' users_in_cache = set( CachedEnrollment.get_cached_users(run)).intersection( set(CachedCurrentGrade.get_cached_users(run))) self.stdout.write( self.style.SUCCESS( 'The students with a final grade are {0}/{1}{2}'.format( FinalGrade.objects.filter(course_run=run).count(), len(users_in_cache), message_detail)))
def setUpTestData(cls): super().setUpTestData() # create an user cls.user = UserFactory.create() cls.cached_edx_user_data = MagicMock( spec=CachedEdxUserData, enrollments=CachedEnrollment.deserialize_edx_data(cls.enrollments_json), certificates=CachedCertificate.deserialize_edx_data(cls.certificates_json), current_grades=CachedCurrentGrade.deserialize_edx_data(cls.current_grades_json), ) # create the programs cls.program = ProgramFactory.create(live=True, financial_aid_availability=False, price=1000) cls.program_financial_aid = ProgramFactory.create(live=True, financial_aid_availability=True, price=1000) # create course runs for the normal program cls.course = CourseFactory.create(program=cls.program) expected_course_keys = [ "course-v1:edX+DemoX+Demo_Course", "course-v1:MITx+8.MechCX+2014_T1", '', None, 'course-v1:odl+FOO102+CR-FALL16' ] cls.cruns = [] for course_key in expected_course_keys: course_run = CourseRunFactory.create( course=cls.course, edx_course_key=course_key ) if course_key: cls.cruns.append(course_run) # and the program with financial aid finaid_course = CourseFactory.create(program=cls.program_financial_aid) cls.now = now_in_utc() cls.end_date = cls.now - timedelta(weeks=45) cls.crun_fa = CourseRunFactory.create( course=finaid_course, start_date=cls.now-timedelta(weeks=52), end_date=cls.end_date, enrollment_start=cls.now-timedelta(weeks=62), enrollment_end=cls.now-timedelta(weeks=53), edx_course_key="course-v1:odl+FOO101+CR-FALL15" ) cls.crun_fa2 = CourseRunFactory.create( course=finaid_course ) CourseRunFactory.create( course=finaid_course, edx_course_key=None )
def get_users_without_frozen_final_grade(course_run): """ Public function to extract all the users that need a final grade freeze for a course run. All the users that are enrolled in a course run and have a current grade must have frozen final grade. Args: course_run (CourseRun): a course run model object Returns: queryset: a queryset of users """ # get the list of users enrolled in the course and have current grade users_in_cache = set(CachedEnrollment.get_cached_users(course_run)).intersection( set(CachedCurrentGrade.get_cached_users(course_run)) ) # get all the users with already frozen final grade users_already_processed = set(FinalGrade.get_frozen_users(course_run)) return User.objects.filter(pk__in=users_in_cache.difference(users_already_processed))