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))
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)
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)
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)
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)
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)
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')
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']))
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)
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))
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)
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)
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.')
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.')
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)
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)
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))
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')
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')
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)
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'})
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')
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 }) ])
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)
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.')
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)
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)
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, [])