Ejemplo n.º 1
0
    def test_delete(self):
        question_services.create_new_question_skill_link(
            self.question_id, self.skill_id)
        question_services.create_new_question_skill_link(
            self.question_id_2, self.skill_id)
        with self.swap(constants, 'ENABLE_NEW_STRUCTURE_EDITORS', True):
            self.login(self.NEW_USER_EMAIL)
            self.delete_json('%s/%s/%s' %
                             (feconf.QUESTION_SKILL_LINK_URL_PREFIX,
                              self.question_id, self.skill_id),
                             expected_status_int=401)
            self.logout()

            self.login(self.ADMIN_EMAIL)
            self.delete_json('%s/%s/%s' %
                             (feconf.QUESTION_SKILL_LINK_URL_PREFIX,
                              self.question_id, self.skill_id))
            question_summaries, _ = (
                question_services.get_question_summaries_linked_to_skills(
                    5, [self.skill_id], ''))
            self.assertEqual(len(question_summaries), 1)
            self.assertEqual(question_summaries[0].id, self.question_id_2)
            self.logout()

            self.login(self.TOPIC_MANAGER_EMAIL)
            self.delete_json('%s/%s/%s' %
                             (feconf.QUESTION_SKILL_LINK_URL_PREFIX,
                              self.question_id_2, self.skill_id))
            question_summaries, _ = (
                question_services.get_question_summaries_linked_to_skills(
                    5, [self.skill_id], ''))
            self.assertEqual(len(question_summaries), 0)
            self.logout()
Ejemplo n.º 2
0
 def test_linking_same_skill_to_question_twice(self):
     question_id_2 = question_services.get_new_question_id()
     self.save_new_question(question_id_2, self.editor_id,
                            self._create_valid_question_data('ABC'),
                            ['skill_1'])
     skill_ids = [
         skill.id for skill in
         question_services.get_skills_linked_to_question(question_id_2)
     ]
     self.assertEqual(len(skill_ids), 1)
     self.assertEqual(skill_ids[0], 'skill_1')
     question_services.create_new_question_skill_link(
         self.editor_id, question_id_2, 'skill_1', 0.3)
     skill_ids = [
         skill.id for skill in
         question_services.get_skills_linked_to_question(question_id_2)
     ]
     self.assertEqual(len(skill_ids), 1)
     self.assertEqual(skill_ids[0], 'skill_1')
     question_services.create_new_question_skill_link(
         self.editor_id, question_id_2, 'skill_2', 0.3)
     skill_ids = [
         skill.id for skill in
         question_services.get_skills_linked_to_question(question_id_2)
     ]
     self.assertEqual(len(skill_ids), 2)
     self.assertItemsEqual(skill_ids, ['skill_1', 'skill_2'])
Ejemplo n.º 3
0
    def setUp(self):
        super(SkillOpportunityModelValidatorTests, self).setUp()

        self.job_class = (
            prod_validation_jobs_one_off.SkillOpportunityModelAuditOneOffJob)

        self.signup(self.ADMIN_EMAIL, self.ADMIN_USERNAME)
        self.signup(self.OWNER_EMAIL, self.OWNER_USERNAME)

        self.admin_id = self.get_user_id_from_email(self.ADMIN_EMAIL)
        self.owner_id = self.get_user_id_from_email(self.OWNER_EMAIL)

        self.set_admins([self.ADMIN_USERNAME])
        self.admin = user_services.get_user_actions_info(self.admin_id)

        for i in python_utils.RANGE(3):
            skill_id = '%s' % i
            self.save_new_skill(skill_id,
                                self.admin_id,
                                description='description %d' % i)

        self.QUESTION_ID = question_services.get_new_question_id()
        self.save_new_question(self.QUESTION_ID, self.owner_id,
                               self._create_valid_question_data('ABC'), ['0'])
        question_services.create_new_question_skill_link(
            self.owner_id, self.QUESTION_ID, '0', 0.3)

        self.model_instance_0 = (
            opportunity_models.SkillOpportunityModel.get('0'))
        self.model_instance_1 = (
            opportunity_models.SkillOpportunityModel.get('1'))
        self.model_instance_2 = (
            opportunity_models.SkillOpportunityModel.get('2'))
