Exemplo n.º 1
0
    def validate(self):
        """Validates StateAnswers domain object entity."""

        if not isinstance(self.exploration_id, basestring):
            raise utils.ValidationError(
                'Expected exploration_id to be a string, received %s' %
                str(self.exploration_id))

        if not isinstance(self.state_name, basestring):
            raise utils.ValidationError(
                'Expected state_name to be a string, received %s' %
                str(self.state_name))

        if self.interaction_id is not None:
            if not isinstance(self.interaction_id, basestring):
                raise utils.ValidationError(
                    'Expected interaction_id to be a string, received %s' %
                    str(self.interaction_id))

            # Verify interaction_id is valid.
            if (self.interaction_id not in
                    interaction_registry.Registry.get_all_interaction_ids()):
                raise utils.ValidationError('Unknown interaction_id: %s' %
                                            self.interaction_id)

        if not isinstance(self.submitted_answer_list, list):
            raise utils.ValidationError(
                'Expected submitted_answer_list to be a list, received %s' %
                str(self.submitted_answer_list))

        if not isinstance(self.schema_version, int):
            raise utils.ValidationError(
                'Expected schema_version to be an integer, received %s' %
                str(self.schema_version))

        if self.schema_version < 1:
            raise utils.ValidationError('schema_version < 1: %d' %
                                        self.schema_version)

        if self.schema_version > feconf.CURRENT_STATE_ANSWERS_SCHEMA_VERSION:
            raise utils.ValidationError(
                'schema_version > feconf.CURRENT_STATE_ANSWERS_SCHEMA_VERSION '
                '(%d): %d' % (feconf.CURRENT_STATE_ANSWERS_SCHEMA_VERSION,
                              self.schema_version))
Exemplo n.º 2
0
    def validate(self):
        """Validates different attributes of the class."""
        if not isinstance(self.can_review_translation_for_language_codes,
                          list):
            raise utils.ValidationError(
                'Expected can_review_translation_for_language_codes to be a '
                'list, found: %s' %
                type(self.can_review_translation_for_language_codes))
        for language_code in self.can_review_translation_for_language_codes:
            if not utils.is_supported_audio_language_code(language_code):
                raise utils.ValidationError('Invalid language_code: %s' %
                                            (language_code))
        if len(self.can_review_translation_for_language_codes) != len(
                set(self.can_review_translation_for_language_codes)):
            raise utils.ValidationError(
                'Expected can_review_translation_for_language_codes list not '
                'to have duplicate values, found: %s' %
                (self.can_review_translation_for_language_codes))

        if not isinstance(self.can_review_voiceover_for_language_codes, list):
            raise utils.ValidationError(
                'Expected can_review_voiceover_for_language_codes to be a '
                'list, found: %s' %
                type(self.can_review_voiceover_for_language_codes))
        for language_code in self.can_review_voiceover_for_language_codes:
            if not utils.is_supported_audio_language_code(language_code):
                raise utils.ValidationError('Invalid language_code: %s' %
                                            (language_code))
        if len(self.can_review_voiceover_for_language_codes) != len(
                set(self.can_review_voiceover_for_language_codes)):
            raise utils.ValidationError(
                'Expected can_review_voiceover_for_language_codes list not to '
                'have duplicate values, found: %s' %
                (self.can_review_voiceover_for_language_codes))

        if not isinstance(self.can_review_questions, bool):
            raise utils.ValidationError(
                'Expected can_review_questions to be a boolean value, '
                'found: %s' % type(self.can_review_questions))

        if not isinstance(self.can_submit_questions, bool):
            raise utils.ValidationError(
                'Expected can_submit_questions to be a boolean value, '
                'found: %s' % type(self.can_submit_questions))
Exemplo n.º 3
0
def does_topic_with_url_fragment_exist(url_fragment):
    """Checks if topic with provided url fragment exists.

    Args:
        url_fragment: str. The url fragment for the topic.

    Returns:
        bool. Whether the the url fragment for the topic exists.

    Raises:
        Exception. Topic URL fragment is not a string.
    """
    if not isinstance(url_fragment, python_utils.BASESTRING):
        raise utils.ValidationError('Topic URL fragment should be a string.')
    existing_topic = (
        topic_fetchers.get_topic_by_url_fragment(url_fragment))
    return existing_topic is not None
Exemplo n.º 4
0
def does_blog_post_with_url_fragment_exist(url_fragment):
    """Checks if blog post with provided url fragment exists.

    Args:
        url_fragment: str. The url fragment for the blog post.

    Returns:
        bool. Whether the the url fragment for the blog post exists.

    Raises:
        Exception. Blog Post URL fragment is not a string.
    """
    if not isinstance(url_fragment, python_utils.BASESTRING):
        raise utils.ValidationError(
            'Blog Post URL fragment should be a string. Recieved:'
            '%s' % url_fragment)
    existing_blog_post = get_blog_post_by_url_fragment(url_fragment)
    return existing_blog_post is not None
Exemplo n.º 5
0
    def validate(self):
        """Validates properties of the MachineTranslatedText.

        Raises:
            ValidationError. One or more attributes of the MachineTranslatedText
                are invalid.
        """
        if not isinstance(self.source_language_code, python_utils.BASESTRING):
            raise utils.ValidationError(
                'Expected source_language_code to be a string, received %s' %
                self.source_language_code)
        # TODO(#12341): Tidy up this logic once we have a canonical list of
        # language codes.
        if not utils.is_supported_audio_language_code(
                self.source_language_code
        ) and not utils.is_valid_language_code(self.source_language_code):
            raise utils.ValidationError('Invalid source language code: %s' %
                                        self.source_language_code)

        if not isinstance(self.target_language_code, python_utils.BASESTRING):
            raise utils.ValidationError(
                'Expected target_language_code to be a string, received %s' %
                self.target_language_code)
        # TODO(#12341): Tidy up this logic once we have a canonical list of
        # language codes.
        if not utils.is_supported_audio_language_code(
                self.target_language_code
        ) and not utils.is_valid_language_code(self.target_language_code):
            raise utils.ValidationError('Invalid target language code: %s' %
                                        self.target_language_code)

        if self.source_language_code is self.target_language_code:
            raise utils.ValidationError(
                ('Expected source_language_code to be different from '
                 'target_language_code: "%s" = "%s"') %
                (self.source_language_code, self.target_language_code))

        if not isinstance(self.source_text, python_utils.BASESTRING):
            raise utils.ValidationError(
                'Expected source_text to be a string, received %s' %
                self.source_text)

        if not isinstance(self.translated_text, python_utils.BASESTRING):
            raise utils.ValidationError(
                'Expected translated_text to be a string, received %s' %
                self.translated_text)
