Пример #1
0
    def test_validate_and_update_from_json_wrong_inputs(self):
        # input incorrectly formatted data
        is_valid, errors, test_model = CourseMetadata.validate_and_update_from_json(
            self.course,
            {
                "advertised_start": {"value": 1, "display_name": "Course Advertised Start Date", },
                "days_early_for_beta": {"value": "supposed to be an integer",
                                        "display_name": "Days Early for Beta Users", },
                "advanced_modules": {"value": 1, "display_name": "Advanced Module List", },
            },
            user=self.user
        )

        # Check valid results from validate_and_update_from_json
        self.assertFalse(is_valid)
        self.assertEqual(len(errors), 3)
        self.assertFalse(test_model)

        error_keys = set([error_obj['model']['display_name'] for error_obj in errors])
        test_keys = set(['Advanced Module List', 'Course Advertised Start Date', 'Days Early for Beta Users'])
        self.assertEqual(error_keys, test_keys)

        # try fresh fetch to ensure no update happened
        fresh = modulestore().get_course(self.course.id)
        test_model = CourseMetadata.fetch(fresh)

        self.assertNotEqual(test_model['advertised_start']['value'], 1, 'advertised_start should not be updated to a wrong value')
        self.assertNotEqual(test_model['days_early_for_beta']['value'], "supposed to be an integer",
                            'days_early_for beta should not be updated to a wrong value')
    def test_validate_and_update_from_json_wrong_inputs(self):
        # input incorrectly formatted data
        is_valid, errors, test_model = CourseMetadata.validate_and_update_from_json(
            self.course,
            {
                "advertised_start": {"value": 1, "display_name": "Course Advertised Start Date", },
                "days_early_for_beta": {"value": "supposed to be an integer",
                                        "display_name": "Days Early for Beta Users", },
                "advanced_modules": {"value": 1, "display_name": "Advanced Module List", },
            },
            user=self.user
        )

        # Check valid results from validate_and_update_from_json
        self.assertFalse(is_valid)
        self.assertEqual(len(errors), 3)
        self.assertFalse(test_model)

        error_keys = set([error_obj['model']['display_name'] for error_obj in errors])
        test_keys = set(['Advanced Module List', 'Course Advertised Start Date', 'Days Early for Beta Users'])
        self.assertEqual(error_keys, test_keys)

        # try fresh fetch to ensure no update happened
        fresh = modulestore().get_course(self.course.id)
        test_model = CourseMetadata.fetch(fresh)

        self.assertNotEqual(test_model['advertised_start']['value'], 1, 'advertised_start should not be updated to a wrong value')
        self.assertNotEqual(test_model['days_early_for_beta']['value'], "supposed to be an integer",
                            'days_early_for beta should not be updated to a wrong value')
Пример #3
0
    def test_validate_and_update_from_json_correct_inputs(self):
        is_valid, errors, test_model = CourseMetadata.validate_and_update_from_json(
            self.course, {
                "advertised_start": {
                    "value": "start A"
                },
                "days_early_for_beta": {
                    "value": 2
                },
                "advanced_modules": {
                    "value": ['combinedopenended']
                },
            },
            user=self.user)
        self.assertTrue(is_valid)
        self.assertTrue(len(errors) == 0)
        self.update_check(test_model)

        # fresh fetch to ensure persistence
        fresh = modulestore().get_course(self.course.id)
        test_model = CourseMetadata.fetch(fresh)
        self.update_check(test_model)

        # Tab gets tested in test_advanced_settings_munge_tabs
        self.assertIn('advanced_modules', test_model,
                      'Missing advanced_modules')
        self.assertEqual(test_model['advanced_modules']['value'],
                         ['combinedopenended'],
                         'advanced_module is not updated')
 def test_validate_update_filtered_edxnotes_on(self):
     """
     If feature flag is on, then edxnotes must not be filtered.
     """
     # pylint: disable=unused-variable
     is_valid, errors, test_model = CourseMetadata.validate_and_update_from_json(
         self.course,
         {
             "edxnotes": {"value": "true"},
         },
         user=self.user
     )
     self.assertIn('edxnotes', test_model)
 def test_validate_update_filtered_on(self):
     """
     If feature flag is on, then giturl must not be filtered.
     """
     # pylint: disable=unused-variable
     is_valid, errors, test_model = CourseMetadata.validate_and_update_from_json(
         self.course,
         {
             "giturl": {"value": "http://example.com"},
         },
         user=self.user
     )
     self.assertIn('giturl', test_model)
Пример #6
0
 def test_validate_update_filtered_edxnotes_on(self):
     """
     If feature flag is on, then edxnotes must not be filtered.
     """
     # pylint: disable=unused-variable
     is_valid, errors, test_model = CourseMetadata.validate_and_update_from_json(
         self.course,
         {
             "edxnotes": {"value": "true"},
         },
         user=self.user
     )
     self.assertIn('edxnotes', test_model)
Пример #7
0
 def test_validate_update_filtered_on(self):
     """
     If feature flag is on, then giturl must not be filtered.
     """
     # pylint: disable=unused-variable
     is_valid, errors, test_model = CourseMetadata.validate_and_update_from_json(
         self.course,
         {
             "giturl": {"value": "http://example.com"},
         },
         user=self.user
     )
     self.assertIn('giturl', test_model)
