コード例 #1
0
ファイル: skill_editor.py プロジェクト: skeezus/oppia
    def put(self, skill_id):
        """Publishes a skill."""
        skill = skill_services.get_skill_by_id(skill_id)
        version = self.payload.get('version')
        _require_valid_version(version, skill.version)

        skill_domain.Skill.require_valid_skill_id(skill_id)

        try:
            skill_services.publish_skill(skill_id, self.user_id)
        except Exception as e:
            raise self.UnauthorizedUserException(e)

        skill_rights = skill_services.get_skill_rights(skill_id, strict=False)
        user_actions_info = user_services.UserActionsInfo(self.user_id)
        can_edit_skill_description = check_can_edit_skill_description(
            user_actions_info)

        self.values.update({
            'skill_is_private':
            skill_rights.skill_is_private,
            'creator_id':
            skill_rights.creator_id,
            'can_edit_skill_description':
            can_edit_skill_description
        })

        self.render_json(self.values)
コード例 #2
0
    def test_get(self):
        # Check that non-admins or non-topic managers cannot access the
        # topics and skills dashboard data.
        skill_id = skill_services.get_new_skill_id()
        skill_id_2 = skill_services.get_new_skill_id()
        self.save_new_skill(skill_id, self.admin_id, 'Description')
        skill_services.publish_skill(skill_id, self.admin_id)
        self.save_new_skill(skill_id_2, self.admin_id, 'Description 2')
        with self.swap(feconf, 'ENABLE_NEW_STRUCTURES', True):
            self.login(self.NEW_USER_EMAIL)
            response = self.testapp.get(
                '%s' % feconf.TOPICS_AND_SKILLS_DASHBOARD_DATA_URL,
                expect_errors=True)
            self.assertEqual(response.status_int, 401)
            self.logout()

            # Check that admins can access the topics and skills dashboard data.
            self.login(self.ADMIN_EMAIL)
            json_response = self.get_json(
                '%s' % feconf.TOPICS_AND_SKILLS_DASHBOARD_DATA_URL)
            self.assertEqual(len(json_response['topic_summary_dicts']), 1)
            self.assertEqual(
                json_response['topic_summary_dicts'][0]['can_edit_topic'],
                True)
            self.assertEqual(json_response['topic_summary_dicts'][0]['id'],
                             self.topic_id)
            self.assertEqual(
                len(json_response['untriaged_skill_summary_dicts']), 1)
            self.assertEqual(
                json_response['untriaged_skill_summary_dicts'][0]['id'],
                skill_id)
            self.assertEqual(
                len(json_response['unpublished_skill_summary_dicts']), 1)
            self.assertEqual(
                json_response['unpublished_skill_summary_dicts'][0]['id'],
                skill_id_2)
            self.logout()

            # Check that topic managers can access the topics and skills
            # dashboard editable topic data. Topic managers should not have
            # access to any unpublished skills.
            self.login(self.TOPIC_MANAGER_EMAIL)
            json_response = self.get_json(
                '%s' % feconf.TOPICS_AND_SKILLS_DASHBOARD_DATA_URL)
            self.assertEqual(len(json_response['topic_summary_dicts']), 1)
            self.assertEqual(
                json_response['topic_summary_dicts'][0]['can_edit_topic'],
                False)
            self.assertEqual(json_response['topic_summary_dicts'][0]['id'],
                             self.topic_id)
            self.assertEqual(json_response['topic_summary_dicts'][0]['id'],
                             self.topic_id)
            self.assertEqual(
                len(json_response['untriaged_skill_summary_dicts']), 1)
            self.assertEqual(
                json_response['untriaged_skill_summary_dicts'][0]['id'],
                skill_id)
            self.assertEqual(
                len(json_response['unpublished_skill_summary_dicts']), 0)
            self.logout()
コード例 #3
0
    def test_get_unpublished_skill_rights_by_creator(self):
        self.save_new_skill('skill_a',
                            self.user_id_admin,
                            'Description A',
                            misconceptions=[],
                            skill_contents=skill_domain.SkillContents(
                                state_domain.SubtitledHtml('1', 'Explanation'),
                                [state_domain.SubtitledHtml('2', 'Example 1')],
                                {}))
        self.save_new_skill('skill_b',
                            self.user_id_admin,
                            'Description B',
                            misconceptions=[],
                            skill_contents=skill_domain.SkillContents(
                                state_domain.SubtitledHtml('1', 'Explanation'),
                                [state_domain.SubtitledHtml('2', 'Example 1')],
                                {}))

        skill_rights = skill_services.get_unpublished_skill_rights_by_creator(
            self.user_id_admin)
        skill_ids = [skill_rights_obj.id for skill_rights_obj in skill_rights]
        self.assertListEqual(skill_ids, ['skill_a', 'skill_b'])

        skill_services.publish_skill(self.SKILL_ID, self.user_id_admin)
        skill_rights = skill_services.get_unpublished_skill_rights_by_creator(
            self.user_id_admin)
        skill_ids = [skill_rights_obj.id for skill_rights_obj in skill_rights]
        self.assertListEqual(skill_ids, ['skill_a', 'skill_b'])