Ejemplo n.º 4
0
    def _generate_dummy_skill_and_questions(self):
        """Generate and loads the database with a skill and 15 questions
        linked to the skill.

        Raises:
            Exception. Cannot load new structures data in production mode.
            Exception. User does not have enough rights to generate data.
        """
        if constants.DEV_MODE:
            if feconf.ROLE_ID_CURRICULUM_ADMIN not in self.user.roles:
                raise Exception(
                    'User does not have enough rights to generate data.')
            skill_id = skill_services.get_new_skill_id()
            skill_name = 'Dummy Skill %s' % python_utils.UNICODE(
                random.getrandbits(32))
            skill = self._create_dummy_skill(skill_id, skill_name,
                                             '<p>Dummy Explanation 1</p>')
            skill_services.save_new_skill(self.user_id, skill)
            for i in range(15):
                question_id = question_services.get_new_question_id()
                question_name = 'Question number %s %s' % (
                    python_utils.UNICODE(i), skill_name)
                question = self._create_dummy_question(question_id,
                                                       question_name,
                                                       [skill_id])
                question_services.add_question(self.user_id, question)
                question_difficulty = list(
                    constants.SKILL_DIFFICULTY_LABEL_TO_FLOAT.values())
                random_difficulty = random.choice(question_difficulty)
                question_services.create_new_question_skill_link(
                    self.user_id, question_id, skill_id, random_difficulty)
        else:
            raise Exception('Cannot generate dummy skills in production.')
Ejemplo n.º 5
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_dict['linked_skill_ids'] = [self.change.skill_id]
        question = question_domain.Question.from_dict(question_dict)
        question.validate()

        self._copy_new_images_to_target_entity_storage()

        question_services.add_question(self.author_id, question)

        skill = skill_fetchers.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(
            self.author_id, question_dict['id'], self.change.skill_id,
            self._get_skill_difficulty())
Ejemplo n.º 6
0
    def post(self, skill_id):
        """Handles POST requests."""
        if not constants.ENABLE_NEW_STRUCTURE_EDITORS:
            raise self.PageNotFoundException

        skill_domain.Skill.require_valid_skill_id(skill_id)
        skill = skill_services.get_skill_by_id(skill_id, strict=False)
        if skill is None:
            raise self.PageNotFoundException(
                'The skill with the given id doesn\'t exist.')

        question_dict = self.payload.get('question_dict')
        if ((question_dict['id'] is not None)
                or ('question_state_data' not in question_dict)
                or ('language_code' not in question_dict)
                or (question_dict['version'] != 1)):
            raise self.InvalidInputException

        question_dict['question_state_data_schema_version'] = (
            feconf.CURRENT_STATES_SCHEMA_VERSION)
        question_dict['id'] = question_services.get_new_question_id()
        try:
            question = question_domain.Question.from_dict(question_dict)
        except:
            raise self.InvalidInputException
        question_services.add_question(self.user_id, question)
        # TODO(vinitamurthi): Replace DEFAULT_SKILL_DIFFICULTY
        # with a value passed from the frontend.
        question_services.create_new_question_skill_link(
            question.id, skill_id, constants.DEFAULT_SKILL_DIFFICULTY)
        self.values.update({'question_id': question.id})
        self.render_json(self.values)
Ejemplo n.º 7
0
    def post(self, skill_id):
        """Handles POST requests."""
        if not feconf.ENABLE_NEW_STRUCTURES:
            raise self.PageNotFoundException

        skill_domain.Skill.require_valid_skill_id(skill_id)
        skill = skill_services.get_skill_by_id(skill_id, strict=False)
        if skill is None:
            raise self.PageNotFoundException(
                'The skill with the given id doesn\'t exist.')

        question_dict = self.payload.get('question_dict')
        if ((question_dict['id'] is not None)
                or ('question_state_data' not in question_dict)
                or ('language_code' not in question_dict)
                or (question_dict['version'] != 1)
                or (question_dict['question_state_schema_version'] !=
                    (feconf.CURRENT_STATES_SCHEMA_VERSION))):
            raise self.InvalidInputException

        question_dict['id'] = question_services.get_new_question_id()
        question = question_domain.Question.from_dict(question_dict)
        question_services.add_question(self.user_id, question)
        question_services.create_new_question_skill_link(question.id, skill_id)
        self.values.update({'question_id': question.id})
        self.render_json(self.values)
