def setUp(self):
     super(SubtopicPageServicesUnitTests, self).setUp()
     self.TOPIC_ID = topic_services.get_new_topic_id()
     self.subtopic_page = (
         subtopic_page_domain.SubtopicPage.create_default_subtopic_page(
             self.subtopic_id, self.TOPIC_ID))
     subtopic_page_services.save_subtopic_page(
         self.user_id, self.subtopic_page, 'Added subtopic', [
             topic_domain.TopicChange({
                 'cmd': topic_domain.CMD_ADD_SUBTOPIC,
                 'subtopic_id': 1,
                 'title': 'Sample'
             })
         ])
     self.subtopic_page_id = (
         subtopic_page_domain.SubtopicPage.get_subtopic_page_id(
             self.TOPIC_ID, 1))
示例#2
0
def add_additional_story(user_id, topic_id, story_id):
    """Adds a story to the additional story reference list of a topic.

    Args:
        user_id: str. The id of the user who is performing the action.
        topic_id: str. The id of the topic to which the story is to be added.
        story_id: str. The story to add to the topic.
    """
    change_list = [
        topic_domain.TopicChange({
            'cmd': topic_domain.CMD_ADD_ADDITIONAL_STORY,
            'story_id': story_id
        })
    ]
    update_topic_and_subtopic_pages(
        user_id, topic_id, change_list,
        'Added %s to additional story ids' % story_id)
示例#3
0
    def put(self, topic_id):
        """Updates properties of the given topic.
        Also, each change_dict given for editing should have an additional
        property called is_topic_change, which would be a boolean. If True, it
        means that change is for a topic (includes adding and removing
        subtopics), while False would mean it is for a Subtopic Page (this
        includes editing its html data as of now).
        """
        topic_domain.Topic.require_valid_topic_id(topic_id)
        topic = topic_services.get_topic_by_id(topic_id, strict=False)

        version = self.payload.get('version')
        self._require_valid_version(version, topic.version)

        commit_message = self.payload.get('commit_message')
        topic_and_subtopic_page_change_dicts = self.payload.get(
            'topic_and_subtopic_page_change_dicts')
        topic_and_subtopic_page_change_list = []
        for change in topic_and_subtopic_page_change_dicts:
            if change['change_affects_subtopic_page']:
                topic_and_subtopic_page_change_list.append(
                    subtopic_page_domain.SubtopicPageChange(change))
            else:
                topic_and_subtopic_page_change_list.append(
                    topic_domain.TopicChange(change))
        try:
            topic_services.update_topic_and_subtopic_pages(
                self.user_id, topic_id, topic_and_subtopic_page_change_list,
                commit_message)
        except utils.ValidationError as e:
            raise self.InvalidInputException(e)

        topic = topic_services.get_topic_by_id(topic_id, strict=False)
        skill_ids = topic.get_all_skill_ids()

        skill_id_to_description_dict = (
            skill_services.get_skill_descriptions_by_ids(topic_id, skill_ids))

        self.values.update({
            'topic_dict':
            topic.to_dict(),
            'skill_id_to_description_dict':
            skill_id_to_description_dict
        })

        self.render_json(self.values)
示例#4
0
    def put(self, topic_id):
        """Updates properties of the given topic.
        Also, each change_dict given for editing should have an additional
        property called is_topic_change, which would be a boolean. If True, it
        means that change is for a topic (includes adding and removing
        subtopics), while False would mean it is for a Subtopic Page (this
        includes editing its html data as of now).
        """
        if not feconf.ENABLE_NEW_STRUCTURES:
            raise self.PageNotFoundException

        topic_domain.Topic.require_valid_topic_id(topic_id)
        topic = topic_services.get_topic_by_id(topic_id, strict=False)
        if topic is None:
            raise self.PageNotFoundException(
                Exception('The topic with the given id doesn\'t exist.'))

        version = self.payload.get('version')
        self._require_valid_version(version, topic.version)

        commit_message = self.payload.get('commit_message')
        topic_and_subtopic_page_change_dicts = self.payload.get(
            'topic_and_subtopic_page_change_dicts')
        topic_and_subtopic_page_change_list = []
        for change in topic_and_subtopic_page_change_dicts:
            if change['change_affects_subtopic_page']:
                topic_and_subtopic_page_change_list.append(
                    subtopic_page_domain.SubtopicPageChange(change))
            else:
                topic_and_subtopic_page_change_list.append(
                    topic_domain.TopicChange(change))
        try:
            topic_services.update_topic_and_subtopic_pages(
                self.user_id, topic_id, topic_and_subtopic_page_change_list,
                commit_message)
        except utils.ValidationError as e:
            raise self.InvalidInputException(e)

        topic_dict = topic_services.get_topic_by_id(topic_id).to_dict()

        self.values.update({
            'topic': topic_dict
        })

        self.render_json(self.values)
