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)

        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.')
Beispiel #2
0
    def setUp(self):
        super(OpportunityServicesUnitTest, self).setUp()
        self.signup(self.OWNER_EMAIL, self.OWNER_USERNAME)
        self.signup(self.CURRICULUM_ADMIN_EMAIL,
                    self.CURRICULUM_ADMIN_USERNAME)

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

        self.set_curriculum_admins([self.CURRICULUM_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 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], 21131,
                '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.')
Beispiel #3
0
    def post(self):
        """Generates structures for Android end-to-end tests.

        This handler generates structures for Android end-to-end tests in
        order to evaluate the integration of network requests from the
        Android client to the backend. This handler should only be called
        once (or otherwise raises an exception), and can only be used in
        development mode (this handler is unavailable in production).

        Note that the handler outputs an empty JSON dict when the request is
        successful.

        The specific structures that are generated:
            Topic: A topic with both a test story and a subtopic.
            Story: A story with 'android_interactions' as a exploration
                node.
            Exploration: 'android_interactions' from the local assets.
            Subtopic: A dummy subtopic to validate the topic.
            Skill: A dummy skill to validate the subtopic.

        Raises:
            Exception. When used in production mode.
            InvalidInputException. The topic is already
                created but not published.
            InvalidInputException. The topic is already published.
        """

        if not constants.DEV_MODE:
            raise Exception('Cannot load new structures data in production.')
        if topic_services.does_topic_with_name_exist('Android test'):
            topic = topic_fetchers.get_topic_by_name('Android test')
            topic_rights = topic_fetchers.get_topic_rights(topic.id,
                                                           strict=False)
            if topic_rights.topic_is_published:
                raise self.InvalidInputException(
                    'The topic is already published.')
            else:
                raise self.InvalidInputException(
                    'The topic exists but is not published.')
        exp_id = '26'
        user_id = feconf.SYSTEM_COMMITTER_ID
        # Generate new Structure id for topic, story, skill and question.
        topic_id = topic_fetchers.get_new_topic_id()
        story_id = story_services.get_new_story_id()
        skill_id = skill_services.get_new_skill_id()
        question_id = question_services.get_new_question_id()

        # Create dummy skill and question.
        skill = self._create_dummy_skill(skill_id, 'Dummy Skill for Android',
                                         '<p>Dummy Explanation 1</p>')
        question = self._create_dummy_question(question_id, 'Question 1',
                                               [skill_id])
        question_services.add_question(user_id, question)
        question_services.create_new_question_skill_link(
            user_id, question_id, skill_id, 0.3)

        # Create and update topic to validate before publishing.
        topic = topic_domain.Topic.create_default_topic(
            topic_id, 'Android test', 'test-topic-one', 'description')
        topic.update_url_fragment('test-topic')
        topic.update_meta_tag_content('tag')
        topic.update_page_title_fragment_for_web('page title for topic')
        # Save the dummy image to the filesystem to be used as thumbnail.
        with python_utils.open_file(os.path.join(feconf.TESTS_DATA_DIR,
                                                 'test_svg.svg'),
                                    'rb',
                                    encoding=None) as f:
            raw_image = f.read()
        fs = fs_domain.AbstractFileSystem(
            fs_domain.GcsFileSystem(feconf.ENTITY_TYPE_TOPIC, topic_id))
        fs.commit('%s/test_svg.svg' % (constants.ASSET_TYPE_THUMBNAIL),
                  raw_image,
                  mimetype='image/svg+xml')
        # Update thumbnail properties.
        topic.update_thumbnail_filename('test_svg.svg')
        topic.update_thumbnail_bg_color('#C6DCDA')

        # Add other structures to the topic.
        topic.add_canonical_story(story_id)
        topic.add_uncategorized_skill_id(skill_id)
        topic.add_subtopic(1, 'Test Subtopic Title')

        # Update and validate subtopic.
        topic.update_subtopic_thumbnail_filename(1, 'test_svg.svg')
        topic.update_subtopic_thumbnail_bg_color(1, '#FFFFFF')
        topic.update_subtopic_url_fragment(1, 'suburl')
        topic.move_skill_id_to_subtopic(None, 1, skill_id)
        subtopic_page = (
            subtopic_page_domain.SubtopicPage.create_default_subtopic_page(
                1, topic_id))

        # Upload local exploration to the datastore and enable feedback.
        exp_services.load_demo(exp_id)
        rights_manager.release_ownership_of_exploration(
            user_services.get_system_user(), exp_id)
        exp_services.update_exploration(
            user_id, exp_id, [
                exp_domain.ExplorationChange({
                    'cmd': exp_domain.CMD_EDIT_EXPLORATION_PROPERTY,
                    'property_name': 'correctness_feedback_enabled',
                    'new_value': True
                })
            ], 'Changed correctness_feedback_enabled.')

        # Add and update the exploration/node to the story.
        story = story_domain.Story.create_default_story(
            story_id, 'Android End to End testing', 'Description', topic_id,
            'android-end-to-end-testing')

        story.add_node('%s%d' % (story_domain.NODE_ID_PREFIX, 1),
                       'Testing with UI Automator')

        story.update_node_description(
            '%s%d' % (story_domain.NODE_ID_PREFIX, 1),
            'To test all Android interactions')
        story.update_node_exploration_id(
            '%s%d' % (story_domain.NODE_ID_PREFIX, 1), exp_id)

        # Save the dummy image to the filesystem to be used as thumbnail.
        with python_utils.open_file(os.path.join(feconf.TESTS_DATA_DIR,
                                                 'test_svg.svg'),
                                    'rb',
                                    encoding=None) as f:
            raw_image = f.read()
        fs = fs_domain.AbstractFileSystem(
            fs_domain.GcsFileSystem(feconf.ENTITY_TYPE_STORY, story_id))
        fs.commit('%s/test_svg.svg' % (constants.ASSET_TYPE_THUMBNAIL),
                  raw_image,
                  mimetype='image/svg+xml')

        story.update_node_thumbnail_filename(
            '%s%d' % (story_domain.NODE_ID_PREFIX, 1), 'test_svg.svg')
        story.update_node_thumbnail_bg_color(
            '%s%d' % (story_domain.NODE_ID_PREFIX, 1), '#F8BF74')

        # Update and validate the story.
        story.update_meta_tag_content('tag')
        story.update_thumbnail_filename('test_svg.svg')
        story.update_thumbnail_bg_color(
            constants.ALLOWED_THUMBNAIL_BG_COLORS['story'][0])

        # Save the previously created structures
        # (skill, story, topic, subtopic).
        skill_services.save_new_skill(user_id, skill)
        story_services.save_new_story(user_id, story)
        topic_services.save_new_topic(user_id, topic)
        subtopic_page_services.save_subtopic_page(
            user_id, subtopic_page, 'Added subtopic', [
                topic_domain.TopicChange({
                    'cmd': topic_domain.CMD_ADD_SUBTOPIC,
                    'subtopic_id': 1,
                    'title': 'Dummy Subtopic Title'
                })
            ])

        # Generates translation opportunities for the Contributor Dashboard.
        exp_ids_in_story = story.story_contents.get_all_linked_exp_ids()
        opportunity_services.add_new_exploration_opportunities(
            story_id, exp_ids_in_story)

        # Publish the story and topic.
        topic_services.publish_story(topic_id, story_id, user_id)
        topic_services.publish_topic(topic_id, user_id)

        # Upload thumbnails to be accessible through AssetsDevHandler.
        self._upload_thumbnail(topic_id, feconf.ENTITY_TYPE_TOPIC)
        self._upload_thumbnail(story_id, feconf.ENTITY_TYPE_STORY)
        self.render_json({})