Exemplo n.º 6
0
    def validate(self):
        """Validates the SubtopicPageContentsObject, verifying that all
        fields are of the correct type.
        """
        self.subtitled_html.validate()

        # TODO(tjiang11): Extract content ids to audio translations out into
        # its own object to reuse throughout audio-capable structures.
        if not isinstance(self.content_ids_to_audio_translations, dict):
            raise utils.ValidationError(
                'Expected content_ids_to_audio_translations to be a dict,'
                'received %s' % self.content_ids_to_audio_translations)
        for (content_id, audio_translations) in (
                self.content_ids_to_audio_translations.iteritems()):

            if not isinstance(content_id, basestring):
                raise utils.ValidationError(
                    'Expected content_id to be a string, received: %s' %
                    content_id)
            if not isinstance(audio_translations, dict):
                raise utils.ValidationError(
                    'Expected audio_translations to be a dict, received %s'
                    % audio_translations)

            allowed_audio_language_codes = [
                language['id'] for language in (
                    constants.SUPPORTED_AUDIO_LANGUAGES)]
            for language_code, translation in audio_translations.iteritems():
                if not isinstance(language_code, basestring):
                    raise utils.ValidationError(
                        'Expected language code to be a string, received: %s' %
                        language_code)

                if language_code not in allowed_audio_language_codes:
                    raise utils.ValidationError(
                        'Unrecognized language code: %s' % language_code)

                translation.validate()

        content_ids = set([self.subtitled_html.content_id])

        audio_content_ids = set(
            [audio[0] for audio
             in self.content_ids_to_audio_translations.iteritems()])
        for c in audio_content_ids:
            if c not in content_ids:
                raise utils.ValidationError(
                    'Expected content_ids_to_audio_translations to contain '
                    'only content_ids in the subtopic page. '
                    'content_ids_to_audio_translations: %s. '
                    'content IDs found: %s' % (audio_content_ids, content_ids))
Exemplo n.º 7
0
    def validate(self):
        """Validates various properties of the story object.

        Raises:
            ValidationError: One or more attributes of story are invalid.
        """
        self.require_valid_title(self.title)

        if not isinstance(self.description, python_utils.BASESTRING):
            raise utils.ValidationError(
                'Expected description to be a string, received %s'
                % self.description)

        if not isinstance(self.notes, python_utils.BASESTRING):
            raise utils.ValidationError(
                'Expected notes to be a string, received %s' % self.notes)

        if not isinstance(self.story_contents_schema_version, int):
            raise utils.ValidationError(
                'Expected story contents schema version to be an integer, '
                'received %s' % self.story_contents_schema_version)

        if (self.story_contents_schema_version !=
                feconf.CURRENT_STORY_CONTENTS_SCHEMA_VERSION):
            raise utils.ValidationError(
                'Expected story contents schema version to be %s, '
                'received %s' % (
                    feconf.CURRENT_STORY_CONTENTS_SCHEMA_VERSION,
                    self.story_contents_schema_version))

        if not isinstance(self.language_code, python_utils.BASESTRING):
            raise utils.ValidationError(
                'Expected language code to be a string, received %s' %
                self.language_code)

        if not utils.is_valid_language_code(self.language_code):
            raise utils.ValidationError(
                'Invalid language code: %s' % self.language_code)

        if not isinstance(
                self.corresponding_topic_id, python_utils.BASESTRING):
            raise utils.ValidationError(
                'Expected corresponding_topic_id should be a string, received: '
                '%s' % self.corresponding_topic_id)

        self.story_contents.validate()
Exemplo n.º 8
0
    def validate(self):
        """Validates various properties of the Skill Summary object.

        Raises:
            ValidationError: One or more attributes of skill summary are
                invalid.
        """
        if not isinstance(self.description, python_utils.BASESTRING):
            raise utils.ValidationError('Description should be a string.')

        if self.description == '':
            raise utils.ValidationError(
                'Description field should not be empty')

        if not isinstance(self.language_code, python_utils.BASESTRING):
            raise utils.ValidationError(
                'Expected language code to be a string, received %s' %
                self.language_code)
        if not utils.is_valid_language_code(self.language_code):
            raise utils.ValidationError('Invalid language code: %s' %
                                        self.language_code)

        if not isinstance(self.misconception_count, int):
            raise utils.ValidationError(
                'Expected misconception_count to be an int, '
                'received \'%s\'' % self.misconception_count)

        if self.misconception_count < 0:
            raise utils.ValidationError(
                'Expected misconception_count to be non-negative, '
                'received \'%s\'' % self.misconception_count)

        if not isinstance(self.worked_examples_count, int):
            raise utils.ValidationError(
                'Expected worked_examples_count to be an int, '
                'received \'%s\'' % self.worked_examples_count)

        if self.worked_examples_count < 0:
            raise utils.ValidationError(
                'Expected worked_examples_count to be non-negative, '
                'received \'%s\'' % self.worked_examples_count)