Ejemplo n.º 8
0
    def put(self, question_id):
        """Updates the QuestionSkillLink models with respect to the given
        question.
        """
        skill_ids_task_list = self.payload.get('skill_ids_task_list')
        if skill_ids_task_list is None:
            raise self.InvalidInputException(
                'Missing fields \'skill_ids_task_list\'in payload')

        for task_dict in skill_ids_task_list:
            if not 'id' in task_dict:
                raise self.InvalidInputException('Missing skill ID.')
            if task_dict['task'] == 'remove':
                question_services.delete_question_skill_link(
                    self.user_id, question_id, task_dict['id'])
            elif task_dict['task'] == 'add':
                question_services.create_new_question_skill_link(
                    self.user_id, question_id, task_dict['id'],
                    task_dict['difficulty'])
            elif task_dict['task'] == 'update_difficulty':
                question_services.update_question_skill_link_difficulty(
                    question_id, task_dict['id'],
                    float(task_dict['difficulty']))
            else:
                raise self.InvalidInputException('Invalid task.')

        self.render_json(self.values)
Ejemplo n.º 9
0
    def test_get_question_count_succeeds(self):
        self.login(self.ADMIN_EMAIL)
        question_id = question_services.get_new_question_id()
        question_id_1 = question_services.get_new_question_id()

        self.save_new_question(question_id, self.admin_id,
                               self._create_valid_question_data('ABC'),
                               [self.skill_id])

        self.save_new_question(question_id_1, self.admin_id,
                               self._create_valid_question_data('ABC2'),
                               [self.skill_id_2])

        question_services.create_new_question_skill_link(
            self.admin_id, question_id, self.skill_id, 0.5)
        question_services.create_new_question_skill_link(
            self.admin_id, question_id_1, self.skill_id_2, 0.3)

        json_response = self.get_json(
            '%s/%s,%s' %
            (feconf.QUESTION_COUNT_URL_PREFIX, self.skill_id, self.skill_id_2))
        self.assertEqual(json_response['total_question_count'], 2)

        json_response = self.get_json(
            '%s/%s' % (feconf.QUESTION_COUNT_URL_PREFIX, self.skill_id))
        self.assertEqual(json_response['total_question_count'], 1)

        json_response = self.get_json(
            '%s/%s' % (feconf.QUESTION_COUNT_URL_PREFIX, self.skill_id_2))
        self.assertEqual(json_response['total_question_count'], 1)
Ejemplo n.º 10
0
 def setUp(self):
     """Completes the setup for QuestionSkillLinkHandlerTest."""
     super(EditableQuestionDataHandlerTest, self).setUp()
     self.skill_id = skill_services.get_new_skill_id()
     self.save_new_skill(self.skill_id, self.admin_id, 'Skill Description')
     question_services.create_new_question_skill_link(
         self.question_id, self.skill_id)
Ejemplo 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())
        html_list = self.get_all_html_content_strings()
        filenames = (
            html_cleaner.get_image_filenames_from_html_strings(html_list))
        image_context = fs_services.get_image_context_for_suggestion_target(
            self.target_type)
        fs_services.copy_images(image_context, self.target_id,
                                feconf.ENTITY_TYPE_QUESTION, self.target_id,
                                filenames)

        question_dict['linked_skill_ids'] = [self.change.skill_id]
        question = question_domain.Question.from_dict(question_dict)
        question.validate()
        question_services.add_question(self.author_id, question)
        skill = skill_fetchers.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(
            self.author_id, question_dict['id'], self.change.skill_id,
            self._get_skill_difficulty())
Ejemplo n.º 12
0
 def test_get_questions_by_skill_ids(self):
     question_services.create_new_question_skill_link(
         self.question_id, 'skill_1')
     questions, _ = (
         question_services.get_questions_by_skill_ids(2, ['skill_1'], ''))
     self.assertEqual(len(questions), 1)
     self.assertEqual(questions[0].to_dict(), self.question.to_dict())