Beispiel #4
0
    def test_mark_topic_as_learnt_and_story_as_completed(self):
        self.NEW_USER_EMAIL = '*****@*****.**'
        self.NEW_USER_USERNAME = '******'

        self.save_new_valid_exploration(
            self.EXP_ID_3, self.admin_id, title='Title 3', end_state_name='End',
            correctness_feedback_enabled=True)
        self.publish_exploration(self.admin_id, self.EXP_ID_3)

        story = story_domain.Story.create_default_story(
            self.NEW_STORY_ID, 'Title', 'Description', self.TOPIC_ID,
            self.STORY_URL_FRAGMENT_TWO)
        story.meta_tag_content = 'story meta content'

        exp_summary_dicts = (
            summary_services.get_displayable_exp_summary_dicts_matching_ids(
                [self.EXP_ID_3], user=self.admin))
        self.node_1 = {
            'id': self.NODE_ID_1,
            'title': 'Title 1',
            'description': 'Description 1',
            'thumbnail_filename': 'image_1.svg',
            'thumbnail_bg_color': constants.ALLOWED_THUMBNAIL_BG_COLORS[
                'chapter'][0],
            'thumbnail_size_in_bytes': 21131,
            'destination_node_ids': [],
            'acquired_skill_ids': [],
            'prerequisite_skill_ids': [],
            'outline': '',
            'outline_is_finalized': False,
            'exploration_id': self.EXP_ID_3,
            'exp_summary_dict': exp_summary_dicts[0],
            'completed': False
        }
        story.story_contents.nodes = [
            story_domain.StoryNode.from_dict(self.node_1)
        ]
        self.nodes = story.story_contents.nodes
        story.story_contents.initial_node_id = 'node_1'
        story.story_contents.next_node_id = 'node_2'
        story_services.save_new_story(self.admin_id, story)
        topic_services.add_canonical_story(
            self.admin_id, self.TOPIC_ID, self.NEW_STORY_ID)
        topic_services.publish_story(
            self.TOPIC_ID, self.NEW_STORY_ID, self.admin_id)

        csrf_token = self.get_new_csrf_token()
        story_services.record_completed_node_in_story_context(
            self.viewer_id, self.STORY_ID, self.NODE_ID_2)
        story_services.record_completed_node_in_story_context(
            self.viewer_id, self.STORY_ID, self.NODE_ID_1)
        with self.swap(constants, 'ENABLE_NEW_STRUCTURE_VIEWER_UPDATES', True):
            self.post_json(
                '%s/staging/topic/%s/%s' % (
                    feconf.STORY_PROGRESS_URL_PREFIX, self.STORY_URL_FRAGMENT,
                    self.NODE_ID_3
                ), {}, csrf_token=csrf_token
            )

        self.assertEqual(len(
            learner_progress_services.get_all_learnt_topic_ids(
                self.viewer_id)), 1)
        self.assertEqual(len(
            learner_progress_services.get_all_completed_story_ids(
                self.viewer_id)), 1)

        def _mock_none_function(_):
            """Mocks None."""
            return None

        story_fetchers_swap = self.swap(
            story_fetchers, 'get_story_by_id', _mock_none_function)

        with story_fetchers_swap:
            with self.capture_logging(min_level=logging.ERROR) as captured_logs:
                self.post_json(
                    '%s/staging/topic/%s/%s' % (
                        feconf.STORY_PROGRESS_URL_PREFIX,
                        self.STORY_URL_FRAGMENT,
                        self.NODE_ID_3
                    ), {}, csrf_token=csrf_token)
                self.assertEqual(
                    captured_logs,
                    ['Could not find a story corresponding to %s '
                     'id.' % self.STORY_ID])
Beispiel #5
0
    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_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,
                                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='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.')

        # The content_count is 3 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.
        self.expected_opportunity_dict_1 = {
            'id': '0',
            'topic_name': 'topic',
            'story_title': 'title 0',
            'chapter_title': 'Node1',
            'content_count': 3,
            'translation_counts': {}
        }

        self.expected_opportunity_dict_2 = {
            'id': '1',
            'topic_name': 'topic',
            'story_title': 'title 1',
            'chapter_title': 'Node1',
            'content_count': 3,
            'translation_counts': {}
        }
    def setUp(self):
        super(ExplorationOpportunitySummaryModelRegenerationJobTest,
              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.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(
            self.topic_id_1, 'topic', 'abbrev-one', 'description')
        topic_1.thumbnail_filename = 'thumbnail.svg'
        topic_1.thumbnail_bg_color = '#C6DCDA'
        topic_1.subtopics = [
            topic_domain.Subtopic(
                1, 'Title', ['skill_id_1'], 'image.svg',
                constants.ALLOWED_THUMBNAIL_BG_COLORS['subtopic'][0],
                'dummy-subtopic-three')
        ]
        topic_1.next_subtopic_id = 2
        subtopic_page = (
            subtopic_page_domain.SubtopicPage.create_default_subtopic_page(
                1, self.topic_id_1))
        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_1)
        topic_services.publish_topic(self.topic_id_1, self.admin_id)

        topic_2 = topic_domain.Topic.create_default_topic(
            self.topic_id_2, 'topic2', 'abbrev-two', 'description')
        topic_2.thumbnail_filename = 'thumbnail.svg'
        topic_2.thumbnail_bg_color = '#C6DCDA'
        topic_2.subtopics = [
            topic_domain.Subtopic(
                1, 'Title', ['skill_id_2'], 'image.svg',
                constants.ALLOWED_THUMBNAIL_BG_COLORS['subtopic'][0],
                'dummy-subtopic-three')
        ]
        subtopic_page = (
            subtopic_page_domain.SubtopicPage.create_default_subtopic_page(
                1, self.topic_id_2))
        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_2.next_subtopic_id = 2
        topic_services.save_new_topic(self.owner_id, topic_2)
        topic_services.publish_topic(self.topic_id_2, self.admin_id)

        story_1 = story_domain.Story.create_default_story(
            story_id_1, 'A story', 'description', self.topic_id_1, 'story-one')
        story_2 = story_domain.Story.create_default_story(
            story_id_2, 'A story', 'description', self.topic_id_2, 'story-two')

        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.publish_story(self.topic_id_1, story_id_1,
                                     self.admin_id)
        topic_services.add_canonical_story(self.owner_id, self.topic_id_2,
                                           story_id_2)
        topic_services.publish_story(self.topic_id_2, story_id_2,
                                     self.admin_id)
        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.')