示例#5
0
    def test_cannot_get_topic_from_model_with_invalid_schema_version(self):
        topic_services.create_new_topic_rights('topic_id', self.user_id_a)
        commit_cmd = topic_domain.TopicChange({
            'cmd': topic_domain.CMD_CREATE_NEW,
            'name': 'name'
        })
        subtopic_dict = {'id': 1, 'title': 'subtopic_title', 'skill_ids': []}
        model = topic_models.TopicModel(id='topic_id',
                                        name='name',
                                        abbreviated_name='abbrev',
                                        canonical_name='canonical_name',
                                        description='description',
                                        next_subtopic_id=1,
                                        language_code='en',
                                        subtopics=[subtopic_dict],
                                        subtopic_schema_version=0,
                                        story_reference_schema_version=0)
        commit_cmd_dicts = [commit_cmd.to_dict()]
        model.commit(self.user_id_a, 'topic model created', commit_cmd_dicts)

        with self.assertRaisesRegexp(
                Exception,
                'Sorry, we can only process v1-v%d subtopic schemas at '
                'present.' % feconf.CURRENT_SUBTOPIC_SCHEMA_VERSION):
            topic_fetchers.get_topic_from_model(model)

        topic_services.create_new_topic_rights('topic_id_2', self.user_id_a)
        model = topic_models.TopicModel(id='topic_id_2',
                                        name='name 2',
                                        description='description 2',
                                        abbreviated_name='abbrev',
                                        canonical_name='canonical_name_2',
                                        next_subtopic_id=1,
                                        language_code='en',
                                        subtopics=[subtopic_dict],
                                        subtopic_schema_version=1,
                                        story_reference_schema_version=0)
        commit_cmd_dicts = [commit_cmd.to_dict()]
        model.commit(self.user_id_a, 'topic model created', commit_cmd_dicts)

        with self.assertRaisesRegexp(
                Exception,
                'Sorry, we can only process v1-v%d story reference schemas at '
                'present.' % feconf.CURRENT_STORY_REFERENCE_SCHEMA_VERSION):
            topic_fetchers.get_topic_from_model(model)
示例#6
0
def delete_additional_story(user_id, topic_id, story_id):
    """Removes story with given id from the topic.

    NOTE TO DEVELOPERS: Presently, this function only removes story_reference
    from additional_story_references list.

    Args:
        user_id: str. The id of the user who is performing the action.
        topic_id: str. The id of the topic from which to remove the story.
        story_id: str. The story to remove from the topic.
    """
    change_list = [topic_domain.TopicChange({
        'cmd': topic_domain.CMD_DELETE_ADDITIONAL_STORY,
        'story_id': story_id
    })]
    update_topic_and_subtopic_pages(
        user_id, topic_id, change_list,
        'Removed %s from additional story ids' % story_id)
示例#7
0
 def test_delete_subtopic_with_skill_ids(self):
     changelist = [topic_domain.TopicChange({
         'cmd': topic_domain.CMD_DELETE_SUBTOPIC,
         'subtopic_id': self.subtopic_id
     })]
     subtopic_page = subtopic_page_services.get_subtopic_page_by_id(
         self.TOPIC_ID, 1, strict=False)
     self.assertEqual(subtopic_page.id, self.TOPIC_ID + '-1')
     topic_services.update_topic_and_subtopic_pages(
         self.user_id_admin, self.TOPIC_ID, changelist,
         'Removed 1 subtopic.')
     subtopic_page = subtopic_page_services.get_subtopic_page_by_id(
         self.TOPIC_ID, 1, strict=False)
     self.assertIsNone(subtopic_page)
     topic = topic_services.get_topic_by_id(self.TOPIC_ID)
     self.assertEqual(
         topic.uncategorized_skill_ids, [self.skill_id_1, self.skill_id_2])
     self.assertEqual(topic.subtopics, [])
    def test_topic_change_object_with_move_skill_id_to_subtopic(self):
        topic_change_object = topic_domain.TopicChange({
            'cmd':
            'move_skill_id_to_subtopic',
            'skill_id':
            'skill_id',
            'old_subtopic_id':
            'old_subtopic_id',
            'new_subtopic_id':
            'new_subtopic_id'
        })

        self.assertEqual(topic_change_object.cmd, 'move_skill_id_to_subtopic')
        self.assertEqual(topic_change_object.skill_id, 'skill_id')
        self.assertEqual(topic_change_object.old_subtopic_id,
                         'old_subtopic_id')
        self.assertEqual(topic_change_object.new_subtopic_id,
                         'new_subtopic_id')
