def test_enrolled_student_features_external_user_keys(self):
        query_features = ('username', 'name', 'email', 'city', 'country',
                          'external_user_key')
        username_with_external_user_key_dict = {}
        for i in range(len(self.users)):
            # Setup some users with ProgramEnrollments
            if i % 2 == 0:
                user = self.users[i]
                external_user_key = f'{user.username}_{i}'
                ProgramEnrollmentFactory.create(
                    user=user, external_user_key=external_user_key)
                username_with_external_user_key_dict[
                    user.username] = external_user_key

        with self.assertNumQueries(2):
            userreports = enrolled_students_features(self.course_key,
                                                     query_features)
        assert len(userreports) == 30
        for report in userreports:
            username = report['username']
            external_key = username_with_external_user_key_dict.get(username)
            if external_key:
                assert external_key == report['external_user_key']
            else:
                assert '' == report['external_user_key']
Beispiel #2
0
 def setUp(self):
     super().setUp()
     self.client.login(username=self.user.username, password=self.password)
     self.set_program_in_catalog_cache(self.program_uuid, self.program)
     ProgramEnrollmentFactory.create(
         user=self.user,
         program_uuid=self.program_uuid,
         external_user_key='0001',
     )
Beispiel #3
0
 def create_enrollment_and_history(self, user=None):
     """
     Create ProgramEnrollment and several History entries
     """
     if user:
         enrollment = ProgramEnrollmentFactory(user=user)
     else:
         enrollment = ProgramEnrollmentFactory()
     for status in ['pending', 'suspended', 'withdrawn', 'enrolled']:
         enrollment.status = status
         enrollment.save()
     return enrollment
Beispiel #4
0
    def test_same_user_key_in_multiple_organizations(self):
        uox_program_enrollment = self._create_waiting_program_enrollment()

        second_organization = OrganizationFactory.create()
        SAMLProviderConfigFactory.create(organization=second_organization,
                                         slug='aiu')
        catalog_org = CatalogOrganizationFactory.create(
            key=second_organization.short_name)
        program_uuid = self._create_catalog_program(catalog_org)['uuid']

        # aiu enrollment with the same student key as our uox user
        aiu_program_enrollment = ProgramEnrollmentFactory.create(
            user=None,
            external_user_key=self.external_id,
            program_uuid=program_uuid)

        UserSocialAuth.objects.create(
            user=UserFactory.create(),
            uid='{0}:{1}'.format('not_used', self.external_id),
        )

        UserSocialAuth.objects.create(
            user=self.user,
            uid='{0}:{1}'.format(self.provider_slug, self.external_id),
        )
        self._assert_program_enrollment_user(uox_program_enrollment, self.user)

        aiu_user = UserFactory.create()
        UserSocialAuth.objects.create(
            user=aiu_user,
            uid='{0}:{1}'.format('aiu', self.external_id),
        )
        self._assert_program_enrollment_user(aiu_program_enrollment, aiu_user)
