示例#1
0
    def test_course_progress(self, mock_get_programs):
        """
        Verify that the progress meter can represent progress in terms of
        serialized courses.
        """
        course_run_key = generate_course_run_key()
        data = [
            ProgramFactory(
                courses=[
                    CourseFactory(course_runs=[
                        CourseRunFactory(key=course_run_key),
                    ]),
                ]
            )
        ]
        mock_get_programs.return_value = data

        self._create_enrollments(course_run_key)

        meter = ProgramProgressMeter(self.user)

        program = data[0]
        expected = [
            ProgressFactory(
                uuid=program['uuid'],
                completed=[],
                in_progress=[program['courses'][0]],
                not_started=[]
            )
        ]

        self.assertEqual(meter.progress(count_only=False), expected)
示例#2
0
    def test_no_id_professional_in_progress(self, mock_get_programs):
        """
        Verify that the progress meter treats no-id-professional enrollments
        as professional.
        """
        course_run_key = generate_course_run_key()
        data = [
            ProgramFactory(
                courses=[
                    CourseFactory(course_runs=[
                        CourseRunFactory(key=course_run_key, type=CourseMode.PROFESSIONAL),
                    ]),
                ]
            )
        ]
        mock_get_programs.return_value = data

        CourseEnrollmentFactory(
            user=self.user, course_id=course_run_key,
            mode=CourseMode.NO_ID_PROFESSIONAL_MODE
        )

        meter = ProgramProgressMeter(self.user)

        program = data[0]
        expected = [
            ProgressFactory(
                uuid=program['uuid'],
                completed=[],
                in_progress=[program['courses'][0]],
                not_started=[]
            )
        ]

        self.assertEqual(meter.progress(count_only=False), expected)
示例#3
0
    def test_handle(self, commit, mock_task, mock_get_programs):
        """
        Verify that relevant tasks are only enqueued when the commit option is passed.
        """
        data = [
            ProgramFactory(courses=[
                CourseFactory(course_runs=[
                    CourseRunFactory(key=self.course_run_key),
                ]),
            ]),
        ]
        mock_get_programs.return_value = data

        GeneratedCertificateFactory(
            user=self.alice,
            course_id=self.course_run_key,
            mode=MODES.verified,
            status=CertificateStatuses.downloadable,
        )

        GeneratedCertificateFactory(
            user=self.bob,
            course_id=self.alternate_course_run_key,
            mode=MODES.verified,
            status=CertificateStatuses.downloadable,
        )

        call_command('backpopulate_program_credentials', commit=commit)

        if commit:
            mock_task.assert_called_once_with(self.alice.username)
        else:
            mock_task.assert_not_called()
示例#4
0
    def test_single_program_engagement(self, mock_get_programs):
        """
        Verify that correct program is returned when the user is enrolled in a
        course run appearing in one program.
        """
        course_run_key = generate_course_run_key()
        data = [
            ProgramFactory(
                courses=[
                    CourseFactory(course_runs=[
                        CourseRunFactory(key=course_run_key),
                    ]),
                ]
            ),
            ProgramFactory(),
        ]
        mock_get_programs.return_value = data

        self._create_enrollments(course_run_key)
        meter = ProgramProgressMeter(self.user)

        self._attach_detail_url(data)
        program = data[0]
        self.assertEqual(meter.engaged_programs, [program])
        self._assert_progress(
            meter,
            ProgressFactory(uuid=program['uuid'], in_progress=1)
        )
        self.assertEqual(meter.completed_programs, [])