示例#9
0
 def test_get_all_skill_ids_assigned_to_some_topic(self):
     change_list = [
         topic_domain.TopicChange({
             'cmd': topic_domain.CMD_MOVE_SKILL_ID_TO_SUBTOPIC,
             'old_subtopic_id': None,
             'new_subtopic_id': 1,
             'skill_id': self.skill_id_1
         })
     ]
     topic_services.update_topic_and_subtopic_pages(
         self.user_id_admin, self.TOPIC_ID, change_list,
         'Moved skill to subtopic.')
     topic_id = topic_services.get_new_topic_id()
     self.save_new_topic(topic_id, self.user_id, 'Name 2', 'Description',
                         [], [], [self.skill_id_1, 'skill_3'], [], 1)
     self.assertEqual(
         topic_services.get_all_skill_ids_assigned_to_some_topic(),
         set([self.skill_id_1, self.skill_id_2, 'skill_3']))
示例#10
0
    def setUp(self):
        super(TopicFetchersUnitTests, self).setUp()
        self.TOPIC_ID = topic_services.get_new_topic_id()
        changelist = [
            topic_domain.TopicChange({
                'cmd': topic_domain.CMD_ADD_SUBTOPIC,
                'title': 'Title',
                'subtopic_id': 1
            })
        ]
        self.save_new_topic(
            self.TOPIC_ID,
            self.user_id,
            name='Name',
            abbreviated_name='abbrev',
            thumbnail_filename='img.png',
            description='Description',
            canonical_story_ids=[self.story_id_1, self.story_id_2],
            additional_story_ids=[self.story_id_3],
            uncategorized_skill_ids=[self.skill_id_1, self.skill_id_2],
            subtopics=[],
            next_subtopic_id=1)
        self.save_new_story(self.story_id_1, self.user_id, 'Title',
                            'Description', 'Notes', self.TOPIC_ID)
        self.save_new_story(self.story_id_3, self.user_id, 'Title 3',
                            'Description 3', 'Notes', self.TOPIC_ID)
        self.signup('*****@*****.**', 'A')
        self.signup('*****@*****.**', 'B')
        self.signup(self.ADMIN_EMAIL, username=self.ADMIN_USERNAME)

        self.user_id_a = self.get_user_id_from_email('*****@*****.**')
        self.user_id_b = self.get_user_id_from_email('*****@*****.**')
        self.user_id_admin = self.get_user_id_from_email(self.ADMIN_EMAIL)
        topic_services.update_topic_and_subtopic_pages(self.user_id_admin,
                                                       self.TOPIC_ID,
                                                       changelist,
                                                       'Added a subtopic')

        self.topic = topic_fetchers.get_topic_by_id(self.TOPIC_ID)
        self.set_admins([self.ADMIN_USERNAME])
        self.set_topic_managers([user_services.get_username(self.user_id_a)])
        self.user_a = user_services.UserActionsInfo(self.user_id_a)
        self.user_b = user_services.UserActionsInfo(self.user_id_b)
        self.user_admin = user_services.UserActionsInfo(self.user_id_admin)
