Exemplo n.º 1
0
    def setUp(self):
        super(TopicServicesUnitTests, self).setUp()
        self.TOPIC_ID = topic_services.get_new_topic_id()
        self.topic = self.save_new_topic(self.TOPIC_ID, self.user_id, 'Name',
                                         'Description',
                                         [self.story_id_1, self.story_id_2],
                                         [self.story_id_3], [self.skill_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)
Exemplo n.º 2
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_fetchers.get_topic_by_id(topic_id, version=0)
        topic_v1 = topic_fetchers.get_topic_by_id(topic_id, version=1)

        self.assertEqual(topic_v1.language_code, 'en')
        self.assertEqual(topic_v0.language_code, 'bn')
Exemplo n.º 3
0
    def test_migrate_story_contents_to_latest_schema(self):
        story_id = story_services.get_new_story_id()
        topic_id = topic_services.get_new_topic_id()
        user_id = 'user_id'
        self.save_new_topic(topic_id, user_id, 'Topic', 'A new topic', [], [],
                            [], [], 0)
        self.save_new_story(story_id, user_id, 'Title', 'Description', 'Notes',
                            topic_id)

        story_model = story_models.StoryModel.get(story_id)
        self.assertEqual(story_model.story_contents_schema_version, 1)

        swap_story_object = self.swap(story_domain, 'Story', MockStoryObject)
        current_schema_version_swap = self.swap(
            feconf, 'CURRENT_STORY_CONTENTS_SCHEMA_VERSION', 2)

        with swap_story_object, current_schema_version_swap:
            story = story_fetchers.get_story_from_model(story_model)

        self.assertEqual(story.story_contents_schema_version, 2)
Exemplo n.º 4
0
    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.')
Exemplo n.º 5
0
    def setUp(self):
        super(StoryMigrationOneOffJobTests, self).setUp()

        # Setup user who will own the test stories.
        self.signup(self.ALBERT_EMAIL, self.ALBERT_NAME)
        self.albert_id = self.get_user_id_from_email(self.ALBERT_EMAIL)
        self.TOPIC_ID = topic_services.get_new_topic_id()
        self.story_id_1 = 'story_id_1'
        self.story_id_2 = 'story_id_2'
        self.story_id_3 = 'story_id_3'
        self.skill_id_1 = 'skill_id_1'
        self.skill_id_2 = 'skill_id_2'
        self.save_new_topic(
            self.TOPIC_ID, self.albert_id, name='Name',
            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.process_and_flush_pending_mapreduce_tasks()
Exemplo n.º 6
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, 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)
        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.')
Exemplo n.º 7
0
    def test_editable_topic_handler_get(self):
        skill_services.delete_skill(self.admin_id, self.skill_id_2)
        # Check that non-admins cannot access the editable topic data.
        self.login(self.NEW_USER_EMAIL)
        self.get_json('%s/%s' %
                      (feconf.TOPIC_EDITOR_DATA_URL_PREFIX, self.topic_id),
                      expected_status_int=401)
        self.logout()

        # Check that admins can access the editable topic data.
        self.login(self.ADMIN_EMAIL)
        with self.swap(feconf, 'CAN_SEND_EMAILS', True):
            messages = self.mail_stub.get_sent_messages(
                to=feconf.ADMIN_EMAIL_ADDRESS)
            self.assertEqual(len(messages), 0)
            json_response = self.get_json(
                '%s/%s' % (feconf.TOPIC_EDITOR_DATA_URL_PREFIX, self.topic_id))
            self.assertEqual(self.topic_id, json_response['topic_dict']['id'])
            self.assertEqual(
                'Skill Description',
                json_response['skill_id_to_description_dict'][self.skill_id])

            messages = self.mail_stub.get_sent_messages(
                to=feconf.ADMIN_EMAIL_ADDRESS)
            expected_email_html_body = ('The deleted skills: %s are still'
                                        ' present in topic with id %s' %
                                        (self.skill_id_2, self.topic_id))
            self.assertEqual(len(messages), 1)
            self.assertIn(expected_email_html_body, messages[0].html.decode())

        self.logout()

        # Check that editable topic handler is accessed only when a topic id
        # passed has an associated topic.
        self.login(self.ADMIN_EMAIL)

        self.get_json('%s/%s' % (feconf.TOPIC_EDITOR_DATA_URL_PREFIX,
                                 topic_services.get_new_topic_id()),
                      expected_status_int=404)

        self.logout()
Exemplo n.º 8
0
    def setUp(self):
        """Completes the sign-up process for the various users."""
        super(BaseTopicsAndSkillsDashboardTests, self).setUp()
        self.signup(self.ADMIN_EMAIL, self.ADMIN_USERNAME)
        self.signup(self.TOPIC_MANAGER_EMAIL, self.TOPIC_MANAGER_USERNAME)
        self.signup(self.NEW_USER_EMAIL, self.NEW_USER_USERNAME)

        self.admin_id = self.get_user_id_from_email(self.ADMIN_EMAIL)
        self.topic_manager_id = self.get_user_id_from_email(
            self.TOPIC_MANAGER_EMAIL)
        self.new_user_id = self.get_user_id_from_email(self.NEW_USER_EMAIL)
        self.set_admins([self.ADMIN_USERNAME])
        self.set_topic_managers([self.TOPIC_MANAGER_USERNAME])
        self.topic_id = topic_services.get_new_topic_id()
        self.linked_skill_id = skill_services.get_new_skill_id()
        self.save_new_skill(self.linked_skill_id, self.admin_id,
                            'Description 3')
        skill_services.publish_skill(self.linked_skill_id, self.admin_id)
        self.save_new_topic(self.topic_id, self.admin_id, 'Name', 'abbrev',
                            None, 'Description', [], [],
                            [self.linked_skill_id], [], 1)
Exemplo n.º 9
0
    def test_skill_which_is_assigned_to_topic_but_not_subtopic(self):
        skill_id = skill_services.get_new_skill_id()
        self.save_new_skill(
            skill_id, self.admin_id, description='DescriptionSkill')
        topic_id = topic_services.get_new_topic_id()
        self.save_new_topic(
            topic_id, self.admin_id, name='TopicName1',
            description='DescriptionTopic', canonical_story_ids=[],
            additional_story_ids=[], uncategorized_skill_ids=[skill_id],
            subtopics=[], next_subtopic_id=1)

        url = '%s/%s' % (
            feconf.SKILL_EDITOR_DATA_URL_PREFIX, skill_id)

        json_response = self.get_json(url)
        self.assertEqual(skill_id, json_response['skill']['id'])
        self.assertIsNone(
            json_response['assigned_skill_topic_data_dict']['TopicName1'])
        self.assertEqual(
            1, len(json_response['grouped_skill_summaries']['Name']))
        self.logout()
Exemplo n.º 10
0
    def setUp(self):
        """Completes the sign-up process for the various users."""
        super(BaseStoryEditorControllerTests, self).setUp()
        self.signup(self.ADMIN_EMAIL, self.ADMIN_USERNAME)
        self.signup(self.NEW_USER_EMAIL, self.NEW_USER_USERNAME)

        self.admin_id = self.get_user_id_from_email(self.ADMIN_EMAIL)
        self.new_user_id = self.get_user_id_from_email(self.NEW_USER_EMAIL)

        self.set_admins([self.ADMIN_USERNAME])

        self.admin = user_services.UserActionsInfo(self.admin_id)
        self.topic_id = topic_services.get_new_topic_id()
        self.story_id = story_services.get_new_story_id()
        self.save_new_story(self.story_id, self.admin_id, self.topic_id)
        self.save_new_topic(
            self.topic_id, self.admin_id, name='Name',
            abbreviated_name='name', url_fragment='name',
            description='Description', canonical_story_ids=[self.story_id],
            additional_story_ids=[], uncategorized_skill_ids=[], subtopics=[],
            next_subtopic_id=1)
Exemplo n.º 11
0
    def test_changing_user_role_from_exploration_editor_to_topic_manager(self):
        user_email = '*****@*****.**'
        username = '******'

        self.signup(user_email, username)
        user_id = self.get_user_id_from_email(self.ADMIN_EMAIL)

        topic_id = topic_services.get_new_topic_id()
        self.save_new_topic(
            topic_id, user_id, name='Name',
            abbreviated_name='abbrev', thumbnail_filename=None,
            description='Description', canonical_story_ids=[],
            additional_story_ids=[], uncategorized_skill_ids=[],
            subtopics=[], next_subtopic_id=1)

        self.login(self.ADMIN_EMAIL, is_super_admin=True)

        response_dict = self.get_json(
            feconf.ADMIN_ROLE_HANDLER_URL,
            params={'method': 'username', 'username': username})

        self.assertEqual(
            response_dict, {username: feconf.ROLE_ID_EXPLORATION_EDITOR})

        # Check role correctly gets updated.
        csrf_token = self.get_new_csrf_token()
        response_dict = self.post_json(
            feconf.ADMIN_ROLE_HANDLER_URL,
            {'role': feconf.ROLE_ID_TOPIC_MANAGER, 'username': username,
             'topic_id': topic_id}, csrf_token=csrf_token)

        self.assertEqual(response_dict, {})

        response_dict = self.get_json(
            feconf.ADMIN_ROLE_HANDLER_URL,
            params={'method': 'username', 'username': username})
        self.assertEqual(
            response_dict, {username: feconf.ROLE_ID_TOPIC_MANAGER})

        self.logout()
Exemplo n.º 12
0
    def setUp(self):
        super(StoryFetchersUnitTests, 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',
                            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)
Exemplo n.º 13
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.')
Exemplo n.º 14
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='name', url_fragment='name-one',
            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, self.TOPIC_ID)
        self.save_new_story(
            self.story_id_3,
            self.user_id,
            self.TOPIC_ID,
            title='Title 3',
            description='Description 3')
        self.signup('*****@*****.**', 'A')
        self.signup('*****@*****.**', 'B')
        self.signup(self.ADMIN_EMAIL, 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)
