コード例 #1
0
class TestSyncCourseRunsCommand(ModuleStoreTestCase):
    """
    Test for the sync course runs management command.
    """
    def setUp(self):
        super(TestSyncCourseRunsCommand, self).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=unicode(self.course.id),
            marketing_url='test_marketing_url',
            eligible_for_financial_aid=False
        )

    def test_course_run_sync(self, mock_catalog_course_runs):
        """
        Verify on executing management command course overview data is updated
        with course run data from course discovery.
        """
        mock_catalog_course_runs.return_value = [self.catalog_course_run]

        call_command('sync_course_runs')
        updated_course_overview = CourseOverview.objects.get(id=self.course.id)

        # assert fields have updated
        for field in sync_command.course_run_fields:
            course_overview_field_name = field.course_overview_name
            catalog_field_name = field.catalog_name

            previous_course_overview_value = getattr(self.course_overview, course_overview_field_name),
            updated_course_overview_value = getattr(updated_course_overview, course_overview_field_name)

            # course overview value matches catalog value
            self.assertEqual(
                updated_course_overview_value,
                self.catalog_course_run.get(catalog_field_name),
            )
            # new value doesn't match old value
            self.assertNotEqual(
                updated_course_overview_value,
                previous_course_overview_value,
            )

    @mock.patch(COMMAND_MODULE + '.log.info')
    def test_course_overview_does_not_exist(self, mock_log_info, mock_catalog_course_runs):
        """
        Verify no error in case if a course run is not found in course overview.
        """
        nonexistent_course_run = CourseRunFactory()
        mock_catalog_course_runs.return_value = [self.catalog_course_run, nonexistent_course_run]

        call_command('sync_course_runs')

        mock_log_info.assert_any_call(
            '[sync_course_runs] course overview record not found for course run: %s',
            nonexistent_course_run['key'],
        )
        updated_marketing_url = CourseOverview.objects.get(id=self.course.id).marketing_url
        self.assertEqual(updated_marketing_url, 'test_marketing_url')

    @mock.patch(COMMAND_MODULE + '.log.info')
    def test_starting_and_ending_logs(self, mock_log_info, mock_catalog_course_runs):
        """
        Verify logging at start and end of the command.
        """
        def _assert_logs(num_updates):
            mock_log_info.assert_any_call('[sync_course_runs] Fetching course runs from catalog service.')
            mock_log_info.assert_any_call(
                '[sync_course_runs] course runs found in catalog: %d, course runs found in course overview: %d,'
                ' course runs not found in course overview: %d, course overviews updated: %d',
                3,
                1,
                2,
                num_updates,
            )
            mock_log_info.reset_mock()

        mock_catalog_course_runs.return_value = [self.catalog_course_run, CourseRunFactory(), CourseRunFactory()]

        call_command('sync_course_runs')
        _assert_logs(num_updates=1)

        call_command('sync_course_runs')
        _assert_logs(num_updates=0)
コード例 #2
0
class TestSyncCourseRunsCommand(ModuleStoreTestCase):
    """
    Test for the sync course runs management command.
    """
    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)

    def test_course_run_sync(self, mock_catalog_course_runs):
        """
        Verify on executing management command course overview data is updated
        with course run data from course discovery.
        """
        mock_catalog_course_runs.return_value = [self.catalog_course_run]

        call_command('sync_course_runs')
        updated_course_overview = CourseOverview.objects.get(id=self.course.id)

        # assert fields have updated
        for field in sync_command.course_run_fields:
            course_overview_field_name = field.course_overview_name
            catalog_field_name = field.catalog_name

            previous_course_overview_value = getattr(
                self.course_overview, course_overview_field_name)
            updated_course_overview_value = getattr(
                updated_course_overview, course_overview_field_name)

            # course overview value matches catalog value
            assert updated_course_overview_value == self.catalog_course_run.get(
                catalog_field_name)  # pylint: disable=no-member, line-too-long
            # new value doesn't match old value
            assert updated_course_overview_value != previous_course_overview_value

    @mock.patch(COMMAND_MODULE + '.log.info')
    def test_course_overview_does_not_exist(self, mock_log_info,
                                            mock_catalog_course_runs):
        """
        Verify no error in case if a course run is not found in course overview.
        """
        nonexistent_course_run = CourseRunFactory()
        mock_catalog_course_runs.return_value = [
            self.catalog_course_run, nonexistent_course_run
        ]

        call_command('sync_course_runs')

        mock_log_info.assert_any_call(
            '[sync_course_runs] course overview record not found for course run: %s',
            nonexistent_course_run['key'],
        )
        updated_marketing_url = CourseOverview.objects.get(
            id=self.course.id).marketing_url
        assert updated_marketing_url == 'test_marketing_url'

    @mock.patch(COMMAND_MODULE + '.log.info')
    def test_starting_and_ending_logs(self, mock_log_info,
                                      mock_catalog_course_runs):
        """
        Verify logging at start and end of the command.
        """
        def _assert_logs(num_updates):
            mock_log_info.assert_any_call(
                '[sync_course_runs] Fetching course runs from catalog service.'
            )
            mock_log_info.assert_any_call(
                '[sync_course_runs] course runs found in catalog: %d, course runs found in course overview: %d,'
                ' course runs not found in course overview: %d, course overviews updated: %d',
                3,
                1,
                2,
                num_updates,
            )
            mock_log_info.reset_mock()

        mock_catalog_course_runs.return_value = [
            self.catalog_course_run,
            CourseRunFactory(),
            CourseRunFactory()
        ]

        call_command('sync_course_runs')
        _assert_logs(num_updates=1)

        call_command('sync_course_runs')
        _assert_logs(num_updates=0)
