Exemple #1
0
    def test_get_with_twenty_or_more_questions_with_multiple_skills(self):
        number_of_skills = 3
        number_of_questions = [1, 2, 2]
        self.topic_id = 'new_topic'
        skill_ids = ([
            skill_services.get_new_skill_id() for _ in range(number_of_skills)
        ])
        self.topic = topic_domain.Topic.create_default_topic(
            self.topic_id, 'new_topic', 'new-topic', 'description', 'fragm')
        for index in range(number_of_skills):
            self.topic.uncategorized_skill_ids.append(skill_ids[index])
        self.topic.thumbnail_filename = 'Image.svg'
        self.topic.thumbnail_bg_color = (
            constants.ALLOWED_THUMBNAIL_BG_COLORS['topic'][0])
        self.topic.practice_tab_is_displayed = True
        subtopic_1 = topic_domain.Subtopic.create_default_subtopic(
            1, 'Subtopic Title 1', 'url-frag-one')
        subtopic_1.skill_ids = ['skill_id_1']
        subtopic_1.url_fragment = 'sub-one-frag'
        self.topic.subtopics = [subtopic_1]
        self.topic.next_subtopic_id = 2
        topic_services.save_new_topic(self.admin_id, self.topic)
        topic_services.publish_topic(self.topic_id, self.admin_id)
        for i in range(number_of_skills):
            self.save_new_skill(skill_ids[i],
                                self.admin_id,
                                description='Skill Description')
        for i in range(number_of_skills):
            for j in range(number_of_questions[i]):
                question_id = question_services.get_new_question_id()
                self.save_new_question(question_id, self.admin_id,
                                       self._create_valid_question_data(j),
                                       [skill_ids[i]])
                question_services.create_new_question_skill_link(
                    self.admin_id, question_id, skill_ids[i], 0.5)

        json_response = self.get_json('%s/staging/%s' %
                                      (feconf.TOPIC_DATA_HANDLER, 'new-topic'))
        expected_dict = {
            'topic_name': 'new_topic',
            'topic_id': self.topic_id,
            'canonical_story_dicts': [],
            'additional_story_dicts': [],
            'practice_tab_is_displayed': True
        }
        self.assertDictContainsSubset(expected_dict, json_response)
        self.logout()
Exemple #2
0
    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 = [
            exp_domain.Exploration.create_default_exploration(
                '%s' % i,
                title='title %d' % i,
                category='category%d' % i,
            ) for i in python_utils.RANGE(2)
        ]

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

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

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

        for index, story in enumerate(stories):
            story.language_code = 'en'
            story_services.save_new_story(self.owner_id, story)
            topic_services.add_canonical_story(self.owner_id, topic.id,
                                               story.id)
            story_services.update_story(self.owner_id, story.id, [
                story_domain.StoryChange({
                    'cmd': 'add_story_node',
                    'node_id': 'node_1',
                    'title': 'Node1',
                }),
                story_domain.StoryChange({
                    'cmd': 'update_story_node_property',
                    'property_name': 'exploration_id',
                    'node_id': 'node_1',
                    'old_value': None,
                    'new_value': explorations[index].id
                })
            ], 'Changes.')
 def test_get_fails_when_skill_ids_dont_exist(self):
     topic = topic_domain.Topic.create_default_topic(
         'topic_id_3', 'topic_without_skills', 'noskills', 'description')
     topic.thumbnail_filename = 'Topic.svg'
     topic.thumbnail_bg_color = (
         constants.ALLOWED_THUMBNAIL_BG_COLORS['topic'][0])
     topic.subtopics.append(
         topic_domain.Subtopic(
             1, 'subtopic_name', ['non_existent_skill'], 'image.svg',
             constants.ALLOWED_THUMBNAIL_BG_COLORS['subtopic'][0], 21131,
             'subtopic-name-three'))
     topic.next_subtopic_id = 2
     topic_services.save_new_topic(self.admin_id, topic)
     topic_services.publish_topic('topic_id_3', self.admin_id)
     self.get_json('%s/staging/%s?selected_subtopic_ids=[1]' %
                   (feconf.PRACTICE_SESSION_DATA_URL_PREFIX, 'noskills'),
                   expected_status_int=404)
    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(
            self.TOPIC_ID, 'topic', 'abbrev', 'description')
        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.')
Exemple #5
0
    def test_get(self):
        self.signup(self.ADMIN_EMAIL, self.ADMIN_USERNAME)
        admin_id = self.get_user_id_from_email(self.ADMIN_EMAIL)
        self.set_admins([self.ADMIN_USERNAME])

        self.login(self.ADMIN_EMAIL, is_super_admin=True)
        topic_id_1 = topic_services.get_new_topic_id()
        topic_id_2 = topic_services.get_new_topic_id()
        private_topic = topic_domain.Topic.create_default_topic(
            topic_id_1, 'private_topic_name', 'abbrev', 'description')
        topic_services.save_new_topic(admin_id, private_topic)
        public_topic = topic_domain.Topic.create_default_topic(
            topic_id_2, 'public_topic_name', 'abbrev', 'description')
        public_topic.thumbnail_filename = 'Topic.svg'
        public_topic.thumbnail_bg_color = (
            constants.ALLOWED_THUMBNAIL_BG_COLORS['topic'][0])
        topic_services.save_new_topic(admin_id, public_topic)
        topic_services.publish_topic(topic_id_2, admin_id)

        csrf_token = self.get_new_csrf_token()
        new_config_value = [{
            'name': 'math',
            'topic_ids': [topic_id_1, topic_id_2]
        }]

        payload = {
            'action': 'save_config_properties',
            'new_config_property_values': {
                config_domain.TOPIC_IDS_FOR_CLASSROOM_PAGES.name: (
                    new_config_value),
            }
        }
        self.post_json('/adminhandler', payload, csrf_token=csrf_token)
        self.logout()

        with self.swap(constants, 'ENABLE_NEW_STRUCTURE_PLAYERS', True):
            json_response = self.get_json(
                '%s/%s' % (feconf.CLASSROOM_DATA_HANDLER, 'math'))
            topic_summary_dict = (
                topic_services.get_topic_summary_by_id(topic_id_2).to_dict())

            expected_dict = {
                'topic_summary_dicts': [topic_summary_dict]
            }
            self.assertDictContainsSubset(expected_dict, json_response)