Beispiel #5
0
 def _create_waiting_program_enrollment(self):
     """ helper method to create a waiting program enrollment """
     return ProgramEnrollmentFactory.create(
         user=None,
         external_user_key=self.external_id,
         program_uuid=self.program_uuid,
     )
    def test_enrollment_already_linked_to_target_user(self):
        self._create_waiting_enrollment(self.program, '0001')
        program_enrollment = ProgramEnrollmentFactory.create(
            user=self.user_2,
            program_uuid=self.program,
            external_user_key='0002',
        )
        self._assert_no_program_enrollment(self.user_1,
                                           self.program,
                                           refresh=False)
        self._assert_program_enrollment(self.user_2,
                                        self.program,
                                        '0002',
                                        refresh=False)

        with LogCapture() as logger:
            errors = link_program_enrollments_to_lms_users(
                self.program, {
                    '0001': self.user_1.username,
                    '0002': self.user_2.username
                })
            expected_error_msg = get_existing_user_message(
                program_enrollment, self.user_2)
            logger.check_present((LOG_PATH, 'WARNING', expected_error_msg))

        self.assertDictEqual(
            errors, {('0002', self.user_2.username): expected_error_msg})
        self._assert_program_enrollment(self.user_1, self.program, '0001')
        self._assert_program_enrollment(self.user_2, self.program, '0002')
    def test_enrollment_already_linked_to_different_user(self):
        self._create_waiting_enrollment(self.program, '0001')
        enrollment = ProgramEnrollmentFactory.create(
            program_uuid=self.program,
            external_user_key='0003',
        )
        user_3 = enrollment.user

        self._assert_no_program_enrollment(self.user_1, self.program, refresh=False)
        self._assert_no_program_enrollment(self.user_2, self.program, refresh=False)
        self._assert_program_enrollment(user_3, self.program, '0003', refresh=False)

        with LogCapture() as logger:
            errors = link_program_enrollments(
                self.program,
                {
                    '0001': self.user_1.username,
                    '0003': self.user_2.username,
                }
            )
            expected_error_msg = _user_already_linked_message(enrollment, self.user_2)
            logger.check_present((LOG_PATH, 'WARNING', expected_error_msg))

        self.assertDictEqual(errors, {'0003': expected_error_msg})
        self._assert_program_enrollment(self.user_1, self.program, '0001')
        self._assert_no_program_enrollment(self.user_2, self.program)
        self._assert_program_enrollment(user_3, self.program, '0003')
Beispiel #8
0
    def test_enrollment_already_linked_to_different_user(self):
        self._create_waiting_enrollment(self.program, '0001')
        enrollment = ProgramEnrollmentFactory.create(
            program_uuid=self.program,
            external_user_key='0003',
        )
        user_3 = enrollment.user

        self._assert_no_program_enrollment(self.user_1,
                                           self.program,
                                           refresh=False)
        self._assert_no_program_enrollment(self.user_2,
                                           self.program,
                                           refresh=False)
        self._assert_program_enrollment(user_3,
                                        self.program,
                                        '0003',
                                        refresh=False)

        with LogCapture() as logger:
            self.call_command(self.program, ('0001', self.user_1.username),
                              ('0003', self.user_2.username))
            logger.check_present(
                (COMMAND_PATH, 'WARNING',
                 get_existing_user_message(enrollment, self.user_2)))

        self._assert_program_enrollment(self.user_1, self.program, '0001')
        self._assert_no_program_enrollment(self.user_2, self.program)
        self._assert_program_enrollment(user_3, self.program, '0003')
    def _setup_enrollments(self, external_user_key, linked_user=None):
        """
        Create enrollments for testing linking.
        The enrollments can be create with already linked edX user.
        """
        program_enrollment = ProgramEnrollmentFactory.create(
            external_user_key=external_user_key,
            program_uuid=self.program_uuid,
            user=linked_user
        )
        course_enrollment = None
        if linked_user:
            course_enrollment = CourseEnrollmentFactory.create(
                course_id=self.course.id,
                user=linked_user,
                mode=CourseMode.MASTERS,
                is_active=True
            )
        program_course_enrollment = ProgramCourseEnrollmentFactory.create(
            program_enrollment=program_enrollment,
            course_key=self.course.id,
            course_enrollment=course_enrollment,
            status='active'
        )

        return program_enrollment, program_course_enrollment
    def _construct_enrollments(self, program_uuids, course_ids, external_user_key, edx_user=None):
        """
        A helper function to setup the program enrollments for a given learner.
        If the edx user is provided, it will try to SSO the user with the enrollments
        Return the expected info object that should be created based on the model setup
        """
        program_enrollments = []
        for program_uuid in program_uuids:
            course_enrollment = None
            program_enrollment = ProgramEnrollmentFactory.create(
                external_user_key=external_user_key,
                program_uuid=program_uuid,
                user=edx_user
            )

            for course_id in course_ids:
                if edx_user:
                    course_enrollment = CourseEnrollmentFactory.create(
                        course_id=course_id,
                        user=edx_user,
                        mode=CourseMode.MASTERS,
                        is_active=True
                    )

                program_course_enrollment = ProgramCourseEnrollmentFactory.create(  # lint-amnesty, pylint: disable=unused-variable
                    program_enrollment=program_enrollment,
                    course_key=course_id,
                    course_enrollment=course_enrollment,
                    status='active',
                )

            program_enrollments.append(program_enrollment)

        serialized = ProgramEnrollmentSerializer(program_enrollments, many=True)
        return serialized.data