Beispiel #7
0
    def setUp(self):
        """Completes the sign-up process for the various users."""
        super(BaseReviewTestsControllerTests, self).setUp()
        self.signup(self.ADMIN_EMAIL, self.ADMIN_USERNAME)
        self.signup(self.OWNER_EMAIL, self.OWNER_USERNAME)
        self.signup(self.VIEWER_EMAIL, self.VIEWER_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.viewer_id = self.get_user_id_from_email(self.VIEWER_EMAIL)

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

        self.topic_id = 'topic_id'
        self.story_id_1 = 'story_id_1'
        self.story_id_2 = 'story_id_2'
        self.story_id_3 = 'story_id_3'
        self.node_id = 'node_1'
        self.node_id_2 = 'node_2'
        self.exp_id = 'exp_id'
        self.story_url_fragment_1 = 'public-story-title'
        self.story_url_fragment_2 = 'private-story-title'

        self.save_new_valid_exploration(self.exp_id,
                                        self.owner_id,
                                        correctness_feedback_enabled=True)
        self.publish_exploration(self.owner_id, self.exp_id)

        self.node_1 = {
            'id':
            self.node_id,
            'title':
            'Title 1',
            'description':
            'Description 1',
            'thumbnail_filename':
            'image.svg',
            'thumbnail_bg_color':
            constants.ALLOWED_THUMBNAIL_BG_COLORS['chapter'][0],
            'destination_node_ids': [],
            'acquired_skill_ids': ['skill_id_1', 'skill_id_2'],
            'prerequisite_skill_ids': [],
            'outline':
            '',
            'outline_is_finalized':
            False,
            'exploration_id':
            self.exp_id
        }

        self.save_new_skill('skill_id_1', self.admin_id, description='Skill 1')
        self.save_new_skill('skill_id_2', self.admin_id, description='Skill 2')

        self.story = story_domain.Story.create_default_story(
            self.story_id_1, 'Public Story Title', 'Description',
            self.topic_id, self.story_url_fragment_1)
        self.story.story_contents.nodes = [
            story_domain.StoryNode.from_dict(self.node_1)
        ]
        self.story.story_contents.initial_node_id = self.node_id
        self.story.story_contents.next_node_id = self.node_id_2
        story_services.save_new_story(self.admin_id, self.story)

        self.story_2 = story_domain.Story.create_default_story(
            self.story_id_2, 'Private Story Title', 'Description',
            self.topic_id, self.story_url_fragment_2)
        story_services.save_new_story(self.admin_id, self.story_2)
        subtopic_1 = topic_domain.Subtopic.create_default_subtopic(
            1, 'Subtopic Title 1')
        subtopic_1.skill_ids = ['skill_id_1']
        subtopic_1.url_fragment = 'sub-one-frag'
        self.save_new_topic(
            self.topic_id,
            'user',
            name='Topic',
            description='A new topic',
            canonical_story_ids=[self.story_id_1, self.story_id_3],
            additional_story_ids=[],
            uncategorized_skill_ids=[],
            subtopics=[subtopic_1],
            next_subtopic_id=2)
        topic_services.publish_topic(self.topic_id, self.admin_id)
        topic_services.publish_story(self.topic_id, self.story_id_1,
                                     self.admin_id)

        self.login(self.VIEWER_EMAIL)
Beispiel #8
0
    def setUp(self):
        super(ContributionOpportunitiesHandlerTest, self).setUp()
        self.signup(self.CURRICULUM_ADMIN_EMAIL,
                    self.CURRICULUM_ADMIN_USERNAME)
        self.signup(self.OWNER_EMAIL, self.OWNER_USERNAME)

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

        self.set_curriculum_admins([self.CURRICULUM_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',
                                            correctness_feedback_enabled=True)
            for i in python_utils.RANGE(2)
        ]

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

        self.topic_id = '0'
        topic = topic_domain.Topic.create_default_topic(
            self.topic_id, 'topic', 'abbrev', 'description')
        self.skill_id_0 = 'skill_id_0'
        self.skill_id_1 = 'skill_id_1'
        self._publish_valid_topic(topic, [self.skill_id_0, self.skill_id_1])

        # Add skill opportunity topic to a classroom.
        config_services.set_property(self.admin_id, 'classroom_pages_data',
                                     [{
                                         'name': 'math',
                                         'url_fragment': 'math-one',
                                         'topic_ids': [self.topic_id],
                                         'course_details': '',
                                         'topic_list_intro': ''
                                     }])

        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': {},
            'translation_in_review_counts': {}
        }

        self.expected_opportunity_dict_2 = {
            'id': '1',
            'topic_name': 'topic',
            'story_title': 'title 1',
            'chapter_title': 'Node1',
            'content_count': 2,
            'translation_counts': {},
            'translation_in_review_counts': {}
        }
        config_services.set_property('admin',
                                     'contributor_dashboard_is_enabled', True)
    def setUp(self):
        super(TranslatableTextHandlerTest, 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',
            correctness_feedback_enabled=True
        ) 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.subtopics = [
            topic_domain.Subtopic(
                1, 'Title', ['skill_id_1'], 'image.svg',
                constants.ALLOWED_THUMBNAIL_BG_COLORS['subtopic'][0],
                '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)

        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.')
Beispiel #10
0
    def setUp(self):
        super(StoryModelValidatorTests, 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',
            ) for i in python_utils.RANGE(6)
        ]

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

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

        language_codes = ['ar', 'en', 'en']
        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 index, story in enumerate(stories):
            story.language_code = language_codes[index]
            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': 'add_story_node',
                        'node_id': 'node_2',
                        'title': 'Node2',
                    }),
                    story_domain.StoryChange({
                        'cmd': 'update_story_node_property',
                        'property_name': 'destination_node_ids',
                        'node_id': 'node_1',
                        'old_value': [],
                        'new_value': ['node_2']
                    }),
                    story_domain.StoryChange(
                        {
                            'cmd': 'update_story_node_property',
                            'property_name': 'exploration_id',
                            'node_id': 'node_1',
                            'old_value': None,
                            'new_value': explorations[index * 2].id
                        }),
                    story_domain.StoryChange(
                        {
                            'cmd': 'update_story_node_property',
                            'property_name': 'exploration_id',
                            'node_id': 'node_2',
                            'old_value': None,
                            'new_value': explorations[index * 2 + 1].id
                        })
                ], 'Changes.')

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

        self.job_class = (
            prod_validation_jobs_one_off.StoryModelAuditOneOffJob)
    def setUp(self):
        super(ContributionOpportunitiesHandlerTest, 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')
        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.')

        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': {}
        }