Ejemplo n.º 13
0
    def test_get_questions_succeeds(self):
        for _ in python_utils.RANGE(0, 4):
            question_id = question_services.get_new_question_id()
            self.save_new_question(question_id, self.admin_id,
                                   self._create_valid_question_data('ABC'),
                                   [self.skill_id, self.skill_id_2])
            question_services.create_new_question_skill_link(
                self.admin_id, question_id, self.skill_id, 0.5)
            question_services.create_new_question_skill_link(
                self.admin_id, question_id, self.skill_id_2, 0.3)

        self.login(self.ADMIN_EMAIL)
        with self.swap(constants, 'NUM_QUESTIONS_PER_PAGE', 2):
            json_response = self.get_json('%s/%s,%s?cursor=' %
                                          (feconf.QUESTIONS_LIST_URL_PREFIX,
                                           self.skill_id, self.skill_id_2))
            question_summary_dicts = json_response['question_summary_dicts']
            self.assertEqual(len(question_summary_dicts), 2)
            next_start_cursor = json_response['next_start_cursor']
            json_response = self.get_json(
                '%s/%s,%s?cursor=%s' %
                (feconf.QUESTIONS_LIST_URL_PREFIX, self.skill_id,
                 self.skill_id_2, next_start_cursor))
            question_summary_dicts_2 = (
                json_response['question_summary_dicts'])
            self.assertEqual(len(question_summary_dicts_2), 2)
            for i in python_utils.RANGE(0, 2):
                self.assertEqual(
                    question_summary_dicts[i]['skill_descriptions'],
                    ['Skill Description 2', 'Skill Description'])
                self.assertEqual(
                    question_summary_dicts_2[i]['skill_descriptions'],
                    ['Skill Description 2', 'Skill Description'])
                self.assertEqual(question_summary_dicts[i]['skill_ids'],
                                 [self.skill_id_2, self.skill_id])
                self.assertEqual(question_summary_dicts_2[i]['skill_ids'],
                                 [self.skill_id_2, self.skill_id])
                self.assertEqual(
                    question_summary_dicts[i]['skill_difficulties'],
                    [0.3, 0.5])
                self.assertEqual(
                    question_summary_dicts_2[i]['skill_difficulties'],
                    [0.3, 0.5])
            json_response = self.get_json(
                '%s/%s?cursor=' %
                (feconf.QUESTIONS_LIST_URL_PREFIX, self.skill_id))
            question_summary_dicts_3 = (
                json_response['question_summary_dicts'])
            self.assertEqual(len(question_summary_dicts_3), 2)
            for i in python_utils.RANGE(0, 2):
                self.assertEqual(
                    question_summary_dicts_3[i]['skill_description'],
                    'Skill Description')
                self.assertEqual(question_summary_dicts_3[i]['skill_id'],
                                 self.skill_id)
                self.assertEqual(
                    question_summary_dicts_3[i]['skill_difficulty'], 0.5)
            self.assertNotEqual(question_summary_dicts[0]['summary']['id'],
                                question_summary_dicts_2[0]['summary']['id'])
        self.logout()
Ejemplo n.º 14
0
    def test_put_with_admin_email_allows_updation(self):
        question_services.create_new_question_skill_link(
            self.editor_id, self.question_id, self.skill_id, 0.5)
        (
            question_summaries, merged_question_skill_links, _) = (
                question_services.get_displayable_question_skill_link_details(
                    5, [self.skill_id], ''))
        self.assertEqual(len(question_summaries), 1)
        self.assertEqual(
            merged_question_skill_links[0].skill_difficulties, [0.5])

        self.login(self.ADMIN_EMAIL)
        csrf_token = self.get_new_csrf_token()
        self.put_json(
            '%s/%s' % (
                feconf.QUESTION_SKILL_LINK_URL_PREFIX, self.question_id
            ), {
                'new_difficulty': 0.9,
                'action': 'update_difficulty',
                'skill_id': self.skill_id
            }, csrf_token=csrf_token)

        self.put_json(
            '%s/%s' % (
                feconf.QUESTION_SKILL_LINK_URL_PREFIX, self.question_id
            ), {
                'difficulty': 0.6,
                'action': 'edit_links',
                'skill_ids_task_list': [{
                    'id': 'skill_2',
                    'task': 'add'
                }]
            }, csrf_token=csrf_token)
        (
            question_summaries, merged_question_skill_links, _) = (
                question_services.get_displayable_question_skill_link_details(
                    5, [self.skill_id, 'skill_2'], ''))
        self.assertEqual(len(question_summaries), 1)
        self.assertEqual(len(merged_question_skill_links), 1)
        self.assertEqual(
            merged_question_skill_links[0].skill_difficulties, [0.6, 0.9])

        self.put_json(
            '%s/%s' % (
                feconf.QUESTION_SKILL_LINK_URL_PREFIX, self.question_id
            ), {
                'difficulty': 0.9,
                'action': 'edit_links',
                'skill_ids_task_list': [{
                    'id': 'skill_2',
                    'task': 'remove'
                }]
            }, csrf_token=csrf_token)
        question_summaries, _, _ = (
            question_services.get_displayable_question_skill_link_details(
                5, ['skill_2'], ''))
        self.assertEqual(len(question_summaries), 0)
        self.logout()
Ejemplo n.º 15
0
    def setUp(self):
        super(MergeSkillHandlerTests, self).setUp()
        self.url = feconf.MERGE_SKILLS_URL

        self.question_id = question_services.get_new_question_id()
        self.question = self.save_new_question(
            self.question_id, self.admin_id,
            self._create_valid_question_data('ABC'), [self.linked_skill_id])
        question_services.create_new_question_skill_link(
            self.admin_id, self.question_id, self.linked_skill_id, 0.5)