Beispiel #11
0
    def test_same_user_key_in_multiple_organizations(self):
        uox_program_enrollment = self._create_waiting_program_enrollment()

        second_organization = OrganizationFactory.create()
        SAMLProviderConfigFactory.create(organization=second_organization, slug='aiu')
        catalog_org = CatalogOrganizationFactory.create(key=second_organization.short_name)
        program_uuid = self._create_catalog_program(catalog_org)['uuid']

        # aiu enrollment with the same student key as our uox user
        aiu_program_enrollment = ProgramEnrollmentFactory.create(
            user=None,
            external_user_key=self.external_id,
            program_uuid=program_uuid
        )

        UserSocialAuth.objects.create(
            user=UserFactory.create(),
            uid='{0}:{1}'.format('not_used', self.external_id),
        )

        UserSocialAuth.objects.create(
            user=self.user,
            uid='{0}:{1}'.format(self.provider_slug, self.external_id),
        )
        self._assert_program_enrollment_user(uox_program_enrollment, self.user)

        aiu_user = UserFactory.create()
        UserSocialAuth.objects.create(
            user=aiu_user,
            uid='{0}:{1}'.format('aiu', self.external_id),
        )
        self._assert_program_enrollment_user(aiu_program_enrollment, aiu_user)
Beispiel #12
0
 def _create_waiting_program_enrollment(self):
     """ helper method to create a waiting program enrollment """
     return ProgramEnrollmentFactory.create(
         user=None,
         external_user_key=self.external_id,
         program_uuid=self.program_uuid,
     )
Beispiel #13
0
 def _create_waiting_enrollment(self, program_uuid, external_user_key):
     """
     Create a waiting program enrollment for the given program and external user key.
     """
     return ProgramEnrollmentFactory.create(
         user=None,
         program_uuid=program_uuid,
         external_user_key=external_user_key,
     )
Beispiel #14
0
 def _setup_enrollments(self, external_user_key, user, created_date):
     """ helper function to setup enrollments """
     with freeze_time(created_date):
         program_enrollment = ProgramEnrollmentFactory(
             user=user,
             external_user_key=external_user_key,
         )
         ProgramCourseEnrollmentFactory(
             program_enrollment=program_enrollment)
     # additional course enrollment that is always fresh
     ProgramCourseEnrollmentFactory(program_enrollment=program_enrollment)
 def _set_up_enrollments(self, external_user_key, user, created_date):
     """ helper function to setup enrollments """
     with freeze_time(created_date):
         program_enrollment = ProgramEnrollmentFactory(
             user=user,
             external_user_key=external_user_key,
         )
         self._set_up_course_enrollment(user, program_enrollment,
                                        self.timed_course_key)
     # additional course enrollment that is always fresh
     self._set_up_course_enrollment(user, program_enrollment,
                                    self.fresh_course_key)
Beispiel #16
0
 def create_program_enrollment(self, external_user_key, user=False):
     """
     Creates and returns a ProgramEnrollment for the given external_user_key and
     user if specified.
     """
     program_enrollment = ProgramEnrollmentFactory.create(
         external_user_key=external_user_key,
         program_uuid=self.program_uuid,
     )
     if user is not False:
         program_enrollment.user = user
         program_enrollment.save()
     return program_enrollment