Beispiel #12
0
    def setUp(self):
        super(
            ExplorationOpportunitySummaryModelRegenerationJobTest, 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.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(
            self.topic_id_1, 'topic', 'abbrev-one', 'description')
        topic_1.thumbnail_filename = 'thumbnail.svg'
        topic_1.thumbnail_bg_color = '#C6DCDA'
        topic_services.save_new_topic(self.owner_id, topic_1)
        topic_services.publish_topic(self.topic_id_1, self.admin_id)

        topic_2 = topic_domain.Topic.create_default_topic(
            self.topic_id_2, 'topic2', 'abbrev-two', 'description')
        topic_2.thumbnail_filename = 'thumbnail.svg'
        topic_2.thumbnail_bg_color = '#C6DCDA'
        topic_services.save_new_topic(self.owner_id, topic_2)
        topic_services.publish_topic(self.topic_id_2, self.admin_id)

        story_1 = story_domain.Story.create_default_story(
            story_id_1, 'A story', 'description', self.topic_id_1,
            'story-one')
        story_2 = story_domain.Story.create_default_story(
            story_id_2, 'A story', 'description', self.topic_id_2,
            'story-two')

        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.publish_story(self.topic_id_1, story_id_1, self.admin_id)
        topic_services.add_canonical_story(
            self.owner_id, self.topic_id_2, story_id_2)
        topic_services.publish_story(self.topic_id_2, story_id_2, self.admin_id)
        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.')
Beispiel #13
0
    def post(self, topic_id):
        """Handles POST requests.
        Currently, this only adds the story to the canonical story id list of
        the topic.
        """
        title = self.normalized_payload.get('title')
        description = self.normalized_payload.get('description')
        thumbnail_filename = self.normalized_payload.get('filename')
        thumbnail_bg_color = self.normalized_payload.get('thumbnailBgColor')
        raw_image = self.normalized_request.get('image')
        story_url_fragment = self.normalized_payload.get('story_url_fragment')

        story_domain.Story.require_valid_title(title)
        if story_services.does_story_exist_with_url_fragment(
                story_url_fragment):
            raise self.InvalidInputException(
                'Story url fragment is not unique across the site.')

        new_story_id = story_services.get_new_story_id()
        # Add the story id to canonical_story_ids in the topic.
        # Topic validation occurs right before the field is updated. If there
        # is a validation failure, the story id will not be added to the
        # canonical_story_ids field in the Topic and the Story model does not
        # get created. Hence, topic_services.add_canonical_story is called
        # before story_services.save_new_story.
        topic_services.add_canonical_story(self.user_id, topic_id, new_story_id)
        story = story_domain.Story.create_default_story(
            new_story_id, title, description, topic_id, story_url_fragment)
        story_services.save_new_story(self.user_id, story)

        try:
            file_format = (
                image_validation_services.
                validate_image_and_filename(raw_image, thumbnail_filename))
        except utils.ValidationError as e:
            raise self.InvalidInputException(e)

        entity_id = new_story_id
        filename_prefix = 'thumbnail'

        image_is_compressible = (
            file_format in feconf.COMPRESSIBLE_IMAGE_FORMATS)
        fs_services.save_original_and_compressed_versions_of_image(
            thumbnail_filename, feconf.ENTITY_TYPE_STORY, entity_id, raw_image,
            filename_prefix, image_is_compressible)

        topic_services.update_story_and_topic_summary(
            self.user_id, new_story_id, [story_domain.StoryChange({
                'cmd': 'update_story_property',
                'property_name': 'thumbnail_filename',
                'old_value': None,
                'new_value': thumbnail_filename
            }), story_domain.StoryChange({
                'cmd': 'update_story_property',
                'property_name': 'thumbnail_bg_color',
                'old_value': None,
                'new_value': thumbnail_bg_color
            }), ], 'Added story thumbnail.', topic_id)

        self.render_json({
            'storyId': new_story_id
        })
Beispiel #14
0
    def setUp(self):
        super(SubtopicPageCommitLogEntryModelValidatorTests, self).setUp()

        self.signup(self.OWNER_EMAIL, self.OWNER_USERNAME)
        self.owner_id = self.get_user_id_from_email(self.OWNER_EMAIL)

        self.signup(USER_EMAIL, USER_NAME)
        self.user_id = self.get_user_id_from_email(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])

        topics = [topic_domain.Topic.create_default_topic(
            '%s' % i,
            'topic%s' % i,
            'abbrev-%s' % chr(120 + i),
            'description%s' % i) for i in python_utils.RANGE(3)]
        rubrics = [
            skill_domain.Rubric(
                constants.SKILL_DIFFICULTIES[0], ['Explanation 1']),
            skill_domain.Rubric(
                constants.SKILL_DIFFICULTIES[1], ['Explanation 2']),
            skill_domain.Rubric(
                constants.SKILL_DIFFICULTIES[2], ['Explanation 3'])]
        skills = [
            skill_domain.Skill.create_default_skill(
                '%s' % i, 'skill%s' % i, rubrics)
            for i in python_utils.RANGE(9)]

        for skill in skills:
            skill_services.save_new_skill(self.owner_id, skill)

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

        for story in stories:
            story_services.save_new_story(self.owner_id, story)

        language_codes = ['ar', 'en', 'en']
        for index, topic in enumerate(topics):
            topic.language_code = language_codes[index]
            topic.add_additional_story('%s' % (index * 2))
            topic.add_canonical_story('%s' % (index * 2 + 1))
            topic.add_uncategorized_skill_id('%s' % (index * 3))
            topic.add_uncategorized_skill_id('%s' % (index * 3 + 1))
            topic.add_uncategorized_skill_id('%s' % (index * 3 + 2))
            topic_services.save_new_topic(self.owner_id, topic)
            if index == 0:
                committer_id = self.user_id
            else:
                committer_id = self.owner_id
            topic_services.update_topic_and_subtopic_pages(
                committer_id, '%s' % index, [topic_domain.TopicChange({
                    'cmd': 'add_subtopic',
                    'title': 'subtopic1',
                    'subtopic_id': 1
                }), topic_domain.TopicChange({
                    'cmd': 'move_skill_id_to_subtopic',
                    'old_subtopic_id': None,
                    'new_subtopic_id': 1,
                    'skill_id': '%s' % (index * 3)
                }), topic_domain.TopicChange({
                    'cmd': 'move_skill_id_to_subtopic',
                    'old_subtopic_id': None,
                    'new_subtopic_id': 1,
                    'skill_id': '%s' % (index * 3 + 1)
                })], 'Changes.')

        self.model_instance_0 = (
            subtopic_models.SubtopicPageCommitLogEntryModel.get_by_id(
                'subtopicpage-0-1-1'))
        self.model_instance_1 = (
            subtopic_models.SubtopicPageCommitLogEntryModel.get_by_id(
                'subtopicpage-1-1-1'))
        self.model_instance_2 = (
            subtopic_models.SubtopicPageCommitLogEntryModel.get_by_id(
                'subtopicpage-2-1-1'))

        self.job_class = (
            prod_validation_jobs_one_off
            .SubtopicPageCommitLogEntryModelAuditOneOffJob)