Exemple #6
0
    def test_get_with_more_questions_with_fifty_or_more_skills(self):
        number_of_skills = 60
        number_of_questions = [0] * 60
        number_of_questions[46] = 2
        number_of_questions[20] = 3
        number_of_questions[29] = 10
        self.topic_id = 'new_topic'
        skill_ids = ([
            skill_services.get_new_skill_id()
            for _ in python_utils.RANGE(number_of_skills)
        ])
        self.topic = topic_domain.Topic.create_default_topic(
            self.topic_id, 'new_topic', 'new-topic', 'description')
        for index in python_utils.RANGE(number_of_skills):
            self.topic.uncategorized_skill_ids.append(skill_ids[index])
        self.topic.thumbnail_filename = 'Image.svg'
        self.topic.thumbnail_bg_color = (
            constants.ALLOWED_THUMBNAIL_BG_COLORS['topic'][0])
        topic_services.save_new_topic(self.admin_id, self.topic)
        topic_services.publish_topic(self.topic_id, self.admin_id)
        for i in python_utils.RANGE(number_of_skills):
            self.save_new_skill(skill_ids[i],
                                self.admin_id,
                                description='Skill Description')
        for i in python_utils.RANGE(number_of_skills):
            for j in python_utils.RANGE(number_of_questions[i]):
                question_id = question_services.get_new_question_id()
                self.save_new_question(question_id, self.admin_id,
                                       self._create_valid_question_data(j),
                                       [skill_ids[i]])
                question_services.create_new_question_skill_link(
                    self.admin_id, question_id, skill_ids[i], 0.5)

        with self.swap(constants, 'ENABLE_NEW_STRUCTURE_PLAYERS', True):
            json_response = self.get_json(
                '%s/staging/%s' % (feconf.TOPIC_DATA_HANDLER, 'new-topic'))
            expected_dict = {
                'topic_name': 'new_topic',
                'topic_id': self.topic_id,
                'canonical_story_dicts': [],
                'additional_story_dicts': [],
                'train_tab_should_be_displayed': True
            }
            self.assertDictContainsSubset(expected_dict, json_response)
        self.logout()