Exemplo n.º 9
0
    def validate(self):
        """Validates the PlatformParameterFilter domain object."""
        if self._type not in self.SUPPORTED_FILTER_TYPES:
            raise utils.ValidationError(
                'Unsupported filter type \'%s\'' % self._type)

        for op, _ in self._conditions:
            if op not in self.SUPPORTED_OP_FOR_FILTERS[self._type]:
                raise utils.ValidationError(
                    'Unsupported comparison operator \'%s\' for %s filter, '
                    'expected one of %s.' % (
                        op, self._type,
                        self.SUPPORTED_OP_FOR_FILTERS[self._type]))

        if self._type == 'server_mode':
            for _, mode in self._conditions:
                if mode not in ALLOWED_SERVER_MODES:
                    raise utils.ValidationError(
                        'Invalid server mode \'%s\', must be one of %s.' % (
                            mode, ALLOWED_SERVER_MODES))
        elif self._type == 'user_locale':
            for _, locale in self._conditions:
                if locale not in ALLOWED_USER_LOCALES:
                    raise utils.ValidationError(
                        'Invalid user locale \'%s\', must be one of %s.' % (
                            locale, ALLOWED_USER_LOCALES))
        elif self._type == 'client_type':
            for _, client_type in self._conditions:
                if client_type not in ALLOWED_CLIENT_TYPES:
                    raise utils.ValidationError(
                        'Invalid client type \'%s\', must be one of %s.' % (
                            client_type, ALLOWED_CLIENT_TYPES))
        elif self._type == 'app_version_flavor':
            for _, flavor in self._conditions:
                if flavor not in ALLOWED_APP_VERSION_FLAVOR:
                    raise utils.ValidationError(
                        'Invalid app version flavor \'%s\', must be one of'
                        ' %s.' % (flavor, ALLOWED_APP_VERSION_FLAVOR))
        elif self._type == 'app_version':
            for _, version in self._conditions:
                if not APP_VERSION_WITHOUT_HASH_REGEXP.match(version):
                    raise utils.ValidationError(
                        'Invalid version expression \'%s\', expected to match'
                        'regexp %s.' % (
                            version, APP_VERSION_WITHOUT_HASH_REGEXP))
Exemplo n.º 10
0
    def validate(self):
        """Validates a suggestion object of type SuggestionAddQuestion.

        Raises:
            ValidationError: One or more attributes of the SuggestionAddQuestion
                object are invalid.
        """
        super(SuggestionAddQuestion, self).validate()

        if self.get_score_type() != suggestion_models.SCORE_TYPE_QUESTION:
            raise utils.ValidationError(
                'Expected the first part of score_category to be "%s" '
                ', received "%s"' % (
                    suggestion_models.SCORE_TYPE_QUESTION,
                    self.get_score_type()))
        if not isinstance(self.change, question_domain.QuestionChange):
            raise utils.ValidationError(
                'Expected change to be an instance of QuestionChange')

        if not self.change.cmd:
            raise utils.ValidationError('Expected change to contain cmd')

        if (
                self.change.cmd !=
                question_domain.CMD_CREATE_NEW_FULLY_SPECIFIED_QUESTION):
            raise utils.ValidationError('Expected cmd to be %s, obtained %s' % (
                question_domain.CMD_CREATE_NEW_FULLY_SPECIFIED_QUESTION,
                self.change.cmd))

        if not self.change.question_dict:
            raise utils.ValidationError(
                'Expected change to contain question_dict')

        question = question_domain.Question(
            None, state_domain.State.from_dict(
                self.change.question_dict['question_state_data']),
            self.change.question_dict['question_state_data_schema_version'],
            self.change.question_dict['language_code'], None,
            self.change.question_dict['linked_skill_ids'])
        question.partial_validate()
        question_state_data_schema_version = (
            self.change.question_dict['question_state_data_schema_version'])
        if not (
                question_state_data_schema_version >= 1 and
                question_state_data_schema_version <=
                feconf.CURRENT_STATE_SCHEMA_VERSION):
            raise utils.ValidationError(
                'Expected question state schema version to be between 1 and '
                '%s' % feconf.CURRENT_STATE_SCHEMA_VERSION)
Exemplo n.º 11
0
    def accept(self, unused_commit_message):
        """Accepts the suggestion.

        Args:
            unused_commit_message: str. This parameter is passed in for
                consistency with the existing suggestions. As a default commit
                message is used in the add_question function, the arg is unused.
        """
        question_dict = self.change.question_dict
        question_dict['version'] = 1
        question_dict['id'] = (question_services.get_new_question_id())
        question = question_domain.Question.from_dict(question_dict)
        question.validate()
        question_services.add_question(self.author_id, question)
        skill = skill_services.get_skill_by_id(self.change.skill_id,
                                               strict=False)
        if skill is None:
            raise utils.ValidationError(
                'The skill with the given id doesn\'t exist.')
        question_services.create_new_question_skill_link(
            question_dict['id'], self.change.skill_id)
Exemplo n.º 12
0
    def validate(self):
        """Validates various properties of the story object.

        Raises:
            ValidationError: One or more attributes of story are invalid.
        """
        if not isinstance(self.title, basestring):
            raise utils.ValidationError(
                'Expected title to be a string, received %s' % self.title)

        if not isinstance(self.description, basestring):
            raise utils.ValidationError(
                'Expected description to be a string, received %s' %
                self.description)

        if not isinstance(self.notes, basestring):
            raise utils.ValidationError(
                'Expected notes to be a string, received %s' % self.notes)

        if not isinstance(self.schema_version, int):
            raise utils.ValidationError(
                'Expected schema version to be an integer, received %s' %
                self.schema_version)

        if self.schema_version != feconf.CURRENT_STORY_CONTENTS_SCHEMA_VERSION:
            raise utils.ValidationError(
                'Expected schema version to be %s, received %s' %
                (feconf.CURRENT_STORY_CONTENTS_SCHEMA_VERSION,
                 self.schema_version))

        if not isinstance(self.language_code, basestring):
            raise utils.ValidationError(
                'Expected language code to be a string, received %s' %
                self.language_code)

        if not any([
                self.language_code == lc['code']
                for lc in constants.ALL_LANGUAGE_CODES
        ]):
            raise utils.ValidationError('Invalid language code: %s' %
                                        self.language_code)

        self.story_contents.validate()