Beispiel #15
0
    def test_regenerate_topic_related_opportunities_action(self):
        self.signup(self.OWNER_EMAIL, self.OWNER_USERNAME)

        owner_id = self.get_user_id_from_email(self.OWNER_EMAIL)

        topic_id = 'topic'
        story_id = 'story'
        exploration = exp_domain.Exploration.create_default_exploration(
            '0', title='title')
        exp_services.save_new_exploration(owner_id, exploration)

        topic = topic_domain.Topic.create_default_topic(
            topic_id=topic_id, name='topic')
        topic_services.save_new_topic(owner_id, topic)

        story = story_domain.Story.create_default_story(
            story_id, title='A story',
            corresponding_topic_id=topic_id)
        story_services.save_new_story(owner_id, story)
        topic_services.add_canonical_story(
            owner_id, topic_id, story_id)
        story_services.update_story(
            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': '0'
            })], 'Changes.')

        all_opportunity_models = list(
            opportunity_models.ExplorationOpportunitySummaryModel.get_all())

        self.assertEqual(len(all_opportunity_models), 1)

        old_creation_time = all_opportunity_models[0].created_on

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

        result = self.post_json(
            '/adminhandler', {
                'action': 'regenerate_topic_related_opportunities',
                'topic_id': 'topic'
            }, csrf_token=csrf_token)

        self.assertEqual(
            result, {
                'opportunities_count': 1
            })

        all_opportunity_models = list(
            opportunity_models.ExplorationOpportunitySummaryModel.get_all())

        self.assertEqual(len(all_opportunity_models), 1)

        new_creation_time = all_opportunity_models[0].created_on

        self.assertLess(old_creation_time, new_creation_time)
    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',
            correctness_feedback_enabled=True
        ) 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.subtopics = [
            topic_domain.Subtopic(
                1, 'Title', ['skill_id_3'], 'image.svg',
                constants.ALLOWED_THUMBNAIL_BG_COLORS['subtopic'][0],
                'dummy-subtopic-three')]
        topic.next_subtopic_id = 2
        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': {}
        }
        config_services.set_property(
            'admin', 'contributor_dashboard_is_enabled', True)
Beispiel #17
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,
                            name='New Topic',
                            abbreviated_name='abbrev',
                            thumbnail_filename=None,
                            description='A new topic',
                            canonical_story_ids=[],
                            additional_story_ids=[],
                            uncategorized_skill_ids=[],
                            subtopics=[],
                            next_subtopic_id=0)
        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)
    def setUp(self):
        super(UserSubmittedSuggestionsHandlerTest, self).setUp()
        self.signup(self.ADMIN_EMAIL, self.ADMIN_USERNAME)
        self.signup(self.OWNER_EMAIL, self.OWNER_USERNAME)
        self.signup(self.EDITOR_EMAIL, self.EDITOR_USERNAME)
        self.signup(self.AUTHOR_EMAIL, 'author')

        self.owner_id = self.get_user_id_from_email(self.OWNER_EMAIL)
        self.TOPIC_ID = 'topic'
        self.STORY_ID = 'story'
        self.EXP_ID = 'exp1'
        exploration = exp_domain.Exploration.create_default_exploration(
            self.EXP_ID, title='Exploration title')
        exp_services.save_new_exploration(self.owner_id, exploration)

        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)

        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': self.EXP_ID
            })
        ], 'Changes.')

        self.owner_id = self.get_user_id_from_email(self.OWNER_EMAIL)
        self.editor_id = self.get_user_id_from_email(self.EDITOR_EMAIL)
        self.author_id = self.get_user_id_from_email(self.AUTHOR_EMAIL)
        self.reviewer_id = self.editor_id

        self.set_admins([self.ADMIN_USERNAME])
        self.editor = user_services.UserActionsInfo(self.editor_id)

        # Login and create exploration and suggestions.
        self.login(self.EDITOR_EMAIL)
        self.save_new_linear_exp_with_state_names_and_interactions(
            self.EXP_ID,
            self.editor_id, ['State 1', 'State 2', 'State 3'], ['TextInput'],
            category='Algebra')

        exp_services.update_exploration(self.owner_id, self.EXP_ID, [
            exp_domain.ExplorationChange({
                'cmd': exp_domain.CMD_EDIT_STATE_PROPERTY,
                'property_name': exp_domain.STATE_PROPERTY_CONTENT,
                'state_name': 'Introduction',
                'new_value': {
                    'content_id': 'content',
                    'html': '<p>new content html</p>'
                }
            })
        ], 'Add content')

        self.logout()

        self.login(self.AUTHOR_EMAIL)
        csrf_token = self.get_new_csrf_token()

        self.post_json('%s/' % feconf.SUGGESTION_URL_PREFIX, {
            'suggestion_type':
            (suggestion_models.SUGGESTION_TYPE_TRANSLATE_CONTENT),
            'target_type': (suggestion_models.TARGET_TYPE_EXPLORATION),
            'target_id':
            self.EXP_ID,
            'target_version_at_submission':
            exploration.version,
            'change': {
                'cmd': exp_domain.CMD_ADD_TRANSLATION,
                'state_name': 'Introduction',
                'content_id': 'content',
                'language_code': 'hi',
                'content_html': '<p>new content html</p>',
                'translation_html': '<p>new content html in Hindi</p>'
            },
            'description':
            'Adds translation',
            'final_reviewer_id':
            None
        },
                       csrf_token=csrf_token)
        self.logout()
    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', 'description')
        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', 'description')
        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)
Beispiel #20
0
    def setUp(self):
        super(ExplorationOpportunitySummaryModelValidatorTests, self).setUp()

        self.job_class = (prod_validation_jobs_one_off.
                          ExplorationOpportunitySummaryModelAuditOneOffJob)
        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',
                                            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_2'], 'image.svg',
                constants.ALLOWED_THUMBNAIL_BG_COLORS['subtopic'][0],
                'dummy-subtopic-three')
        ]
        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.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-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)

        story_change_list = [
            story_domain.StoryChange({
                'cmd': 'add_story_node',
                'node_id': 'node_%s' % i,
                'title': 'Node %s' % i,
            }) for i in python_utils.RANGE(1, 4)
        ]

        story_change_list += [
            story_domain.StoryChange({
                'cmd': 'update_story_node_property',
                'property_name': 'destination_node_ids',
                'node_id': 'node_%s' % i,
                'old_value': [],
                'new_value': ['node_%s' % (i + 1)]
            }) for i in python_utils.RANGE(1, 3)
        ]

        story_change_list += [
            story_domain.StoryChange({
                'cmd': 'update_story_node_property',
                'property_name': 'exploration_id',
                'node_id': 'node_%s' % i,
                'old_value': None,
                'new_value': '%s' % i
            }) for i in python_utils.RANGE(1, 4)
        ]

        story_services.update_story(self.owner_id, self.STORY_ID,
                                    story_change_list, 'Changes.')

        self.model_instance_1 = (
            opportunity_models.ExplorationOpportunitySummaryModel.get_by_id(
                '1'))
        self.model_instance_2 = (
            opportunity_models.ExplorationOpportunitySummaryModel.get_by_id(
                '2'))
        self.model_instance_3 = (
            opportunity_models.ExplorationOpportunitySummaryModel.get_by_id(
                '3'))