コード例 #4
0
    def test_get_unpublished_skill_rights_by_creator(self):
        self.save_new_skill(
            'skill_a', self.user_id_admin, 'Description A', misconceptions=[],
            skill_contents=skill_domain.SkillContents(
                state_domain.SubtitledHtml('1', '<p>Explanation</p>'), [
                    state_domain.SubtitledHtml('2', '<p>Example 1</p>')],
                state_domain.RecordedVoiceovers.from_dict(
                    {'voiceovers_mapping': {'1': {}, '2': {}}}),
                state_domain.WrittenTranslations.from_dict(
                    {'translations_mapping': {'1': {}, '2': {}}})))
        self.save_new_skill(
            'skill_b', self.user_id_admin, 'Description B', misconceptions=[],
            skill_contents=skill_domain.SkillContents(
                state_domain.SubtitledHtml('1', '<p>Explanation</p>'), [
                    state_domain.SubtitledHtml('2', '<p>Example 1</p>')],
                state_domain.RecordedVoiceovers.from_dict(
                    {'voiceovers_mapping': {'1': {}, '2': {}}}),
                state_domain.WrittenTranslations.from_dict(
                    {'translations_mapping': {'1': {}, '2': {}}})))

        skill_rights = skill_services.get_unpublished_skill_rights_by_creator(
            self.user_id_admin)
        skill_ids = [skill_rights_obj.id for skill_rights_obj in skill_rights]
        self.assertListEqual(skill_ids, ['skill_a', 'skill_b'])

        skill_services.publish_skill(self.SKILL_ID, self.user_id_admin)
        skill_rights = skill_services.get_unpublished_skill_rights_by_creator(
            self.user_id_admin)
        skill_ids = [skill_rights_obj.id for skill_rights_obj in skill_rights]
        self.assertListEqual(skill_ids, ['skill_a', 'skill_b'])
コード例 #5
0
    def setUp(self):
        """Completes the sign-up process for the various users."""
        super(BaseTopicsAndSkillsDashboardTests, self).setUp()
        self.signup(self.ADMIN_EMAIL, self.ADMIN_USERNAME)
        self.signup(self.TOPIC_MANAGER_EMAIL, self.TOPIC_MANAGER_USERNAME)
        self.signup(self.NEW_USER_EMAIL, self.NEW_USER_USERNAME)

        self.admin_id = self.get_user_id_from_email(self.ADMIN_EMAIL)
        self.topic_manager_id = self.get_user_id_from_email(
            self.TOPIC_MANAGER_EMAIL)
        self.new_user_id = self.get_user_id_from_email(self.NEW_USER_EMAIL)
        self.set_admins([self.ADMIN_USERNAME])
        self.set_topic_managers([self.TOPIC_MANAGER_USERNAME])
        self.topic_id = topic_services.get_new_topic_id()
        self.linked_skill_id = skill_services.get_new_skill_id()
        self.save_new_skill(self.linked_skill_id, self.admin_id,
                            'Description 3')
        skill_services.publish_skill(self.linked_skill_id, self.admin_id)
        self.save_new_topic(self.topic_id, self.admin_id, 'Name', 'abbrev',
                            None, 'Description', [], [],
                            [self.linked_skill_id], [], 1)
コード例 #6
0
    def post(self):
        description = self.payload.get('description')
        linked_topic_ids = self.payload.get('linked_topic_ids')
        explanation_dict = self.payload.get('explanation_dict')
        rubrics = self.payload.get('rubrics')
        if not isinstance(rubrics, list):
            raise self.InvalidInputException('Rubrics should be a list.')

        if not isinstance(explanation_dict, dict):
            raise self.InvalidInputException('Explanation should be a dict.')

        try:
            state_domain.SubtitledHtml.from_dict(explanation_dict)
        except:
            raise self.InvalidInputException(
                'Explanation should be a valid SubtitledHtml dict.')

        rubrics = [skill_domain.Rubric.from_dict(rubric) for rubric in rubrics]
        new_skill_id = skill_services.get_new_skill_id()
        if linked_topic_ids is not None:
            topics = topic_fetchers.get_topics_by_ids(linked_topic_ids)
            for topic in topics:
                if topic is None:
                    raise self.InvalidInputException
                topic_services.add_uncategorized_skill(self.user_id, topic.id,
                                                       new_skill_id)

        skill_domain.Skill.require_valid_description(description)

        skill = skill_domain.Skill.create_default_skill(
            new_skill_id, description, rubrics)
        skill.update_explanation(explanation_dict)
        skill_services.save_new_skill(self.user_id, skill)
        skill_services.publish_skill(skill.id, self.user_id)

        self.render_json({'skillId': new_skill_id})