Exemplo n.º 13
0
    def validate(self):
        """Validates the classifier before it is saved to storage."""

        if not isinstance(self.id, basestring):
            raise utils.ValidationError(
                'Expected id to be a string, received %s' % self.id)

        if not isinstance(self.exp_id, basestring):
            raise utils.ValidationError(
                'Expected exp_id to be a string, received %s' % self.exp_id)

        if not isinstance(self.exp_version_when_created, int):
            raise utils.ValidationError(
                'Expected exp_version_when_created to be an int, received %s' %
                self.exp_version_when_created)

        if not isinstance(self.state_name, basestring):
            raise utils.ValidationError(
                'Expected id to be a string, received %s' % self.state_name)
        utils.require_valid_name(self.state_name, 'the state name')

        if not isinstance(self.algorithm_id, basestring):
            raise utils.ValidationError(
                'Expected algorithm_id to be a string, received %s' %
                self.algorithm_id)
        utils.require_valid_name(self.algorithm_id, 'the algorithm id')
        algorithm_ids = [
            classifier_details['algorithm_id'] for classifier_details in
            feconf.INTERACTION_CLASSIFIER_MAPPING.values()
        ]
        if self.algorithm_id not in algorithm_ids:
            raise utils.ValidationError('Invalid algorithm id: %s' %
                                        self.algorithm_id)

        if not isinstance(self.classifier_data, dict):
            raise utils.ValidationError(
                'Expected classifier_data to be a dict, received %s' %
                (self.classifier_data))
        classifier_class = (
            classifier_registry.Registry.get_classifier_by_algorithm_id(
                self.algorithm_id))
        classifier_class.validate(self.classifier_data)
Exemplo n.º 14
0
def update_blog_post(blog_post_id, change_dict):
    """Updates the blog post and its summary model in the datastore.

    Args:
        blog_post_id: str. The ID of the blog post which is to be updated.
        change_dict: dict. A dict containing all the changes keyed by
            corresponding field name (title, content, thumbnail_filename,
            tags).
    """
    updated_blog_post = apply_change_dict(blog_post_id, change_dict)
    if 'title' in change_dict:
        blog_post_models = blog_models.BlogPostModel.query().filter(
            blog_models.BlogPostModel.title == updated_blog_post.title).filter(
                blog_models.BlogPostModel.deleted == False).fetch()  # pylint: disable=singleton-comparison
        if blog_post_models != []:
            raise utils.ValidationError(
                'Blog Post with given title already exists: %s' %
                updated_blog_post.title)

    _save_blog_post(updated_blog_post)
    updated_blog_post_summary = compute_summary_of_blog_post(updated_blog_post)
    _save_blog_post_summary(updated_blog_post_summary)
Exemplo n.º 15
0
    def validate(self):
        """Validates a visualization object.

        This is only used in tests for the validity of interactions.
        """
        # Check that the calculation id exists.
        calculation_registry.Registry.get_calculation_by_id(
            self.calculation_id)

        # Check that the options_dict is valid.
        expected_option_names = sorted(
            [spec['name'] for spec in self._OPTIONS_SPECS])
        actual_option_names = sorted(self.options.keys())
        if actual_option_names != expected_option_names:
            raise utils.ValidationError(
                'For visualization %s, expected option names %s; received '
                'names %s' %
                (self.id, expected_option_names, actual_option_names))

        # Check that the schemas are correct.
        for spec in self._OPTIONS_SPECS:
            schema_utils.normalize_against_schema(self.options[spec['name']],
                                                  spec['schema'])
Exemplo n.º 16
0
    def validate(self):
        """Validates the Question domain object before it is saved."""

        if not isinstance(self.question_id, basestring):
            raise utils.ValidationError(
                'Expected ID to be a string, received %s' % self.question_id)

        if not isinstance(self.title, basestring):
            raise utils.ValidationError(
                'Expected title to be a string, received %s' % self.title)

        if not isinstance(self.question_data, dict):
            raise utils.ValidationError(
                'Expected question_data to be a dict, received %s' %
                self.question_data)
        question_data = exp_domain.State.from_dict(self.question_data)
        question_data.validate(None, True)

        if not isinstance(self.question_data_schema_version, int):
            raise utils.ValidationError(
                'Expected question_data_schema_version to be a integer,' +
                'received %s' % self.question_data_schema_version)

        if not isinstance(self.collection_id, basestring):
            raise utils.ValidationError(
                'Expected collection_id to be a string, received %s' %
                self.collection_id)

        if not isinstance(self.language_code, basestring):
            raise utils.ValidationError(
                'Expected language_code to be a string, received %s' %
                self.language_code)

        if not any([
                self.language_code == lc['code']
                for lc in constants.ALL_LANGUAGE_CODES
        ]):
            raise utils.ValidationError('Invalid language code: %s' %
                                        self.language_code)
Exemplo n.º 17
0
    def validate(cls, value_dict):
        """Validates customization args for a rich text component.

        Raises:
            TypeError. If any customization arg is invalid.
        """
        arg_names_to_obj_classes = {}
        customization_arg_specs = cls.rich_text_component_specs[
            cls.__name__]['customization_arg_specs']
        for customization_arg_spec in customization_arg_specs:
            arg_name = '%s-with-value' % customization_arg_spec['name']
            schema = customization_arg_spec['schema']
            if schema['type'] != 'custom':
                obj_type = schema['type']
            else:
                obj_type = schema['obj_type']
            obj_class = cls.obj_types_to_obj_classes[obj_type]
            arg_names_to_obj_classes[arg_name] = obj_class

        required_attr_names = list(arg_names_to_obj_classes.keys())
        attr_names = list(value_dict.keys())

        if set(attr_names) != set(required_attr_names):
            missing_attr_names = list(
                set(required_attr_names) - set(attr_names))
            extra_attr_names = list(set(attr_names) - set(required_attr_names))
            raise utils.ValidationError(
                'Missing attributes: %s, Extra attributes: %s' % (
                    ', '.join(missing_attr_names),
                    ', '.join(extra_attr_names)
                )
            )

        for arg_name in required_attr_names:
            arg_obj_class = arg_names_to_obj_classes[arg_name]
            arg_obj_class.normalize(value_dict[arg_name])