示例#11
0
def replace_skill_id_in_all_topics(user_id, old_skill_id, new_skill_id):
    """Replaces the old skill id with the new one in all the associated topics.

    Args:
        user_id: str. The unique user ID of the user.
        old_skill_id: str. The old skill id.
        new_skill_id: str. The new skill id.

    Raises:
        Exception. The new skill already present.
    """
    all_topics = topic_fetchers.get_all_topics()
    for topic in all_topics:
        change_list = []
        if old_skill_id in topic.get_all_skill_ids():
            if new_skill_id in topic.get_all_skill_ids():
                raise Exception(
                    'Found topic \'%s\' contains the two skills to be merged. '
                    'Please unassign one of these skills from topic '
                    'and retry this operation.' % topic.name)
            if old_skill_id in topic.uncategorized_skill_ids:
                change_list.extend([topic_domain.TopicChange({
                    'cmd': 'remove_uncategorized_skill_id',
                    'uncategorized_skill_id': old_skill_id
                }), topic_domain.TopicChange({
                    'cmd': 'add_uncategorized_skill_id',
                    'new_uncategorized_skill_id': new_skill_id
                })])
            for subtopic in topic.subtopics:
                if old_skill_id in subtopic.skill_ids:
                    change_list.extend([topic_domain.TopicChange({
                        'cmd': topic_domain.CMD_REMOVE_SKILL_ID_FROM_SUBTOPIC,
                        'subtopic_id': subtopic.id,
                        'skill_id': old_skill_id
                    }), topic_domain.TopicChange({
                        'cmd': 'remove_uncategorized_skill_id',
                        'uncategorized_skill_id': old_skill_id
                    }), topic_domain.TopicChange({
                        'cmd': 'add_uncategorized_skill_id',
                        'new_uncategorized_skill_id': new_skill_id
                    }), topic_domain.TopicChange({
                        'cmd': topic_domain.CMD_MOVE_SKILL_ID_TO_SUBTOPIC,
                        'old_subtopic_id': None,
                        'new_subtopic_id': subtopic.id,
                        'skill_id': new_skill_id
                    })])
                    break
            topic_services.update_topic_and_subtopic_pages(
                user_id, topic.id, change_list,
                'Replace skill id %s with skill id %s in the topic' % (
                    old_skill_id, new_skill_id))
示例#12
0
def delete_skill(user_id, topic_id, skill_id):
    """Removes skill with given id from the topic.

    Args:
        user_id: str. The id of the user who is performing the action.
        topic_id: str. The id of the topic from which to remove the skill.
        skill_id: str. The skill to remove from the topic.
    """
    topic = get_topic_by_id(topic_id)
    old_skill_ids = copy.deepcopy(topic.skill_ids)
    topic.delete_skill(skill_id)
    change_list = [topic_domain.TopicChange({
        'cmd': 'update_topic_property',
        'property_name': 'skill_ids',
        'old_value': old_skill_ids,
        'new_value': topic.skill_ids
    })]
    update_topic(
        user_id, topic_id, change_list, 'Removed %s from skill ids' % skill_id)
示例#13
0
def add_skill(user_id, topic_id, skill_id):
    """Adds a skill with given id to the topic.

    Args:
        user_id: str. The id of the user who is performing the action.
        topic_id: str. The id of the topic to which the skill is to be added.
        skill_id: str. The skill to add to the topic.
    """
    topic = get_topic_by_id(topic_id)
    old_skill_ids = copy.deepcopy(topic.skill_ids)
    topic.add_skill(skill_id)
    change_list = [topic_domain.TopicChange({
        'cmd': 'update_topic_property',
        'property_name': 'skill_ids',
        'old_value': old_skill_ids,
        'new_value': topic.skill_ids
    })]
    update_topic(
        user_id, topic_id, change_list, 'Added %s to skill ids' % skill_id)
示例#14
0
    def setUp(self):
        """Completes the sign-up process for the various users."""
        super(BaseQuestionsListControllerTests, self).setUp()
        self.signup(self.CURRICULUM_ADMIN_EMAIL,
                    self.CURRICULUM_ADMIN_USERNAME)
        self.admin_id = self.get_user_id_from_email(
            self.CURRICULUM_ADMIN_EMAIL)

        self.set_curriculum_admins([self.CURRICULUM_ADMIN_USERNAME])

        self.admin = user_services.get_user_actions_info(self.admin_id)
        self.skill_id = skill_services.get_new_skill_id()
        self.save_new_skill(self.skill_id,
                            self.admin_id,
                            description='Skill Description')
        self.skill_id_2 = skill_services.get_new_skill_id()
        self.save_new_skill(self.skill_id_2,
                            self.admin_id,
                            description='Skill Description 2')
        self.topic_id = topic_fetchers.get_new_topic_id()
        self.save_new_topic(
            self.topic_id,
            self.admin_id,
            name='Name',
            description='Description',
            canonical_story_ids=[],
            additional_story_ids=[],
            uncategorized_skill_ids=[self.skill_id, self.skill_id_2],
            subtopics=[],
            next_subtopic_id=1)
        self.skill_id_3 = skill_services.get_new_skill_id()
        changelist = [
            topic_domain.TopicChange({
                'cmd': topic_domain.CMD_ADD_SUBTOPIC,
                'title': 'Title',
                'subtopic_id': 1,
                'url_fragment': 'dummy-fragment'
            })
        ]
        topic_services.update_topic_and_subtopic_pages(self.admin_id,
                                                       self.topic_id,
                                                       changelist,
                                                       'Added subtopic.')