Beispiel #17
0
    def setUpTestData(cls):
        super().setUpTestData()
        cls.user_0 = UserFactory(username=cls.username_0)  # No enrollments
        CourseOverviewFactory(id=cls.course_key_p)
        CourseOverviewFactory(id=cls.course_key_q)
        enrollment_test_data = [  # ID
            (cls.user_0, None, cls.program_uuid_x, cls.curriculum_uuid_a,
             PEStatuses.ENROLLED),  # 1
            (None, cls.ext_3, cls.program_uuid_x, cls.curriculum_uuid_b,
             PEStatuses.PENDING),  # 2
            (None, cls.ext_4, cls.program_uuid_y, cls.curriculum_uuid_a,
             PEStatuses.ENROLLED),  # 3
            (cls.user_0, None, cls.program_uuid_y, cls.curriculum_uuid_b,
             PEStatuses.SUSPENDED),  # 4
        ]
        for user, external_user_key, program_uuid, curriculum_uuid, status in enrollment_test_data:
            ProgramEnrollmentFactory(
                user=user,
                external_user_key=external_user_key,
                program_uuid=program_uuid,
                curriculum_uuid=curriculum_uuid,
                status=status,
            )
        course_enrollment_test_data = [  # ID
            (1, cls.course_key_p, PCEStatuses.ACTIVE, True),  # 1
            (2, cls.course_key_q, PCEStatuses.ACTIVE, False),  # 2
            (3, cls.course_key_p, PCEStatuses.ACTIVE, True),  # 3
            (4, cls.course_key_q, PCEStatuses.ACTIVE, False),  # 4
        ]
        for program_enrollment_id, course_key, status, course_staff in course_enrollment_test_data:
            program_enrollment = ProgramEnrollment.objects.get(
                id=program_enrollment_id)
            course_enrollment = (CourseEnrollmentFactory(
                course_id=course_key,
                user=program_enrollment.user,
                mode=CourseMode.MASTERS,
            ) if program_enrollment.user else None)

            program_course_enrollment = ProgramCourseEnrollmentFactory(
                program_enrollment=program_enrollment,
                course_enrollment=course_enrollment,
                course_key=course_key,
                status=status,
            )
            if course_staff:
                if program_enrollment.user:
                    CourseStaffRole(course_key).add_users(
                        program_enrollment.user)
                else:
                    CourseAccessRoleAssignmentFactory(
                        enrollment=program_course_enrollment)
Beispiel #18
0
 def create_enrollment_and_history(self, user=None):
     """
     Create ProgramEnrollment and several History entries
     """
     if user:
         enrollment = ProgramEnrollmentFactory(user=user)
     else:
         enrollment = ProgramEnrollmentFactory()
     for status in ['pending', 'suspended', 'canceled', 'enrolled']:
         enrollment.status = status
         enrollment.save()
     return enrollment
 def create_enrollment_and_history(self,
                                   user=None,
                                   external_user_key='defaultExternalKey'):
     """
     Create ProgramEnrollment and several History entries
     """
     if user:
         enrollment = ProgramEnrollmentFactory(
             user=user, external_user_key=external_user_key)
     else:
         enrollment = ProgramEnrollmentFactory(
             external_user_key=external_user_key)
     for status in ['pending', 'suspended', 'canceled', 'enrolled']:
         enrollment.status = status
         enrollment.save()
     return enrollment