Exemplo n.º 18
0
    def validate(self):
        """Validates the CommunityContributionStats object.

        Raises:
            ValidationError. One or more attributes of the
                CommunityContributionStats object is invalid.
        """
        for language_code, reviewer_count in (
                self.translation_reviewer_counts_by_lang_code.items()):
            if reviewer_count < 0:
                raise utils.ValidationError(
                    'Expected the translation reviewer count to be '
                    'non-negative for %s language code, recieved: %s.' %
                    (language_code, reviewer_count))
            # Translation languages are a part of audio languages.
            if not utils.is_supported_audio_language_code(language_code):
                raise utils.ValidationError(
                    'Invalid language code for the translation reviewer '
                    'counts: %s.' % language_code)

        for language_code, suggestion_count in (
                self.translation_suggestion_counts_by_lang_code.items()):
            if suggestion_count < 0:
                raise utils.ValidationError(
                    'Expected the translation suggestion count to be '
                    'non-negative for %s language code, recieved: %s.' %
                    (language_code, suggestion_count))
            # Translation languages are a part of audio languages.
            if not utils.is_supported_audio_language_code(language_code):
                raise utils.ValidationError(
                    'Invalid language code for the translation suggestion '
                    'counts: %s.' % language_code)

        if self.question_reviewer_count < 0:
            raise utils.ValidationError(
                'Expected the question reviewer count to be non-negative, '
                'recieved: %s.' % (self.question_reviewer_count))

        if self.question_suggestion_count < 0:
            raise utils.ValidationError(
                'Expected the question suggestion count to be non-negative, '
                'recieved: %s.' % (self.question_suggestion_count))
Exemplo n.º 19
0
    def validate(self):
        """Validates the PlatformParameterFilter domain object."""
        if self._type not in self.SUPPORTED_FILTER_TYPES:
            raise utils.ValidationError('Unsupported filter type \'%s\'' %
                                        self._type)

        for op, _ in self._conditions:
            if op not in self.SUPPORTED_OP_FOR_FILTERS[self._type]:
                raise utils.ValidationError(
                    'Unsupported comparison operator \'%s\' for %s filter, '
                    'expected one of %s.' %
                    (op, self._type,
                     self.SUPPORTED_OP_FOR_FILTERS[self._type]))

        if self._type == 'server_mode':
            for _, mode in self._conditions:
                if not any([
                        mode == server_mode.value
                        for server_mode in ALLOWED_SERVER_MODES
                ]):
                    raise utils.ValidationError(
                        'Invalid server mode \'%s\', must be one of %s.' %
                        (mode, ALLOWED_SERVER_MODES))
        elif self._type == 'platform_type':
            for _, platform_type in self._conditions:
                if platform_type not in ALLOWED_PLATFORM_TYPES:
                    raise utils.ValidationError(
                        'Invalid platform type \'%s\', must be one of %s.' %
                        (platform_type, ALLOWED_PLATFORM_TYPES))
        elif self._type == 'app_version_flavor':
            for _, flavor in self._conditions:
                if flavor not in ALLOWED_APP_VERSION_FLAVORS:
                    raise utils.ValidationError(
                        'Invalid app version flavor \'%s\', must be one of'
                        ' %s.' % (flavor, ALLOWED_APP_VERSION_FLAVORS))
        elif self._type == 'app_version':
            for _, version in self._conditions:
                if not APP_VERSION_WITHOUT_HASH_REGEXP.match(version):
                    raise utils.ValidationError(
                        'Invalid version expression \'%s\', expected to match'
                        'regexp %s.' %
                        (version, APP_VERSION_WITHOUT_HASH_REGEXP))
Exemplo n.º 20
0
    def validate(self):
        """Validates various properties of the story summary object.

        Raises:
            ValidationError: One or more attributes of story summary are
                invalid.
        """
        if not isinstance(self.title, python_utils.BASESTRING):
            raise utils.ValidationError(
                'Expected title to be a string, received %s' % self.title)

        if self.title == '':
            raise utils.ValidationError('Title field should not be empty')

        if not isinstance(self.description, python_utils.BASESTRING):
            raise utils.ValidationError(
                'Expected description to be a string, received %s' %
                self.description)

        if not isinstance(self.node_count, int):
            raise utils.ValidationError(
                'Expected node_count to be an int, received \'%s\'' %
                (self.node_count))

        if self.node_count < 0:
            raise utils.ValidationError(
                'Expected node_count to be non-negative, received \'%s\'' %
                (self.node_count))

        if not isinstance(self.language_code, python_utils.BASESTRING):
            raise utils.ValidationError(
                'Expected language code to be a string, received %s' %
                self.language_code)

        if not utils.is_valid_language_code(self.language_code):
            raise utils.ValidationError('Invalid language code: %s' %
                                        self.language_code)
Exemplo n.º 21
0
    def validate(self):
        """Validates various properties of the SubtopicPage object.

        Raises:
            ValidationError. One or more attributes of the subtopic page are
                invalid.
        """
        if not isinstance(self.topic_id, python_utils.BASESTRING):
            raise utils.ValidationError(
                'Expected topic_id to be a string, received %s' %
                self.topic_id)
        if not isinstance(self.version, int):
            raise utils.ValidationError(
                'Expected version number to be an int, received %s' %
                self.version)
        self.page_contents.validate()

        if not isinstance(self.page_contents_schema_version, int):
            raise utils.ValidationError(
                'Expected page contents schema version to be an integer, '
                'received %s' % self.page_contents_schema_version)
        if (
                self.page_contents_schema_version !=
                feconf.CURRENT_SUBTOPIC_PAGE_CONTENTS_SCHEMA_VERSION):
            raise utils.ValidationError(
                'Expected page contents schema version to be %s, received %s'
                % (
                    feconf.CURRENT_SUBTOPIC_PAGE_CONTENTS_SCHEMA_VERSION,
                    self.page_contents_schema_version)
            )

        if not isinstance(self.language_code, python_utils.BASESTRING):
            raise utils.ValidationError(
                'Expected language code to be a string, received %s' %
                self.language_code)
        if not any(
                self.language_code == lc['code']
                for lc in constants.SUPPORTED_CONTENT_LANGUAGES
        ):
            raise utils.ValidationError(
                'Invalid language code: %s' % self.language_code)