Exemple #7
0
 def test_get_fails_when_skill_ids_dont_exist(self):
     topic = topic_domain.Topic.create_default_topic(
         'topic_id_3', 'topic_without_skills', 'abbrev')
     topic.thumbnail_filename = 'Topic.svg'
     topic.thumbnail_bg_color = (
         constants.ALLOWED_THUMBNAIL_BG_COLORS['topic'][0])
     topic.subtopics.append(topic_domain.Subtopic(
         1, 'subtopic_name', ['non_existent_skill'], 'image.svg',
         constants.ALLOWED_THUMBNAIL_BG_COLORS['subtopic'][0]))
     topic.next_subtopic_id = 2
     topic_services.save_new_topic(self.admin_id, topic)
     topic_services.publish_topic('topic_id_3', self.admin_id)
     with self.swap(constants, 'ENABLE_NEW_STRUCTURE_PLAYERS', True):
         self.get_json(
             '%s/%s?selected_subtopic_ids=1' % (
                 feconf.PRACTICE_SESSION_DATA_URL_PREFIX,
                 'topic_without_skills'),
             expected_status_int=404)
    def setUp(self):
        """Completes the sign-up process for the various users."""
        super(BasePracticeSessionsControllerTests, 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.topic_id = 'topic'
        self.topic_id_1 = 'topic1'
        self.skill_id1 = 'skill_id_1'
        self.skill_id2 = 'skill_id_2'

        self.save_new_skill(
            self.skill_id1, self.admin_id, description='Skill 1')
        self.save_new_skill(
            self.skill_id2, self.admin_id, description='Skill 2')

        self.topic = topic_domain.Topic.create_default_topic(
            self.topic_id, 'public_topic_name',
            'public-topic-name', 'description')
        self.topic.subtopics.append(topic_domain.Subtopic(
            1, 'subtopic_name', [self.skill_id1], 'image.svg',
            constants.ALLOWED_THUMBNAIL_BG_COLORS['subtopic'][0],
            'subtopic-name-one'))
        self.topic.subtopics.append(topic_domain.Subtopic(
            2, 'subtopic_name_2', [self.skill_id2], 'image.svg',
            constants.ALLOWED_THUMBNAIL_BG_COLORS['subtopic'][0],
            'subtopic-name-two'))
        self.topic.next_subtopic_id = 3
        self.topic.thumbnail_filename = 'Topic.svg'
        self.topic.thumbnail_bg_color = (
            constants.ALLOWED_THUMBNAIL_BG_COLORS['topic'][0])
        topic_services.save_new_topic(self.admin_id, self.topic)

        self.topic = topic_domain.Topic.create_default_topic(
            self.topic_id_1, 'private_topic_name',
            'private-topic-name', 'description')
        self.topic.thumbnail_filename = 'Topic.svg'
        self.topic.thumbnail_bg_color = (
            constants.ALLOWED_THUMBNAIL_BG_COLORS['topic'][0])
        topic_services.save_new_topic(self.admin_id, self.topic)

        topic_services.publish_topic(self.topic_id, self.admin_id)
    def _publish_topic(self, topic_id, topic_name):
        """Creates and publishes a topic.

        Args:
            topic_id: str. Topic ID.
            topic_name: str. Topic name.
        """
        topic = topic_domain.Topic.create_default_topic(
            topic_id, topic_name, 'abbrev', 'description')
        topic.thumbnail_filename = 'thumbnail.svg'
        topic.thumbnail_bg_color = '#C6DCDA'
        topic.subtopics = [
            topic_domain.Subtopic(
                1, 'Title', ['skill_id_3'], 'image.svg',
                constants.ALLOWED_THUMBNAIL_BG_COLORS['subtopic'][0], 21131,
                'dummy-subtopic-three')]
        topic.next_subtopic_id = 2
        topic_services.save_new_topic(self.admin_id, topic)
        topic_services.publish_topic(topic_id, self.admin_id)
    def setUp(self):
        super(OpportunityServicesIntegrationTest, self).setUp()
        self.signup(self.ADMIN_EMAIL, self.ADMIN_USERNAME)
        self.signup(self.OWNER_EMAIL, self.OWNER_USERNAME)

        self.admin_id = self.get_user_id_from_email(self.ADMIN_EMAIL)
        self.owner_id = self.get_user_id_from_email(self.OWNER_EMAIL)

        self.set_admins([self.ADMIN_USERNAME])
        self.admin = user_services.UserActionsInfo(self.admin_id)

        self.TOPIC_ID = 'topic'
        self.STORY_ID = 'story'
        self.USER_ID = 'user'
        self.SKILL_ID = 'skill'
        self.QUESTION_ID = question_services.get_new_question_id()

        # Since a valid exploration is created here, it has EndExploration
        # state as well, so the content in that has to be taken into account as
        # well when checking content_count in the tests.
        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(
            self.TOPIC_ID, 'topic', 'abbrev', 'description')
        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)
Exemple #11
0
    def setUp(self):
        super(StorySnapshotMetadataModelValidatorTests, self).setUp()

        self.signup(self.OWNER_EMAIL, self.OWNER_USERNAME)
        self.signup(USER_EMAIL, USER_NAME)

        self.owner_id = self.get_user_id_from_email(self.OWNER_EMAIL)
        self.user_id = self.get_user_id_from_email(USER_EMAIL)

        topic = topic_domain.Topic.create_default_topic(
            '0', 'topic', 'abbrev', 'description')

        stories = [story_domain.Story.create_default_story(
            '%s' % i,
            'title %d' % i,
            'description %d' % i,
            '0',
            'title-%s' % chr(97 + i)
        ) for i in python_utils.RANGE(3)]

        for story in stories:
            if story.id != '0':
                story_services.save_new_story(self.owner_id, story)
            else:
                story_services.save_new_story(self.user_id, story)
            topic.add_canonical_story(story.id)

        topic_services.save_new_topic(self.owner_id, topic)

        self.model_instance_0 = (
            story_models.StorySnapshotMetadataModel.get_by_id(
                '0-1'))
        self.model_instance_1 = (
            story_models.StorySnapshotMetadataModel.get_by_id(
                '1-1'))
        self.model_instance_2 = (
            story_models.StorySnapshotMetadataModel.get_by_id(
                '2-1'))

        self.job_class = (
            prod_validation_jobs_one_off
            .StorySnapshotMetadataModelAuditOneOffJob)
Exemple #12
0
 def test_get_with_five_or_more_questions(self):
     number_of_questions = 6
     self.topic_id = 'new_topic'
     self.skill_id_1 = skill_services.get_new_skill_id()
     self.topic = topic_domain.Topic.create_default_topic(
         self.topic_id, 'new_topic', 'abbrev')
     self.topic.uncategorized_skill_ids.append(self.skill_id_1)
     self.topic.thumbnail_filename = 'Image.svg'
     self.topic.thumbnail_bg_color = (
         constants.ALLOWED_THUMBNAIL_BG_COLORS['topic'][0])
     topic_services.save_new_topic(self.admin_id, self.topic)
     topic_services.publish_topic(self.topic_id, self.admin_id)
     self.save_new_skill(self.skill_id_1,
                         self.admin_id,
                         description='Skill Description 1')
     for index in python_utils.RANGE(number_of_questions):
         question_id = question_services.get_new_question_id()
         self.save_new_question(question_id, self.admin_id,
                                self._create_valid_question_data(index),
                                [self.skill_id_1])
         question_services.create_new_question_skill_link(
             self.admin_id, question_id, self.skill_id_1, 0.5)
     with self.swap(constants, 'ENABLE_NEW_STRUCTURE_PLAYERS', True):
         json_response = self.get_json(
             '%s/%s' % (feconf.TOPIC_DATA_HANDLER, 'new_topic'))
         expected_dict = {
             'topic_name': 'new_topic',
             'topic_id': self.topic_id,
             'canonical_story_dicts': [],
             'additional_story_dicts': [],
             'uncategorized_skill_ids': [self.skill_id_1],
             'subtopics': [],
             'degrees_of_mastery': {
                 self.skill_id_1: None
             },
             'skill_descriptions': {
                 self.skill_id_1: 'Skill Description 1'
             },
             'train_tab_should_be_displayed': True
         }
         self.assertDictContainsSubset(expected_dict, json_response)
     self.logout()