示例#5
0
    def setUpClass(cls):
        super().setUpClass()

        cls.user = UserFactory()
        modulestore_course = ModuleStoreCourseFactory()
        course_run = CourseRunFactory(key=str(modulestore_course.id))
        course = CourseFactory(course_runs=[course_run])
        enterprise_customer = EnterpriseCustomerFactory(
            uuid=cls.enterprise_uuid)
        enterprise_customer_user = EnterpriseCustomerUserFactory(
            user_id=cls.user.id, enterprise_customer=enterprise_customer)
        CourseEnrollmentFactory(is_active=True,
                                course_id=modulestore_course.id,
                                user=cls.user)
        EnterpriseCourseEnrollmentFactory(
            course_id=modulestore_course.id,
            enterprise_customer_user=enterprise_customer_user)

        cls.program = ProgramFactory(
            uuid=cls.program_uuid,
            courses=[course],
            title='Journey to cooking',
            type='MicroMasters',
            authoring_organizations=[{
                'key': 'MAX'
            }],
        )
        cls.site = SiteFactory(domain='test.localhost')
    def test_handle_mode_slugs(self, mock_task, mock_get_programs):
        """
        Verify that course run types are taken into account when identifying
        qualifying course run certificates.
        """
        data = [
            ProgramFactory(
                courses=[
                    CourseFactory(course_runs=[
                        CourseRunFactory(key=self.course_run_key, type='honor'),
                    ]),
                ]
            ),
        ]
        mock_get_programs.return_value = data

        GeneratedCertificateFactory(
            user=self.alice,
            course_id=self.course_run_key,
            mode=MODES.honor,
            status=CertificateStatuses.downloadable,
        )

        GeneratedCertificateFactory(
            user=self.bob,
            course_id=self.course_run_key,
            mode=MODES.verified,
            status=CertificateStatuses.downloadable,
        )

        call_command('backpopulate_program_credentials', commit=True)

        mock_task.assert_called_once_with(self.alice.username)
示例#7
0
    def setUp(self):
        """ Test case setup """
        super().setUp()

        self.client = Client()
        user = AdminFactory()
        self.view_url = reverse('admin:enterprise_override_attributes')
        self.client.login(username=user.username, password=TEST_PASSWORD)

        self.users = []
        for _ in range(3):
            self.users.append(UserFactory())

        self.course = CourseRunFactory()
        self.course_id = self.course.get('key')  # lint-amnesty, pylint: disable=no-member
        self.csv_data = [
            [self.users[0].id, self.course_id, 'OP_4321'],
            [self.users[1].id, self.course_id, 'OP_8765'],
            [self.users[2].id, self.course_id, 'OP_2109'],
        ]
        self.csv_data_for_existing_attributes = [
            [self.users[0].id, self.course_id, 'OP_1234'],
            [self.users[1].id, self.course_id, 'OP_5678'],
            [self.users[2].id, self.course_id, 'OP_9012'],
        ]

        for user in self.users:
            CourseEnrollmentFactory(
                course_id=self.course_id,
                user=user
            )
示例#8
0
    def setUpClass(cls):
        super().setUpClass()

        modulestore_course = ModuleStoreCourseFactory()
        course_run = CourseRunFactory(key=str(modulestore_course.id))
        course = CourseFactory(course_runs=[course_run])
        cls.program = ProgramFactory(uuid=cls.program_uuid, courses=[course])
示例#9
0
    def test_handle_professional(self, mock_task, mock_get_programs):
        """ Verify the task can handle both professional and no-id-professional modes. """
        mock_get_programs.return_value = [
            ProgramFactory(courses=[
                CourseFactory(course_runs=[
                    CourseRunFactory(key=self.course_run_key,
                                     type='professional'),
                ]),
            ]),
        ]

        GeneratedCertificateFactory(
            user=self.alice,
            course_id=self.course_run_key,
            mode=CourseMode.PROFESSIONAL,
            status=CertificateStatuses.downloadable,
        )

        GeneratedCertificateFactory(
            user=self.bob,
            course_id=self.course_run_key,
            mode=CourseMode.NO_ID_PROFESSIONAL_MODE,
            status=CertificateStatuses.downloadable,
        )

        call_command('backpopulate_program_credentials', commit=True)

        # The task should be called for both users since professional and no-id-professional are equivalent.
        mock_task.assert_has_calls(
            [mock.call(self.alice.username),
             mock.call(self.bob.username)],
            any_order=True)
示例#10
0
    def create_program(self):
        """DRY helper for creating test program data."""
        course_run = CourseRunFactory(key=self.course_id)
        course = CourseFactory(course_runs=[course_run])

        program_type = ProgramTypeFactory()
        return ProgramFactory(courses=[course], type=program_type['name'])