Ejemplo n.º 16
0
    def test_get_questions_and_skill_descriptions_by_skill_ids(self):
        question_services.create_new_question_skill_link(
            self.editor_id, self.question_id, 'skill_1', 0.3)

        questions, _ = (question_fetchers.
                        get_questions_and_skill_descriptions_by_skill_ids(
                            2, ['skill_1'], 0))

        self.assertEqual(len(questions), 1)
        self.assertEqual(questions[0].to_dict(), self.question.to_dict())
Ejemplo n.º 17
0
    def test_get(self):
        # Create 5 questions linked to the same skill.
        for i in range(0, 3):  #pylint: disable=unused-variable
            question_id = question_services.get_new_question_id()
            self.save_new_question(question_id, self.admin_id,
                                   self._create_valid_question_data('ABC'))
            question_services.create_new_question_skill_link(
                question_id, self.skill_id)

        with self.swap(constants, 'ENABLE_NEW_STRUCTURES', True):
            self.login(self.ADMIN_EMAIL)
            with self.swap(constants, 'NUM_QUESTIONS_PER_PAGE', 1):
                json_response = self.get_json(
                    '%s/%s?cursor=' %
                    (feconf.TOPIC_EDITOR_QUESTION_URL, self.topic_id))
                question_summary_dicts = json_response[
                    'question_summary_dicts']
                self.assertEqual(len(question_summary_dicts), 1)
                next_start_cursor = json_response['next_start_cursor']
                json_response = self.get_json(
                    '%s/%s?cursor=%s' % (feconf.TOPIC_EDITOR_QUESTION_URL,
                                         self.topic_id, next_start_cursor))
                question_summary_dicts_2 = (
                    json_response['question_summary_dicts'])
                self.assertEqual(len(question_summary_dicts_2), 1)
                self.assertNotEqual(question_summary_dicts[0]['id'],
                                    question_summary_dicts_2[0]['id'])
            self.logout()

            self.login(self.TOPIC_MANAGER_EMAIL)
            response = self.testapp.get(
                '%s/%s?cursor=' %
                (feconf.TOPIC_EDITOR_QUESTION_URL, self.topic_id))
            self.assertEqual(response.status_int, 200)
            self.logout()

            topic_services.assign_role(self.admin, self.topic_manager,
                                       topic_domain.ROLE_MANAGER,
                                       self.topic_id)

            self.login(self.TOPIC_MANAGER_EMAIL)
            json_response = self.get_json(
                '%s/%s' % (feconf.TOPIC_EDITOR_QUESTION_URL, self.topic_id))
            question_summary_dicts = json_response['question_summary_dicts']
            self.assertEqual(len(question_summary_dicts), 3)
            self.logout()

            self.login(self.NEW_USER_EMAIL)
            response = self.testapp.get(
                '%s/%s?cursor=' %
                (feconf.TOPIC_EDITOR_QUESTION_URL, self.topic_id),
                expect_errors=True)
            self.assertEqual(response.status_int, 401)
            self.logout()
Ejemplo n.º 18
0
 def test_get_with_twenty_or_more_questions(self):
     number_of_questions = 50
     self.topic_id = 'new_topic'
     self.skill_id_1 = skill_services.get_new_skill_id()
     self.skill_id_2 = skill_services.get_new_skill_id()
     self.topic = topic_domain.Topic.create_default_topic(
         self.topic_id, 'new_topic', 'new-topic', 'description', 'fragm')
     self.topic.uncategorized_skill_ids.append(self.skill_id_1)
     self.topic.thumbnail_filename = 'Image.svg'
     self.topic.thumbnail_bg_color = (
         constants.ALLOWED_THUMBNAIL_BG_COLORS['topic'][0])
     self.topic.practice_tab_is_displayed = True
     subtopic_1 = topic_domain.Subtopic.create_default_subtopic(
         1, 'Subtopic Title 1', 'url-frag-one')
     subtopic_1.skill_ids = [self.skill_id_2]
     subtopic_1.url_fragment = 'sub-one-frag'
     self.topic.subtopics = [subtopic_1]
     self.topic.next_subtopic_id = 2
     self.topic.skill_ids_for_diagnostic_test = [self.skill_id_2]
     topic_services.save_new_topic(self.admin_id, self.topic)
     topic_services.publish_topic(self.topic_id, self.admin_id)
     self.save_new_skill(self.skill_id_1,
                         self.admin_id,
                         description='Skill Description 1')
     for index in range(number_of_questions):
         question_id = question_services.get_new_question_id()
         self.save_new_question(question_id, self.admin_id,
                                self._create_valid_question_data(index),
                                [self.skill_id_1])
         question_services.create_new_question_skill_link(
             self.admin_id, question_id, self.skill_id_1, 0.5)
     json_response = self.get_json('%s/staging/%s' %
                                   (feconf.TOPIC_DATA_HANDLER, 'new-topic'))
     expected_dict = {
         'topic_name': 'new_topic',
         'topic_id': self.topic_id,
         'canonical_story_dicts': [],
         'additional_story_dicts': [],
         'uncategorized_skill_ids': [self.skill_id_1],
         'subtopics': [subtopic_1.to_dict()],
         'degrees_of_mastery': {
             self.skill_id_1: None,
             self.skill_id_2: None
         },
         'skill_descriptions': {
             self.skill_id_1: 'Skill Description 1',
             self.skill_id_2: None
         },
         'practice_tab_is_displayed': True
     }
     self.assertDictContainsSubset(expected_dict, json_response)
     self.logout()