Beispiel #20
0
 def add_user_to_course_program_team(
     cls, user, add_to_team=True, enroll_in_program=True, connect_enrollments=True, external_user_key=None
 ):
     """
     Set up a test user by enrolling them in self.course, and then optionaly:
         - enroll them in a program
         - link their program and course enrollments
         - give their program enrollment an external_user_key
     """
     course_enrollment = CourseEnrollmentFactory.create(user=user, course_id=cls.course.id)
     if add_to_team:
         cls.team.add_user(user)
     if enroll_in_program:
         program_enrollment = ProgramEnrollmentFactory.create(user=user, external_user_key=external_user_key)
         if connect_enrollments:
             ProgramCourseEnrollmentFactory.create(
                 program_enrollment=program_enrollment, course_enrollment=course_enrollment
             )
Beispiel #21
0
    def _create_user_program_enrollments(self, *users, **kwargs):  # lint-amnesty, pylint: disable=missing-function-docstring
        # supply mode for enrollment. Use 'masters' to create a masters track enrollment
        for index, user in enumerate(users):
            course_enrollment = CourseEnrollmentFactory(
                course_id=self.course.id,
                user=user,
                created=self.date,
                mode=kwargs.get('mode', 'audit'))

            program_enrollment = ProgramEnrollmentFactory(
                user=user,
                external_user_key='program_user_key_{}'.format(index),
            )

            ProgramCourseEnrollmentFactory(
                program_enrollment=program_enrollment,
                course_enrollment=course_enrollment,
                course_key=self.course.id,
            )
Beispiel #22
0
    def _construct_enrollments(self,
                               program_uuids,
                               course_ids,
                               external_user_key,
                               edx_user=None):
        """
        A helper function to setup the program enrollments for a given learner.
        If the edx user is provided, it will try to SSO the user with the enrollments
        Return the expected info object that should be created based on the model setup
        """
        expected_enrollments = []
        for program_uuid in program_uuids:
            expected_enrollment = {}
            expected_course_enrollment = {}
            course_enrollment = None
            program_enrollment = ProgramEnrollmentFactory.create(
                external_user_key=external_user_key,
                program_uuid=program_uuid,
                user=edx_user)
            expected_enrollment['program_enrollment'] = {
                'created':
                self._serialize_datetime(program_enrollment.created),
                'modified':
                self._serialize_datetime(program_enrollment.modified),
                'program_uuid': program_enrollment.program_uuid,
                'external_user_key': external_user_key,
                'status': program_enrollment.status
            }

            for course_id in course_ids:
                if edx_user:
                    course_enrollment = CourseEnrollmentFactory.create(
                        course_id=course_id,
                        user=edx_user,
                        mode=CourseMode.MASTERS,
                        is_active=True)
                    expected_course_enrollment = {
                        'course_id': str(course_enrollment.course_id),
                        'is_active': course_enrollment.is_active,
                        'mode': course_enrollment.mode,
                    }

                program_course_enrollment = ProgramCourseEnrollmentFactory.create(
                    program_enrollment=program_enrollment,
                    course_key=course_id,
                    course_enrollment=course_enrollment,
                    status='active',
                )
                expected_program_course_enrollment = {
                    'created':
                    self._serialize_datetime(
                        program_course_enrollment.created),
                    'modified':
                    self._serialize_datetime(
                        program_course_enrollment.modified),
                    'status':
                    program_course_enrollment.status,
                    'course_key':
                    str(program_course_enrollment.course_key),
                }
                if expected_course_enrollment:
                    expected_program_course_enrollment[
                        'course_enrollment'] = expected_course_enrollment

                expected_enrollment.setdefault(
                    'program_course_enrollments',
                    []).append(expected_program_course_enrollment)

            expected_enrollments.append(expected_enrollment)

        return expected_enrollments
Beispiel #23
0
 def _create_program_and_course_enrollment(self, program_uuid, user):
     program_enrollment = ProgramEnrollmentFactory(
         user=user, program_uuid=program_uuid)
     ProgramCourseEnrollmentFactory(program_enrollment=program_enrollment)
     return program_enrollment