コード例 #7
0
 def test_normal_user_cannot_publish_skill(self):
     with self.assertRaisesRegexp(
             Exception,
             'The user does not have enough rights to publish the skill.'):
         skill_services.publish_skill(self.SKILL_ID, self.USER_ID)
コード例 #8
0
 def test_cannot_publish_already_published_skill(self):
     skill_services.publish_skill(self.SKILL_ID, self.user_id_admin)
     with self.assertRaisesRegexp(Exception,
                                  'The skill is already published.'):
         skill_services.publish_skill(self.SKILL_ID, self.user_id_admin)
コード例 #9
0
 def test_cannot_publish_skill_with_invalid_skill_id(self):
     with self.assertRaisesRegexp(Exception,
                                  'The given skill does not exist.'):
         skill_services.publish_skill('invalid_skill_id', self.USER_ID)
コード例 #10
0
    def setUp(self):
        super(ContributionOpportunitiesHandlerTest, self).setUp()
        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])

        explorations = [exp_domain.Exploration.create_default_exploration(
            '%s' % i,
            title='title %d' % i,
            category='category%d' % i,
        ) for i in python_utils.RANGE(2)]

        for exp in explorations:
            exp_services.save_new_exploration(self.owner_id, exp)

        topic = topic_domain.Topic.create_default_topic(
            topic_id='0', name='topic')
        topic_services.save_new_topic(self.owner_id, topic)

        self.skill_id_0 = 'skill_id_0'
        self.skill_id_1 = 'skill_id_1'
        self.skill_ids = [self.skill_id_0, self.skill_id_1]
        for skill_id in self.skill_ids:
            self.save_new_skill(skill_id, self.admin_id, 'skill_description')
            skill_services.publish_skill(skill_id, self.admin_id)
            topic_services.add_uncategorized_skill(
                self.admin_id, '0', skill_id)

        self.expected_skill_opportunity_dict_0 = {
            'id': self.skill_id_0,
            'skill_description': 'skill_description',
            'question_count': 0,
            'topic_name': 'topic'
        }
        self.expected_skill_opportunity_dict_1 = {
            'id': self.skill_id_1,
            'skill_description': 'skill_description',
            'question_count': 0,
            'topic_name': 'topic'
        }

        stories = [story_domain.Story.create_default_story(
            '%s' % i,
            title='title %d' % i,
            corresponding_topic_id='0'
        ) for i in python_utils.RANGE(2)]

        for index, story in enumerate(stories):
            story.language_code = 'en'
            story_services.save_new_story(self.owner_id, story)
            topic_services.add_canonical_story(
                self.owner_id, topic.id, story.id)
            story_services.update_story(
                self.owner_id, story.id, [story_domain.StoryChange({
                    'cmd': 'add_story_node',
                    'node_id': 'node_1',
                    'title': 'Node1',
                }), story_domain.StoryChange({
                    'cmd': 'update_story_node_property',
                    'property_name': 'exploration_id',
                    'node_id': 'node_1',
                    'old_value': None,
                    'new_value': explorations[index].id
                })], 'Changes.')

        self.expected_opportunity_dict_1 = {
            'id': '0',
            'topic_name': 'topic',
            'story_title': 'title 0',
            'chapter_title': 'Node1',
            'content_count': 2,
            'translation_counts': {}
        }

        self.expected_opportunity_dict_2 = {
            'id': '1',
            'topic_name': 'topic',
            'story_title': 'title 1',
            'chapter_title': 'Node1',
            'content_count': 2,
            'translation_counts': {}
        }