Exemplo n.º 15
0
    def setUp(self):
        """Completes the sign-up process for the various users."""
        super(BaseTopicEditorControllerTest, 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.topic_id = topic_services.get_new_topic_id()
        self.save_new_topic(self.topic_id, self.admin_id, 'Name',
                            'Description', [], [], [], [])
Exemplo n.º 16
0
    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, [])
Exemplo n.º 17
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, name='topic name',
            abbreviated_name='topic-name', url_fragment='topic-name',
            description='Description', canonical_story_ids=[],
            additional_story_ids=[], uncategorized_skill_ids=[],
            subtopics=[], next_subtopic_id=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_fetchers.get_topic_by_id(topic_id, version=0)
        topic_v1 = topic_fetchers.get_topic_by_id(topic_id, version=1)

        self.assertEqual(topic_v1.language_code, 'en')
        self.assertEqual(topic_v0.language_code, 'bn')
Exemplo n.º 18
0
    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.')
Exemplo n.º 19
0
    def test_editable_skill_handler_delete_when_associated_topics_exist(self):
        self.login(self.ADMIN_EMAIL)
        # Check DELETE removes skill from the topic and returns 200 when the
        # skill still has associated topics.
        topic_id = topic_services.get_new_topic_id()
        self.save_new_topic(topic_id,
                            self.admin_id,
                            name='Topic1',
                            description='Description1',
                            canonical_story_ids=[],
                            additional_story_ids=[],
                            uncategorized_skill_ids=[self.skill_id],
                            subtopics=[],
                            next_subtopic_id=1)

        topic = topic_fetchers.get_topic_by_id(topic_id)
        self.assertTrue(self.skill_id in topic.get_all_skill_ids())

        self.delete_json(self.url, expected_status_int=200)

        topic = topic_fetchers.get_topic_by_id(topic_id)
        self.assertFalse(self.skill_id in topic.get_all_skill_ids())
        self.logout()
    def setUp(self):
        """Completes the sign-up process for the various users."""
        super(BaseTopicsAndSkillsDashboardTests, self).setUp()
        self.signup(self.ADMIN_EMAIL, self.ADMIN_USERNAME)
        self.signup(self.TOPIC_MANAGER_EMAIL, self.TOPIC_MANAGER_USERNAME)
        self.signup(self.NEW_USER_EMAIL, self.NEW_USER_USERNAME)

        self.admin_id = self.get_user_id_from_email(self.ADMIN_EMAIL)
        self.topic_manager_id = self.get_user_id_from_email(
            self.TOPIC_MANAGER_EMAIL)
        self.new_user_id = self.get_user_id_from_email(self.NEW_USER_EMAIL)
        self.set_admins([self.ADMIN_USERNAME])
        self.set_topic_managers([self.TOPIC_MANAGER_USERNAME])
        self.topic_id = topic_services.get_new_topic_id()
        self.linked_skill_id = skill_services.get_new_skill_id()
        self.save_new_skill(self.linked_skill_id,
                            self.admin_id,
                            description='Description 3')
        self.subtopic_skill_id = skill_services.get_new_skill_id()
        self.save_new_skill(self.subtopic_skill_id,
                            self.admin_id,
                            description='Subtopic Skill')

        subtopic = topic_domain.Subtopic.create_default_subtopic(
            1, 'Subtopic Title')
        subtopic.skill_ids = [self.subtopic_skill_id]
        self.save_new_topic(self.topic_id,
                            self.admin_id,
                            name='Name',
                            abbreviated_name='name',
                            url_fragment='name',
                            description='Description',
                            canonical_story_ids=[],
                            additional_story_ids=[],
                            uncategorized_skill_ids=[self.linked_skill_id],
                            subtopics=[subtopic],
                            next_subtopic_id=2)