示例#15
0
    def setUp(self):
        """Completes the sign-up process for the various users."""
        super(BaseQuestionsListControllerTests, self).setUp()
        self.signup(self.ADMIN_EMAIL, self.ADMIN_USERNAME)
        self.admin_id = self.get_user_id_from_email(self.ADMIN_EMAIL)

        self.set_admins([self.ADMIN_USERNAME])

        self.admin = user_services.UserActionsInfo(self.admin_id)
        self.skill_id = skill_services.get_new_skill_id()
        self.save_new_skill(self.skill_id,
                            self.admin_id,
                            description='Skill Description')
        self.skill_id_2 = skill_services.get_new_skill_id()
        self.save_new_skill(self.skill_id_2,
                            self.admin_id,
                            description='Skill Description 2')
        self.topic_id = topic_services.get_new_topic_id()
        self.save_new_topic(
            self.topic_id,
            self.admin_id,
            name='Name',
            abbreviated_name='abbrev',
            thumbnail_filename=None,
            description='Description',
            canonical_story_ids=[],
            additional_story_ids=[],
            uncategorized_skill_ids=[self.skill_id, self.skill_id_2],
            subtopics=[],
            next_subtopic_id=1)
        self.skill_id_3 = skill_services.get_new_skill_id()
        changelist = [
            topic_domain.TopicChange({
                'cmd': topic_domain.CMD_ADD_SUBTOPIC,
                'title': 'Title',
                'subtopic_id': 1
            })
        ]
        topic_services.update_topic_and_subtopic_pages(self.admin_id,
                                                       self.topic_id,
                                                       changelist,
                                                       'Added subtopic.')
示例#16
0
def add_canonical_story(user_id, topic_id, story_id):
    """Adds a story to the canonical story id list of a topic.

    Args:
        user_id: str. The id of the user who is performing the action.
        topic_id: str. The id of the topic to which the story is to be added.
        story_id: str. The story to add to the topic.
    """
    topic = get_topic_by_id(topic_id)
    old_canonical_story_ids = copy.deepcopy(topic.canonical_story_ids)
    topic.add_canonical_story(story_id)
    change_list = [topic_domain.TopicChange({
        'cmd': 'update_topic_property',
        'property_name': 'canonical_story_ids',
        'old_value': old_canonical_story_ids,
        'new_value': topic.canonical_story_ids
    })]
    update_topic_and_subtopic_pages(
        user_id, topic_id, change_list,
        'Added %s to canonical story ids' % story_id)
示例#17
0
def delete_uncategorized_skill(user_id, topic_id, uncategorized_skill_id):
    """Removes skill with given id from the topic.

    Args:
        user_id: str. The id of the user who is performing the action.
        topic_id: str. The id of the topic from which to remove the skill.
        uncategorized_skill_id: str. The uncategorized skill to remove from the
            topic.
    """
    change_list = [
        topic_domain.TopicChange({
            'cmd':
            'remove_uncategorized_skill_id',
            'uncategorized_skill_id':
            uncategorized_skill_id
        })
    ]
    update_topic_and_subtopic_pages(
        user_id, topic_id, change_list,
        'Removed %s from uncategorized skill ids' % uncategorized_skill_id)
示例#18
0
 def setUp(self) -> None:
     super(SubtopicPageServicesUnitTests, self).setUp()
     self.TOPIC_ID = topic_fetchers.get_new_topic_id(
     )  # type: ignore[no-untyped-call]
     self.subtopic_page = (
         subtopic_page_domain.SubtopicPage.
         create_default_subtopic_page(  # type: ignore[no-untyped-call]
             self.subtopic_id, self.TOPIC_ID))
     subtopic_page_services.save_subtopic_page(
         self.user_id, self.subtopic_page, 'Added subtopic', [
             topic_domain.TopicChange({
                 'cmd': topic_domain.CMD_ADD_SUBTOPIC,
                 'subtopic_id': 1,
                 'title': 'Sample',
                 'url_fragment': 'sample-fragment'
             })
         ])
     self.subtopic_page_id = (
         subtopic_page_domain.SubtopicPage.get_subtopic_page_id(
             self.TOPIC_ID, 1))