示例#11
0
    def setUpClass(cls):
        super(TestProgramDetails, cls).setUpClass()

        modulestore_course = ModuleStoreCourseFactory()
        course_run = CourseRunFactory(key=unicode(modulestore_course.id))  # pylint: disable=no-member
        course = CourseFactory(course_runs=[course_run])

        cls.data = ProgramFactory(uuid=cls.program_uuid, courses=[course])
 def setUp(self):
     super(TestSyncCourseRunsCommand, self).setUp()
     # create mongo course
     self.course = CourseFactory.create()
     # load this course into course overview
     CourseOverview.get_from_id(self.course.id)
     # create a catalog course run with the same course id.
     self.catalog_course_run = CourseRunFactory(
         key=unicode(self.course.id), marketing_url='test_marketing_url')
示例#13
0
    def test_shared_enrollment_engagement(self, mock_get_programs):
        """
        Verify that correct programs are returned when the user is enrolled in a
        single course run appearing in multiple programs.
        """
        shared_course_run_key, solo_course_run_key = (generate_course_run_key() for __ in range(2))

        batch = [
            ProgramFactory(
                courses=[
                    CourseFactory(course_runs=[
                        CourseRunFactory(key=shared_course_run_key),
                    ]),
                ]
            )
            for __ in range(2)
        ]

        joint_programs = sorted(batch, key=lambda program: program['title'])
        data = joint_programs + [
            ProgramFactory(
                courses=[
                    CourseFactory(course_runs=[
                        CourseRunFactory(key=solo_course_run_key),
                    ]),
                ]
            ),
            ProgramFactory(),
        ]

        mock_get_programs.return_value = data

        # Enrollment for the shared course run created last (most recently).
        self._create_enrollments(solo_course_run_key, shared_course_run_key)
        meter = ProgramProgressMeter(self.user)

        self._attach_detail_url(data)
        programs = data[:3]
        self.assertEqual(meter.engaged_programs, programs)
        self._assert_progress(
            meter,
            *(ProgressFactory(uuid=program['uuid'], in_progress=1) for program in programs)
        )
        self.assertEqual(meter.completed_programs, [])
示例#14
0
    def test_mutiple_program_engagement(self, mock_get_programs):
        """
        Verify that correct programs are returned in the correct order when the
        user is enrolled in course runs appearing in programs.
        """
        newer_course_run_key, older_course_run_key = (generate_course_run_key() for __ in range(2))
        data = [
            ProgramFactory(
                courses=[
                    CourseFactory(course_runs=[
                        CourseRunFactory(key=newer_course_run_key),
                    ]),
                ]
            ),
            ProgramFactory(
                courses=[
                    CourseFactory(course_runs=[
                        CourseRunFactory(key=older_course_run_key),
                    ]),
                ]
            ),
            ProgramFactory(),
        ]
        mock_get_programs.return_value = data

        # The creation time of the enrollments matters to the test. We want
        # the first_course_run_key to represent the newest enrollment.
        self._create_enrollments(older_course_run_key, newer_course_run_key)
        meter = ProgramProgressMeter(self.site, self.user)

        self._attach_detail_url(data)
        programs = data[:2]
        self.assertEqual(meter.engaged_programs, programs)

        grades = {
            newer_course_run_key: 0.0,
            older_course_run_key: 0.0,
        }
        self._assert_progress(
            meter,
            *(ProgressFactory(uuid=program['uuid'], in_progress=1, grades=grades) for program in programs)
        )
        self.assertEqual(meter.completed_programs, [])
 def test_program_uuid_args(self, mock_get_programs, mock_task):
     course_1_id = 'course-v1:edX+Test+1'
     course_2_id = 'course-v1:edX+Test+2'
     program = ProgramFactory(
         courses=[
             CourseFactory(course_runs=[
                 CourseRunFactory(key=course_1_id),
                 CourseRunFactory(key=course_2_id)
             ])
         ],
         curricula=[],
     )
     self.expected_options['program_uuids'] = [program['uuid']]
     mock_get_programs.return_value = [program]
     call_command(Command(), '--program_uuids', program['uuid'])
     assert mock_task.called
     assert mock_task.call_args[0][0] == self.expected_options
     assert mock_task.call_args[0][1].sort() == [course_1_id,
                                                 course_2_id].sort()
