def setup(self, db, settings): # Set up data that's the same for standalone or multisite self.date_for = utc_yesterday() self.site = Site.objects.first() self.courses = [CourseOverviewFactory(), CourseOverviewFactory()] # Two for "our" course, one for another course in the same site self.enrollments = [ CourseEnrollmentFactory(course_id=self.courses[0].id), CourseEnrollmentFactory(course_id=self.courses[0].id), CourseEnrollmentFactory(course_id=self.courses[1].id), ] self.ce0_sm = StudentModuleFactory.from_course_enrollment( self.enrollments[0], created=as_datetime(self.date_for), modified=as_datetime(self.date_for)) # Handle site mode specifices if organizations_support_sites(): settings.FEATURES['FIGURES_IS_MULTISITE'] = True self.org = OrganizationFactory(sites=[self.site]) for course in self.courses: OrganizationCourseFactory(organization=self.org, course_id=str(course.id)) map_users_to_org(self.org, [ce.user for ce in self.enrollments]) # For our tests, we focus on a single enrollment. We should not # need to stand up other site data, but if we find we do need to, # then here's the place to do it else: self.org = OrganizationFactory()
def test_get_course_enrollments_for_site_exclude_same_user_different_site( self): """ Test that CEs are not returned from course from another Site, in cases where a user has CEs in desired Site, but also in another Site. """ course_overviews = [CourseOverviewFactory() for i in range(2)] OrganizationCourseFactory(organization=self.organization, course_id=str(course_overviews[0].id)) OrganizationCourseFactory(organization=self.default_site_org, course_id=str(course_overviews[1].id)) uom_our_site = UserOrganizationMappingFactory( organization=self.organization) # enroll same user in a course associated w/ an Organization not connected to our Site uom_other_site = UserOrganizationMappingFactory( user=uom_our_site.user, organization=self.default_site_org) CourseEnrollmentFactory(course_id=course_overviews[1].id, user=uom_our_site.user) expected_ce = [ CourseEnrollmentFactory(course_id=course_overviews[0].id, user=uom_our_site.user) ] course_enrollments = figures.sites.get_course_enrollments_for_site( self.site) assert set([ce.id for ce in course_enrollments ]) == set([ce.id for ce in expected_ce])
def setup(self, db, settings): super(TestLearnerDetailsViewSetMultisite, self).setup(db) # TODO:REFACTOR:Make base 'multisite scaffolding' view test class to # set up the sites, orgs, and users. Put into tests/views/base.py settings.FEATURES['FIGURES_IS_MULTISITE'] = True is_multisite = figures.helpers.is_multisite() assert is_multisite self.my_site_org = OrganizationFactory(sites=[self.site]) self.other_site = SiteFactory(domain='other-site.test') self.other_site_org = OrganizationFactory(sites=[self.other_site]) self.my_course_overviews = [ CourseOverviewFactory() for i in range(0, 4) ] for co in self.my_course_overviews: OrganizationCourseFactory(organization=self.my_site_org, course_id=str(co.id)) # Set up users and enrollments for 'my site' self.my_site_users = [UserFactory() for i in range(3)] for user in self.my_site_users: UserOrganizationMappingFactory(user=user, organization=self.my_site_org) # Create a mix of enrollments: # one learner in one course, same for the other, then two learners in # the same course, and keep one course w/out learners self.my_enrollments = [ CourseEnrollmentFactory(course=self.my_course_overviews[0], user=self.my_site_users[0]), CourseEnrollmentFactory(course=self.my_course_overviews[1], user=self.my_site_users[1]), CourseEnrollmentFactory(course=self.my_course_overviews[2], user=self.my_site_users[0]), CourseEnrollmentFactory(course=self.my_course_overviews[2], user=self.my_site_users[1]), ] self.caller = UserFactory() UserOrganizationMappingFactory(user=self.caller, organization=self.my_site_org, is_amc_admin=True) self.my_site_users.append(self.caller) # Set up other site's data self.other_site_enrollment = CourseEnrollmentFactory() OrganizationCourseFactory( organization=self.other_site_org, course_id=self.other_site_enrollment.course.id) UserOrganizationMappingFactory(user=self.other_site_enrollment.user, organization=self.other_site_org) self.expected_result_keys = [ 'id', 'username', 'name', 'email', 'country', 'is_active', 'year_of_birth', 'level_of_education', 'gender', 'date_joined', 'bio', 'courses', 'language_proficiencies', 'profile_image' ]
def setup(self, db): self.today = datetime.date(2018, 6, 1) self.course_overview = CourseOverviewFactory() if OPENEDX_RELEASE == GINKGO: self.course_enrollments = [ CourseEnrollmentFactory(course_id=self.course_overview.id) for i in range(4) ] else: self.course_enrollments = [ CourseEnrollmentFactory(course=self.course_overview) for i in range(4) ] if organizations_support_sites(): self.my_site = SiteFactory(domain='my-site.test') self.my_site_org = OrganizationFactory(sites=[self.my_site]) OrganizationCourseFactory(organization=self.my_site_org, course_id=str(self.course_overview.id)) for ce in self.course_enrollments: UserOrganizationMappingFactory(user=ce.user, organization=self.my_site_org) self.course_access_roles = [ CourseAccessRoleFactory( user=self.course_enrollments[i].user, course_id=self.course_enrollments[i].course_id, role=role, ) for i, role in enumerate(self.COURSE_ROLES) ] # create student modules for yesterday and today for day in [prev_day(self.today), self.today]: self.student_modules = [ StudentModuleFactory(course_id=ce.course_id, student=ce.user, created=ce.created, modified=as_datetime(day)) for ce in self.course_enrollments ] self.cert_days_to_complete = [10, 20, 30] self.expected_avg_cert_days_to_complete = 20 self.generated_certificates = [ GeneratedCertificateFactory( user=self.course_enrollments[i].user, course_id=self.course_enrollments[i].course_id, created_date=(self.course_enrollments[i].created + datetime.timedelta(days=days)), ) for i, days in enumerate(self.cert_days_to_complete) ]
def enrollment_data(db): """Test data for course id filtering """ course_overviews = [CourseOverviewFactory() for i in range(2)] expected_enrollments = [] for co in course_overviews: expected_enrollments += [ CourseEnrollmentFactory(course_id=co.id) for i in range(2) ] # Create enrollment we don't want other_enrollment = CourseEnrollmentFactory() return dict(course_overviews=course_overviews, expected_enrollments=expected_enrollments, other_enrollment=other_enrollment)
def test_no_update_has_lcgm_no_sm(self, monkeypatch): """We have an LCGM but not an SM record The function under test should return the existing LCGM """ monkeypatch.setattr( 'figures.pipeline.enrollment_metrics.get_site_for_course', lambda val: self.site) monkeypatch.setattr( 'figures.pipeline.enrollment_metrics._collect_progress_data', lambda val: self.progress_data) # Create a course enrollment for which we won't have student module records ce = CourseEnrollmentFactory( course_id=self.course_enrollment.course_id) if organizations_support_sites(): UserOrganizationMappingFactory(organization=self.org, user=ce.user) lcgm = LearnerCourseGradeMetricsFactory(course_id=ce.course_id, user=ce.user) ce_sm = StudentModule.objects.filter(course_id=ce.course_id, student_id=ce.user.id) assert not ce_sm metrics = collect_metrics_for_enrollment(site=self.site, course_enrollment=ce, date_for=self.today, student_modules=ce_sm) assert not metrics
def setup(self, db): self.today = datetime.date(2018, 6, 1) self.course_overviews = [CourseOverviewFactory() for i in range(1, 3)] self.course_enrollments = [] for co in self.course_overviews: self.course_enrollments.extend( [CourseEnrollmentFactory(course_id=co.id) for i in range(1, 3)])
def test_get_course_enrollments_for_site(self): expected_ce = [CourseEnrollmentFactory() for i in range(3)] with mock.patch('figures.helpers.settings.FEATURES', self.features): course_enrollments = figures.sites.get_course_enrollments_for_site( self.site) assert set([ce.id for ce in course_enrollments ]) == set([ce.id for ce in expected_ce])
def setUp(self): self.User = get_user_model() self.users = [make_user(**data) for data in USER_DATA] self.course_overview = CourseOverviewFactory() self.course_enrollments = [ CourseEnrollmentFactory(course_id=self.course_overview.id, user=self.users[i]) for i in range(2)]
def test_bulk_calculate_course_progress_unlinked_course_error(db, monkeypatch): """Tests 'bulk_calculate_course_progress_data' function The function under test iterates over a set of course enrollment records, So we create a couple of records to iterate over and mock the collect function """ course_overview = CourseOverviewFactory() course_enrollments = [ CourseEnrollmentFactory(course_id=course_overview.id) for i in range(2) ] mapping = { ce.course_id: LearnerCourseGradeMetricsFactory(course_id=str(ce.course_id), user=ce.user, sections_worked=1, sections_possible=2) for ce in course_enrollments } def mock_metrics(course_enrollment, **_kwargs): return mapping[course_enrollment.course_id] monkeypatch.setattr( 'figures.pipeline.enrollment_metrics.collect_metrics_for_enrollment', mock_metrics) with pytest.raises(UnlinkedCourseError) as e_info: data = bulk_calculate_course_progress_data(course_overview.id)
def test_bulk_calculate_course_progress_data_happy_path(db, monkeypatch): """Tests 'bulk_calculate_course_progress_data' function The function under test iterates over a set of course enrollment records, So we create a couple of records to iterate over and mock the collect function """ course_overview = CourseOverviewFactory() course_enrollments = [ CourseEnrollmentFactory(course_id=course_overview.id) for i in range(2) ] mapping = { ce.course_id: LearnerCourseGradeMetricsFactory(course_id=str(ce.course_id), user=ce.user, sections_worked=1, sections_possible=2) for ce in course_enrollments } def mock_metrics(course_enrollment, **_kwargs): return mapping[course_enrollment.course_id] monkeypatch.setattr( 'figures.pipeline.enrollment_metrics.get_site_for_course', lambda val: SiteFactory()) monkeypatch.setattr( 'figures.pipeline.enrollment_metrics.collect_metrics_for_enrollment', mock_metrics) data = bulk_calculate_course_progress_data(course_overview.id) assert data['average_progress'] == 0.5
def setup(self, db): self.course_enrollment = CourseEnrollmentFactory() if OPENEDX_RELEASE == GINKGO: self.course_id = self.course_enrollment.course_id else: self.course_id = self.course_enrollment.course.id self.lcg = LearnerCourseGrades(self.course_enrollment.user.id, self.course_id) # set up our sections # This is a quick job. We can do it cleaner # We do want to label each subsection grade # to make it easier to identify them in the # tests self.msg1 = MockSubsectionGrade(tw_earned=0.0, tw_possible=0.0), self.msg2 = MockSubsectionGrade(tw_earned=0.0, tw_possible=0.5) self.msg3 = MockSubsectionGrade(tw_earned=0.5, tw_possible=1.0) self.graded_sections = [self.msg2, self.msg3] self.all_sections = [self.msg1, self.msg2, self.msg3] self.lcg.course_grade.chapter_grades = OrderedDict( alpha=dict( sections=[self.msg1], url_name=u'ec7e84694fca2d073731a462a5916a7a', display_name=u'Module 1 - Overview', ), bravo=dict( sections=[self.msg2, self.msg3], url_name=u'2f43c0b7da59ed40156155f9a8ca4d40', display_name=u'Module 2 - First Principles', ))
def course_test_data(): """Temporary fixture. Will remove as we abstract testing """ months_back = 6 site = SiteFactory() course_overview = CourseOverviewFactory() if organizations_support_sites(): org = OrganizationFactory(sites=[site]) else: org = OrganizationFactory() OrganizationCourseFactory(organization=org, course_id=str(course_overview.id)) enrollments = [ CourseEnrollmentFactory(course_id=course_overview.id) for i in range(3) ] users = [enrollment.user for enrollment in enrollments] student_modules = [] dates = generate_date_series(months_back=months_back) assert dates data_spec = list(zip(dates, list(range(months_back)))) return dict( site=site, org=org, users=users, course_overview=course_overview, enrollments=enrollments, student_modules=student_modules, months_back=months_back, dates=dates, data_spec=data_spec, )
def test_course_has_enrollments_but_no_active_for_yesterday(self, monkeypatch): """We have enrollments, but none were active yesterday """ monkeypatch.setattr('figures.course.get_site_for_course', lambda val: self.site) [CourseEnrollmentFactory(course_id=self.course_overview.id) for _ in range(2)] result = update_enrollment_data_for_course(self.course_overview.id) assert result == []
def setup(self, db): super(TestCourseEnrollmentViewSet, self).setup(db) self.special_fields = ('create', 'user',) self.course_enrollments = [ CourseEnrollmentFactory() for i in range(1,5) ] self.sample_course_id = self.course_enrollments[0].course_id
def setup(self, db): self.model = CourseEnrollment # self.special_fields = set(['course', 'created', 'user', 'course_overview' ]) self.special_fields = set(['created', 'user', 'course_id']) self.expected_results_keys = set( ['id', 'user', 'created', 'is_active', 'mode', 'course_id']) field_names = (o.name for o in self.model._meta.fields if o.name not in self.date_fields) self.model_obj = CourseEnrollmentFactory() self.serializer = CourseEnrollmentSerializer(instance=self.model_obj)
def test_get_course_enrollments_for_site(self, ce_count): course_overview = CourseOverviewFactory() OrganizationCourseFactory(organization=self.organization, course_id=str(course_overview.id)) expected_ce = [CourseEnrollmentFactory( course_id=course_overview.id) for i in range(ce_count)] course_enrollments = figures.sites.get_course_enrollments_for_site(self.site) assert set([ce.id for ce in course_enrollments]) == set( [ce.id for ce in expected_ce])
def make_course_enrollments(user, courses, **kwargs): ''' creates course enrollments for every course in COURSE_DATA for the given user ''' course_enrollments = [] for course in courses: course_enrollments.append( CourseEnrollmentFactory( course_id=course.id, user=user, ))
def setup(self, db): self.site = Site.objects.first() self.certificate_date = datetime.datetime(2018, 4, 1, tzinfo=utc) self.course_enrollment = CourseEnrollmentFactory() self.generated_certificate = GeneratedCertificateFactory( user=self.course_enrollment.user, course_id=self.course_enrollment.course_id, created_date=self.certificate_date, ) self.serializer = LearnerCourseDetailsSerializer( instance=self.course_enrollment)
def setup(self, db): self.today = date.today() self.site = SiteFactory() if organizations_support_sites(): self.org = OrganizationFactory(sites=[self.site]) else: self.org = OrganizationFactory() self.datetime_1 = datetime(2020, 2, 2, tzinfo=utc) self.datetime_2 = self.datetime_1 + relativedelta( months=1) # future of date_1 self.course_overview = CourseOverviewFactory() self.course_enrollment = CourseEnrollmentFactory( course_id=self.course_overview.id) self.course_enrollment_2 = CourseEnrollmentFactory( course_id=self.course_overview.id) if organizations_support_sites(): OrganizationCourseFactory(organization=self.org, course_id=str(self.course_overview.id)) UserOrganizationMappingFactory(organization=self.org, user=self.course_enrollment.user) UserOrganizationMappingFactory(organization=self.org, user=self.course_enrollment_2.user) self.student_modules = [ StudentModuleFactory(student=self.course_enrollment.user, course_id=self.course_enrollment.course_id, modified=self.datetime_1), StudentModuleFactory(student=self.course_enrollment.user, course_id=self.course_enrollment.course_id, modified=self.datetime_2), # This student module does not belong to the user in course_enrollment StudentModuleFactory(course_id=self.course_enrollment.course_id, modified=self.datetime_2) ] self.learner_sm = StudentModule.objects.filter( course_id=self.course_enrollment.course_id, student=self.course_enrollment.user).order_by('-modified') self.progress_data = dict(points_possible=100, points_earned=25, sections_worked=4, count=5)
def setup(self, db, settings): super(TestLearnerDetailsViewSetStandalone, self).setup(db) self.course_overviews = [CourseOverviewFactory() for i in range(0, 4)] self.users = [UserFactory() for i in range(3)] self.enrollments = [ CourseEnrollmentFactory(course=self.course_overviews[0], user=self.users[0]), CourseEnrollmentFactory(course=self.course_overviews[1], user=self.users[1]), CourseEnrollmentFactory(course=self.course_overviews[2], user=self.users[0]), CourseEnrollmentFactory(course=self.course_overviews[2], user=self.users[1]), ] self.expected_result_keys = [ 'id', 'username', 'name', 'email', 'country', 'is_active', 'year_of_birth', 'level_of_education', 'gender', 'date_joined', 'bio', 'courses', 'language_proficiencies', 'profile_image' ]
def setup(self, db): self.course_enrollments = [CourseEnrollmentFactory() for i in range(1, 5)] if organizations_support_sites(): self.my_site = SiteFactory(domain='my-site.test') self.my_site_org = OrganizationFactory(sites=[self.my_site]) for ce in self.course_enrollments: OrganizationCourseFactory(organization=self.my_site_org, course_id=str(ce.course.id)) UserOrganizationMappingFactory(user=ce.user, organization=self.my_site_org) self.student_module = StudentModuleFactory()
def test_get_progress_data_with_no_data(self): """Tests that the serializer method succeeds when no learner course grade metrics records """ expected_data = { 'course_progress_history': [], 'course_progress_details': None, 'course_progress': 0.0, 'course_completed': False } assert not LearnerCourseGradeMetrics.objects.count() course_enrollment = CourseEnrollmentFactory() data = self.serializer.get_progress_data(course_enrollment) assert data == expected_data
def test_enrollments_active_on_date(self): our_date_for = fake.date_this_year() other_date_for = days_from(our_date_for, -1) our_ce = [ CourseEnrollmentFactory(course_id=self.course_overview.id) for _ in range(2) ] our_sm = [] for ce in our_ce: our_sm.extend([ StudentModuleFactory.from_course_enrollment( ce, modified=our_date_for), StudentModuleFactory.from_course_enrollment( ce, created=our_date_for) ]) # Create enrollment we should not get in our results other_ce = CourseEnrollmentFactory(course_id=self.course_overview.id) StudentModuleFactory.from_course_enrollment(other_ce, created=other_date_for, modified=other_date_for) course = Course(self.course_overview.id) found_ce = course.enrollments_active_on_date(our_date_for) assert set(found_ce) == set(our_ce)
def setup(self, db): self.site = Site.objects.first() self.date_for = datetime.date(2018, 2, 2) self.course_enrollment = CourseEnrollmentFactory() self.grade_data = dict(points_possible=10.0, points_earned=5.0, sections_worked=2, sections_possible=2) self.create_rec = self.grade_data.copy() self.create_rec.update( dict(site=self.site, date_for=self.date_for, user=self.course_enrollment.user, course_id=self.course_enrollment.course_id))
def test_student_modules_for_course_enrollment(monkeypatch): """Test we get the correct student modules for the given course enrollment """ site = SiteFactory() ce = CourseEnrollmentFactory() ce_sm = [StudentModuleFactory(student=ce.user, course_id=ce.course_id)] # Create another student module record to make sure this is not in our # query results StudentModuleFactory() if organizations_support_sites(): monkeypatch.setattr('figures.sites.is_multisite', lambda: True) our_org = OrganizationFactory(sites=[site]) other_org = OrganizationFactory(sites=[SiteFactory()]) other_org_ce = CourseEnrollmentFactory() other_sm = StudentModuleFactory(student=other_org_ce.user, course_id=other_org_ce.course_id) UserOrganizationMappingFactory(user=ce.user, organization=our_org) UserOrganizationMappingFactory(user=other_org_ce.user, organization=other_org) sm = figures.sites.student_modules_for_course_enrollment(site, ce) assert set(sm) == set(ce_sm)
def setup(self, db): self.site = SiteFactory() self.date_1 = datetime(2020, 2, 2, tzinfo=utc) self.date_2 = self.date_1 + relativedelta(months=1) # future of date_1 self.course_enrollment = CourseEnrollmentFactory() self.student_modules = [ StudentModuleFactory(student=self.course_enrollment.user, course_id=self.course_enrollment.course_id, modified=self.date_1), StudentModuleFactory(student=self.course_enrollment.user, course_id=self.course_enrollment.course_id, modified=self.date_2) ] self.progress_data = dict(points_possible=100, points_earned=25, sections_worked=4, count=5)
def setup(self, db): # self.model = CourseEnrollment # self.user_attributes = { # 'username': '******', # 'profile__name': 'Alpha One', # 'profile__country': 'CA', # } #self.user = UserFactory(**self.user_attributes) self.certificate_date = datetime.datetime(2018, 4, 1, tzinfo=utc) self.course_enrollment = CourseEnrollmentFactory() self.generated_certificate = GeneratedCertificateFactory( user=self.course_enrollment.user, course_id=self.course_enrollment.course_id, created_date=self.certificate_date, ) self.serializer = LearnerCourseDetailsSerializer( instance=self.course_enrollment)
def test_course_has_active_enrollments_for_yesterday(self): """We have enrollments who were active yesterday """ expected_ce = [CourseEnrollmentFactory(course_id=self.course_overview.id) for _ in range(2)] ce = CourseEnrollment.objects.filter(course_id=self.course_overview.id) def mock_update_metrics(site, ce): return ce with patch('figures.pipeline.enrollment_metrics_next.Course') as course_class: with patch('figures.pipeline.enrollment_metrics_next.EnrollmentData.objects') as edm: course_class.return_value.enrollments_active_on_date.return_value = ce course_class.return_value.site = self.site edm.update_metrics = mock_update_metrics result = update_enrollment_data_for_course(self.course_overview.id) assert set(result) == set(expected_ce)
def setup(self, db): super(TestCourseEnrollmentViewSet, self).setup(db) self.special_fields = ( 'create', 'user', ) self.course_overview = CourseOverviewFactory() self.course_enrollments = [ CourseEnrollmentFactory(course_id=self.course_overview.id) for i in range(1, 5) ] self.sample_course_id = self.course_enrollments[0].course_id if is_multisite(): self.organization = OrganizationFactory(sites=[self.site]) OrganizationCourseFactory(organization=self.organization, course_id=str(self.course_overview.id))