Exemplo n.º 21
0
    def test_editable_topic_handler_delete(self):
        # Check that admins can delete a topic.
        self.login(self.ADMIN_EMAIL)
        self.delete_json('%s/%s' %
                         (feconf.TOPIC_EDITOR_DATA_URL_PREFIX, self.topic_id),
                         expected_status_int=200)
        self.logout()

        # Check that non-admins cannot delete a topic.
        self.login(self.NEW_USER_EMAIL)
        self.delete_json('%s/%s' %
                         (feconf.TOPIC_EDITOR_DATA_URL_PREFIX, self.topic_id),
                         expected_status_int=401)
        self.logout()

        # Check that topic can not be deleted when the topic id passed does
        # not have a topic associated with it.
        self.login(self.ADMIN_EMAIL)

        self.delete_json('%s/%s' % (feconf.TOPIC_EDITOR_DATA_URL_PREFIX,
                                    topic_services.get_new_topic_id()),
                         expected_status_int=404)

        self.logout()
Exemplo n.º 22
0
    def test_changing_user_role_from_exploration_editor_to_topic_manager(self):
        user_email = '*****@*****.**'
        username = '******'

        self.signup(user_email, username)
        user_id = self.get_user_id_from_email(self.ADMIN_EMAIL)

        topic_id = topic_services.get_new_topic_id()
        self.save_new_topic(
            topic_id, user_id, 'Name', 'Description', [], [], [], [], 1)

        self.login(self.ADMIN_EMAIL, is_super_admin=True)

        response_dict = self.get_json(
            feconf.ADMIN_ROLE_HANDLER_URL,
            params={'method': 'username', 'username': username})

        self.assertEqual(
            response_dict, {username: feconf.ROLE_ID_EXPLORATION_EDITOR})

        # Check role correctly gets updated.
        csrf_token = self.get_new_csrf_token()
        response_dict = self.post_json(
            feconf.ADMIN_ROLE_HANDLER_URL,
            {'role': feconf.ROLE_ID_TOPIC_MANAGER, 'username': username,
             'topic_id': topic_id}, csrf_token=csrf_token)

        self.assertEqual(response_dict, {})

        response_dict = self.get_json(
            feconf.ADMIN_ROLE_HANDLER_URL,
            params={'method': 'username', 'username': username})
        self.assertEqual(
            response_dict, {username: feconf.ROLE_ID_TOPIC_MANAGER})

        self.logout()