Beispiel #21
0
    def setUp(self):
        """Completes the sign up process for the various users."""
        super(BaseStoryViewerControllerTests, self).setUp()
        self.VIEWER_EMAIL = '*****@*****.**'
        self.VIEWER_USERNAME = '******'
        self.signup(self.CURRICULUM_ADMIN_EMAIL, self.CURRICULUM_ADMIN_USERNAME)
        self.admin_id = self.get_user_id_from_email(self.CURRICULUM_ADMIN_EMAIL)
        self.set_curriculum_admins([self.CURRICULUM_ADMIN_USERNAME])
        self.admin = user_services.get_user_actions_info(self.admin_id)
        self.login(self.CURRICULUM_ADMIN_EMAIL)
        self.TOPIC_ID = 'topic_id'
        self.STORY_ID = 'story_id'
        self.STORY_URL_FRAGMENT = 'title-one'
        self.STORY_URL_FRAGMENT_TWO = 'story-two'
        self.NODE_ID_1 = 'node_1'
        self.NODE_ID_2 = 'node_2'
        self.NODE_ID_3 = 'node_3'
        self.EXP_ID_0 = '0'
        self.EXP_ID_1 = '1'
        self.EXP_ID_2 = '2'
        self.EXP_ID_3 = 'exp_3'
        self.EXP_ID_7 = '7'
        self.NEW_TOPIC_ID = 'new_topic_id'
        self.NEW_STORY_ID = 'new_story_id'

        self.save_new_valid_exploration(
            self.EXP_ID_0, self.admin_id, title='Title 1', end_state_name='End',
            correctness_feedback_enabled=True)
        self.save_new_valid_exploration(
            self.EXP_ID_1, self.admin_id, title='Title 2', end_state_name='End',
            correctness_feedback_enabled=True)
        self.save_new_valid_exploration(
            self.EXP_ID_2, self.admin_id, title='Title 4', end_state_name='End',
            correctness_feedback_enabled=True)
        self.save_new_valid_exploration(
            self.EXP_ID_7, self.admin_id, title='Title 3', end_state_name='End',
            correctness_feedback_enabled=True)
        self.publish_exploration(self.admin_id, self.EXP_ID_0)
        self.publish_exploration(self.admin_id, self.EXP_ID_1)
        self.publish_exploration(self.admin_id, self.EXP_ID_2)
        self.publish_exploration(self.admin_id, self.EXP_ID_7)

        story = story_domain.Story.create_default_story(
            self.STORY_ID, 'Title', 'Description', self.TOPIC_ID,
            self.STORY_URL_FRAGMENT)
        story.meta_tag_content = 'story meta content'

        exp_summary_dicts = (
            summary_services.get_displayable_exp_summary_dicts_matching_ids(
                [self.EXP_ID_0, self.EXP_ID_1, self.EXP_ID_7], user=self.admin))
        self.node_1 = {
            'id': self.NODE_ID_1,
            'title': 'Title 1',
            'description': 'Description 1',
            'thumbnail_filename': 'image_1.svg',
            'thumbnail_bg_color': constants.ALLOWED_THUMBNAIL_BG_COLORS[
                'chapter'][0],
            'thumbnail_size_in_bytes': 21131,
            'destination_node_ids': ['node_3'],
            'acquired_skill_ids': [],
            'prerequisite_skill_ids': [],
            'outline': '',
            'outline_is_finalized': False,
            'exploration_id': self.EXP_ID_1,
            'exp_summary_dict': exp_summary_dicts[1],
            'completed': False
        }
        self.node_2 = {
            'id': self.NODE_ID_2,
            'title': 'Title 2',
            'description': 'Description 2',
            'thumbnail_filename': 'image_2.svg',
            'thumbnail_bg_color': constants.ALLOWED_THUMBNAIL_BG_COLORS[
                'chapter'][0],
            'thumbnail_size_in_bytes': 21131,
            'destination_node_ids': ['node_1'],
            'acquired_skill_ids': [],
            'prerequisite_skill_ids': [],
            'outline': '',
            'outline_is_finalized': False,
            'exploration_id': self.EXP_ID_0,
            'exp_summary_dict': exp_summary_dicts[0],
            'completed': True
        }
        self.node_3 = {
            'id': self.NODE_ID_3,
            'title': 'Title 3',
            'description': 'Description 3',
            'thumbnail_filename': 'image_3.svg',
            'thumbnail_bg_color': constants.ALLOWED_THUMBNAIL_BG_COLORS[
                'chapter'][0],
            'thumbnail_size_in_bytes': 21131,
            'destination_node_ids': [],
            'acquired_skill_ids': [],
            'prerequisite_skill_ids': [],
            'outline': '',
            'outline_is_finalized': False,
            'exploration_id': self.EXP_ID_7,
            'exp_summary_dict': exp_summary_dicts[2],
            'completed': False
        }
        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)
        ]
        self.nodes = story.story_contents.nodes
        story.story_contents.initial_node_id = 'node_2'
        story.story_contents.next_node_id = 'node_4'
        story_services.save_new_story(self.admin_id, story)
        subtopic_1 = topic_domain.Subtopic.create_default_subtopic(
            1, 'Subtopic Title 1')
        subtopic_1.skill_ids = ['skill_id_1']
        subtopic_1.url_fragment = 'sub-one-frag'
        self.save_new_topic(
            self.TOPIC_ID, 'user', name='Topic',
            description='A new topic', canonical_story_ids=[story.id],
            additional_story_ids=[], uncategorized_skill_ids=[],
            subtopics=[subtopic_1], next_subtopic_id=2)
        topic_services.publish_topic(self.TOPIC_ID, self.admin_id)
        topic_services.publish_story(
            self.TOPIC_ID, self.STORY_ID, self.admin_id)
        self.logout()
        self.signup(self.VIEWER_EMAIL, self.VIEWER_USERNAME)
        self.viewer_id = self.get_user_id_from_email(self.VIEWER_EMAIL)
        self.login(self.VIEWER_EMAIL)
        self._record_completion(self.viewer_id, self.STORY_ID, self.NODE_ID_2)
    def setUp(self):
        super(VoiceoverApplicationServicesUnitTests, self).setUp()
        self.signup(self.ADMIN_EMAIL, self.ADMIN_USERNAME)
        self.signup(self.OWNER_EMAIL, self.OWNER_USERNAME)
        self.signup(self.APPLICANT_EMAIL, self.APPLICANT_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.applicant_id = self.get_user_id_from_email(self.APPLICANT_EMAIL)

        self.applicant = user_services.get_user_actions_info(self.applicant_id)

        self.set_admins([self.ADMIN_USERNAME])
        self.admin = user_services.get_user_actions_info(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 = [
            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(2)
        ]

        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-three')
        ]
        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, 'a-story')
        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.')

        self.set_user_role(self.ADMIN_USERNAME, feconf.ROLE_ID_VOICEOVER_ADMIN)
Beispiel #23
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 feconf.ROLE_ID_CURRICULUM_ADMIN not in self.user.roles:
                raise Exception(
                    'User does not have enough rights to generate data.')
            topic_id_1 = topic_fetchers.get_new_topic_id()
            topic_id_2 = topic_fetchers.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', '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)

            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')
            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': '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'
                })]
            )

            # Generates translation opportunities for the Contributor Dashboard.
            exp_ids_in_story = story.story_contents.get_all_linked_exp_ids()
            opportunity_services.add_new_exploration_opportunities(
                story_id, exp_ids_in_story)

            topic_services.publish_story(topic_id_1, story_id, self.user_id)
        else:
            raise Exception('Cannot load new structures data in production.')