Пример #8
0
    def post(self, request, course_id):
        """ POST handler """
        serializer = ProctoredExamSettingsSerializer if request.user.is_staff else LimitedProctoredExamSettingsSerializer
        exam_config = serializer(
            data=request.data.get('proctored_exam_settings', {}))
        valid_request = exam_config.is_valid()
        if not request.user.is_staff and valid_request and ProctoredExamSettingsSerializer(
                data=request.data.get('proctored_exam_settings',
                                      {})).is_valid():
            return Response(status=status.HTTP_403_FORBIDDEN)

        with modulestore().bulk_operations(CourseKey.from_string(course_id)):
            course_module = self._get_and_validate_course_access(
                request.user, course_id)
            course_metadata = CourseMetadata().fetch_all(course_module)

            models_to_update = {}
            for setting_key, value in exam_config.data.items():
                model = course_metadata.get(setting_key)
                if model:
                    models_to_update[setting_key] = copy.deepcopy(model)
                    models_to_update[setting_key]['value'] = value

            # validate data formats and update the course module object
            is_valid, errors, updated_data = CourseMetadata.validate_and_update_from_json(
                course_module,
                models_to_update,
                user=request.user,
            )

            if not is_valid:
                error_messages = [{
                    error.get('key'): error.get('message')
                } for error in errors]
                return Response({'detail': error_messages},
                                status=status.HTTP_400_BAD_REQUEST)

            # save to mongo
            modulestore().update_item(course_module, request.user.id)

            # merge updated settings with all existing settings.
            # do this because fields that could not be modified are excluded from the result
            course_metadata = {**course_metadata, **updated_data}
            updated_setttings = self._get_proctored_exam_setting_values(
                course_metadata)
            serializer = ProctoredExamSettingsSerializer(updated_setttings)
            return Response({'proctored_exam_settings': serializer.data})
    def test_validate_from_json_correct_inputs(self):
        is_valid, errors, test_model = CourseMetadata.validate_and_update_from_json(
            self.course,
            {
                "advertised_start": {"value": "start A"},
                "days_early_for_beta": {"value": 2},
                "advanced_modules": {"value": ['combinedopenended']},
            },
            user=self.user
        )
        self.assertTrue(is_valid)
        self.assertTrue(len(errors) == 0)
        self.update_check(test_model)

        # Tab gets tested in test_advanced_settings_munge_tabs
        self.assertIn('advanced_modules', test_model, 'Missing advanced_modules')
        self.assertEqual(test_model['advanced_modules']['value'], ['combinedopenended'], 'advanced_module is not updated')
Пример #10
0
    def test_validate_and_update_from_json_correct_inputs(self):
        is_valid, errors, test_model = CourseMetadata.validate_and_update_from_json(
            self.course,
            {
                "advertised_start": {"value": "start A"},
                "days_early_for_beta": {"value": 2},
                "advanced_modules": {"value": ["combinedopenended"]},
            },
            user=self.user,
        )
        self.assertTrue(is_valid)
        self.assertTrue(len(errors) == 0)
        self.update_check(test_model)

        # fresh fetch to ensure persistence
        fresh = modulestore().get_course(self.course.id)
        test_model = CourseMetadata.fetch(fresh)
        self.update_check(test_model)

        # Tab gets tested in test_advanced_settings_munge_tabs
        self.assertIn("advanced_modules", test_model, "Missing advanced_modules")
        self.assertEqual(
            test_model["advanced_modules"]["value"], ["combinedopenended"], "advanced_module is not updated"
        )
Пример #11
0
def custom_settings_handler(request, course_key_string):
    """
    Course settings configuration
    GET
        html: get the page
        json: get the model
    PUT, POST
        json: update the Course's settings. The payload is a json rep of the
            metadata dicts.
    """
    course_key = CourseKey.from_string(course_key_string)
    with modulestore().bulk_operations(course_key):
        course_module = get_course_and_check_access(course_key, request.user)
        if 'text/html' in request.META.get('HTTP_ACCEPT',
                                           '') and request.method == 'GET':

            return render_to_response(
                'custom_settings.html', {
                    'context_course':
                    course_module,
                    'is_new':
                    course_module.is_new,
                    'invitation_only':
                    course_module.invitation_only,
                    'visible_to_manager_only':
                    course_module.visible_to_manager_only,
                })
        elif 'application/json' in request.META.get('HTTP_ACCEPT', ''):
            if request.method == 'GET':
                return JsonResponse(CourseMetadata.fetch(course_module))
            else:
                try:
                    # validate data formats and update the course module.
                    # Note: don't update mongo yet, but wait until after any tabs are changed
                    is_valid, errors, updated_data = CourseMetadata.validate_and_update_from_json(
                        course_module,
                        request.json,
                        user=request.user,
                    )

                    if is_valid:
                        try:
                            additional_info = {
                                'is_new':
                                request.POST.get('is_new', False),
                                'invitation_only':
                                request.POST.get('invitation_only', False),
                                'visible_to_manager_only':
                                request.POST.get('visible_to_manager_only',
                                                 False)
                            }
                            CourseMetadata.update_from_dict(
                                additional_info, course_module, request.user)
                            course_search_index_handler(
                                request, course_key_string)
                        except InvalidTabsException as err:
                            log.exception(err.message)
                            response_message = [{
                                'message':
                                _('An error occurred while trying to save your tabs'
                                  ),
                                'model': {
                                    'display_name': _('Tabs Exception')
                                }
                            }]
                            return JsonResponseBadRequest(response_message)

                        return JsonResponse(updated_data)
                    else:
                        return JsonResponseBadRequest(errors)

                # Handle all errors that validation doesn't catch
                except (TypeError, ValueError, InvalidTabsException) as err:
                    return HttpResponseBadRequest(django.utils.html.escape(
                        err.message),
                                                  content_type="text/plain")