Ejemplo n.º 19
0
    def post(self, question_id, skill_id):
        """Links a question to a skill."""
        skill_domain.Skill.require_valid_skill_id(skill_id)
        skill = skill_services.get_skill_by_id(skill_id, strict=False)
        if skill is None:
            raise self.PageNotFoundException(
                'The skill with the given id doesn\'t exist.')

        # TODO(vinitamurthi): Replace DEFAULT_SKILL_DIFFICULTY
        # with a value passed from the frontend.
        question_services.create_new_question_skill_link(
            question_id, skill_id, constants.DEFAULT_SKILL_DIFFICULTY)
        self.render_json(self.values)
Ejemplo n.º 20
0
    def post(self, question_id, skill_id):
        """Links a question to a skill."""
        if not constants.ENABLE_NEW_STRUCTURES:
            raise self.PageNotFoundException

        skill_domain.Skill.require_valid_skill_id(skill_id)
        skill = skill_services.get_skill_by_id(skill_id, strict=False)
        if skill is None:
            raise self.PageNotFoundException(
                'The skill with the given id doesn\'t exist.')

        question_services.create_new_question_skill_link(question_id, skill_id)
        self.render_json(self.values)
Ejemplo n.º 21
0
    def test_get_with_more_questions_with_fifty_or_more_skills(self):
        number_of_skills = 60
        number_of_questions = [0] * 60
        number_of_questions[46] = 2
        number_of_questions[20] = 3
        number_of_questions[29] = 10
        self.topic_id = 'new_topic'
        skill_ids = ([
            skill_services.get_new_skill_id()
            for _ in python_utils.RANGE(number_of_skills)
        ])
        self.topic = topic_domain.Topic.create_default_topic(
            self.topic_id, 'new_topic', 'new-topic', 'description')
        for index in python_utils.RANGE(number_of_skills):
            self.topic.uncategorized_skill_ids.append(skill_ids[index])
        self.topic.thumbnail_filename = 'Image.svg'
        self.topic.thumbnail_bg_color = (
            constants.ALLOWED_THUMBNAIL_BG_COLORS['topic'][0])
        self.topic.practice_tab_is_displayed = True
        subtopic_1 = topic_domain.Subtopic.create_default_subtopic(
            1, 'Subtopic Title 1')
        subtopic_1.skill_ids = ['skill_id_1']
        subtopic_1.url_fragment = 'sub-one-frag'
        self.topic.subtopics = [subtopic_1]
        self.topic.next_subtopic_id = 2
        topic_services.save_new_topic(self.admin_id, self.topic)
        topic_services.publish_topic(self.topic_id, self.admin_id)
        for i in python_utils.RANGE(number_of_skills):
            self.save_new_skill(skill_ids[i],
                                self.admin_id,
                                description='Skill Description')
        for i in python_utils.RANGE(number_of_skills):
            for j in python_utils.RANGE(number_of_questions[i]):
                question_id = question_services.get_new_question_id()
                self.save_new_question(question_id, self.admin_id,
                                       self._create_valid_question_data(j),
                                       [skill_ids[i]])
                question_services.create_new_question_skill_link(
                    self.admin_id, question_id, skill_ids[i], 0.5)

        json_response = self.get_json('%s/staging/%s' %
                                      (feconf.TOPIC_DATA_HANDLER, 'new-topic'))
        expected_dict = {
            'topic_name': 'new_topic',
            'topic_id': self.topic_id,
            'canonical_story_dicts': [],
            'additional_story_dicts': [],
            'practice_tab_is_displayed': True
        }
        self.assertDictContainsSubset(expected_dict, json_response)
        self.logout()