Exemplo n.º 23
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', 'Description',
                            [self.story_id_1, self.story_id_2],
                            [self.story_id_3],
                            [self.skill_id_1, self.skill_id_2], [], 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)
Exemplo n.º 24
0
    def _load_dummy_new_structures_data(self):
        """Loads the database with two topics (one of which is empty), a story
        and three skills in the topic (two of them in a subtopic) and a question
        attached to each skill.

        Raises:
            Exception: Cannot load new structures data in production mode.
            Exception: User does not have enough rights to generate data.
        """
        if constants.DEV_MODE:
            if self.user.role != feconf.ROLE_ID_ADMIN:
                raise Exception(
                    'User does not have enough rights to generate data.')
            topic_id_1 = topic_services.get_new_topic_id()
            topic_id_2 = topic_services.get_new_topic_id()
            story_id = story_services.get_new_story_id()
            skill_id_1 = skill_services.get_new_skill_id()
            skill_id_2 = skill_services.get_new_skill_id()
            skill_id_3 = skill_services.get_new_skill_id()
            question_id_1 = question_services.get_new_question_id()
            question_id_2 = question_services.get_new_question_id()
            question_id_3 = question_services.get_new_question_id()

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

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

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

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

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

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

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

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

            topic_services.publish_story(topic_id_1, story_id, self.user_id)
            topic_services.publish_topic(topic_id_1, self.user_id)
        else:
            raise Exception('Cannot load new structures data in production.')