Exemplo n.º 22
0
    def validate(self):
        """Checks that user_id, created_exploration_ids and
        edited_exploration_ids fields of this UserContributions
        domain object are valid.

        Raises:
            ValidationError. The user_id is not str.
            ValidationError. The created_exploration_ids is not a list.
            ValidationError. The exploration_id in created_exploration_ids
                is not str.
            ValidationError. The edited_exploration_ids is not a list.
            ValidationError. The exploration_id in edited_exploration_ids
                is not str.
        """
        if not isinstance(self.user_id, python_utils.BASESTRING):
            raise utils.ValidationError(
                'Expected user_id to be a string, received %s' % self.user_id)
        if not self.user_id:
            raise utils.ValidationError('No user id specified.')

        if not isinstance(self.created_exploration_ids, list):
            raise utils.ValidationError(
                'Expected created_exploration_ids to be a list, received %s'
                % self.created_exploration_ids)
        for exploration_id in self.created_exploration_ids:
            if not isinstance(exploration_id, python_utils.BASESTRING):
                raise utils.ValidationError(
                    'Expected exploration_id in created_exploration_ids '
                    'to be a string, received %s' % (
                        exploration_id))

        if not isinstance(self.edited_exploration_ids, list):
            raise utils.ValidationError(
                'Expected edited_exploration_ids to be a list, received %s'
                % self.edited_exploration_ids)
        for exploration_id in self.edited_exploration_ids:
            if not isinstance(exploration_id, python_utils.BASESTRING):
                raise utils.ValidationError(
                    'Expected exploration_id in edited_exploration_ids '
                    'to be a string, received %s' % (
                        exploration_id))
Exemplo n.º 23
0
    def validate(self):
        """Validates a suggestion object of type SuggestionTranslateContent.

        Raises:
            ValidationError. One or more attributes of the
                SuggestionTranslateContent object are invalid.
        """
        super(SuggestionTranslateContent, self).validate()

        if not isinstance(self.change, exp_domain.ExplorationChange):
            raise utils.ValidationError(
                'Expected change to be an ExplorationChange, received %s' %
                type(self.change))
        # The score sub_type needs to match the validation for exploration
        # category, i.e the second part of the score_category should match
        # the target exploration's category and we have a prod validation
        # for the same.
        if self.get_score_type() != suggestion_models.SCORE_TYPE_TRANSLATION:
            raise utils.ValidationError(
                'Expected the first part of score_category to be %s '
                ', received %s' % (suggestion_models.SCORE_TYPE_TRANSLATION,
                                   self.get_score_type()))

        if self.change.cmd != exp_domain.CMD_ADD_TRANSLATION:
            raise utils.ValidationError(
                'Expected cmd to be %s, received %s' %
                (exp_domain.CMD_ADD_TRANSLATION, self.change.cmd))

        if not utils.is_supported_audio_language_code(
                self.change.language_code):
            raise utils.ValidationError('Invalid language_code: %s' %
                                        self.change.language_code)

        if self.language_code is None:
            raise utils.ValidationError('language_code cannot be None')

        if self.language_code != self.change.language_code:
            raise utils.ValidationError(
                'Expected language_code to be %s, received %s' %
                (self.change.language_code, self.language_code))
Exemplo n.º 24
0
    def validate(self):
        """Validates the Question summary domain object before it is saved.

        Raises:
            ValidationError. One or more attributes of question summary are
                invalid.
        """
        if not isinstance(self.id, python_utils.BASESTRING):
            raise utils.ValidationError(
                'Expected id to be a string, received %s' % self.id)

        if not isinstance(self.question_content, python_utils.BASESTRING):
            raise utils.ValidationError(
                'Expected question content to be a string, received %s' %
                self.question_content)

        if not isinstance(self.interaction_id, python_utils.BASESTRING):
            raise utils.ValidationError(
                'Expected interaction id to be a string, received %s' %
                self.interaction_id)

        if not isinstance(self.created_on, datetime.datetime):
            raise utils.ValidationError(
                'Expected created on to be a datetime, received %s' %
                self.created_on)

        if not isinstance(self.last_updated, datetime.datetime):
            raise utils.ValidationError(
                'Expected last updated to be a datetime, received %s' %
                self.last_updated)

        if not (isinstance(self.misconception_ids, list) and (
                all(isinstance(elem, python_utils.BASESTRING) for elem in (
                    self.misconception_ids)))):
            raise utils.ValidationError(
                'Expected misconception ids to be a list of '
                'strings, received %s' % self.misconception_ids)
Exemplo n.º 25
0
    def validate(self):
        """Validates the EvaluationContext domain object."""
        if self._client_type not in ALLOWED_CLIENT_TYPES:
            raise utils.ValidationError(
                'Invalid client type \'%s\', must be one of %s.' % (
                    self._client_type, ALLOWED_CLIENT_TYPES))

        if (
                self._browser_type is not None and
                self._browser_type not in ALLOWED_BROWSER_TYPES):
            raise utils.ValidationError(
                'Invalid browser type \'%s\', must be one of %s.' % (
                    self._browser_type, ALLOWED_BROWSER_TYPES))

        if self._app_version is not None:
            match = APP_VERSION_WITH_HASH_REGEXP.match(self._app_version)
            if match is None:
                raise utils.ValidationError(
                    'Invalid version \'%s\', expected to match regexp %s.' % (
                        self._app_version, APP_VERSION_WITH_HASH_REGEXP))
            elif (
                    match.group(2) is not None and
                    match.group(2) not in ALLOWED_APP_VERSION_FLAVOR):
                raise utils.ValidationError(
                    'Invalid version flavor \'%s\', must be one of %s if'
                    ' specified.' % (
                        match.group(2), ALLOWED_APP_VERSION_FLAVOR))

        if self._user_locale not in ALLOWED_USER_LOCALES:
            raise utils.ValidationError(
                'Invalid user locale \'%s\', must be one of %s.' % (
                    self._user_locale, ALLOWED_USER_LOCALES))

        if self._server_mode not in ALLOWED_SERVER_MODES:
            raise utils.ValidationError(
                'Invalid server mode \'%s\', must be one of %s.' % (
                    self._server_mode, ALLOWED_SERVER_MODES))