示例#19
0
    def test_get_topic_by_version(self):
        topic_id = topic_services.get_new_topic_id()
        self.save_new_topic(
            topic_id, self.user_id, 'topic name', 'Description',
            [], [], [], [], 1)

        changelist = [topic_domain.TopicChange({
            'cmd': topic_domain.CMD_UPDATE_TOPIC_PROPERTY,
            'property_name': topic_domain.TOPIC_PROPERTY_LANGUAGE_CODE,
            'old_value': 'en',
            'new_value': 'bn'
        })]
        topic_services.update_topic_and_subtopic_pages(
            self.user_id, topic_id, changelist, 'Change language code')

        topic_v0 = topic_services.get_topic_by_id(topic_id, version=0)
        topic_v1 = topic_services.get_topic_by_id(topic_id, version=1)

        self.assertEqual(topic_v1.language_code, 'en')
        self.assertEqual(topic_v0.language_code, 'bn')
示例#20
0
    def test_update_subtopic_property(self):
        topic = topic_services.get_topic_by_id(self.TOPIC_ID)

        self.assertEqual(len(topic.subtopics), 1)
        self.assertEqual(topic.subtopics[0].title, 'Title')

        changelist = [topic_domain.TopicChange({
            'cmd': topic_domain.CMD_UPDATE_SUBTOPIC_PROPERTY,
            'property_name': 'title',
            'subtopic_id': 1,
            'old_value': 'Title',
            'new_value': 'New Title'
        })]
        topic_services.update_topic_and_subtopic_pages(
            self.user_id_admin, self.TOPIC_ID, changelist,
            'Update title of subtopic.')
        topic = topic_services.get_topic_by_id(self.TOPIC_ID)

        self.assertEqual(len(topic.subtopics), 1)
        self.assertEqual(topic.subtopics[0].title, 'New Title')
示例#21
0
def add_uncategorized_skill(user_id, topic_id, uncategorized_skill_id):
    """Adds a skill with given id to the topic.

    Args:
        user_id: str. The id of the user who is performing the action.
        topic_id: str. The id of the topic to which the skill is to be added.
        uncategorized_skill_id: str. The id of the uncategorized skill to add
            to the topic.
    """
    change_list = [
        topic_domain.TopicChange({
            'cmd':
            'add_uncategorized_skill_id',
            'new_uncategorized_skill_id':
            uncategorized_skill_id
        })
    ]
    update_topic_and_subtopic_pages(
        user_id, topic_id, change_list,
        'Added %s to uncategorized skill ids' % uncategorized_skill_id)
示例#22
0
 def test_get_all_skill_ids_assigned_to_some_topic(self):
     change_list = [topic_domain.TopicChange({
         'cmd': topic_domain.CMD_MOVE_SKILL_ID_TO_SUBTOPIC,
         'old_subtopic_id': None,
         'new_subtopic_id': 1,
         'skill_id': self.skill_id_1
     })]
     topic_services.update_topic_and_subtopic_pages(
         self.user_id_admin, self.TOPIC_ID, change_list,
         'Moved skill to subtopic.')
     topic_id = topic_fetchers.get_new_topic_id()
     self.save_new_topic(
         topic_id, self.user_id, name='Name 2', description='Description',
         abbreviated_name='random', url_fragment='name-three',
         canonical_story_ids=[], additional_story_ids=[],
         uncategorized_skill_ids=[self.skill_id_1, 'skill_3'],
         subtopics=[], next_subtopic_id=1)
     self.assertEqual(
         topic_fetchers.get_all_skill_ids_assigned_to_some_topic(),
         {self.skill_id_1, self.skill_id_2, 'skill_3'})
示例#23
0
    def test_opportunities_updates_with_updating_topic_name(self):
        story_services.update_story(self.owner_id, self.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': '0'
            })
        ], 'Changes.')

        translation_opportunities, _, _ = (
            opportunity_services.get_translation_opportunities('hi', None))
        self.assertEqual(len(translation_opportunities), 1)

        opportunity = translation_opportunities[0]
        self.assertEqual(opportunity['story_title'], 'A story')
        self.assertEqual(opportunity['topic_name'], 'topic')

        topic_services.update_topic_and_subtopic_pages(
            self.owner_id, self.TOPIC_ID, [
                topic_domain.TopicChange({
                    'cmd': 'update_topic_property',
                    'property_name': 'name',
                    'old_value': 'topic',
                    'new_value': 'A new topic'
                })
            ], 'Change topic title.')

        translation_opportunities, _, _ = (
            opportunity_services.get_translation_opportunities('hi', None))
        self.assertEqual(len(translation_opportunities), 1)

        opportunity = translation_opportunities[0]
        self.assertEqual(opportunity['story_title'], 'A story')
        self.assertEqual(opportunity['topic_name'], 'A new topic')