Exemplo n.º 25
0
    def _load_dummy_new_structures_data(self):
        """Loads the database with two topics (one of which is empty), a story
        and three skills in the topic (two of them in a subtopic) and a question
        attached to each skill.

        Raises:
            Exception: Cannot load new structures data in production mode.
            Exception: User does not have enough rights to generate data.
        """
        if constants.DEV_MODE:
            if self.user.role != feconf.ROLE_ID_ADMIN:
                raise Exception(
                    'User does not have enough rights to generate data.')
            topic_id_1 = topic_services.get_new_topic_id()
            topic_id_2 = topic_services.get_new_topic_id()
            story_id = story_services.get_new_story_id()
            skill_id_1 = skill_services.get_new_skill_id()
            skill_id_2 = skill_services.get_new_skill_id()
            skill_id_3 = skill_services.get_new_skill_id()
            question_id_1 = question_services.get_new_question_id()
            question_id_2 = question_services.get_new_question_id()
            question_id_3 = question_services.get_new_question_id()

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

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

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

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

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

            subtopic_page = (
                subtopic_page_domain.SubtopicPage.create_default_subtopic_page(
                    1, topic_id_1))
            # These explorations were chosen since they pass the validations
            # for published stories.
            self._reload_exploration('15')
            self._reload_exploration('25')
            self._reload_exploration('13')

            story = story_domain.Story.create_default_story(
                story_id, 'Help Jaime win the Arcade', topic_id_1)

            story_node_dicts = [{
                'exp_id':
                '15',
                'title':
                'What are the place values?',
                'description':
                'Jaime learns the place value of each digit ' +
                'in a big number.'
            }, {
                'exp_id':
                '25',
                'title':
                'Finding the value of a number',
                'description':
                'Jaime understands the value of his ' + 'arcade score.'
            }, {
                'exp_id':
                '13',
                'title':
                'Comparing Numbers',
                'description':
                'Jaime learns if a number is smaller or ' +
                'greater than another number.'
            }]

            def generate_dummy_story_nodes(node_id, exp_id, title,
                                           description):
                """Generates and connects sequential story nodes.

                Args:
                    node_id: int. The node id.
                    exp_id: str. The exploration id.
                    title: str. The title of the story node.
                    description: str. The description of the story node.
                """

                story.add_node('%s%d' % (story_domain.NODE_ID_PREFIX, node_id),
                               title)
                story.update_node_description(
                    '%s%d' % (story_domain.NODE_ID_PREFIX, node_id),
                    description)
                story.update_node_exploration_id(
                    '%s%d' % (story_domain.NODE_ID_PREFIX, node_id), exp_id)

                if node_id != len(story_node_dicts):
                    story.update_node_destination_node_ids(
                        '%s%d' % (story_domain.NODE_ID_PREFIX, node_id),
                        ['%s%d' % (story_domain.NODE_ID_PREFIX, node_id + 1)])

                exp_services.update_exploration(self.user_id, exp_id, [
                    exp_domain.ExplorationChange({
                        'cmd': exp_domain.CMD_EDIT_EXPLORATION_PROPERTY,
                        'property_name': 'category',
                        'new_value': 'Astronomy'
                    })
                ], 'Change category')

            for i, story_node_dict in enumerate(story_node_dicts):
                generate_dummy_story_nodes(i + 1, **story_node_dict)

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

            topic_services.publish_story(topic_id_1, story_id, self.user_id)
        else:
            raise Exception('Cannot load new structures data in production.')
Exemplo n.º 26
0
    def setUp(self):
        super(StoryProgressUnitTests, self).setUp()

        self.STORY_1_ID = 'story_id'
        self.STORY_ID_1 = 'story_id_1'
        self.NODE_ID_3 = 'node_3'
        self.NODE_ID_4 = 'node_4'

        self.owner_id = 'owner'
        self.TOPIC_ID = topic_services.get_new_topic_id()
        self.save_new_topic(self.TOPIC_ID, self.USER_ID, 'New Topic', 'abbrev',
                            None, 'A new topic', [], [], [], [], 0)
        story = story_domain.Story.create_default_story(
            self.STORY_1_ID, 'Title', self.TOPIC_ID)
        story.description = ('Description')
        self.node_1 = {
            'id': self.NODE_ID_1,
            'title': 'Title 1',
            'destination_node_ids': ['node_2'],
            'acquired_skill_ids': [],
            'prerequisite_skill_ids': [],
            'outline': '',
            'outline_is_finalized': False,
            'exploration_id': None
        }
        self.node_2 = {
            'id': self.NODE_ID_2,
            'title': 'Title 2',
            'destination_node_ids': ['node_3'],
            'acquired_skill_ids': [],
            'prerequisite_skill_ids': [],
            'outline': '',
            'outline_is_finalized': False,
            'exploration_id': None
        }
        self.node_3 = {
            'id': self.NODE_ID_3,
            'title': 'Title 3',
            'destination_node_ids': ['node_4'],
            'acquired_skill_ids': [],
            'prerequisite_skill_ids': [],
            'outline': '',
            'outline_is_finalized': False,
            'exploration_id': None
        }
        self.node_4 = {
            'id': self.NODE_ID_4,
            'title': 'Title 4',
            'destination_node_ids': [],
            'acquired_skill_ids': [],
            'prerequisite_skill_ids': [],
            'outline': '',
            'outline_is_finalized': False,
            'exploration_id': None
        }
        story.story_contents.nodes = [
            story_domain.StoryNode.from_dict(self.node_1),
            story_domain.StoryNode.from_dict(self.node_2),
            story_domain.StoryNode.from_dict(self.node_3),
            story_domain.StoryNode.from_dict(self.node_4)
        ]
        self.nodes = story.story_contents.nodes
        story.story_contents.initial_node_id = 'node_1'
        story.story_contents.next_node_id = 'node_5'
        story_services.save_new_story(self.USER_ID, story)
        topic_services.add_canonical_story(self.USER_ID, self.TOPIC_ID,
                                           story.id)