Ejemplo n.º 22
0
 def test_get_questions_with_multi_skill_ids(self):
     question_id_1 = question_services.get_new_question_id()
     question_1 = self.save_new_question(
         question_id_1, self.editor_id,
         self._create_valid_question_data('ABC'), ['skill_1', 'skill_2'])
     question_services.create_new_question_skill_link(
         self.editor_id, question_id_1, 'skill_1', 0.3)
     question_services.create_new_question_skill_link(
         self.editor_id, question_id_1, 'skill_2', 0.5)
     questions, _, _ = (question_services.
                        get_questions_and_skill_descriptions_by_skill_ids(
                            2, ['skill_1', 'skill_2'], ''))
     self.assertEqual(len(questions), 1)
     self.assertEqual(questions[0].to_dict(), question_1.to_dict())
Ejemplo n.º 23
0
    def test_get_question_skill_links_of_question(self):
        # If the question id doesnt exist at all, it returns an empty list.
        skills = (question_services.get_skills_linked_to_question(
            'non_existent_question_id'))
        self.assertEqual(len(skills), 0)

        question_id_2 = question_services.get_new_question_id()
        self.save_new_question(question_id_2, self.editor_id,
                               self._create_valid_question_data('ABC'))

        question_id_3 = question_services.get_new_question_id()
        self.save_new_question(question_id_3, self.editor_id,
                               self._create_valid_question_data('ABC'))
        question_services.create_new_question_skill_link(
            self.question_id, 'skill_1', 0.5)
        question_services.create_new_question_skill_link(
            question_id_2, 'skill_1', 0.3)
        question_services.create_new_question_skill_link(
            question_id_2, 'skill_2', 0.0)
        question_services.create_new_question_skill_link(
            question_id_3, 'skill_2', 0.1)

        skills = (
            question_services.get_skills_linked_to_question(question_id_2))

        self.assertTrue(isinstance(skills[0], skill_domain.Skill))
        self.assertEqual(len(skills), 2)
        skill_ids = [skill.id for skill in skills]
        self.assertItemsEqual(skill_ids, ['skill_1', 'skill_2'])
Ejemplo n.º 24
0
    def test_get_question_skill_links_of_question(self):
        # If the question id doesnt exist at all, it returns an empty list.
        question_skill_links = (
            question_services.get_question_skill_links_of_question(
                'non_existent_question_id'))
        self.assertEqual(len(question_skill_links), 0)

        question_id_2 = question_services.get_new_question_id()
        self.save_new_question(question_id_2, self.editor_id,
                               self._create_valid_question_data('ABC'))

        question_id_3 = question_services.get_new_question_id()
        self.save_new_question(question_id_3, self.editor_id,
                               self._create_valid_question_data('ABC'))
        question_services.create_new_question_skill_link(
            self.question_id, 'skill_1')
        question_services.create_new_question_skill_link(
            question_id_2, 'skill_1')
        question_services.create_new_question_skill_link(
            question_id_2, 'skill_2')
        question_services.create_new_question_skill_link(
            question_id_3, 'skill_2')

        question_skill_links = (
            question_services.get_question_skill_links_of_question(
                question_id_2))

        self.assertTrue(
            isinstance(question_skill_links[0],
                       question_domain.QuestionSkillLink))
        self.assertEqual(len(question_skill_links), 2)
        skill_ids = [
            question_skill.skill_id for question_skill in question_skill_links
        ]
        self.assertItemsEqual(skill_ids, ['skill_1', 'skill_2'])
Ejemplo n.º 25
0
    def test_get_questions_and_skill_descriptions_by_skill_ids(self) -> None:
        question_services.create_new_question_skill_link(  # type: ignore[no-untyped-call]
            self.editor_id, self.question_id, 'skill_1', 0.3)

        questions, _ = (question_fetchers.
                        get_questions_and_skill_descriptions_by_skill_ids(
                            2, ['skill_1'], 0))

        # Ruling out the possibility of None for mypy type checking.
        assert questions[0] is not None
        self.assertEqual(len(questions), 1)
        self.assertEqual(
            questions[0].to_dict(),
            self.question.to_dict())  # type: ignore[no-untyped-call]
