def test_cannot_mark_node_outline_as_unfinalized_with_invalid_node_id( self): change_list = [ story_domain.StoryChange({ 'cmd': story_domain.CMD_UPDATE_STORY_NODE_OUTLINE_STATUS, 'node_id': 'invalid_node', 'old_value': '', 'new_value': '' }) ] with self.assertRaisesRegexp( Exception, 'The node with id invalid_node is not part of this story'): story_services.update_story(self.USER_ID, self.STORY_ID, change_list, 'Mark node outline as unfinalized.')
def test_cannot_update_initial_node_with_invalid_node_id(self): change_list = [ story_domain.StoryChange({ 'cmd': story_domain.CMD_UPDATE_STORY_CONTENTS_PROPERTY, 'property_name': story_domain.INITIAL_NODE_ID, 'old_value': '', 'new_value': 'new_initial_node_id' }) ] with self.assertRaisesRegexp( Exception, 'The node with id new_initial_node_id is not part of this story' ): story_services.update_story(self.USER_ID, self.STORY_ID, change_list, 'Updated story initial_node_id.')
def test_opportunity_get_deleted_with_removing_exploration_from_story_node( self): self.add_exploration_0_to_story() translation_opportunities, _, _ = ( opportunity_services.get_translation_opportunities('hi', None)) self.assertEqual(len(translation_opportunities), 1) story_services.update_story( self.owner_id, self.STORY_ID, [story_domain.StoryChange({ 'cmd': 'delete_story_node', 'node_id': 'node_1', })], 'Deleted one node.') translation_opportunities, _, _ = ( opportunity_services.get_translation_opportunities('hi', None)) self.assertEqual(len(translation_opportunities), 0)
def setUp(self): super(OpportunityServicesUnitTest, self).setUp() self.signup(self.OWNER_EMAIL, self.OWNER_USERNAME) self.owner_id = self.get_user_id_from_email(self.OWNER_EMAIL) self.TOPIC_ID = 'topic' self.STORY_ID = 'story' explorations = [ self.save_new_valid_exploration('%s' % i, self.owner_id, title='title %d' % i, category='category%d' % i, end_state_name='End State') for i in python_utils.RANGE(5) ] for exp in explorations: self.publish_exploration(self.owner_id, exp.id) topic = topic_domain.Topic.create_default_topic( topic_id=self.TOPIC_ID, name='topic', abbreviated_name='abbrev') topic_services.save_new_topic(self.owner_id, topic) story = story_domain.Story.create_default_story( self.STORY_ID, title='A story', corresponding_topic_id=self.TOPIC_ID) story_services.save_new_story(self.owner_id, story) topic_services.add_canonical_story(self.owner_id, self.TOPIC_ID, self.STORY_ID) 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.')
def setUp(self): super(TranslatableTextHandlerTest, self).setUp() self.signup(self.OWNER_EMAIL, self.OWNER_USERNAME) self.owner_id = self.get_user_id_from_email(self.OWNER_EMAIL) explorations = [self.save_new_valid_exploration( '%s' % i, self.owner_id, title='title %d' % i, category='category%d' % i, end_state_name='End State' ) for i in python_utils.RANGE(2)] for exp in explorations: self.publish_exploration(self.owner_id, exp.id) topic = topic_domain.Topic.create_default_topic( '0', 'topic', 'abbrev', 'description') topic_services.save_new_topic(self.owner_id, topic) stories = [story_domain.Story.create_default_story( '%s' % i, 'title %d' % i, 'description %d' % i, '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.')
def test_update_story_language_code(self): story = story_fetchers.get_story_by_id(self.STORY_ID) self.assertEqual(story.language_code, 'en') change_list = [story_domain.StoryChange({ 'cmd': story_domain.CMD_UPDATE_STORY_PROPERTY, 'property_name': story_domain.STORY_PROPERTY_LANGUAGE_CODE, 'old_value': 'en', 'new_value': 'bn' })] story_services.update_story( self.USER_ID, self.STORY_ID, change_list, 'Updated story language_code.') story = story_fetchers.get_story_by_id(self.STORY_ID) self.assertEqual(story.language_code, 'bn')
def test_cannot_update_node_exploration_id_with_invalid_node_id(self): change_list = [ story_domain.StoryChange({ 'cmd': story_domain.CMD_UPDATE_STORY_NODE_PROPERTY, 'property_name': story_domain.STORY_NODE_PROPERTY_EXPLORATION_ID, 'node_id': 'invalid_node', 'old_value': '', 'new_value': 'exp_id' }) ] with self.assertRaisesRegexp( Exception, 'The node with id invalid_node is not part of this story'): story_services.update_story(self.USER_ID, self.STORY_ID, change_list, 'Updated story node_exploration_id.')
def setUp(self): super(StoryFetchersUnitTests, self).setUp() self.STORY_ID = story_services.get_new_story_id() self.TOPIC_ID = topic_fetchers.get_new_topic_id() self.save_new_topic(self.TOPIC_ID, self.USER_ID, name='Topic', description='A new topic', canonical_story_ids=[], additional_story_ids=[], uncategorized_skill_ids=[], subtopics=[], next_subtopic_id=0) self.save_new_story(self.STORY_ID, self.USER_ID, self.TOPIC_ID) topic_services.add_canonical_story(self.USER_ID, self.TOPIC_ID, self.STORY_ID) changelist = [ story_domain.StoryChange({ 'cmd': story_domain.CMD_ADD_STORY_NODE, 'node_id': self.NODE_ID_1, 'title': 'Title 1' }) ] story_services.update_story(self.USER_ID, self.STORY_ID, changelist, 'Added node.') self.story = story_fetchers.get_story_by_id(self.STORY_ID) self.signup('*****@*****.**', 'A') self.signup('*****@*****.**', 'B') self.signup(self.CURRICULUM_ADMIN_EMAIL, self.CURRICULUM_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.CURRICULUM_ADMIN_EMAIL)) self.set_curriculum_admins([self.CURRICULUM_ADMIN_USERNAME]) self.set_topic_managers([user_services.get_username(self.user_id_a)], self.TOPIC_ID) self.user_a = user_services.get_user_actions_info(self.user_id_a) self.user_b = user_services.get_user_actions_info(self.user_id_b) self.user_admin = user_services.get_user_actions_info( self.user_id_admin)
def test_publish_and_unpublish_story(self): self.save_new_story('public_story', self.USER_ID, 'Title', 'Description', 'Notes', self.TOPIC_ID) topic_services.add_canonical_story(self.USER_ID, self.TOPIC_ID, 'public_story') changelist = [ story_domain.StoryChange({ 'cmd': story_domain.CMD_ADD_STORY_NODE, 'node_id': self.NODE_ID_1, 'title': 'Title 1' }) ] story_services.update_story(self.USER_ID, 'public_story', changelist, 'Added node.') self.save_new_default_exploration('exp_id', self.user_id_a, title='title') self.publish_exploration(self.user_id_a, 'exp_id') change_list = [ story_domain.StoryChange({ 'cmd': story_domain.CMD_UPDATE_STORY_NODE_PROPERTY, 'property_name': (story_domain.STORY_NODE_PROPERTY_EXPLORATION_ID), 'node_id': 'node_1', 'old_value': None, 'new_value': 'exp_id' }) ] story_services.update_story(self.USER_ID, 'public_story', change_list, 'Updated story node.') story_rights = story_services.get_story_rights('public_story') self.assertFalse(story_rights.story_is_published) story_services.publish_story('public_story', self.user_id_admin) with self.assertRaisesRegexp( Exception, 'The user does not have enough rights to unpublish the story.' ): story_services.unpublish_story('public_story', self.user_id_a)
def test_update_story_node_outline(self): story = story_fetchers.get_story_by_id(self.STORY_ID) self.assertEqual(story.story_contents.nodes[0].outline, '') change_list = [story_domain.StoryChange({ 'cmd': story_domain.CMD_UPDATE_STORY_NODE_PROPERTY, 'property_name': ( story_domain.STORY_NODE_PROPERTY_OUTLINE), 'node_id': 'node_1', 'old_value': '', 'new_value': 'new_outline' })] story_services.update_story( self.USER_ID, self.STORY_ID, change_list, 'Updated story outline.') story = story_fetchers.get_story_by_id(self.STORY_ID) self.assertEqual(story.story_contents.nodes[0].outline, 'new_outline')
def test_cannot_update_story_with_non_story_change_changelist(self): observed_log_messages = [] def _mock_logging_function(msg, *args): """Mocks logging.error().""" observed_log_messages.append(msg % args) logging_swap = self.swap(logging, 'error', _mock_logging_function) assert_raises_regexp_context_manager = self.assertRaisesRegexp( Exception, 'Expected change to be of type StoryChange') with logging_swap, assert_raises_regexp_context_manager: story_services.update_story(self.USER_ID, self.STORY_ID, [{}], 'Updated story node.') self.assertEqual(observed_log_messages, [ 'Exception Expected change to be of type StoryChange %s [{}]' % self.STORY_ID ])
def test_update_story_notes(self): story = story_fetchers.get_story_by_id(self.STORY_ID) self.assertEqual(story.notes, 'Notes') change_list = [ story_domain.StoryChange({ 'cmd': story_domain.CMD_UPDATE_STORY_PROPERTY, 'property_name': story_domain.STORY_PROPERTY_NOTES, 'old_value': 'Notes', 'new_value': 'New notes' }) ] story_services.update_story(self.USER_ID, self.STORY_ID, change_list, 'Updated story notes.') story = story_fetchers.get_story_by_id(self.STORY_ID) self.assertEqual(story.notes, 'New notes')
def test_update_story_with_invalid_corresponding_topic_id_value(self): topic_id = topic_services.get_new_topic_id() story_id = story_services.get_new_story_id() self.save_new_story( story_id, self.USER_ID, 'Title', 'Description', 'Notes', topic_id) changelist = [ story_domain.StoryChange({ 'cmd': story_domain.CMD_ADD_STORY_NODE, 'node_id': self.NODE_ID_1, 'title': 'Title 1' }) ] with self.assertRaisesRegexp( Exception, ('Expected story to only belong to a valid topic, but ' 'found an topic with ID: %s' % topic_id)): story_services.update_story( self.USER_ID, story_id, changelist, 'Added node.')
def test_cannot_delete_starting_node_of_story(self): changelist = [ story_domain.StoryChange({ 'cmd': story_domain.CMD_ADD_STORY_NODE, 'node_id': self.NODE_ID_2, 'title': 'Title 2' }), story_domain.StoryChange({ 'cmd': story_domain.CMD_UPDATE_STORY_NODE_PROPERTY, 'property_name': ( story_domain.STORY_NODE_PROPERTY_DESTINATION_NODE_IDS), 'node_id': self.NODE_ID_2, 'old_value': [], 'new_value': [self.NODE_ID_1] }), story_domain.StoryChange({ 'cmd': story_domain.CMD_UPDATE_STORY_NODE_OUTLINE_STATUS, 'node_id': self.NODE_ID_2, 'old_value': False, 'new_value': True }), story_domain.StoryChange({ 'cmd': story_domain.CMD_UPDATE_STORY_CONTENTS_PROPERTY, 'property_name': ( story_domain.INITIAL_NODE_ID), 'old_value': self.NODE_ID_1, 'new_value': self.NODE_ID_2 }) ] story_services.update_story( self.USER_ID, self.STORY_ID, changelist, 'Added node.') change_list = [story_domain.StoryChange({ 'cmd': story_domain.CMD_DELETE_STORY_NODE, 'node_id': self.NODE_ID_2 })] with self.assertRaisesRegexp( Exception, 'The node with id %s is the starting node for the story, ' 'change the starting node before deleting it.' % self.NODE_ID_2): story_services.update_story( self.USER_ID, self.STORY_ID, change_list, 'Delete node.')
def test_cannot_update_story_with_mismatch_of_story_versions(self): self.save_new_default_exploration('exp_id', self.user_id_a, title='title') self.publish_exploration(self.user_id_a, 'exp_id') change_list = [ story_domain.StoryChange({ 'cmd': story_domain.CMD_UPDATE_STORY_NODE_PROPERTY, 'property_name': (story_domain.STORY_NODE_PROPERTY_EXPLORATION_ID), 'node_id': self.NODE_ID_1, 'old_value': None, 'new_value': 'exp_id' }) ] story_model = story_models.StoryModel.get(self.STORY_ID) story_model.version = 0 story_model.commit(self.user_id_a, 'Changed version', []) with self.assertRaisesRegexp( Exception, 'Unexpected error: trying to update version 1 of story ' 'from version 2. Please reload the page and try again.'): story_services.update_story(self.USER_ID, self.STORY_ID, change_list, 'Updated story node.') story_model = story_models.StoryModel.get(self.STORY_ID) story_model.version = 10 story_model.commit(self.user_id_a, 'Changed version', []) with self.assertRaisesRegexp( Exception, 'Trying to update version 11 of story from version 2, ' 'which is too old. Please reload the page and try again.'): story_services.update_story(self.USER_ID, self.STORY_ID, change_list, 'Updated story node.')
def setUp(self): super(StoryServicesUnitTests, self).setUp() self.STORY_ID = story_services.get_new_story_id() self.TOPIC_ID = topic_services.get_new_topic_id() self.save_new_topic(self.TOPIC_ID, self.USER_ID, name='Topic', abbreviated_name='abbrev', thumbnail_filename=None, description='A new topic', canonical_story_ids=[], additional_story_ids=[], uncategorized_skill_ids=[], subtopics=[], next_subtopic_id=0) self.save_new_story(self.STORY_ID, self.USER_ID, 'Title', 'Description', 'Notes', self.TOPIC_ID) topic_services.add_canonical_story(self.USER_ID, self.TOPIC_ID, self.STORY_ID) changelist = [ story_domain.StoryChange({ 'cmd': story_domain.CMD_ADD_STORY_NODE, 'node_id': self.NODE_ID_1, 'title': 'Title 1' }) ] story_services.update_story(self.USER_ID, self.STORY_ID, changelist, 'Added node.') self.story = story_fetchers.get_story_by_id(self.STORY_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) 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 test_cannot_update_destination_node_ids_with_invalid_node_id(self): change_list = [ story_domain.StoryChange({ 'cmd': story_domain.CMD_UPDATE_STORY_NODE_PROPERTY, 'property_name': (story_domain.STORY_NODE_PROPERTY_DESTINATION_NODE_IDS), 'node_id': 'invalid_node', 'old_value': [], 'new_value': [] }) ] with self.assertRaisesRegexp( Exception, 'The node with id invalid_node is not part of this story'): story_services.update_story( self.USER_ID, self.STORY_ID, change_list, 'Updated story new_destination_node_ids.')
def test_cannot_update_node_exploration_id_with_existing_exploration_id( self): self.save_new_default_exploration('exp_id', self.user_id_a, title='title') self.publish_exploration(self.user_id_a, 'exp_id') change_list = [ story_domain.StoryChange({ 'cmd': story_domain.CMD_UPDATE_STORY_NODE_PROPERTY, 'property_name': (story_domain.STORY_NODE_PROPERTY_EXPLORATION_ID), 'node_id': self.NODE_ID_1, 'old_value': None, 'new_value': 'exp_id' }) ] story_services.update_story(self.USER_ID, self.STORY_ID, change_list, 'Updated story node.') change_list = [ story_domain.StoryChange({ 'cmd': story_domain.CMD_UPDATE_STORY_NODE_PROPERTY, 'property_name': story_domain.STORY_NODE_PROPERTY_EXPLORATION_ID, 'node_id': self.NODE_ID_1, 'old_value': '', 'new_value': 'exp_id' }) ] with self.assertRaisesRegexp( Exception, 'A node with exploration id exp_id already exists.'): story_services.update_story(self.USER_ID, self.STORY_ID, change_list, 'Updated story node_exploration_id.')
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 update_story_and_topic_summary(committer_id, story_id, change_list, commit_message, topic_id): """Updates a story. Commits changes. Then generates a new topic summary. Args: committer_id: str. The id of the user who is performing the update action. story_id: str. The story id. change_list: list(StoryChange). These changes are applied in sequence to produce the resulting story. commit_message: str or None. A description of changes made to the story. topic_id: str. The id of the topic to which the story is belongs. """ story_services.update_story(committer_id, story_id, change_list, commit_message) # Generate new TopicSummary after a Story has been updated to # make sure the TopicSummaryTile displays the correct number # of chapters on the classroom page. generate_topic_summary(topic_id)
def test_cannot_update_story_with_invalid_exploration_id(self): change_list = [ story_domain.StoryChange({ 'cmd': story_domain.CMD_UPDATE_STORY_NODE_PROPERTY, 'property_name': (story_domain.STORY_NODE_PROPERTY_EXPLORATION_ID), 'node_id': self.NODE_ID_1, 'old_value': None, 'new_value': 'invalid_exp_id' }) ] with self.assertRaisesRegexp( Exception, 'Expected story to only reference valid explorations'): story_services.update_story(self.USER_ID, self.STORY_ID, change_list, 'Updated story node.')
def test_verification_is_unsuccessful_when_deletion_failed(self): wipeout_service.delete_user( wipeout_service.get_pending_deletion_request(self.user_2_id)) story_services.update_story(self.user_2_id, self.STORY_2_ID, [ story_domain.StoryChange({ 'cmd': story_domain.CMD_ADD_STORY_NODE, 'node_id': 'node_1', 'title': 'Title 2' }) ], 'Add node.') self.assertFalse( wipeout_service.verify_user_deleted( wipeout_service.get_pending_deletion_request(self.user_2_id))) wipeout_service.delete_user( wipeout_service.get_pending_deletion_request(self.user_2_id)) self.assertTrue( wipeout_service.verify_user_deleted( wipeout_service.get_pending_deletion_request(self.user_2_id)))
def test_update_story_acquired_skill_ids(self): story = story_fetchers.get_story_by_id(self.STORY_ID) self.assertEqual(story.story_contents.nodes[0].acquired_skill_ids, []) change_list = [story_domain.StoryChange({ 'cmd': story_domain.CMD_UPDATE_STORY_NODE_PROPERTY, 'property_name': ( story_domain.STORY_NODE_PROPERTY_ACQUIRED_SKILL_IDS), 'node_id': 'node_1', 'old_value': [], 'new_value': ['skill_id'] })] story_services.update_story( self.USER_ID, self.STORY_ID, change_list, 'Updated story acquired_skill_ids.') story = story_fetchers.get_story_by_id(self.STORY_ID) self.assertEqual( story.story_contents.nodes[0].acquired_skill_ids, ['skill_id'])
def test_opportunity_updates_with_updating_story_node_title(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['chapter_title'], 'Node1') story_services.update_story(self.owner_id, self.STORY_ID, [ story_domain.StoryChange({ 'cmd': 'update_story_node_property', 'property_name': 'title', 'node_id': 'node_1', 'old_value': 'Node1', 'new_value': 'A new Node1' }) ], 'Change node title.') translation_opportunities, _, _ = ( opportunity_services.get_translation_opportunities('hi', None)) self.assertEqual(len(translation_opportunities), 1) opportunity = translation_opportunities[0] self.assertEqual(opportunity['chapter_title'], 'A new Node1')
def test_post_returns_ready_for_review_when_acquired_skills_exist(self): csrf_token = self.get_new_csrf_token() self.save_new_skill('skill_1', self.admin_id, description='Skill Description') self.save_new_question('question_1', self.admin_id, self._create_valid_question_data('ABC'), ['skill_1']) question_services.create_new_question_skill_link( self.admin_id, 'question_1', 'skill_1', 0.3) changelist = [ story_domain.StoryChange({ 'cmd': story_domain.CMD_UPDATE_STORY_NODE_PROPERTY, 'property_name': (story_domain.STORY_NODE_PROPERTY_ACQUIRED_SKILL_IDS), 'node_id': self.NODE_ID_1, 'old_value': [], 'new_value': ['skill_1'] }) ] story_services.update_story(self.admin_id, self.STORY_ID, changelist, 'Added acquired skill.') story_services.record_completed_node_in_story_context( self.viewer_id, self.STORY_ID, self.NODE_ID_2) story_services.record_completed_node_in_story_context( self.viewer_id, self.STORY_ID, self.NODE_ID_1) with self.swap(constants, 'ENABLE_NEW_STRUCTURE_VIEWER_UPDATES', True): json_response = self.post_json( '%s/staging/topic/%s/%s' % (feconf.STORY_PROGRESS_URL_PREFIX, self.STORY_URL_FRAGMENT, self.NODE_ID_3), {}, csrf_token=csrf_token) self.assertEqual(len(json_response['summaries']), 0) self.assertIsNone(json_response['next_node_id']) self.assertTrue(json_response['ready_for_review_test'])
def test_update_story_which_not_corresponding_topic_id(self): topic_id = topic_services.get_new_topic_id() self.save_new_topic( topic_id, self.USER_ID, 'A New Topic', 'A new topic description.', [], [], [], [], 0) story_id = story_services.get_new_story_id() self.save_new_story( story_id, self.USER_ID, 'Title', 'Description', 'Notes', topic_id) changelist = [ story_domain.StoryChange({ 'cmd': story_domain.CMD_ADD_STORY_NODE, 'node_id': self.NODE_ID_1, 'title': 'Title 1' }) ] with self.assertRaisesRegexp( Exception, ('Expected story to belong to the topic %s, but it is ' 'neither a part of the canonical stories or the ' 'additional stories of the topic.' % topic_id)): story_services.update_story( self.USER_ID, story_id, changelist, 'Added node.')
def test_opportunity_get_deleted_with_deleting_topic(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) topic_services.delete_topic(self.owner_id, self.TOPIC_ID) translation_opportunities, _, _ = ( opportunity_services.get_translation_opportunities('hi', None)) self.assertEqual(len(translation_opportunities), 0)
def test_missing_story_commit_log_entry_model_failure(self): story_services.update_story( self.owner_id, '0', [story_domain.StoryChange({ 'cmd': 'update_story_property', 'property_name': 'title', 'new_value': 'New title', 'old_value': 'title 0' })], 'Changes.') story_models.StoryCommitLogEntryModel.get_by_id( 'story-0-1').delete() expected_output = [ ( u'[u\'failed validation check for ' 'story_commit_log_entry_ids field check of ' 'StoryModel\', ' '[u"Entity id 0: based on field ' 'story_commit_log_entry_ids having value ' 'story-0-1, expected model StoryCommitLogEntryModel ' 'with id story-0-1 but it doesn\'t exist"]]'), u'[u\'fully-validated StoryModel\', 2]'] self.run_job_and_check_output( expected_output, sort=True, literal_eval=False)
def put(self, topic_id, story_id): """Updates properties of the given story.""" if not constants.ENABLE_NEW_STRUCTURE_EDITORS: raise self.PageNotFoundException story_domain.Story.require_valid_story_id(story_id) topic_domain.Topic.require_valid_topic_id(topic_id) story = story_services.get_story_by_id(story_id, strict=False) if story is None: raise self.PageNotFoundException topic = topic_services.get_topic_by_id(topic_id, strict=False) if topic is None or story_id not in topic.canonical_story_ids: raise self.PageNotFoundException version = self.payload.get('version') self._require_valid_version(version, story.version) commit_message = self.payload.get('commit_message') change_dicts = self.payload.get('change_dicts') change_list = [ story_domain.StoryChange(change_dict) for change_dict in change_dicts ] try: story_services.update_story( self.user_id, story_id, change_list, commit_message) except utils.ValidationError as e: raise self.InvalidInputException(e) story_dict = story_services.get_story_by_id(story_id).to_dict() self.values.update({ 'story': story_dict }) self.render_json(self.values)
def map(item): if not constants.ENABLE_NEW_STRUCTURE_EDITORS: return if item.deleted: yield (StoryMigrationOneOffJob._DELETED_KEY, 1) return # Note: the read will bring the story up to the newest version. story = story_services.get_story_by_id(item.id) try: story.validate() except Exception as e: logging.error('Story %s failed validation: %s' % (item.id, e)) yield (StoryMigrationOneOffJob._ERROR_KEY, 'Story %s failed validation: %s' % (item.id, e)) return # Write the new story into the datastore if it's different from # the old version. if (item.story_contents_schema_version <= feconf.CURRENT_STORY_CONTENTS_SCHEMA_VERSION): commit_cmds = [ story_domain.StoryChange({ 'cmd': story_domain.CMD_MIGRATE_SCHEMA_TO_LATEST_VERSION, 'from_version': item.story_contents_schema_version, 'to_version': feconf.CURRENT_STORY_CONTENTS_SCHEMA_VERSION }) ] story_services.update_story( feconf.MIGRATION_BOT_USERNAME, item.id, commit_cmds, 'Update story contents schema version to %d.' % (feconf.CURRENT_STORY_CONTENTS_SCHEMA_VERSION)) yield (StoryMigrationOneOffJob._MIGRATED_KEY, 1)