Exemplo n.º 26
0
    def validate(self):
        """Validates an ActivityRights object.

        Raises:
          utils.ValidationError: if any of the owners, editors and viewers
          lists overlap, or if a community-owned exploration has owners,
          editors or viewers specified.
        """
        if self.community_owned:
            if self.owner_ids or self.editor_ids or self.viewer_ids:
                raise utils.ValidationError(
                    'Community-owned explorations should have no owners, '
                    'editors or viewers specified.')

        if self.community_owned and self.status == ACTIVITY_STATUS_PRIVATE:
            raise utils.ValidationError(
                'Community-owned explorations cannot be private.')

        if self.status != ACTIVITY_STATUS_PRIVATE and self.viewer_ids:
            raise utils.ValidationError(
                'Public explorations should have no viewers specified.')

        owner_editor = set(self.owner_ids).intersection(set(self.editor_ids))
        owner_viewer = set(self.owner_ids).intersection(set(self.viewer_ids))
        editor_viewer = set(self.editor_ids).intersection(set(self.viewer_ids))
        if owner_editor:
            raise utils.ValidationError(
                'A user cannot be both an owner and an editor: %s' %
                owner_editor)
        if owner_viewer:
            raise utils.ValidationError(
                'A user cannot be both an owner and a viewer: %s' %
                owner_viewer)
        if editor_viewer:
            raise utils.ValidationError(
                'A user cannot be both an owner and an editor: %s' %
                editor_viewer)
Exemplo n.º 27
0
    def partial_validate(self):
        """Validates the Question domain object, but doesn't require the
        object to contain an ID and a version. To be used to validate the
        question before it is finalized.
        """

        if not isinstance(self.language_code, python_utils.BASESTRING):
            raise utils.ValidationError(
                'Expected language_code to be a string, received %s' %
                self.language_code)

        if not self.linked_skill_ids:
            raise utils.ValidationError(
                'linked_skill_ids is either null or an empty list')

        if not (isinstance(self.linked_skill_ids, list) and (all(
                isinstance(elem, python_utils.BASESTRING)
                for elem in (self.linked_skill_ids)))):
            raise utils.ValidationError(
                'Expected linked_skill_ids to be a list of strings, '
                'received %s' % self.linked_skill_ids)

        if len(set(self.linked_skill_ids)) != len(self.linked_skill_ids):
            raise utils.ValidationError(
                'linked_skill_ids has duplicate skill ids')

        if not isinstance(self.question_state_data_schema_version, int):
            raise utils.ValidationError(
                'Expected schema version to be an integer, received %s' %
                self.question_state_data_schema_version)

        if not isinstance(self.question_state_data, state_domain.State):
            raise utils.ValidationError(
                'Expected question state data to be a State object, '
                'received %s' % self.question_state_data)

        if not utils.is_valid_language_code(self.language_code):
            raise utils.ValidationError('Invalid language code: %s' %
                                        self.language_code)

        interaction_specs = interaction_registry.Registry.get_all_specs()
        at_least_one_correct_answer = False
        dest_is_specified = False
        interaction = self.question_state_data.interaction
        for answer_group in interaction.answer_groups:
            if answer_group.outcome.labelled_as_correct:
                at_least_one_correct_answer = True
            if answer_group.outcome.dest is not None:
                dest_is_specified = True

        if interaction.default_outcome.labelled_as_correct:
            at_least_one_correct_answer = True

        if interaction.default_outcome.dest is not None:
            dest_is_specified = True

        if not at_least_one_correct_answer:
            raise utils.ValidationError(
                'Expected at least one answer group to have a correct ' +
                'answer.')

        if dest_is_specified:
            raise utils.ValidationError(
                'Expected all answer groups to have destination as None.')

        if not interaction.hints:
            raise utils.ValidationError(
                'Expected the question to have at least one hint')

        if ((interaction.solution is None)
                and (interaction_specs[interaction.id]['can_have_solution'])):
            raise utils.ValidationError(
                'Expected the question to have a solution')
        self.question_state_data.validate({}, False)
Exemplo n.º 28
0
def _save_collection(committer_id, collection, commit_message, change_list):
    """Validates a collection and commits it to persistent storage. If
    successful, increments the version number of the incoming collection domain
    object by 1.

    Args:
        committer_id: str. ID of the given committer.
        collection: Collection. The collection domain object to be saved.
        commit_message: str. The commit message.
        change_list: list(dict). List of changes applied to a collection. Each
            entry in change_list is a dict that represents a CollectionChange.

    Raises:
        ValidationError: An invalid exploration was referenced in the
            collection.
        Exception: The collection model and the incoming collection domain
            object have different version numbers.
    """
    if not change_list:
        raise Exception(
            'Unexpected error: received an invalid change list when trying to '
            'save collection %s: %s' % (collection.id, change_list))

    collection_rights = rights_manager.get_collection_rights(collection.id)
    if collection_rights.status != rights_manager.ACTIVITY_STATUS_PRIVATE:
        collection.validate(strict=True)
    else:
        collection.validate(strict=False)

    # Validate that all explorations referenced by the collection exist.
    exp_ids = collection.exploration_ids
    exp_summaries = (
        exp_services.get_exploration_summaries_matching_ids(exp_ids))
    exp_summaries_dict = {
        exp_id: exp_summaries[ind]
        for (ind, exp_id) in enumerate(exp_ids)
    }
    for collection_node in collection.nodes:
        if not exp_summaries_dict[collection_node.exploration_id]:
            raise utils.ValidationError(
                'Expected collection to only reference valid explorations, '
                'but found an exploration with ID: %s (was it deleted?)' %
                collection_node.exploration_id)

    # Ensure no explorations are being added that are 'below' the public status
    # of this collection. If the collection is private, it can have both
    # private and public explorations. If it's public, it can only have public
    # explorations.
    # TODO(bhenning): Ensure the latter is enforced above when trying to
    # publish a collection.
    if rights_manager.is_collection_public(collection.id):
        validate_exps_in_collection_are_public(collection)

    collection_model = collection_models.CollectionModel.get(collection.id,
                                                             strict=False)
    if collection_model is None:
        collection_model = collection_models.CollectionModel(id=collection.id)
    else:
        if collection.version > collection_model.version:
            raise Exception(
                'Unexpected error: trying to update version %s of collection '
                'from version %s. Please reload the page and try again.' %
                (collection_model.version, collection.version))
        elif collection.version < collection_model.version:
            raise Exception(
                'Trying to update version %s of collection from version %s, '
                'which is too old. Please reload the page and try again.' %
                (collection_model.version, collection.version))

    collection_model.category = collection.category
    collection_model.title = collection.title
    collection_model.objective = collection.objective
    collection_model.language_code = collection.language_code
    collection_model.tags = collection.tags
    collection_model.schema_version = collection.schema_version
    collection_model.collection_contents = {
        'nodes':
        [collection_node.to_dict() for collection_node in collection.nodes],
        'skills': {
            skill_id: skill.to_dict()
            for skill_id, skill in collection.skills.iteritems()
        },
        'next_skill_index':
        collection.next_skill_index
    }
    collection_model.node_count = len(collection_model.nodes)
    collection_model.commit(committer_id, commit_message, change_list)
    memcache_services.delete(_get_collection_memcache_key(collection.id))
    index_collections_given_ids([collection.id])

    collection.version += 1