示例#16
0
    def test_get_course_runs(self, mock_get_edx_api_data):
        """
        Test retrieval of course runs.
        """
        catalog_course_runs = [CourseRunFactory() for __ in xrange(10)]
        mock_get_edx_api_data.return_value = catalog_course_runs

        data = get_course_runs()
        self.assertTrue(mock_get_edx_api_data.called)
        self.assert_contract(mock_get_edx_api_data.call_args)
        self.assertEqual(data, catalog_course_runs)
    def setUp(self):
        super().setUp()

        self.url = reverse('dashboard')

        self.create_programs_config()
        self.client.login(username=self.user.username, password=self.password)

        course_run = CourseRunFactory(key=str(self.course.id))  # pylint: disable=no-member
        course = CatalogCourseFactory(course_runs=[course_run])
        self.programs = [ProgramFactory(courses=[course]) for __ in range(2)]
示例#18
0
    def setUpClass(cls):
        super(TestProgramListing, cls).setUpClass()

        cls.course = ModuleStoreCourseFactory()
        course_run = CourseRunFactory(key=six.text_type(cls.course.id))
        course = CourseFactory(course_runs=[course_run])

        cls.first_program = ProgramFactory(courses=[course])
        cls.second_program = ProgramFactory(courses=[course])

        cls.data = sorted([cls.first_program, cls.second_program], key=cls.program_sort_key)
    def setUpClass(cls):
        super().setUpClass()

        cls.course = ModuleStoreCourseFactory()
        course_run = CourseRunFactory(key=str(cls.course.id))  # lint-amnesty, pylint: disable=no-member
        course = CourseFactory(course_runs=[course_run])

        cls.first_program = ProgramFactory(courses=[course])
        cls.second_program = ProgramFactory(courses=[course])

        cls.data = sorted([cls.first_program, cls.second_program], key=cls.program_sort_key)
 def setUp(self):
     super().setUp()
     # create mongo course
     self.course = CourseFactory.create()
     # load this course into course overview
     self.course_overview = CourseOverview.get_from_id(self.course.id)
     # create a catalog course run with the same course id.
     self.catalog_course_run = CourseRunFactory(
         key=str(self.course.id),
         marketing_url='test_marketing_url',
         eligible_for_financial_aid=False)
示例#21
0
    def setUp(self):
        super(TestProgramDataExtender, self).setUp()

        self.course = ModuleStoreCourseFactory()
        self.course.start = datetime.datetime.now(utc) - datetime.timedelta(days=1)
        self.course.end = datetime.datetime.now(utc) + datetime.timedelta(days=1)
        self.course = self.update_course(self.course, self.user.id)

        self.course_run = CourseRunFactory(key=unicode(self.course.id))
        self.catalog_course = CourseFactory(course_runs=[self.course_run])
        self.program = ProgramFactory(courses=[self.catalog_course])
示例#22
0
 def setUp(self):
     super(TestSyncCourseRunsCommand, self).setUp()  # lint-amnesty, pylint: disable=super-with-arguments
     # create mongo course
     self.course = CourseFactory.create()
     # load this course into course overview
     self.course_overview = CourseOverview.get_from_id(self.course.id)
     # create a catalog course run with the same course id.
     self.catalog_course_run = CourseRunFactory(
         key=six.text_type(self.course.id),
         marketing_url='test_marketing_url',
         eligible_for_financial_aid=False)
示例#23
0
    def test_multiple_published_course_runs(self):
        """
        Learner should not be eligible for one click purchase if:
            - program has a course with more than one published course run
        """
        course_run_1 = CourseRunFactory(
            key=str(ModuleStoreCourseFactory().id),
            status='published'
        )
        course_run_2 = CourseRunFactory(
            key=str(ModuleStoreCourseFactory().id),
            status='published'
        )
        course = CourseFactory(course_runs=[course_run_1, course_run_2])
        program = ProgramFactory(
            courses=[
                CourseFactory(course_runs=[
                    CourseRunFactory(
                        key=str(ModuleStoreCourseFactory().id),
                        status='published'
                    )
                ]),
                course,
                CourseFactory(course_runs=[
                    CourseRunFactory(
                        key=str(ModuleStoreCourseFactory().id),
                        status='published'
                    )
                ])
            ],
            is_program_eligible_for_one_click_purchase=True,
            applicable_seat_types=['verified']
        )
        data = ProgramDataExtender(program, self.user).extend()

        self.assertFalse(data['is_learner_eligible_for_one_click_purchase'])

        course_run_2['status'] = 'unpublished'
        data = ProgramDataExtender(program, self.user).extend()

        self.assertTrue(data['is_learner_eligible_for_one_click_purchase'])
