Exemplo n.º 1
0
    def test_create_and_get_question_skill_link(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'))

        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_3, 'skill_2', 0.2)

        question_summaries, skill_descriptions, _ = (
            question_services.get_question_summaries_and_skill_descriptions(
                5, ['skill_1', 'skill_2', 'skill_3'], ''))

        with self.assertRaisesRegexp(
                Exception,
                'Querying linked question summaries for more than 3 '
                'skills at a time is not supported currently.'):
            question_services.get_question_summaries_and_skill_descriptions(
                5, ['skill_1', 'skill_2', 'skill_3', 'skill_4'], '')
        question_ids = [summary.id for summary in question_summaries]
        skill_descriptions = [
            description for description in skill_descriptions
        ]

        self.assertEqual(len(question_ids), 3)
        self.assertEqual(len(skill_descriptions), 3)
        self.assertItemsEqual(question_ids,
                              [self.question_id, question_id_2, question_id_3])

        # Make sure the correct skill description corresponds to respective
        # question summaries.
        for index, description in enumerate(skill_descriptions):
            if (question_ids[index] == self.question_id
                    or question_ids[index] == question_id_2):
                self.assertEqual('Skill Description 1', description)
            else:
                self.assertEqual('Skill Description 2', description)

        question_summaries, skill_descriptions, _ = (
            question_services.get_question_summaries_and_skill_descriptions(
                5, ['skill_1', 'skill_3'], ''))
        question_ids = [summary.id for summary in question_summaries]
        self.assertEqual(len(question_ids), 2)
        self.assertItemsEqual(question_ids, [self.question_id, question_id_2])

        with self.assertRaisesRegexp(
                Exception,
                'The given question is already linked to given skill'):
            question_services.create_new_question_skill_link(
                self.question_id, 'skill_1', 0.3)
Exemplo n.º 2
0
    def test_post(self):
        with self.swap(constants, 'ENABLE_NEW_STRUCTURE_EDITORS', True):
            self.login(self.NEW_USER_EMAIL)
            response = self.get_html_response(feconf.CREATOR_DASHBOARD_URL)
            csrf_token = self.get_csrf_token_from_response(response)
            self.post_json(
                '%s/%s/%s' % (
                    feconf.QUESTION_SKILL_LINK_URL_PREFIX, self.question_id,
                    self.skill_id
                ), {}, csrf_token=csrf_token, expected_status_int=401)
            self.logout()

            self.login(self.ADMIN_EMAIL)
            response = self.get_html_response(feconf.CREATOR_DASHBOARD_URL)
            csrf_token = self.get_csrf_token_from_response(response)
            self.post_json(
                '%s/%s/%s' % (
                    feconf.QUESTION_SKILL_LINK_URL_PREFIX, self.question_id,
                    self.skill_id
                ), {}, csrf_token=csrf_token)
            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)
            self.assertEqual(
                skill_descriptions[0], 'Skill Description')
            self.logout()

            self.login(self.TOPIC_MANAGER_EMAIL)
            response = self.get_html_response(feconf.CREATOR_DASHBOARD_URL)
            csrf_token = self.get_csrf_token_from_response(response)
            self.post_json(
                '%s/%s/%s' % (
                    feconf.QUESTION_SKILL_LINK_URL_PREFIX, self.question_id_2,
                    self.skill_id
                ), {}, csrf_token=csrf_token)
            question_summaries, skill_descriptions, _ = (
                question_services.get_question_summaries_and_skill_descriptions(
                    5, [self.skill_id], ''))
            self.assertEqual(len(question_summaries), 2)
            question_ids = [
                summary.id for summary in question_summaries
            ]
            self.assertItemsEqual(
                question_ids, [self.question_id, self.question_id_2])
            self.logout()