Exemplo n.º 29
0
def update_story(
        committer_id, story_id, change_list, commit_message):
    """Updates a story. Commits changes.

    # NOTE: This function should not be called on its own. Access it
    # through `topic_services.update_story_and_topic_summary`.

    Args:
        committer_id: str. The id of the user who is performing the update
            action.
        story_id: str. The story id.
        change_list: list(StoryChange). These changes are applied in sequence to
            produce the resulting story.
        commit_message: str or None. A description of changes made to the
            story.

    Raises:
        ValidationError. Exploration is already linked to a different story.
    """
    if not commit_message:
        raise ValueError('Expected a commit message but received none.')

    old_story = story_fetchers.get_story_by_id(story_id)
    new_story, exp_ids_removed_from_story, exp_ids_added_to_story = (
        apply_change_list(story_id, change_list))
    story_is_published = _is_story_published_and_present_in_topic(new_story)
    exploration_context_models_to_be_deleted = (
        exp_models.ExplorationContextModel.get_multi(
            exp_ids_removed_from_story))
    exploration_context_models_to_be_deleted = [
        model for model in exploration_context_models_to_be_deleted
        if model is not None]
    exploration_context_models_collisions_list = (
        exp_models.ExplorationContextModel.get_multi(
            exp_ids_added_to_story))
    for context_model in exploration_context_models_collisions_list:
        if context_model is not None and context_model.story_id != story_id:
            raise utils.ValidationError(
                'The exploration with ID %s is already linked to story '
                'with ID %s' % (context_model.id, context_model.story_id))

    if (
            old_story.url_fragment != new_story.url_fragment and
            does_story_exist_with_url_fragment(new_story.url_fragment)):
        raise utils.ValidationError(
            'Story Url Fragment is not unique across the site.')
    _save_story(
        committer_id, new_story, commit_message, change_list,
        story_is_published)
    create_story_summary(new_story.id)
    if story_is_published and _is_topic_published(new_story):
        opportunity_services.update_exploration_opportunities(
            old_story, new_story)
    suggestion_services.auto_reject_translation_suggestions_for_exp_ids(
        exp_ids_removed_from_story)

    exp_models.ExplorationContextModel.delete_multi(
        exploration_context_models_to_be_deleted)

    new_exploration_context_models = [exp_models.ExplorationContextModel(
        id=exp_id,
        story_id=story_id
    ) for exp_id in exp_ids_added_to_story]
    exp_models.ExplorationContextModel.update_timestamps_multi(
        new_exploration_context_models)
    exp_models.ExplorationContextModel.put_multi(new_exploration_context_models)
Exemplo n.º 30
0
def validate_explorations_for_story(exp_ids, strict):
    """Validates the explorations in the given story and checks whether they
    are compatible with the mobile app and ready for publishing.

    Args:
        exp_ids: list(str). The exp IDs to validate.
        strict: bool. Whether to raise an Exception when a validation error
            is encountered. If not, a list of the error messages are
            returned. strict should be True when this is called before
            saving the story and False when this function is called from the
            frontend.

    Returns:
        list(str). The various validation error messages (if strict is
        False).

    Raises:
        ValidationError. Expected story to only reference valid explorations.
        ValidationError. Exploration with ID is not public. Please publish
            explorations before adding them to a story.
        ValidationError. All explorations in a story should be of the same
            category.
    """
    validation_error_messages = []

    # Strict = False, since the existence of explorations is checked below.
    exps_dict = (
        exp_fetchers.get_multiple_explorations_by_id(exp_ids, strict=False))

    exp_rights = (
        rights_manager.get_multiple_exploration_rights_by_ids(exp_ids))

    exp_rights_dict = {}

    for rights in exp_rights:
        if rights is not None:
            exp_rights_dict[rights.id] = rights.status

    for exp_id in exp_ids:
        if exp_id not in exps_dict:
            error_string = (
                'Expected story to only reference valid explorations, but found'
                ' a reference to an invalid exploration with ID: %s'
                % exp_id)
            if strict:
                raise utils.ValidationError(error_string)
            validation_error_messages.append(error_string)
        else:
            if exp_rights_dict[exp_id] != constants.ACTIVITY_STATUS_PUBLIC:
                error_string = (
                    'Exploration with ID %s is not public. Please publish '
                    'explorations before adding them to a story.'
                    % exp_id)
                if strict:
                    raise utils.ValidationError(error_string)
                validation_error_messages.append(error_string)

    if exps_dict:
        for exp_id in exp_ids:
            if exp_id in exps_dict:
                sample_exp_id = exp_id
                break
        common_exp_category = exps_dict[sample_exp_id].category
        for exp_id in exps_dict:
            exp = exps_dict[exp_id]
            if exp.category != common_exp_category:
                error_string = (
                    'All explorations in a story should be of the '
                    'same category. The explorations with ID %s and %s have'
                    ' different categories.' % (sample_exp_id, exp_id))
                if strict:
                    raise utils.ValidationError(error_string)
                validation_error_messages.append(error_string)
            try:
                validation_error_messages.extend(
                    exp_services.validate_exploration_for_story(exp, strict))
            except Exception as e:
                logging.exception(
                    'Exploration validation failed for exploration with ID: '
                    '%s. Error: %s' % (exp_id, e))
                raise Exception(e)

    return validation_error_messages