示例#24
0
    def setUpClass(cls):
        super(TestProgramDetails, cls).setUpClass()

        modulestore_course = ModuleStoreCourseFactory()
        course_run = CourseRunFactory(key=six.text_type(modulestore_course.id))
        course = CourseFactory(course_runs=[course_run])

        cls.program_data = ProgramFactory(uuid=cls.program_uuid, courses=[course])
        cls.pathway_data = PathwayFactory()
        cls.program_data['pathway_ids'] = [cls.pathway_data['id']]
        cls.pathway_data['program_uuids'] = [cls.program_data['uuid']]
        del cls.pathway_data['programs']
示例#25
0
    def setUpClass(cls):
        super(TestProgramDetails, cls).setUpClass()

        modulestore_course = ModuleStoreCourseFactory()
        course_run = CourseRunFactory(key=unicode(modulestore_course.id))  # pylint: disable=no-member
        course = CourseFactory(course_runs=[course_run])

        cls.program_data = ProgramFactory(uuid=cls.program_uuid, courses=[course])
        cls.pathway_data = CreditPathwayFactory()
        cls.program_data['pathway_ids'] = [cls.pathway_data['id']]
        cls.pathway_data['program_uuids'] = [cls.program_data['uuid']]
        del cls.pathway_data['programs']
示例#26
0
    def setUpClass(cls):
        super().setUpClass()

        modulestore_course = ModuleStoreCourseFactory()
        course_run = CourseRunFactory(key=str(modulestore_course.id))  # lint-amnesty, pylint: disable=no-member
        course = CourseFactory(course_runs=[course_run])

        cls.program_data = ProgramFactory(uuid=cls.program_uuid, courses=[course])
        cls.pathway_data = PathwayFactory()
        cls.program_data['pathway_ids'] = [cls.pathway_data['id']]
        cls.pathway_data['program_uuids'] = [cls.program_data['uuid']]
        del cls.pathway_data['programs']  # lint-amnesty, pylint: disable=unsupported-delete-operation
    def test_unrelated_program_not_listed(self, mock_get_programs):
        """Verify that unrelated programs don't appear in the listing."""
        nonexistent_course_run_id = generate_course_run_key()

        course_run = CourseRunFactory(key=nonexistent_course_run_id)
        course = CatalogCourseFactory(course_runs=[course_run])
        unrelated_program = ProgramFactory(courses=[course])

        mock_get_programs.return_value = self.programs + [unrelated_program]

        response = self.client.get(self.url)
        self.assert_related_programs(response)
        self.assertNotContains(response, unrelated_program['title'])
示例#28
0
    def test_get_course_run_details(self, mock_get_course_run_details):
        """
        Test for Python API `get_course_run_details` function.
        """
        course_run = CourseRunFactory()

        mock_get_course_run_details.return_value = {
            'title': course_run['title'],
        }

        results = get_course_run_details(course_run['key'], ['title'])

        assert results['title'] == course_run['title']
示例#29
0
    def test_course_pricing_when_all_course_runs_have_no_seats(self):
        # Create three seatless course runs and add them to the program
        course_runs = []
        for __ in range(3):
            course = ModuleStoreCourseFactory()
            course = self.update_course(course, self.user.id)
            course_runs.append(CourseRunFactory(key=unicode(course.id), seats=[]))
        program = ProgramFactory(courses=[CourseFactory(course_runs=course_runs)])

        data = ProgramMarketingDataExtender(program, self.user).extend()

        self.assertEqual(data['number_of_courses'], len(program['courses']))
        self.assertEqual(data['full_program_price'], 0.0)
        self.assertEqual(data['avg_price_per_course'], 0.0)
示例#30
0
 def test_get_course_run_details(self, mock_get_edx_api_data):
     """
     Test retrieval of details about a specific course run
     """
     course_run = CourseRunFactory()
     course_run_details = {
         'content_language': course_run['content_language'],
         'weeks_to_complete': course_run['weeks_to_complete'],
         'max_effort': course_run['max_effort']
     }
     mock_get_edx_api_data.return_value = course_run_details
     data = get_course_run_details(course_run['key'], ['content_language', 'weeks_to_complete', 'max_effort'])
     self.assertTrue(mock_get_edx_api_data.called)
     self.assertEqual(data, course_run_details)