コード例 #3
0
class EnrollmentAttributeOverrideViewTest(ModuleStoreTestCase):
    """
    Tests for course creator admin.
    """

    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
            )

    def create_csv(self, header=None, data=None):
        """Create csv"""
        header = header or ['lms_user_id', 'course_id', 'opportunity_id']
        data = data or self.csv_data
        tmp_csv_path = os.path.join(tempfile.gettempdir(), 'data.csv')
        with open(tmp_csv_path, 'w') as csv_file:
            csv_writer = csv.writer(csv_file)
            csv_writer.writerow(header)
            csv_writer.writerows(data)

        return tmp_csv_path

    def verify_enrollment_attributes(self, data=None):
        """
        Verify that data from csv is imported correctly and tables have correct data.
        """
        data = data or self.csv_data
        for user_id, course_id, opportunity_id in data:
            enrollment = CourseEnrollment.objects.get(user_id=user_id, course_id=course_id)
            enrollment_attribute = CourseEnrollmentAttribute.objects.get(
                enrollment=enrollment,
                namespace='salesforce',
                name='opportunity_id'
            )
            assert enrollment_attribute.value == opportunity_id

    def test_get(self):
        """
        Tests that HTTP GET is working as expected.
        """
        response = self.client.get(self.view_url)
        assert response.status_code == 200
        assert isinstance(response.context['form'], CSVImportForm)

    def test_post(self):
        """
        Tests that HTTP POST is working as expected when creating new attributes and updating.
        """
        csv_path = self.create_csv()
        post_data = {'csv_file': open(csv_path)}
        response = self.client.post(self.view_url, data=post_data)
        assert response.status_code == 302
        self.verify_enrollment_attributes()

        # override existing
        csv_path = self.create_csv(data=self.csv_data_for_existing_attributes)
        post_data = {'csv_file': open(csv_path)}
        response = self.client.post(self.view_url, data=post_data)
        assert response.status_code == 302
        self.verify_enrollment_attributes(data=self.csv_data_for_existing_attributes)

    def test_post_with_no_csv(self):
        """
        Tests that HTTP POST without out csv file is working as expected.
        """
        response = self.client.post(self.view_url)
        assert response.context['form'].errors == {'csv_file': ['This field is required.']}

    def test_post_with_incorrect_csv_header(self):
        """
        Tests that HTTP POST with incorrect csv header is working as expected.
        """
        csv_path = self.create_csv(header=['a', 'b'])
        post_data = {'csv_file': open(csv_path)}
        response = self.client.post(self.view_url, data=post_data)
        assert response.context['form'].errors == {
            'csv_file': [
                'Expected a CSV file with [lms_user_id, course_id, opportunity_id] '
                'columns, but found [a, b] columns instead.'
            ]
        }

    def test_post_with_no_enrollment_error(self):
        """
        Tests that HTTP POST is working as expected when for some records there is no enrollment.
        """
        csv_data = self.csv_data + [[999, self.course_id, 'NOPE'], [1000, self.course_id, 'NONE']]
        csv_path = self.create_csv(data=csv_data)
        post_data = {'csv_file': open(csv_path)}
        response = self.client.post(self.view_url, data=post_data)
        assert response.status_code == 302
        messages = []
        for msg in get_messages(response.wsgi_request):
            messages.append(str(msg))
        assert messages == [
            'Successfully updated learner enrollment opportunity ids.',
            'Enrollment attributes were not updated for records at following line numbers '
            'in csv because no enrollment found for these records: 4, 5'
        ]