Exemplo n.º 27
0
    def test_handler_updates_story_summary_dicts(self):
        self.login(self.ADMIN_EMAIL)

        topic_id = topic_services.get_new_topic_id()
        canonical_story_id = story_services.get_new_story_id()
        additional_story_id = story_services.get_new_story_id()

        # 'self.topic_id' does not contain any canonical_story_summary_dicts
        # or additional_story_summary_dicts.
        response = self.get_json(
            '%s/%s' % (feconf.TOPIC_EDITOR_STORY_URL, self.topic_id))

        self.assertEqual(response['canonical_story_summary_dicts'], [])
        self.assertEqual(response['additional_story_summary_dicts'], [])

        self.save_new_topic(topic_id,
                            self.admin_id,
                            name='New name',
                            abbreviated_name='abbrev',
                            thumbnail_filename=None,
                            description='New description',
                            canonical_story_ids=[canonical_story_id],
                            additional_story_ids=[additional_story_id],
                            uncategorized_skill_ids=[self.skill_id],
                            subtopics=[],
                            next_subtopic_id=1)

        self.save_new_story(canonical_story_id, self.admin_id, 'title',
                            'description', 'note', topic_id)
        self.save_new_story(additional_story_id, self.admin_id,
                            'another title', 'another description',
                            'another note', topic_id)

        topic_services.publish_story(topic_id, canonical_story_id,
                                     self.admin_id)

        response = self.get_json('%s/%s' %
                                 (feconf.TOPIC_EDITOR_STORY_URL, topic_id))
        canonical_story_summary_dict = response[
            'canonical_story_summary_dicts'][0]
        additional_story_summary_dict = response[
            'additional_story_summary_dicts'][0]

        self.assertEqual(canonical_story_summary_dict['description'],
                         'description')
        self.assertEqual(canonical_story_summary_dict['title'], 'title')
        self.assertEqual(canonical_story_summary_dict['id'],
                         canonical_story_id)
        self.assertEqual(canonical_story_summary_dict['story_is_published'],
                         True)

        self.assertEqual(additional_story_summary_dict['description'],
                         'another description')
        self.assertEqual(additional_story_summary_dict['title'],
                         'another title')
        self.assertEqual(additional_story_summary_dict['id'],
                         additional_story_id)
        self.assertEqual(additional_story_summary_dict['story_is_published'],
                         False)

        self.logout()