コード例 #11
0
    def _load_dummy_new_structures_data(self):
        """Loads the database with two topics (one of which is empty), a story
        and three skills in the topic (two of them in a subtopic) and a question
        attached to each 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 self.user.role != feconf.ROLE_ID_ADMIN:
                raise Exception(
                    'User does not have enough rights to generate data.')
            topic_id_1 = topic_services.get_new_topic_id()
            topic_id_2 = topic_services.get_new_topic_id()
            story_id = story_services.get_new_story_id()
            skill_id_1 = skill_services.get_new_skill_id()
            skill_id_2 = skill_services.get_new_skill_id()
            skill_id_3 = skill_services.get_new_skill_id()
            question_id_1 = question_services.get_new_question_id()
            question_id_2 = question_services.get_new_question_id()
            question_id_3 = question_services.get_new_question_id()

            skill_1 = self._create_dummy_skill(skill_id_1, 'Dummy Skill 1',
                                               '<p>Dummy Explanation 1</p>')
            skill_2 = self._create_dummy_skill(skill_id_2, 'Dummy Skill 2',
                                               '<p>Dummy Explanation 2</p>')
            skill_3 = self._create_dummy_skill(skill_id_3, 'Dummy Skill 3',
                                               '<p>Dummy Explanation 3</p>')

            question_1 = self._create_dummy_question(question_id_1,
                                                     'Question 1',
                                                     [skill_id_1])
            question_2 = self._create_dummy_question(question_id_2,
                                                     'Question 2',
                                                     [skill_id_2])
            question_3 = self._create_dummy_question(question_id_3,
                                                     'Question 3',
                                                     [skill_id_3])
            question_services.add_question(self.user_id, question_1)
            question_services.add_question(self.user_id, question_2)
            question_services.add_question(self.user_id, question_3)

            question_services.create_new_question_skill_link(
                self.user_id, question_id_1, skill_id_1, 0.3)
            question_services.create_new_question_skill_link(
                self.user_id, question_id_2, skill_id_2, 0.5)
            question_services.create_new_question_skill_link(
                self.user_id, question_id_3, skill_id_3, 0.7)

            topic_1 = topic_domain.Topic.create_default_topic(
                topic_id_1, 'Dummy Topic 1', 'abbrev')
            topic_2 = topic_domain.Topic.create_default_topic(
                topic_id_2, 'Empty Topic', 'abbrev')

            topic_1.add_canonical_story(story_id)
            topic_1.add_uncategorized_skill_id(skill_id_1)
            topic_1.add_uncategorized_skill_id(skill_id_2)
            topic_1.add_uncategorized_skill_id(skill_id_3)
            topic_1.add_subtopic(1, 'Dummy Subtopic Title')
            topic_1.move_skill_id_to_subtopic(None, 1, skill_id_2)
            topic_1.move_skill_id_to_subtopic(None, 1, skill_id_3)

            subtopic_page = (
                subtopic_page_domain.SubtopicPage.create_default_subtopic_page(
                    1, topic_id_1))
            self._reload_exploration('0')
            self._reload_exploration('16')
            story = story_domain.Story.create_default_story(
                story_id, 'Dummy Story 1', topic_id_1)
            story.add_node('%s%d' % (story_domain.NODE_ID_PREFIX, 1),
                           'Dummy Chapter 1')
            story.update_node_destination_node_ids(
                '%s%d' % (story_domain.NODE_ID_PREFIX, 1),
                ['%s%d' % (story_domain.NODE_ID_PREFIX, 2)])
            story.update_node_exploration_id(
                '%s%d' % (story_domain.NODE_ID_PREFIX, 1), '0')

            story.add_node('%s%d' % (story_domain.NODE_ID_PREFIX, 2),
                           'Dummy Chapter 2')
            story.update_node_exploration_id(
                '%s%d' % (story_domain.NODE_ID_PREFIX, 2), '16')

            skill_services.save_new_skill(self.user_id, skill_1)
            skill_services.save_new_skill(self.user_id, skill_2)
            skill_services.save_new_skill(self.user_id, skill_3)
            story_services.save_new_story(self.user_id, story)
            topic_services.save_new_topic(self.user_id, topic_1)
            topic_services.save_new_topic(self.user_id, topic_2)
            subtopic_page_services.save_subtopic_page(
                self.user_id, subtopic_page, 'Added subtopic', [
                    topic_domain.TopicChange({
                        'cmd': topic_domain.CMD_ADD_SUBTOPIC,
                        'subtopic_id': 1,
                        'title': 'Dummy Subtopic Title'
                    })
                ])

            topic_services.publish_story(topic_id_1, story_id, self.user_id)
            topic_services.publish_topic(topic_id_1, self.user_id)
            skill_services.publish_skill(skill_id_1, self.user_id)
            skill_services.publish_skill(skill_id_2, self.user_id)
            skill_services.publish_skill(skill_id_3, self.user_id)
        else:
            raise Exception('Cannot load new structures data in production.')