Beispiel #24
0
    def setUp(self):
        """Completes the sign up process for the various users."""
        super(BaseStoryViewerControllerTests, self).setUp()
        self.VIEWER_EMAIL = '*****@*****.**'
        self.VIEWER_USERNAME = '******'
        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.login(self.ADMIN_EMAIL)
        self.TOPIC_ID = 'topic_id'
        self.STORY_ID = 'story_id'
        self.NODE_ID_1 = 'node_1'
        self.NODE_ID_2 = 'node_2'
        self.NODE_ID_3 = 'node_3'
        self.EXP_ID_0 = '0'
        self.EXP_ID_1 = '1'
        self.EXP_ID_7 = '7'

        self.save_new_valid_exploration(self.EXP_ID_0,
                                        self.admin_id,
                                        title='Title 1',
                                        end_state_name='End')
        self.save_new_valid_exploration(self.EXP_ID_1,
                                        self.admin_id,
                                        title='Title 2',
                                        end_state_name='End')
        self.save_new_valid_exploration(self.EXP_ID_7,
                                        self.admin_id,
                                        title='Title 3',
                                        end_state_name='End')
        self.publish_exploration(self.admin_id, self.EXP_ID_0)
        self.publish_exploration(self.admin_id, self.EXP_ID_1)
        self.publish_exploration(self.admin_id, self.EXP_ID_7)

        story = story_domain.Story.create_default_story(
            self.STORY_ID, 'Title', self.TOPIC_ID)
        story.description = ('Description')
        exp_summary_dicts = (
            summary_services.get_displayable_exp_summary_dicts_matching_ids(
                [self.EXP_ID_0, self.EXP_ID_1, self.EXP_ID_7],
                user=self.admin))
        self.node_1 = {
            'id': self.NODE_ID_1,
            'title': 'Title 1',
            'destination_node_ids': ['node_3'],
            'acquired_skill_ids': [],
            'prerequisite_skill_ids': [],
            'outline': '',
            'outline_is_finalized': False,
            'exploration_id': self.EXP_ID_1,
            'exp_summary_dict': exp_summary_dicts[1],
            'completed': False
        }
        self.node_2 = {
            'id': self.NODE_ID_2,
            'title': 'Title 2',
            'destination_node_ids': ['node_1'],
            'acquired_skill_ids': [],
            'prerequisite_skill_ids': [],
            'outline': '',
            'outline_is_finalized': False,
            'exploration_id': self.EXP_ID_0,
            'exp_summary_dict': exp_summary_dicts[0],
            'completed': True
        }
        self.node_3 = {
            'id': self.NODE_ID_3,
            'title': 'Title 3',
            'destination_node_ids': [],
            'acquired_skill_ids': [],
            'prerequisite_skill_ids': [],
            'outline': '',
            'outline_is_finalized': False,
            'exploration_id': self.EXP_ID_7,
            'exp_summary_dict': exp_summary_dicts[2],
            'completed': False
        }
        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)
        ]
        self.nodes = story.story_contents.nodes
        story.story_contents.initial_node_id = 'node_2'
        story.story_contents.next_node_id = 'node_4'
        story_services.save_new_story(self.admin_id, story)
        self.save_new_topic(self.TOPIC_ID,
                            'user',
                            name='Topic',
                            abbreviated_name='abbrev',
                            thumbnail_filename='Topic.png',
                            description='A new topic',
                            canonical_story_ids=[story.id],
                            additional_story_ids=[],
                            uncategorized_skill_ids=[],
                            subtopics=[],
                            next_subtopic_id=0)
        topic_services.publish_topic(self.TOPIC_ID, self.admin_id)
        topic_services.publish_story(self.TOPIC_ID, self.STORY_ID,
                                     self.admin_id)
        self.logout()
        self.signup(self.VIEWER_EMAIL, self.VIEWER_USERNAME)
        self.viewer_id = self.get_user_id_from_email(self.VIEWER_EMAIL)
        self.login(self.VIEWER_EMAIL)
        self._record_completion(self.viewer_id, self.STORY_ID, self.NODE_ID_2)
Beispiel #25
0
    def setUp(self):
        super(OpportunityServicesIntegrationTest, self).setUp()
        self.signup(self.CURRICULUM_ADMIN_EMAIL,
                    self.CURRICULUM_ADMIN_USERNAME)
        self.signup(self.OWNER_EMAIL, self.OWNER_USERNAME)

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

        self.set_curriculum_admins([self.CURRICULUM_ADMIN_USERNAME])
        self.admin = user_services.get_user_actions_info(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 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], 21131,
                '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)
Beispiel #26
0
    def setUp(self):
        """Completes the sign-up process for the various users."""
        super(BaseReviewTestsControllerTests, self).setUp()
        self.signup(self.ADMIN_EMAIL, self.ADMIN_USERNAME)
        self.signup(self.OWNER_EMAIL, self.OWNER_USERNAME)
        self.signup(self.VIEWER_EMAIL, self.VIEWER_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.viewer_id = self.get_user_id_from_email(self.VIEWER_EMAIL)

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

        self.topic_id = 'topic_id'
        self.story_id_1 = 'story_id_1'
        self.story_id_2 = 'story_id_2'
        self.story_id_3 = 'story_id_3'
        self.node_id = 'node_1'
        self.node_id_2 = 'node_2'
        self.exp_id = 'exp_id'

        self.save_new_valid_exploration(self.exp_id, self.owner_id)
        self.publish_exploration(self.owner_id, self.exp_id)

        self.node_1 = {
            'id': self.node_id,
            'title': 'Title 1',
            'destination_node_ids': [],
            'acquired_skill_ids': ['skill_id_1', 'skill_id_2'],
            'prerequisite_skill_ids': [],
            'outline': '',
            'outline_is_finalized': False,
            'exploration_id': self.exp_id
        }

        self.save_new_skill('skill_id_1', self.admin_id, description='Skill 1')
        self.save_new_skill('skill_id_2', self.admin_id, description='Skill 2')

        self.story = story_domain.Story.create_default_story(
            self.story_id_1, 'Public Story Title', self.topic_id)
        self.story.story_contents.nodes = [
            story_domain.StoryNode.from_dict(self.node_1)
        ]
        self.story.story_contents.initial_node_id = self.node_id
        self.story.story_contents.next_node_id = self.node_id_2
        story_services.save_new_story(self.admin_id, self.story)

        self.story_2 = story_domain.Story.create_default_story(
            self.story_id_2, 'Private Story Title', self.topic_id)
        story_services.save_new_story(self.admin_id, self.story_2)
        self.save_new_topic(
            self.topic_id,
            'user',
            name='Topic',
            abbreviated_name='abbrev',
            thumbnail_filename='Topic.png',
            description='A new topic',
            canonical_story_ids=[self.story_id_1, self.story_id_3],
            additional_story_ids=[],
            uncategorized_skill_ids=[],
            subtopics=[],
            next_subtopic_id=0)
        topic_services.publish_topic(self.topic_id, self.admin_id)
        topic_services.publish_story(self.topic_id, self.story_id_1,
                                     self.admin_id)

        self.login(self.VIEWER_EMAIL)
Beispiel #27
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)
        else:
            raise Exception('Cannot load new structures data in production.')