Exemplo n.º 28
0
    def test_editable_topic_handler_put(self):
        # Check that admins can edit a topic.
        change_cmd = {
            'version':
            2,
            'commit_message':
            'Some changes and added a subtopic.',
            'topic_and_subtopic_page_change_dicts': [{
                'cmd': 'update_topic_property',
                'property_name': 'name',
                'old_value': '',
                'new_value': 'A new name'
            }, {
                'cmd': 'update_subtopic_page_property',
                'property_name': 'page_contents_html',
                'old_value': {
                    'html': '',
                    'content_id': 'content'
                },
                'subtopic_id': 1,
                'new_value': {
                    'html': '<p>New Data</p>',
                    'content_id': 'content'
                }
            }, {
                'cmd': 'add_subtopic',
                'subtopic_id': 2,
                'title': 'Title2'
            }, {
                'cmd': 'update_subtopic_page_property',
                'property_name': 'page_contents_html',
                'old_value': {
                    'html': '',
                    'content_id': 'content'
                },
                'new_value': {
                    'html': '<p>New Value</p>',
                    'content_id': 'content'
                },
                'subtopic_id': 2
            }, {
                'cmd': 'update_subtopic_page_property',
                'property_name': 'page_contents_audio',
                'old_value': {
                    'voiceovers_mapping': {
                        'content': {}
                    }
                },
                'new_value': {
                    'voiceovers_mapping': {
                        'content': {
                            'en': {
                                'filename': 'test.mp3',
                                'file_size_bytes': 100,
                                'needs_update': False,
                                'duration_secs': 0.34342
                            }
                        }
                    }
                },
                'subtopic_id': 2
            }]
        }
        self.login(self.ADMIN_EMAIL)
        csrf_token = self.get_new_csrf_token()
        skill_services.delete_skill(self.admin_id, self.skill_id_2)

        with self.swap(feconf, 'CAN_SEND_EMAILS', True):
            messages = self.mail_stub.get_sent_messages(
                to=feconf.ADMIN_EMAIL_ADDRESS)
            self.assertEqual(len(messages), 0)
            json_response = self.put_json(
                '%s/%s' % (feconf.TOPIC_EDITOR_DATA_URL_PREFIX, self.topic_id),
                change_cmd,
                csrf_token=csrf_token)
            self.assertEqual(self.topic_id, json_response['topic_dict']['id'])
            self.assertEqual('A new name', json_response['topic_dict']['name'])
            self.assertEqual(2, len(json_response['topic_dict']['subtopics']))
            self.assertEqual(
                'Skill Description',
                json_response['skill_id_to_description_dict'][self.skill_id])

            messages = self.mail_stub.get_sent_messages(
                to=feconf.ADMIN_EMAIL_ADDRESS)
            expected_email_html_body = ('The deleted skills: %s are still'
                                        ' present in topic with id %s' %
                                        (self.skill_id_2, self.topic_id))
            self.assertEqual(len(messages), 1)
            self.assertIn(expected_email_html_body, messages[0].html.decode())

        # Test if the corresponding subtopic pages were created.
        json_response = self.get_json(
            '%s/%s/%s' %
            (feconf.SUBTOPIC_PAGE_EDITOR_DATA_URL_PREFIX, self.topic_id, 1))
        self.assertEqual(
            {
                'subtitled_html': {
                    'html': '<p>New Data</p>',
                    'content_id': 'content'
                },
                'recorded_voiceovers': {
                    'voiceovers_mapping': {
                        'content': {}
                    }
                },
                'written_translations': {
                    'translations_mapping': {
                        'content': {}
                    }
                }
            }, json_response['subtopic_page']['page_contents'])
        json_response = self.get_json(
            '%s/%s/%s' %
            (feconf.SUBTOPIC_PAGE_EDITOR_DATA_URL_PREFIX, self.topic_id, 2))
        self.assertEqual(
            {
                'subtitled_html': {
                    'html': '<p>New Value</p>',
                    'content_id': 'content'
                },
                'recorded_voiceovers': {
                    'voiceovers_mapping': {
                        'content': {
                            'en': {
                                'file_size_bytes': 100,
                                'filename': 'test.mp3',
                                'needs_update': False,
                                'duration_secs': 0.34342
                            }
                        }
                    }
                },
                'written_translations': {
                    'translations_mapping': {
                        'content': {}
                    }
                }
            }, json_response['subtopic_page']['page_contents'])
        self.logout()

        # Test that any topic manager cannot edit the topic.
        self.login(self.TOPIC_MANAGER_EMAIL)
        self.put_json('%s/%s' %
                      (feconf.TOPIC_EDITOR_DATA_URL_PREFIX, self.topic_id),
                      change_cmd,
                      csrf_token=csrf_token,
                      expected_status_int=401)
        self.logout()

        # Check that non-admins and non-topic managers cannot edit a topic.
        self.put_json('%s/%s' %
                      (feconf.TOPIC_EDITOR_DATA_URL_PREFIX, self.topic_id),
                      change_cmd,
                      csrf_token=csrf_token,
                      expected_status_int=401)

        # Check that topic can not be edited when version is None.
        self.login(self.ADMIN_EMAIL)

        json_response = self.put_json(
            '%s/%s' % (feconf.TOPIC_EDITOR_DATA_URL_PREFIX, self.topic_id),
            {'version': None},
            csrf_token=csrf_token,
            expected_status_int=400)
        self.assertEqual(json_response['error'],
                         'Invalid POST request: a version must be specified.')

        self.logout()

        # Check topic can not be edited when payload version differs from
        # topic version.
        self.login(self.ADMIN_EMAIL)

        topic_id_1 = topic_services.get_new_topic_id()
        self.save_new_topic(topic_id_1,
                            self.admin_id,
                            name='Name 1',
                            abbreviated_name='abbrev',
                            thumbnail_filename=None,
                            description='Description 1',
                            canonical_story_ids=[],
                            additional_story_ids=[],
                            uncategorized_skill_ids=[self.skill_id],
                            subtopics=[],
                            next_subtopic_id=1)

        json_response = self.put_json(
            '%s/%s' % (feconf.TOPIC_EDITOR_DATA_URL_PREFIX, topic_id_1),
            {'version': '3'},
            csrf_token=csrf_token,
            expected_status_int=400)

        self.assertEqual(
            json_response['error'],
            'Trying to update version 1 of topic from version 3, '
            'which is too old. Please reload the page and try again.')

        self.logout()
Exemplo n.º 29
0
    def test_get_new_topic_id(self):
        new_topic_id = topic_services.get_new_topic_id()

        self.assertEqual(len(new_topic_id), 12)
        self.assertEqual(topic_models.TopicModel.get_by_id(new_topic_id), None)