Exemple #13
0
 def test_get_with_no_skills_ids(self):
     self.topic = topic_domain.Topic.create_default_topic(
         self.topic_id, 'topic_with_no_skills', 'abbrev')
     topic_services.save_new_topic(self.admin_id, self.topic)
     topic_services.publish_topic(self.topic_id, self.admin_id)
     with self.swap(constants, 'ENABLE_NEW_STRUCTURE_PLAYERS', True):
         json_response = self.get_json(
             '%s/%s' % (feconf.TOPIC_DATA_HANDLER, 'topic_with_no_skills'))
         expected_dict = {
             'topic_name': 'topic_with_no_skills',
             'topic_id': self.topic_id,
             'canonical_story_dicts': [],
             'additional_story_dicts': [],
             'uncategorized_skill_ids': [],
             'subtopics': [],
             'degrees_of_mastery': {},
             'skill_descriptions': {},
             'train_tab_should_be_displayed': False
         }
         self.assertDictContainsSubset(expected_dict, json_response)
Exemple #14
0
 def test_get_with_no_skills_ids(self):
     self.topic = topic_domain.Topic.create_default_topic(
         self.topic_id, 'topic_with_no_skills',
         'topic-with-no-skills', 'description')
     topic_services.save_new_topic(self.admin_id, self.topic)
     topic_services.publish_topic(self.topic_id, self.admin_id)
     json_response = self.get_json(
         '%s/staging/%s' % (
             feconf.TOPIC_DATA_HANDLER, 'topic-with-no-skills'))
     expected_dict = {
         'topic_name': 'topic_with_no_skills',
         'topic_id': self.topic_id,
         'canonical_story_dicts': [],
         'additional_story_dicts': [],
         'uncategorized_skill_ids': [],
         'subtopics': [],
         'degrees_of_mastery': {},
         'skill_descriptions': {},
         'practice_tab_is_displayed': False
     }
     self.assertDictContainsSubset(expected_dict, json_response)
Exemple #15
0
    def test_get_all_topic_names(self):
        response = self.get_json('/getalltopicnames')
        self.assertEqual(response, {'topic_names': []})

        topic_id = '0'
        topic = topic_domain.Topic.create_default_topic(
            topic_id, 'topic', 'abbrev', 'description')
        topic.thumbnail_filename = 'thumbnail.svg'
        topic.thumbnail_bg_color = '#C6DCDA'
        topic.subtopics = [
            topic_domain.Subtopic(
                1, 'Title', ['skill_id_3'], 'image.svg',
                constants.ALLOWED_THUMBNAIL_BG_COLORS['subtopic'][0], 21131,
                'dummy-subtopic-three')
        ]
        topic.next_subtopic_id = 2
        topic_services.save_new_topic(self.owner_id, topic)
        topic_services.publish_topic(topic_id, self.admin_id)

        response = self.get_json('/getalltopicnames')
        self.assertEqual(response, {'topic_names': ['topic']})