Beispiel #28
0
    def setUp(self):
        """Completes the sign up process for the various users."""
        super(BaseStoryViewerControllerTests, self).setUp()
        self.VIEWER_EMAIL = '*****@*****.**'
        self.VIEWER_USERNAME = '******'
        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.login(self.ADMIN_EMAIL)
        self.TOPIC_ID = 'topic_id'
        self.STORY_ID_1 = 'story_id_1'
        self.NODE_ID_1 = 'node_1'
        self.NODE_ID_2 = 'node_2'
        self.NODE_ID_3 = 'node_3'
        self.EXP_ID = 'exp_id'

        self.save_new_valid_exploration(self.EXP_ID,
                                        self.admin_id,
                                        title='Bridges in England',
                                        category='Architecture',
                                        language_code='en')
        rights_manager.publish_exploration(self.admin, self.EXP_ID)
        self.save_new_topic(self.TOPIC_ID, 'user', 'Topic', 'A new topic', [],
                            [], [], [], 0)
        story = story_domain.Story.create_default_story(
            self.STORY_ID_1, 'Title', self.TOPIC_ID)
        story.description = ('Description')
        exp_summary_dict = (
            summary_services.get_displayable_exp_summary_dicts_matching_ids(
                [self.EXP_ID], user=self.admin)[0])
        self.node_1 = {
            'id': self.NODE_ID_1,
            'title': 'Title 1',
            'destination_node_ids': ['node_3'],
            'acquired_skill_ids': [],
            'prerequisite_skill_ids': [],
            'outline': '',
            'outline_is_finalized': False,
            'exploration_id': self.EXP_ID,
            'exp_summary_dict': exp_summary_dict,
            'completed': False
        }
        self.node_2 = {
            'id': self.NODE_ID_2,
            'title': 'Title 2',
            'destination_node_ids': ['node_1'],
            'acquired_skill_ids': [],
            'prerequisite_skill_ids': [],
            'outline': '',
            'outline_is_finalized': False,
            'exploration_id': self.EXP_ID,
            'exp_summary_dict': exp_summary_dict,
            'completed': True
        }
        self.node_3 = {
            'id': self.NODE_ID_3,
            'title': 'Title 3',
            '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)
        ]
        self.nodes = story.story_contents.nodes
        story.story_contents.initial_node_id = 'node_2'
        story.story_contents.next_node_id = 'node_4'
        story_services.save_new_story(self.admin_id, story)
        story_services.publish_story(self.STORY_ID_1, self.admin_id)
        self.logout()
        self.signup(self.VIEWER_EMAIL, self.VIEWER_USERNAME)
        self.viewer_id = self.get_user_id_from_email(self.VIEWER_EMAIL)
        self.login(self.VIEWER_EMAIL)
        self._record_completion(self.viewer_id, self.STORY_ID_1,
                                self.NODE_ID_2)
Beispiel #29
0
    def test_redirect_for_single_node_story(self):
        self.login(self.CURRICULUM_ADMIN_EMAIL)
        self.STORY_URL_FRAGMENT = 'story-two'
        self.NEW_USER_EMAIL = '*****@*****.**'
        self.NEW_USER_USERNAME = '******'

        self.save_new_valid_exploration(self.EXP_ID_0,
                                        self.admin_id,
                                        title='Title 1',
                                        end_state_name='End',
                                        correctness_feedback_enabled=True)
        self.publish_exploration(self.admin_id, self.EXP_ID_0)

        story = story_domain.Story.create_default_story(
            self.NEW_STORY_ID, 'Title', 'Description', self.NEW_TOPIC_ID,
            self.STORY_URL_FRAGMENT)
        story.meta_tag_content = 'story meta content'

        exp_summary_dicts = (
            summary_services.get_displayable_exp_summary_dicts_matching_ids(
                [self.EXP_ID_0], user=self.admin))
        self.node_1 = {
            'id':
            self.NODE_ID_1,
            'title':
            'Title 1',
            'description':
            'Description 1',
            'thumbnail_filename':
            'image_1.svg',
            'thumbnail_bg_color':
            constants.ALLOWED_THUMBNAIL_BG_COLORS['chapter'][0],
            'thumbnail_size_in_bytes':
            21131,
            'destination_node_ids': [],
            'acquired_skill_ids': [],
            'prerequisite_skill_ids': [],
            'outline':
            '',
            'outline_is_finalized':
            False,
            'exploration_id':
            self.EXP_ID_1,
            'exp_summary_dict':
            exp_summary_dicts[0],
            'completed':
            False
        }
        story.story_contents.nodes = [
            story_domain.StoryNode.from_dict(self.node_1)
        ]
        self.nodes = story.story_contents.nodes
        story.story_contents.initial_node_id = 'node_1'
        story.story_contents.next_node_id = 'node_2'
        story_services.save_new_story(self.admin_id, story)
        subtopic_1 = topic_domain.Subtopic.create_default_subtopic(
            1, 'Subtopic Title 1')
        subtopic_1.skill_ids = ['skill_id_1']
        subtopic_1.url_fragment = 'sub-one-frag'
        self.save_new_topic(self.NEW_TOPIC_ID,
                            'user',
                            name='new topic',
                            url_fragment='topic-frag',
                            description='A new topic',
                            canonical_story_ids=[story.id],
                            additional_story_ids=[],
                            uncategorized_skill_ids=[],
                            subtopics=[subtopic_1],
                            next_subtopic_id=2)
        topic_services.publish_topic(self.NEW_TOPIC_ID, self.admin_id)
        topic_services.publish_story(self.NEW_TOPIC_ID, self.NEW_STORY_ID,
                                     self.admin_id)
        self.logout()
        self.signup(self.NEW_USER_EMAIL, self.NEW_USER_USERNAME)
        self.login(self.NEW_USER_EMAIL)
        with self.swap(constants, 'ENABLE_NEW_STRUCTURE_VIEWER_UPDATES', True):
            response = self.get_html_response(
                '%s/staging/topic-frag/%s/%s' %
                (feconf.STORY_PROGRESS_URL_PREFIX, self.STORY_URL_FRAGMENT,
                 self.NODE_ID_1),
                expected_status_int=302)
            self.assertEqual(
                'http://localhost/learn/staging/topic-frag/story/story-two',
                response.headers['location'])
Beispiel #30
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.CURRICULUM_ADMIN_EMAIL,
                    self.CURRICULUM_ADMIN_USERNAME)
        self.admin_id = self.get_user_id_from_email(
            self.CURRICULUM_ADMIN_EMAIL)
        self.set_curriculum_admins([self.CURRICULUM_ADMIN_USERNAME])
        self.admin = user_services.get_user_actions_info(self.admin_id)

        self.topic_id = 'topic'
        self.story_id_1 = 'story_id_1'
        self.story_id_2 = 'story_id_2'
        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', 'description', self.topic_id,
            'story-frag-one')
        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', 'description', self.topic_id,
            'story-frag-two')
        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', 'public', 'description',
            'fragm')
        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], 21131,
                'subtopic-name'))
        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))
        self.topic.meta_tag_content = 'topic meta content'
        self.topic.page_title_fragment_for_web = 'topic page title'
        self.topic.skill_ids_for_diagnostic_test = [self.skill_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)

        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)