示例#24
0
def save_new_topic(committer_id, topic):
    """Saves a new topic.

    Args:
        committer_id: str. ID of the committer.
        topic: Topic. Topic to be saved.

    Raises:
        Exception. Topic with same name already exists.
    """
    existing_topic = get_topic_by_name(topic.name)
    if existing_topic is not None:
        raise Exception('Topic with name \'%s\' already exists' % topic.name)

    commit_message = ('New topic created with name \'%s\'.' % topic.name)
    _create_topic(committer_id, topic, commit_message, [
        topic_domain.TopicChange({
            'cmd': topic_domain.CMD_CREATE_NEW,
            'name': topic.name
        })
    ])
示例#25
0
def unpublish_story(topic_id, story_id, committer_id):
    """Marks the given story as unpublished.

    Args:
        topic_id: str. The id of the topic.
        story_id: str. The id of the given story.
        committer_id: str. ID of the committer.

    Raises:
        Exception. The given story does not exist.
        Exception. The story is already unpublished.
        Exception. The user does not have enough rights to unpublish the story.
    """
    user = user_services.get_user_actions_info(committer_id)
    if role_services.ACTION_CHANGE_STORY_STATUS not in user.actions:
        raise Exception(
            'The user does not have enough rights to unpublish the story.')
    topic = topic_fetchers.get_topic_by_id(topic_id, strict=None)
    if topic is None:
        raise Exception('A topic with the given ID doesn\'t exist')
    story = story_fetchers.get_story_by_id(story_id, strict=False)
    if story is None:
        raise Exception('A story with the given ID doesn\'t exist')
    topic.unpublish_story(story_id)
    change_list = [
        topic_domain.TopicChange({
            'cmd': topic_domain.CMD_UNPUBLISH_STORY,
            'story_id': story_id
        })
    ]
    _save_topic(committer_id, topic, 'Unpublished story with id %s' % story_id,
                change_list)
    generate_topic_summary(topic.id)

    # Delete corresponding exploration opportunities and reject associated
    # translation suggestions.
    exp_ids = story.story_contents.get_all_linked_exp_ids()
    opportunity_services.delete_exploration_opportunities(exp_ids)
    suggestion_services.auto_reject_translation_suggestions_for_exp_ids(
        exp_ids)