Exemplo n.º 3
0
    def get(self, comma_separated_skill_ids):
        """Handles GET requests."""
        start_cursor = self.request.get('cursor')
        skill_ids = comma_separated_skill_ids.split(',')

        for skill_id in skill_ids:
            try:
                skill_domain.Skill.require_valid_skill_id(skill_id)
            except Exception:
                raise self.PageNotFoundException(Exception('Invalid skill id'))

        try:
            skill_services.get_multi_skills(skill_ids)
        except Exception as e:
            raise self.PageNotFoundException(e)

        question_summaries, skill_descriptions_list, next_start_cursor = (
            question_services.get_question_summaries_and_skill_descriptions(
                constants.NUM_QUESTIONS_PER_PAGE, skill_ids, start_cursor))
        return_dicts = []
        for index, summary in enumerate(question_summaries):
            return_dicts.append({
                'summary':
                summary.to_dict(),
                'skill_descriptions':
                skill_descriptions_list[index]
            })

        self.values.update({
            'question_summary_dicts': return_dicts,
            'next_start_cursor': next_start_cursor
        })
        self.render_json(self.values)
Exemplo n.º 4
0
    def get(self, topic_id):
        """Handles GET requests."""
        if not constants.ENABLE_NEW_STRUCTURE_EDITORS:
            raise self.PageNotFoundException
        topic_domain.Topic.require_valid_topic_id(topic_id)

        start_cursor = self.request.get('cursor')
        topic = topic_services.get_topic_by_id(topic_id)
        skill_ids = topic.get_all_skill_ids()

        question_summaries, skill_descriptions, next_start_cursor = (
            question_services.get_question_summaries_and_skill_descriptions(
                constants.NUM_QUESTIONS_PER_PAGE, skill_ids, start_cursor))
        return_dicts = []
        for index, summary in enumerate(question_summaries):
            return_dicts.append({
                'summary': summary.to_dict(),
                'skill_description': skill_descriptions[index]
            })

        self.values.update({
            'question_summary_dicts': return_dicts,
            'next_start_cursor': next_start_cursor
        })
        self.render_json(self.values)
Exemplo n.º 5
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, 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()

            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_and_skill_descriptions(
                    5, [self.skill_id], ''))
            self.assertEqual(len(question_summaries), 0)
            self.logout()
Exemplo n.º 6
0
 def test_post_with_topic_manager_email_allows_question_linking(self):
     self.login(self.TOPIC_MANAGER_EMAIL)
     csrf_token = self.get_new_csrf_token()
     self.post_json('%s/%s/%s' % (feconf.QUESTION_SKILL_LINK_URL_PREFIX,
                                  self.question_id, self.skill_id), {},
                    csrf_token=csrf_token)
     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)
     self.assertEqual(grouped_skill_descriptions[0], ['Skill Description'])
     self.logout()
Exemplo n.º 7
0
 def test_post_with_topic_manager_email_allows_question_linking(self):
     self.login(self.TOPIC_MANAGER_EMAIL)
     response = self.get_html_response(feconf.CREATOR_DASHBOARD_URL)
     csrf_token = self.get_csrf_token_from_response(response)
     self.post_json('%s/%s/%s' % (feconf.QUESTION_SKILL_LINK_URL_PREFIX,
                                  self.question_id, self.skill_id), {},
                    csrf_token=csrf_token)
     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)
     self.assertEqual(skill_descriptions[0], 'Skill Description')
     self.logout()
Exemplo n.º 8
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()
Exemplo n.º 9
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, [])
Exemplo n.º 10
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()
Exemplo n.º 11
0
    def test_accept_question_suggestion(self):
        suggestion_to_accept = self.get_json(
            '%s?suggestion_type=%s' % (
                feconf.SUGGESTION_LIST_URL_PREFIX,
                suggestion_models.SUGGESTION_TYPE_ADD_QUESTION)
            )['suggestions'][0]

        self.login(self.ADMIN_EMAIL)
        csrf_token = self.get_new_csrf_token()
        with self.swap(constants, 'ENABLE_NEW_STRUCTURE_PLAYERS', True):
            self.put_json('%s/topic/%s/%s' % (
                feconf.SUGGESTION_ACTION_URL_PREFIX,
                suggestion_to_accept['target_id'],
                suggestion_to_accept['suggestion_id']), {
                    'action': u'accept',
                    'commit_message': u'commit message',
                    'review_message': u'This looks good!',
                    'skill_id': self.SKILL_ID
                }, csrf_token=csrf_token)

        suggestion_post_accept = self.get_json(
            '%s?suggestion_type=%s' % (
                feconf.SUGGESTION_LIST_URL_PREFIX,
                suggestion_models.SUGGESTION_TYPE_ADD_QUESTION)
            )['suggestions'][0]
        self.assertEqual(
            suggestion_post_accept['status'],
            suggestion_models.STATUS_ACCEPTED)
        questions, grouped_skill_descriptions, _ = (
            question_services.get_question_summaries_and_skill_descriptions(
                1, [self.SKILL_ID], ''))
        self.assertEqual(len(questions), 1)
        self.assertEqual(questions[0].creator_id, self.author_id)
        self.assertEqual(
            grouped_skill_descriptions[0], [self.SKILL_DESCRIPTION])
        self.assertEqual(
            questions[0].question_content,
            self.question_dict['question_state_data']['content']['html']
        )
        thread_messages = feedback_services.get_messages(
            suggestion_to_accept['suggestion_id'])
        last_message = thread_messages[len(thread_messages) - 1]
        self.assertEqual(last_message.text, 'This looks good!')