Exemple #16
0
    def _publish_valid_topic(self, topic, uncategorized_skill_ids):
        """Saves and publishes a valid topic with linked skills and subtopic.

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

        for skill_id in uncategorized_skill_ids:
            self.save_new_skill(skill_id,
                                self.admin_id,
                                description='skill_description')
            topic_services.add_uncategorized_skill(self.admin_id, topic.id,
                                                   skill_id)
Exemple #17
0
    def setUp(self):
        super(OpportunityServicesIntegrationTest, self).setUp()
        self.signup(self.ADMIN_EMAIL, self.ADMIN_USERNAME)
        self.signup(self.OWNER_EMAIL, self.OWNER_USERNAME)

        self.admin_id = self.get_user_id_from_email(self.ADMIN_EMAIL)
        self.owner_id = self.get_user_id_from_email(self.OWNER_EMAIL)

        self.set_admins([self.ADMIN_USERNAME])
        self.admin = user_services.UserActionsInfo(self.admin_id)

        self.TOPIC_ID = 'topic'
        self.STORY_ID = 'story'
        self.USER_ID = 'user'
        self.SKILL_ID = 'skill'
        self.QUESTION_ID = question_services.get_new_question_id()
        explorations = [
            exp_domain.Exploration.create_default_exploration(
                '%s' % i,
                title='title %d' % i,
                category='category%d' % i,
            ) for i in python_utils.RANGE(5)
        ]

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

        topic = topic_domain.Topic.create_default_topic(topic_id=self.TOPIC_ID,
                                                        name='topic')
        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)
Exemple #18
0
    def test_regeneration_job_skips_invalid_topic(self):
        observed_log_messages = []

        def _mock_get_topic_by_id(unused_topic_id):
            """Mocks get_topic_by_id()."""
            return 'invalid_topic'

        def _mock_logging_function(msg, *args):
            """Mocks logging.error()."""
            observed_log_messages.append(msg % args)

        topic = topic_domain.Topic.create_default_topic(
            self.TOPIC_ID, 'A title', 'url-frag-two', 'description')
        topic_services.save_new_topic(self.albert_id, topic)

        get_topic_by_id_swap = self.swap(topic_fetchers, 'get_topic_by_id',
                                         _mock_get_topic_by_id)
        logging_exception_swap = self.swap(logging, 'exception',
                                           _mock_logging_function)

        with get_topic_by_id_swap, logging_exception_swap:
            job_id = (topic_jobs_one_off.RegenerateTopicSummaryOneOffJob.
                      create_new())
            topic_jobs_one_off.RegenerateTopicSummaryOneOffJob.enqueue(job_id)
            self.process_and_flush_pending_mapreduce_tasks()

        output = topic_jobs_one_off.RegenerateTopicSummaryOneOffJob.get_output(
            job_id)

        self.assertEqual(observed_log_messages, [
            u'Failed to create topic summary %s: \'unicode\' '
            'object has no attribute \'canonical_story_references\'' % topic.id
        ])
        for message in output:
            self.assertRegexpMatches(
                message,
                'object has no attribute \'canonical_story_references\'')
Exemple #19
0
    def setUp(self):
        """Completes the sign-up process for the various users."""
        super(BasePracticeSessionsControllerTests, 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.topic_id = 'topic'
        self.topic_id_1 = 'topic1'

        self.topic = topic_domain.Topic.create_default_topic(
            self.topic_id, 'public_topic_name')
        self.topic.uncategorized_skill_ids.append('skill_id_1')
        self.topic.subtopics.append(topic_domain.Subtopic(
            1, 'subtopic_name', ['skill_id_2']))
        self.topic.next_subtopic_id = 2
        topic_services.save_new_topic(self.admin_id, self.topic)

        self.topic = topic_domain.Topic.create_default_topic(
            self.topic_id_1, 'private_topic_name')
        topic_services.save_new_topic(self.admin_id, self.topic)

        topic_services.publish_topic(self.topic_id, self.admin_id)
Exemple #20
0
    def test_job_skips_deleted_topic(self):
        """Tests that RemoveDeletedSkillsFromTopicOneOffJob job skips
        deleted topic and does not attempt to remove uncategorized skills for
        skills that are deleted.
        """
        topic = topic_domain.Topic.create_default_topic(
            self.TOPIC_ID, 'A name', 'abbrev', 'description')
        topic.add_uncategorized_skill_id('skill_1')
        topic.add_uncategorized_skill_id('skill_2')
        topic_services.save_new_topic(self.albert_id, topic)

        # Delete the topic before migration occurs.
        topic_services.delete_topic(self.albert_id, self.TOPIC_ID)

        # Ensure the topic is deleted.
        with self.assertRaisesRegexp(Exception, 'Entity .* not found'):
            topic_fetchers.get_topic_by_id(self.TOPIC_ID)

        # Start migration job on sample topic.
        job_id = (topic_jobs_one_off.RemoveDeletedSkillsFromTopicOneOffJob.
                  create_new())
        topic_jobs_one_off.RemoveDeletedSkillsFromTopicOneOffJob.enqueue(
            job_id)

        # This running without errors indicates the deleted topic is
        # being ignored.
        self.process_and_flush_pending_mapreduce_tasks()

        # Ensure the topic is still deleted.
        with self.assertRaisesRegexp(Exception, 'Entity .* not found'):
            topic_fetchers.get_topic_by_id(self.TOPIC_ID)

        output = (topic_jobs_one_off.RemoveDeletedSkillsFromTopicOneOffJob.
                  get_output(job_id))
        expected = [[u'topic_deleted', [u'Encountered 1 deleted topics.']]]
        self.assertEqual(expected, [ast.literal_eval(x) for x in output])
    def setUp(self):
        super(OpportunityServicesUnitTest, self).setUp()
        self.signup(self.OWNER_EMAIL, self.OWNER_USERNAME)
        self.signup(self.ADMIN_EMAIL, self.ADMIN_USERNAME)

        self.admin_id = self.get_user_id_from_email(self.ADMIN_EMAIL)
        self.owner_id = self.get_user_id_from_email(self.OWNER_EMAIL)

        self.set_admins([self.ADMIN_USERNAME])

        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',
                                            correctness_feedback_enabled=True)
            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(
            self.TOPIC_ID, 'topic', 'abbrev', 'description')
        topic.thumbnail_filename = 'thumbnail.svg'
        topic.thumbnail_bg_color = '#C6DCDA'
        topic.subtopics = [
            topic_domain.Subtopic(
                1, 'Title', ['skill_id_1'], 'image.svg',
                constants.ALLOWED_THUMBNAIL_BG_COLORS['subtopic'][0],
                'dummy-subtopic-url')
        ]
        topic.next_subtopic_id = 2
        topic_services.save_new_topic(self.owner_id, topic)
        topic_services.publish_topic(self.TOPIC_ID, self.admin_id)

        story = story_domain.Story.create_default_story(
            self.STORY_ID, 'A story', 'Description', self.TOPIC_ID,
            'story-two')
        story_services.save_new_story(self.owner_id, story)
        topic_services.add_canonical_story(self.owner_id, self.TOPIC_ID,
                                           self.STORY_ID)
        topic_services.publish_story(self.TOPIC_ID, self.STORY_ID,
                                     self.admin_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(OpportunityServicesIntegrationTest, self).setUp()
        self.signup(self.ADMIN_EMAIL, self.ADMIN_USERNAME)
        self.signup(self.OWNER_EMAIL, self.OWNER_USERNAME)

        self.admin_id = self.get_user_id_from_email(self.ADMIN_EMAIL)
        self.owner_id = self.get_user_id_from_email(self.OWNER_EMAIL)

        self.set_admins([self.ADMIN_USERNAME])
        self.admin = user_services.UserActionsInfo(self.admin_id)

        self.TOPIC_ID = 'topic'
        self.STORY_ID = 'story'
        self.USER_ID = 'user'
        self.SKILL_ID = 'skill'
        self.QUESTION_ID = question_services.get_new_question_id()
        self.THREAD_ID = 'exploration.exp1.thread_1'

        # Since a valid exploration is created here, it has EndExploration
        # state as well, so the content in that has to be taken into account as
        # well when checking content_count in the tests.
        explorations = [
            self.save_new_valid_exploration('%s' % i,
                                            self.owner_id,
                                            title='title %d' % i,
                                            category='category%d' % i,
                                            end_state_name='End State',
                                            correctness_feedback_enabled=True)
            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(
            self.TOPIC_ID, 'topic', 'abbrev', 'description')
        topic.thumbnail_filename = 'thumbnail.svg'
        topic.thumbnail_bg_color = '#C6DCDA'
        topic.subtopics = [
            topic_domain.Subtopic(
                1, 'Title', ['skill_id_1'], 'image.svg',
                constants.ALLOWED_THUMBNAIL_BG_COLORS['subtopic'][0],
                'dummy-subtopic-url')
        ]
        topic.next_subtopic_id = 2
        subtopic_page = (
            subtopic_page_domain.SubtopicPage.create_default_subtopic_page(
                1, self.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(self.TOPIC_ID, self.admin_id)

        story = story_domain.Story.create_default_story(
            self.STORY_ID, 'A story', 'description', self.TOPIC_ID,
            'story-one')
        story_services.save_new_story(self.owner_id, story)
        topic_services.add_canonical_story(self.owner_id, self.TOPIC_ID,
                                           self.STORY_ID)
        topic_services.publish_story(self.TOPIC_ID, self.STORY_ID,
                                     self.admin_id)
    def setUp(self):
        super(ContributionOpportunitiesHandlerTest, self).setUp()
        self.signup(self.ADMIN_EMAIL, self.ADMIN_USERNAME)
        self.signup(self.OWNER_EMAIL, self.OWNER_USERNAME)

        self.admin_id = self.get_user_id_from_email(self.ADMIN_EMAIL)
        self.owner_id = self.get_user_id_from_email(self.OWNER_EMAIL)

        self.set_admins([self.ADMIN_USERNAME])

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

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

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

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

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

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

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

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

        self.expected_opportunity_dict_2 = {
            'id': '1',
            'topic_name': 'topic',
            'story_title': 'title 1',
            'chapter_title': 'Node1',
            'content_count': 2,
            'translation_counts': {}
        }
Exemple #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.')
Exemple #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.')
Exemple #26
0
    def setUp(self):
        super(ExplorationOpportunitySummaryModelRegenerationJobTest,
              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_1 = 'topic1'
        self.topic_id_2 = 'topic2'

        story_id_1 = 'story1'
        story_id_2 = 'story2'

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

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

        topic_1 = topic_domain.Topic.create_default_topic(
            topic_id=self.topic_id_1, name='topic1', abbreviated_name='abbrev')
        topic_services.save_new_topic(self.owner_id, topic_1)

        topic_2 = topic_domain.Topic.create_default_topic(
            topic_id=self.topic_id_2, name='topic2', abbreviated_name='abbrev')
        topic_services.save_new_topic(self.owner_id, topic_2)

        story_1 = story_domain.Story.create_default_story(
            story_id_1,
            title='A story',
            corresponding_topic_id=self.topic_id_1)
        story_2 = story_domain.Story.create_default_story(
            story_id_2,
            title='A story',
            corresponding_topic_id=self.topic_id_2)

        story_services.save_new_story(self.owner_id, story_1)
        story_services.save_new_story(self.owner_id, story_2)
        topic_services.add_canonical_story(self.owner_id, self.topic_id_1,
                                           story_id_1)
        topic_services.add_canonical_story(self.owner_id, self.topic_id_2,
                                           story_id_2)
        story_services.update_story(self.owner_id, story_id_1, [
            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.')
        story_services.update_story(self.owner_id, story_id_2, [
            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': '1'
            })
        ], 'Changes.')
Exemple #27
0
    def test_get(self):
        self.signup(self.CURRICULUM_ADMIN_EMAIL,
                    self.CURRICULUM_ADMIN_USERNAME)
        admin_id = self.get_user_id_from_email(self.CURRICULUM_ADMIN_EMAIL)
        self.set_curriculum_admins([self.CURRICULUM_ADMIN_USERNAME])

        self.login(self.CURRICULUM_ADMIN_EMAIL, is_super_admin=True)
        topic_id_1 = topic_fetchers.get_new_topic_id()
        topic_id_2 = topic_fetchers.get_new_topic_id()
        private_topic = topic_domain.Topic.create_default_topic(
            topic_id_1, 'private_topic_name', 'private-topic-name',
            'description')
        topic_services.save_new_topic(admin_id, private_topic)
        public_topic = topic_domain.Topic.create_default_topic(
            topic_id_2, 'public_topic_name', 'public-topic-name',
            'description')
        public_topic.thumbnail_filename = 'Topic.svg'
        public_topic.thumbnail_bg_color = (
            constants.ALLOWED_THUMBNAIL_BG_COLORS['topic'][0])
        public_topic.subtopics = [
            topic_domain.Subtopic(
                1, 'Title', ['skill_id_1', 'skill_id_2', 'skill_id_3'],
                'image.svg',
                constants.ALLOWED_THUMBNAIL_BG_COLORS['subtopic'][0], 21131,
                'dummy-subtopic-three')
        ]
        public_topic.next_subtopic_id = 2
        topic_services.save_new_topic(admin_id, public_topic)
        topic_services.publish_topic(topic_id_2, admin_id)

        csrf_token = self.get_new_csrf_token()
        new_config_value = [{
            'name': 'math',
            'topic_ids': [topic_id_1, topic_id_2],
            'course_details': 'Course details for classroom.',
            'topic_list_intro': 'Topics covered for classroom',
            'url_fragment': 'math',
        }]

        payload = {
            'action': 'save_config_properties',
            'new_config_property_values': {
                config_domain.CLASSROOM_PAGES_DATA.name: (new_config_value),
            }
        }
        self.post_json('/adminhandler', payload, csrf_token=csrf_token)
        self.logout()

        json_response = self.get_json('%s/%s' %
                                      (feconf.CLASSROOM_DATA_HANDLER, 'math'))
        public_topic_summary_dict = (
            topic_fetchers.get_topic_summary_by_id(topic_id_2).to_dict())
        public_topic_summary_dict['is_published'] = True
        private_topic_summary_dict = (
            topic_fetchers.get_topic_summary_by_id(topic_id_1).to_dict())
        private_topic_summary_dict['is_published'] = False

        expected_dict = {
            'name':
            'math',
            'topic_summary_dicts':
            [private_topic_summary_dict, public_topic_summary_dict],
            'course_details':
            'Course details for classroom.',
            'topic_list_intro':
            'Topics covered for classroom'
        }
        self.assertDictContainsSubset(expected_dict, json_response)
Exemple #28
0
    def setUp(self):
        """Completes the sign-up process for the various users."""
        super(BaseTopicViewerControllerTests, self).setUp()
        self.signup(self.NEW_USER_EMAIL, self.NEW_USER_USERNAME)
        self.user_id = self.get_user_id_from_email(self.NEW_USER_EMAIL)
        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.topic_id = 'topic'
        self.story_id_1 = 'story_id_1'
        self.story_id_2 = 'story_id_2'
        self.topic_id_1 = 'topic1'
        self.topic_id_2 = 'topic2'
        self.skill_id_1 = skill_services.get_new_skill_id()
        self.skill_id_2 = skill_services.get_new_skill_id()

        self.story_1 = story_domain.Story.create_default_story(
            self.story_id_1, 'story_title', self.topic_id_1)
        self.story_1.description = 'story_description'
        self.story_1.node_titles = []

        self.story_2 = story_domain.Story.create_default_story(
            self.story_id_2, 'story_title', self.topic_id_2)
        self.story_2.description = 'story_description'
        self.story_2.node_titles = []

        self.topic = topic_domain.Topic.create_default_topic(
            self.topic_id, 'public_topic_name', 'abbrev')
        self.topic.uncategorized_skill_ids.append(self.skill_id_1)
        self.topic.subtopics.append(
            topic_domain.Subtopic(
                1, 'subtopic_name', [self.skill_id_2], 'image.svg',
                constants.ALLOWED_THUMBNAIL_BG_COLORS['subtopic'][0]))
        self.topic.next_subtopic_id = 2
        self.topic.thumbnail_filename = 'Image.svg'
        self.topic.thumbnail_bg_color = (
            constants.ALLOWED_THUMBNAIL_BG_COLORS['topic'][0])
        self.topic.canonical_story_references.append(
            topic_domain.StoryReference.create_default_story_reference(
                self.story_id_1))
        self.topic.additional_story_references.append(
            topic_domain.StoryReference.create_default_story_reference(
                self.story_id_2))

        topic_services.save_new_topic(self.admin_id, self.topic)
        story_services.save_new_story(self.admin_id, self.story_1)
        story_services.save_new_story(self.admin_id, self.story_2)

        self.topic = topic_domain.Topic.create_default_topic(
            self.topic_id_1, 'private_topic_name', 'abbrev')
        self.topic.thumbnail_filename = 'Image.svg'
        self.topic.thumbnail_bg_color = (
            constants.ALLOWED_THUMBNAIL_BG_COLORS['topic'][0])
        topic_services.save_new_topic(self.admin_id, self.topic)

        topic_services.publish_topic(self.topic_id, self.admin_id)
        topic_services.publish_story(self.topic_id, self.story_id_1,
                                     self.admin_id)
        topic_services.publish_story(self.topic_id, self.story_id_2,
                                     self.admin_id)

        self.save_new_skill(self.skill_id_1,
                            self.user_id,
                            description='Skill Description 1')
        self.save_new_skill(self.skill_id_2,
                            self.user_id,
                            description='Skill Description 2')
        skill_services.create_user_skill_mastery(self.user_id, self.skill_id_1,
                                                 0.3)
        skill_services.create_user_skill_mastery(self.user_id, self.skill_id_2,
                                                 0.5)
    def setUp(self):
        super(ContributionOpportunitiesHandlerTest, self).setUp()
        self.signup(self.ADMIN_EMAIL, self.ADMIN_USERNAME)
        self.signup(self.OWNER_EMAIL, self.OWNER_USERNAME)

        self.admin_id = self.get_user_id_from_email(self.ADMIN_EMAIL)
        self.owner_id = self.get_user_id_from_email(self.OWNER_EMAIL)

        self.set_admins([self.ADMIN_USERNAME])

        explorations = [
            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.thumbnail_filename = 'thumbnail.svg'
        topic.thumbnail_bg_color = '#C6DCDA'
        topic_services.save_new_topic(self.owner_id, topic)
        topic_services.publish_topic('0', self.admin_id)

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

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

        stories = [
            story_domain.Story.create_default_story('%s' % i, 'title %d' % i,
                                                    'description %d' % i, '0',
                                                    'title-%s' % chr(97 + i))
            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)
            topic_services.publish_story(topic.id, story.id, self.admin_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.')

        # The content_count is 4 for the expected dicts below since a valid
        # exploration with EndExploration is created above, so the content in
        # the last state is also included in the count. This content includes:
        # 2 content, 1 TextInput interaction customization argument
        # (placeholder), and 1 outcome.
        self.expected_opportunity_dict_1 = {
            'id': '0',
            'topic_name': 'topic',
            'story_title': 'title 0',
            'chapter_title': 'Node1',
            'content_count': 2,
            'translation_counts': {}
        }

        self.expected_opportunity_dict_2 = {
            'id': '1',
            'topic_name': 'topic',
            'story_title': 'title 1',
            'chapter_title': 'Node1',
            'content_count': 2,
            'translation_counts': {}
        }
Exemple #30
0
    def test_interactions_are_reported_correctly(self):
        topic_id_1 = 'topicid1'
        topic_id_2 = 'topicid2'
        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()

        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>')

        topic_1 = topic_domain.Topic.create_default_topic(
            topic_id_1, 'Dummy Topic 1', 'dummy-topic-one', 'description')
        topic_2 = topic_domain.Topic.create_default_topic(
            topic_id_2, 'Empty Topic', 'empty-topic', '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)

        # These explorations were chosen since they pass the validations
        # for published stories.
        exp_services.load_demo('15')
        exp_services.load_demo('25')
        exp_services.load_demo('13')
        exp_services.update_exploration(
            self.user_id, '15', [
                exp_domain.ExplorationChange({
                    'cmd': exp_domain.CMD_EDIT_EXPLORATION_PROPERTY,
                    'property_name': 'correctness_feedback_enabled',
                    'new_value': True
                })
            ], 'Changed correctness_feedback_enabled.')
        exp_services.update_exploration(
            self.user_id, '25', [
                exp_domain.ExplorationChange({
                    'cmd': exp_domain.CMD_EDIT_EXPLORATION_PROPERTY,
                    'property_name': 'correctness_feedback_enabled',
                    'new_value': True
                })
            ], 'Changed correctness_feedback_enabled.')
        exp_services.update_exploration(
            self.user_id, '13', [
                exp_domain.ExplorationChange({
                    'cmd': exp_domain.CMD_EDIT_EXPLORATION_PROPERTY,
                    'property_name': 'correctness_feedback_enabled',
                    'new_value': True
                })
            ], 'Changed correctness_feedback_enabled.')

        story = story_domain.Story.create_default_story(
            story_id, 'Help Jaime win the Arcade', 'Description', topic_id_1,
            'help-jamie-win-arcade')

        story_node_dicts = [{
            'exp_id': '15',
            'title': 'What are the place values?',
            'description': 'a'
        }, {
            'exp_id': '25',
            'title': 'Finding the value of a number',
            'description': 'b'
        }, {
            'exp_id': '13',
            'title': 'Comparing Numbers',
            'description': 'c'
        }]

        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)

        topic_services.publish_story(topic_id_1, story_id, self.user_id)
        job_id = (topic_jobs_one_off.InteractionsInStoriesAuditOneOffJob.
                  create_new())
        topic_jobs_one_off.InteractionsInStoriesAuditOneOffJob.enqueue(job_id)
        self.process_and_flush_pending_mapreduce_tasks()

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

        expected = [[
            '%s (%s)' % ('Dummy Topic 1', topic_id_1),
            [
                u'[u\'EndExploration\', u\'ImageClickInput\', u\'Continue\', '
                u'u\'MultipleChoiceInput\', u\'TextInput\']'
            ]
        ], ['%s (%s)' % ('Empty Topic', topic_id_2), [u'[]']]]
        self.assertEqual(expected, [ast.literal_eval(x) for x in output])