示例#26
0
    def setUp(self):
        """Completes the sign-up process for the various users."""
        super(BaseTopicEditorControllerTests, self).setUp()
        self.signup(self.TOPIC_MANAGER_EMAIL, self.TOPIC_MANAGER_USERNAME)
        self.signup(self.NEW_USER_EMAIL, self.NEW_USER_USERNAME)
        self.signup(self.ADMIN_EMAIL, self.ADMIN_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_manager = user_services.UserActionsInfo(
            self.topic_manager_id)
        self.admin = user_services.UserActionsInfo(self.admin_id)
        self.new_user = user_services.UserActionsInfo(self.new_user_id)
        self.skill_id = skill_services.get_new_skill_id()
        self.save_new_skill(self.skill_id, self.admin_id, 'Skill Description')
        self.skill_id_2 = skill_services.get_new_skill_id()
        self.save_new_skill(self.skill_id_2, self.admin_id,
                            'Skill Description 2')
        self.topic_id = topic_services.get_new_topic_id()
        self.save_new_topic(self.topic_id, self.admin_id, 'Name',
                            'Description', [], [],
                            [self.skill_id, self.skill_id_2], [], 1)
        changelist = [
            topic_domain.TopicChange({
                'cmd': topic_domain.CMD_ADD_SUBTOPIC,
                'title': 'Title',
                'subtopic_id': 1
            })
        ]
        topic_services.update_topic_and_subtopic_pages(self.admin_id,
                                                       self.topic_id,
                                                       changelist,
                                                       'Added subtopic.')
示例#27
0
    def _publish_valid_topic(self, topic, uncategorized_skill_ids):
        """Saves and publishes a valid topic with linked skills and subtopic.

        Args:
            topic: Topic. The topic to be saved and published.
            uncategorized_skill_ids: list(str). List of uncategorized skills IDs
                to add to the supplied topic.
        """
        topic.thumbnail_filename = 'thumbnail.svg'
        topic.thumbnail_bg_color = '#C6DCDA'
        subtopic_id = 1
        subtopic_skill_id = 'subtopic_skill_id' + topic.id
        topic.subtopics = [
            topic_domain.Subtopic(
                subtopic_id, 'Title', [subtopic_skill_id], 'image.svg',
                constants.ALLOWED_THUMBNAIL_BG_COLORS['subtopic'][0], 21131,
                'dummy-subtopic')
        ]
        topic.next_subtopic_id = 2
        subtopic_page = (
            subtopic_page_domain.SubtopicPage.create_default_subtopic_page(
                subtopic_id, topic.id))
        subtopic_page_services.save_subtopic_page(
            self.owner_id, subtopic_page, 'Added subtopic', [
                topic_domain.TopicChange({
                    'cmd': topic_domain.CMD_ADD_SUBTOPIC,
                    'subtopic_id': 1,
                    'title': 'Sample'
                })
            ])
        topic_services.save_new_topic(self.owner_id, topic)
        topic_services.publish_topic(topic.id, self.admin_id)

        for skill_id in uncategorized_skill_ids:
            self.save_new_skill(skill_id,
                                self.admin_id,
                                description='skill_description')
            topic_services.add_uncategorized_skill(self.admin_id, topic.id,
                                                   skill_id)
示例#28
0
    def test_migrate_subtopic_to_latest_schema(self):
        topic_services.create_new_topic_rights('topic_id', 'user_id_admin')
        commit_cmd = topic_domain.TopicChange({
            'cmd': topic_domain.CMD_CREATE_NEW,
            'name': 'name'
        })
        subtopic_dict = {
            'id': 1,
            'title': 'subtopic_title',
            'skill_ids': []
        }
        model = topic_models.TopicModel(
            id='topic_id',
            name='name',
            canonical_name='Name',
            next_subtopic_id=1,
            language_code='en',
            subtopics=[subtopic_dict],
            subtopic_schema_version=1
        )
        commit_cmd_dicts = [commit_cmd.to_dict()]
        model.commit(
            'user_id_admin', 'topic model created', commit_cmd_dicts)

        swap_topic_object = self.swap(topic_domain, 'Topic', MockTopicObject)
        current_schema_version_swap = self.swap(
            feconf, 'CURRENT_SUBTOPIC_SCHEMA_VERSION', 2)

        with swap_topic_object, current_schema_version_swap:
            topic = topic_services.get_topic_from_model(model)

        self.assertEqual(topic.subtopic_schema_version, 2)
        self.assertEqual(topic.name, 'name')
        self.assertEqual(topic.canonical_name, 'name')
        self.assertEqual(topic.next_subtopic_id, 1)
        self.assertEqual(topic.language_code, 'en')
        self.assertEqual(len(topic.subtopics), 1)
        self.assertEqual(topic.subtopics[0].to_dict(), subtopic_dict)
示例#29
0
def delete_story(user_id, topic_id, story_id):
    """Removes story with given id from the topic.

    NOTE TO DEVELOPERS: Presently, this function only removes story_id from
    canonical_story_ids list.

    Args:
        user_id: str. The id of the user who is performing the action.
        topic_id: str. The id of the topic from which to remove the story.
        story_id: str. The story to remove from the topic.
    """
    topic = get_topic_by_id(topic_id)
    old_canonical_story_ids = copy.deepcopy(topic.canonical_story_ids)
    topic.delete_story(story_id)
    change_list = [topic_domain.TopicChange({
        'cmd': 'update_topic_property',
        'property_name': 'canonical_story_ids',
        'old_value': old_canonical_story_ids,
        'new_value': topic.canonical_story_ids
    })]
    update_topic_and_subtopic_pages(
        user_id, topic_id, change_list,
        'Removed %s from canonical story ids' % story_id)
    def test_job_when_subtopics_do_not_have_math_rich_text(self):
        topic_id1 = topic_services.get_new_topic_id()
        subtopic_page1 = (
            subtopic_page_domain.SubtopicPage.create_default_subtopic_page(
                1, topic_id1))
        subtopic_page_services.save_subtopic_page(
            self.albert_id, subtopic_page1, 'Added subtopic', [
                topic_domain.TopicChange({
                    'cmd': topic_domain.CMD_ADD_SUBTOPIC,
                    'subtopic_id': 1,
                    'title': 'Sample'
                })
            ])

        job_id = (
            topic_jobs_one_off.SubTopicPageMathRteAuditOneOffJob.create_new())
        topic_jobs_one_off.SubTopicPageMathRteAuditOneOffJob.enqueue(job_id)
        self.process_and_flush_pending_tasks()

        output = (topic_jobs_one_off.SubTopicPageMathRteAuditOneOffJob.
                  get_output(job_id))

        self.assertEqual(output, [])