Ejemplo n.º 26
0
    def test_create_question_skill_link_increments_question_count(self):
        opportunity_services.create_skill_opportunity(self.SKILL_ID,
                                                      'description')
        self.save_new_question(self.QUESTION_ID, self.USER_ID,
                               self._create_valid_question_data('ABC'),
                               [self.SKILL_ID])

        question_services.create_new_question_skill_link(
            self.USER_ID, self.QUESTION_ID, self.SKILL_ID, 0.3)

        skill_opportunities, _, _ = (
            opportunity_services.get_skill_opportunities(None))
        opportunity = skill_opportunities[0]
        self.assertEqual(opportunity.question_count, 1)
Ejemplo n.º 27
0
    def test_get_skills_of_question(self):
        # If the question id doesnt exist at all, it returns an empty list.
        with self.assertRaisesRegexp(
            Exception, 'Entity for class QuestionModel with id '
            'non_existent_question_id not found'):
            question_services.get_skills_linked_to_question(
                'non_existent_question_id')
        question_id_2 = question_services.get_new_question_id()
        self.save_new_question(
            question_id_2, self.editor_id,
            self._create_valid_question_data('ABC'), ['skill_1'])

        question_id_3 = question_services.get_new_question_id()
        self.save_new_question(
            question_id_3, self.editor_id,
            self._create_valid_question_data('ABC'), ['skill_2'])
        question_services.create_new_question_skill_link(
            self.editor_id, self.question_id, 'skill_1', 0.5)
        question_services.create_new_question_skill_link(
            self.editor_id, question_id_2, 'skill_1', 0.3)
        question_services.create_new_question_skill_link(
            self.editor_id, question_id_2, 'skill_2', 0.0)
        question_services.create_new_question_skill_link(
            self.editor_id, question_id_3, 'skill_2', 0.1)

        skills = (
            question_services.get_skills_linked_to_question(
                question_id_2))

        self.assertTrue(isinstance(skills[0], skill_domain.Skill))
        self.assertEqual(len(skills), 2)
        skill_ids = [skill.id for skill in skills]
        self.assertItemsEqual(
            skill_ids, ['skill_1', 'skill_2'])
Ejemplo n.º 28
0
    def test_get_question_summaries_and_skill_descriptions_with_no_skill_ids(
            self):
        question_id = question_services.get_new_question_id()
        self.save_new_question(question_id, self.editor_id,
                               self._create_valid_question_data('ABC'))

        question_services.create_new_question_skill_link(
            question_id, 'skill_1', 0.5)

        question_summaries, skill_descriptions, _ = (
            question_services.get_question_summaries_and_skill_descriptions(
                2, [], ''))

        self.assertEqual(question_summaries, [])
        self.assertEqual(skill_descriptions, [])
Ejemplo n.º 29
0
 def test_delete_with_admin_email_allows_question_deletion(self):
     question_services.create_new_question_skill_link(
         self.editor_id, self.question_id, self.skill_id, 0.3)
     question_services.create_new_question_skill_link(
         self.editor_id, self.question_id_2, self.skill_id, 0.3)
     self.login(self.ADMIN_EMAIL)
     self.delete_json('%s/%s/%s' % (feconf.QUESTION_SKILL_LINK_URL_PREFIX,
                                    self.question_id, self.skill_id))
     question_summaries, grouped_skill_descriptions, _ = (
         question_services.get_question_summaries_and_skill_descriptions(
             5, [self.skill_id], ''))
     self.assertEqual(len(question_summaries), 1)
     self.assertEqual(question_summaries[0].id, self.question_id_2)
     self.assertEqual(grouped_skill_descriptions[0], ['Skill Description'])
     self.logout()
Ejemplo n.º 30
0
 def test_delete_with_topic_manager_email_allows_question_deletion(self):
     question_services.create_new_question_skill_link(
         self.editor_id, self.question_id, self.skill_id, 0.5)
     question_services.create_new_question_skill_link(
         self.editor_id, self.question_id_2, self.skill_id, 0.5)
     self.login(self.TOPIC_MANAGER_EMAIL)
     self.delete_json('%s/%s/%s' % (feconf.QUESTION_SKILL_LINK_URL_PREFIX,
                                    self.question_id, self.skill_id))
     question_summaries, skill_descriptions, _ = (
         question_services.get_question_summaries_and_skill_descriptions(
             5, [self.skill_id], ''))
     self.assertEqual(len(question_summaries), 1)
     self.assertEqual(question_summaries[0].id, self.question_id_2)
     self.assertEqual(skill_descriptions[0], 'Skill Description')
     self.logout()