Beispiel #24
0
    def setUpTestData(cls):
        super(ProgramEnrollmentReadingTests, cls).setUpTestData()
        cls.user_0 = UserFactory(username=cls.username_0)  # No enrollments
        cls.user_1 = UserFactory(username=cls.username_1)
        cls.user_2 = UserFactory(username=cls.username_2)
        cls.user_3 = UserFactory(username=cls.username_3)
        cls.user_4 = UserFactory(username=cls.username_4)
        CourseOverviewFactory(id=cls.course_key_p)
        CourseOverviewFactory(id=cls.course_key_q)
        CourseOverviewFactory(id=cls.course_key_r)
        enrollment_test_data = [                                                                      # ID
            (cls.user_1, None, cls.program_uuid_x, cls.curriculum_uuid_a, PEStatuses.ENROLLED),       # 1
            (cls.user_2, None, cls.program_uuid_x, cls.curriculum_uuid_a, PEStatuses.PENDING),        # 2
            (cls.user_3, cls.ext_3, cls.program_uuid_x, cls.curriculum_uuid_b, PEStatuses.ENROLLED),  # 3
            (cls.user_4, cls.ext_4, cls.program_uuid_x, cls.curriculum_uuid_b, PEStatuses.PENDING),   # 4
            (None, cls.ext_5, cls.program_uuid_x, cls.curriculum_uuid_b, PEStatuses.SUSPENDED),       # 5
            (None, cls.ext_6, cls.program_uuid_y, cls.curriculum_uuid_c, PEStatuses.CANCELED),        # 6
            (cls.user_3, cls.ext_3, cls.program_uuid_y, cls.curriculum_uuid_c, PEStatuses.CANCELED),  # 7
            (None, cls.ext_4, cls.program_uuid_y, cls.curriculum_uuid_c, PEStatuses.ENROLLED),        # 8
            (cls.user_1, None, cls.program_uuid_x, cls.curriculum_uuid_b, PEStatuses.SUSPENDED),      # 9
            (cls.user_2, None, cls.program_uuid_y, cls.curriculum_uuid_c, PEStatuses.ENDED),          # 10
        ]
        for user, external_user_key, program_uuid, curriculum_uuid, status in enrollment_test_data:
            ProgramEnrollmentFactory(
                user=user,
                external_user_key=external_user_key,
                program_uuid=program_uuid,
                curriculum_uuid=curriculum_uuid,
                status=status,
            )
        course_enrollment_test_data = [                   # ID
            (1, cls.course_key_p, PCEStatuses.ACTIVE),    # 1
            (1, cls.course_key_q, PCEStatuses.ACTIVE),    # 2
            (9, cls.course_key_r, PCEStatuses.ACTIVE),    # 3
            (2, cls.course_key_p, PCEStatuses.INACTIVE),  # 4
            (3, cls.course_key_p, PCEStatuses.ACTIVE),    # 5
            (5, cls.course_key_p, PCEStatuses.INACTIVE),  # 6
            (8, cls.course_key_p, PCEStatuses.ACTIVE),    # 7
            (8, cls.course_key_q, PCEStatuses.INACTIVE),  # 8
            (2, cls.course_key_r, PCEStatuses.INACTIVE),  # 9
            (6, cls.course_key_r, PCEStatuses.INACTIVE),  # 10
            (8, cls.course_key_r, PCEStatuses.ACTIVE),    # 11
            (7, cls.course_key_q, PCEStatuses.ACTIVE),    # 12

        ]
        for program_enrollment_id, course_key, status in course_enrollment_test_data:
            program_enrollment = ProgramEnrollment.objects.get(id=program_enrollment_id)
            course_enrollment = (
                CourseEnrollmentFactory(
                    course_id=course_key,
                    user=program_enrollment.user,
                    mode=CourseMode.MASTERS,
                )
                if program_enrollment.user
                else None
            )
            ProgramCourseEnrollmentFactory(
                program_enrollment=program_enrollment,
                course_enrollment=course_enrollment,
                course_key=course_key,
                status=status,
            )