Exemplo n.º 12
0
 def test_post_with_admin_email_allows_question_linking(self):
     with self.swap(constants, 'ENABLE_NEW_STRUCTURE_EDITORS', True):
         self.login(self.ADMIN_EMAIL)
         response = self.get_html_response(feconf.CREATOR_DASHBOARD_URL)
         csrf_token = self.get_csrf_token_from_response(response)
         self.post_json(
             '%s/%s/%s' % (
                 feconf.QUESTION_SKILL_LINK_URL_PREFIX, self.question_id,
                 self.skill_id
             ), {}, csrf_token=csrf_token)
         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)
         self.assertEqual(
             skill_descriptions[0], 'Skill Description')
         self.logout()
Exemplo n.º 13
0
    def get(self, topic_id):
        """Handles GET requests."""
        start_cursor = self.request.get('cursor')
        topic = topic_services.get_topic_by_id(topic_id)
        skill_ids = topic.get_all_skill_ids()

        question_summaries, skill_descriptions, next_start_cursor = (
            question_services.get_question_summaries_and_skill_descriptions(
                constants.NUM_QUESTIONS_PER_PAGE, skill_ids, start_cursor))
        return_dicts = []
        for index, summary in enumerate(question_summaries):
            return_dicts.append({
                'summary': summary.to_dict(),
                'skill_description': skill_descriptions[index]
            })

        self.values.update({
            'question_summary_dicts': return_dicts,
            'next_start_cursor': next_start_cursor
        })
        self.render_json(self.values)
Exemplo n.º 14
0
 def test_delete_with_admin_email_allows_question_deletion(self):
     question_services.create_new_question_skill_link(
         self.question_id, self.skill_id, 0.3)
     question_services.create_new_question_skill_link(
         self.question_id_2, self.skill_id, 0.3)
     with self.swap(constants, 'ENABLE_NEW_STRUCTURE_EDITORS', True):
         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, 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()
Exemplo n.º 15
0
class QuestionsListHandler(base.BaseHandler):
    """Manages receiving of all question summaries for display in topic editor
    and skill editor page.
    """
    GET_HANDLER_ERROR_RETURN_TYPE = feconf.HANDLER_TYPE_JSON

    @acl_decorators.open_access
    def get(self, comma_separated_skill_ids):
        """Handles GET requests."""
        start_cursor = self.request.get('cursor')
        skill_ids = comma_separated_skill_ids.split(',')

        for skill_id in skill_ids:
            try:
                skill_domain.Skill.require_valid_skill_id(skill_id)
            except Exception:
                raise self.PageNotFoundException(Exception('Invalid skill id'))

        try:
            skill_services.get_multi_skills(skill_ids)
        except Exception, e:
            raise self.PageNotFoundException(e)

        question_summaries, skill_descriptions_list, next_start_cursor = (
            question_services.get_question_summaries_and_skill_descriptions(
                constants.NUM_QUESTIONS_PER_PAGE, skill_ids, start_cursor))
        return_dicts = []
        for index, summary in enumerate(question_summaries):
            return_dicts.append({
                'summary':
                summary.to_dict(),
                'skill_descriptions':
                skill_descriptions_list[index]
            })

        self.values.update({
            'question_summary_dicts': return_dicts,
            'next_start_cursor': next_start_cursor
        })
        self.render_json(self.values)