Exemplo n.º 30
0
    def test_editable_topic_handler_put(self):
        # Check that admins can edit a topic.
        change_cmd = {
            'version':
            2,
            'commit_message':
            'Some changes and added a subtopic.',
            'topic_and_subtopic_page_change_dicts': [{
                'change_affects_subtopic_page':
                False,
                'cmd':
                'update_topic_property',
                'property_name':
                'name',
                'old_value':
                '',
                'new_value':
                'A new name'
            }, {
                'change_affects_subtopic_page':
                True,
                'cmd':
                'update_subtopic_page_property',
                'property_name':
                'page_contents_html',
                'old_value': {
                    'html': '',
                    'content_id': 'content'
                },
                'subtopic_id':
                1,
                'new_value': {
                    'html': '<p>New Data</p>',
                    'content_id': 'content'
                }
            }, {
                'change_affects_subtopic_page':
                False,
                'cmd':
                'add_subtopic',
                'subtopic_id':
                2,
                'title':
                'Title2'
            }, {
                'change_affects_subtopic_page':
                True,
                'cmd':
                'update_subtopic_page_property',
                'property_name':
                'page_contents_html',
                'old_value': {
                    'html': '',
                    'content_id': 'content'
                },
                'new_value': {
                    'html': '<p>New Value</p>',
                    'content_id': 'content'
                },
                'subtopic_id':
                2
            }, {
                'change_affects_subtopic_page':
                True,
                'cmd':
                'update_subtopic_page_property',
                'property_name':
                'page_contents_audio',
                'old_value': {
                    'content': {}
                },
                'new_value': {
                    'content': {
                        'en': {
                            'filename': 'test.mp3',
                            'file_size_bytes': 100,
                            'needs_update': False
                        }
                    }
                },
                'subtopic_id':
                2
            }]
        }
        self.login(self.ADMIN_EMAIL)
        response = self.get_html_response(
            '%s/%s' % (feconf.TOPIC_EDITOR_URL_PREFIX, self.topic_id))
        csrf_token = self.get_csrf_token_from_response(response)

        json_response = self.put_json(
            '%s/%s' % (feconf.TOPIC_EDITOR_DATA_URL_PREFIX, self.topic_id),
            change_cmd,
            csrf_token=csrf_token)
        self.assertEqual(self.topic_id, json_response['topic_dict']['id'])
        self.assertEqual('A new name', json_response['topic_dict']['name'])
        self.assertEqual(2, len(json_response['topic_dict']['subtopics']))
        self.assertEqual(
            'Skill Description',
            json_response['skill_id_to_description_dict'][self.skill_id])

        # Test if the corresponding subtopic pages were created.
        json_response = self.get_json(
            '%s/%s/%s' %
            (feconf.SUBTOPIC_PAGE_EDITOR_DATA_URL_PREFIX, self.topic_id, 1))
        self.assertEqual(
            {
                'subtitled_html': {
                    'html': '<p>New Data</p>',
                    'content_id': 'content'
                },
                'content_ids_to_audio_translations': {
                    'content': {}
                },
                'written_translations': {
                    'translations_mapping': {
                        'content': {}
                    }
                }
            }, json_response['subtopic_page']['page_contents'])
        json_response = self.get_json(
            '%s/%s/%s' %
            (feconf.SUBTOPIC_PAGE_EDITOR_DATA_URL_PREFIX, self.topic_id, 2))
        self.assertEqual(
            {
                'subtitled_html': {
                    'html': '<p>New Value</p>',
                    'content_id': 'content'
                },
                'content_ids_to_audio_translations': {
                    'content': {
                        'en': {
                            'file_size_bytes': 100,
                            'filename': 'test.mp3',
                            'needs_update': False
                        }
                    }
                },
                'written_translations': {
                    'translations_mapping': {
                        'content': {}
                    }
                }
            }, json_response['subtopic_page']['page_contents'])
        self.logout()

        # Test that any topic manager cannot edit the topic.
        self.login(self.TOPIC_MANAGER_EMAIL)
        self.put_json('%s/%s' %
                      (feconf.TOPIC_EDITOR_DATA_URL_PREFIX, self.topic_id),
                      change_cmd,
                      csrf_token=csrf_token,
                      expected_status_int=401)
        self.logout()

        # Check that non-admins and non-topic managers cannot edit a topic.
        self.put_json('%s/%s' %
                      (feconf.TOPIC_EDITOR_DATA_URL_PREFIX, self.topic_id),
                      change_cmd,
                      csrf_token=csrf_token,
                      expected_status_int=401)

        # Check that topic can not be edited when version is None.
        self.login(self.ADMIN_EMAIL)

        json_response = self.put_json(
            '%s/%s' % (feconf.TOPIC_EDITOR_DATA_URL_PREFIX, self.topic_id),
            {'version': None},
            csrf_token=csrf_token,
            expected_status_int=400)
        self.assertEqual(json_response['error'],
                         'Invalid POST request: a version must be specified.')

        self.logout()

        # Check topic can not be edited when payload version differs from
        # topic version.
        self.login(self.ADMIN_EMAIL)

        topic_id_1 = topic_services.get_new_topic_id()
        self.save_new_topic(topic_id_1, self.admin_id, 'Name 1',
                            'Description 1', [], [], [self.skill_id], [], 1)

        json_response = self.put_json(
            '%s/%s' % (feconf.TOPIC_EDITOR_DATA_URL_PREFIX, topic_id_1),
            {'version': '3'},
            csrf_token=csrf_token,
            expected_status_int=400)

        self.assertEqual(
            json_response['error'],
            'Trying to update version 1 of topic from version 3, '
            'which is too old. Please reload the page and try again.')

        self.logout()