Example #1
0
    def setUp(self):
        """Create exploration with two versions"""
        super(VersioningIntegrationTest, self).setUp()

        self.EXP_ID = '0'

        exp_services.delete_demo(self.EXP_ID)
        exp_services.load_demo(self.EXP_ID)

        EDITOR_EMAIL = '*****@*****.**'
        self.register_editor(EDITOR_EMAIL)
        self.login(EDITOR_EMAIL)

        # In version 2, change the objective and the initial state content.
        exploration = exp_services.get_exploration_by_id(self.EXP_ID)
        exp_services.update_exploration(
           EDITOR_EMAIL, self.EXP_ID, [{
                'cmd': 'edit_exploration_property',
                'property_name': 'objective',
                'new_value': 'the objective',
            }, {
                'cmd': 'edit_state_property',
                'property_name': 'content',
                'state_name': exploration.init_state_name,
                'new_value': [{'type': 'text', 'value': 'ABC'}],
            }], 'Change objective and init state content')
Example #2
0
    def test_editor_page(self):
        """Test access to editor pages for the sample exploration."""
        exp_services.delete_demo('0')
        exp_services.load_demo('0')

        # Check that non-editors can access, but not edit, the editor page.
        response = self.testapp.get('/create/0')
        self.assertEqual(response.status_int, 200)
        self.assertIn('Welcome to Oppia!', response.body)
        self.assert_cannot_edit(response.body)

        # Log in as an editor.
        self.login(self.EDITOR_EMAIL)

        # Check that it is now possible to access and edit the editor page.
        response = self.testapp.get('/create/0')
        self.assertIn('Welcome to Oppia!', response.body)
        self.assertEqual(response.status_int, 200)
        self.assert_can_edit(response.body)
        self.assertIn('Stats', response.body)
        self.assertIn('History', response.body)
        # Test that the value generator JS is included.
        self.assertIn('RandomSelector', response.body)

        self.logout()
Example #3
0
    def post(self):
        """Handles POST requests."""
        try:
            if self.payload.get('action') == 'reload_exploration':
                exploration_id = self.payload.get('explorationId')
                logging.info(
                    '[ADMIN] %s reloaded exploration %s' %
                    (self.user_id, exploration_id))
                exp_services.delete_demo(unicode(exploration_id))
                exp_services.load_demo(unicode(exploration_id))
            elif self.payload.get('action') == 'save_config_properties':
                new_config_property_values = self.payload.get(
                    'new_config_property_values')
                logging.info('[ADMIN] %s saved config property values: %s' %
                             (self.user_id, new_config_property_values))
                for (name, value) in new_config_property_values.iteritems():
                    config_services.set_property(self.user_id, name, value)
            elif self.payload.get('action') == 'revert_config_property':
                config_property_id = self.payload.get('config_property_id')
                logging.info('[ADMIN] %s reverted config property: %s' %
                             (self.user_id, config_property_id))
                config_services.revert_property(
                    self.user_id, config_property_id)
            elif self.payload.get('action') == 'refresh_computed_property':
                computed_property_name = self.payload.get(
                    'computed_property_name')
                config_domain.Registry.get_config_property(
                    computed_property_name).refresh_default_value()

            self.render_json({})
        except Exception as e:
            self.render_json({'error': unicode(e)})
            raise
Example #4
0
    def test_loading_and_validation_and_deletion_of_demo_explorations(self):
        """Test loading, validation and deletion of the demo explorations."""
        self.assertEqual(exp_services.count_explorations(), 0)

        self.assertGreaterEqual(
            len(feconf.DEMO_EXPLORATIONS), 1,
            msg='There must be at least one demo exploration.')

        for ind in range(len(feconf.DEMO_EXPLORATIONS)):
            start_time = datetime.datetime.utcnow()

            exp_id = str(ind)
            exp_services.load_demo(exp_id)
            exploration = exp_services.get_exploration_by_id(exp_id)
            warnings = exploration.validate(strict=True)
            if warnings:
                raise Exception(warnings)

            duration = datetime.datetime.utcnow() - start_time
            processing_time = duration.seconds + duration.microseconds / 1E6
            print 'Loaded and validated exploration %s (%.2f seconds)' % (
                exploration.title.encode('utf-8'), processing_time)

        self.assertEqual(
            exp_services.count_explorations(), len(feconf.DEMO_EXPLORATIONS))

        for ind in range(len(feconf.DEMO_EXPLORATIONS)):
            exp_services.delete_demo(str(ind))
        self.assertEqual(exp_services.count_explorations(), 0)
Example #5
0
    def setUp(self):
        """Before the test, create an exploration_dict."""
        super(ClassifyHandlerTest, self).setUp()
        self.enable_string_classifier = self.swap(
            feconf, 'ENABLE_STRING_CLASSIFIER', True)

        # Reading YAML exploration into a dictionary.
        yaml_path = os.path.join(os.path.dirname(os.path.realpath(__file__)),
                                 '../tests/data/string_classifier_test.yaml')
        with open(yaml_path, 'r') as yaml_file:
            self.yaml_content = yaml_file.read()

        self.login(self.VIEWER_EMAIL)
        self.signup(self.VIEWER_EMAIL, self.VIEWER_USERNAME)

        # Load demo exploration.
        self.exp_id = '0'
        self.title = 'Testing String Classifier'
        self.category = 'Test'
        exp_services.delete_demo(self.exp_id)
        exp_services.load_demo(self.exp_id)

        # Creating the exploration domain object.
        self.exploration = exp_domain.Exploration.from_untitled_yaml(
            self.exp_id,
            self.title,
            self.category,
            self.yaml_content)
Example #6
0
    def setUp(self):
        """Before the test, create an exploration_dict."""
        super(ClassifyHandlerTest, self).setUp()
        self.enable_string_classifier = self.swap(
            feconf, 'ENABLE_STRING_CLASSIFIER', True)

        # Reading YAML exploration into a dictionary.
        yaml_path = os.path.join(os.path.dirname(os.path.realpath(__file__)),
                                 '../tests/data/string_classifier_test.yaml')
        with open(yaml_path, 'r') as yaml_file:
            self.yaml_content = yaml_file.read()

        self.login(self.VIEWER_EMAIL)
        self.signup(self.VIEWER_EMAIL, self.VIEWER_USERNAME)

        # Load demo exploration.
        self.exp_id = '0'
        self.title = 'Testing String Classifier'
        self.category = 'Test'
        exp_services.delete_demo(self.exp_id)
        exp_services.load_demo(self.exp_id)

        # Creating the exploration domain object.
        self.exploration = exp_domain.Exploration.from_untitled_yaml(
            self.exp_id,
            self.title,
            self.category,
            self.yaml_content)
Example #7
0
    def setUp(self):
        """Load a demo exploration and register self.EDITOR_EMAIL."""
        super(ImageHandlerTest, self).setUp()

        exp_services.delete_demo('0')
        exp_services.load_demo('0')
        self.signup(self.EDITOR_EMAIL, self.EDITOR_USERNAME)
Example #8
0
    def post(self):
        """Handles POST requests."""
        try:
            if self.payload.get('action') == 'reload_exploration':
                exploration_id = self.payload.get('explorationId')
                logging.info('[ADMIN] %s reloaded exploration %s' %
                             (self.user_id, exploration_id))
                exp_services.delete_demo(unicode(exploration_id))
                exp_services.load_demo(unicode(exploration_id))
            elif self.payload.get('action') == 'save_config_properties':
                new_config_property_values = self.payload.get(
                    'new_config_property_values')
                logging.info('[ADMIN] %s saved config property values: %s' %
                             (self.user_id, new_config_property_values))
                for (name, value) in new_config_property_values.iteritems():
                    config_services.set_property(self.user_id, name, value)
            elif self.payload.get('action') == 'revert_config_property':
                config_property_id = self.payload.get('config_property_id')
                logging.info('[ADMIN] %s reverted config property: %s' %
                             (self.user_id, config_property_id))
                config_services.revert_property(self.user_id,
                                                config_property_id)
            elif self.payload.get('action') == 'refresh_computed_property':
                computed_property_name = self.payload.get(
                    'computed_property_name')
                config_domain.Registry.get_config_property(
                    computed_property_name).refresh_default_value()

            self.render_json({})
        except Exception as e:
            self.render_json({'error': unicode(e)})
            raise
Example #9
0
    def setUp(self):
        """Create exploration with two versions"""
        super(VersioningIntegrationTest, self).setUp()

        self.EXP_ID = '0'

        exp_services.delete_demo(self.EXP_ID)
        exp_services.load_demo(self.EXP_ID)

        self.login(self.EDITOR_EMAIL)

        # In version 2, change the objective and the initial state content.
        exploration = exp_services.get_exploration_by_id(self.EXP_ID)
        exp_services.update_exploration(
            self.EDITOR_EMAIL, self.EXP_ID,
            [{
                'cmd': 'edit_exploration_property',
                'property_name': 'objective',
                'new_value': 'the objective',
            }, {
                'cmd': 'edit_state_property',
                'property_name': 'content',
                'state_name': exploration.init_state_name,
                'new_value': [{
                    'type': 'text',
                    'value': 'ABC'
                }],
            }], 'Change objective and init state content')
Example #10
0
    def test_editor_page(self):
        """Test access to editor pages for the sample exploration."""
        exp_services.delete_demo('0')
        exp_services.load_demo('0')

        # Check that non-editors can access, but not edit, the editor page.
        response = self.testapp.get('/create/0')
        self.assertEqual(response.status_int, 200)
        self.assertIn('Welcome to Oppia!', response.body)
        self.assert_cannot_edit(response.body)

        # Log in as an editor.
        self.login(self.EDITOR_EMAIL)

        # Check that it is now possible to access and edit the editor page.
        response = self.testapp.get('/create/0')
        self.assertIn('Welcome to Oppia!', response.body)
        self.assertEqual(response.status_int, 200)
        self.assert_can_edit(response.body)
        self.assertIn('Stats', response.body)
        self.assertIn('History', response.body)
        # Test that the value generator JS is included.
        self.assertIn('RandomSelector', response.body)

        self.logout()
Example #11
0
    def test_give_feedback_handler(self):
        """Test giving feedback handler."""
        self.signup(self.VIEWER_EMAIL, self.VIEWER_USERNAME)

        # Load demo exploration
        exp_id = '0'
        exp_services.delete_demo('0')
        exp_services.load_demo('0')

        # Viewer opens exploration
        self.login(self.VIEWER_EMAIL)
        exploration_dict = self.get_json(
            '%s/%s' % (feconf.EXPLORATION_INIT_URL_PREFIX, exp_id))
        state_name_1 = exploration_dict['exploration']['init_state_name']

        # Viewer gives 1st feedback
        self.post_json(
            '/explorehandler/give_feedback/%s' % exp_id,
            {
                'state_name': state_name_1,
                'feedback': 'This is a feedback message.',
            }
        )

        self.logout()
Example #12
0
    def test_give_feedback_handler(self):
        """Test giving feedback handler."""
        self.signup(self.VIEWER_EMAIL, self.VIEWER_USERNAME)

        # Load demo exploration
        exp_id = '0'
        exp_services.delete_demo('0')
        exp_services.load_demo('0')

        # Viewer opens exploration
        self.login(self.VIEWER_EMAIL)
        exploration_dict = self.get_json(
            '%s/%s' % (feconf.EXPLORATION_INIT_URL_PREFIX, exp_id))
        state_name_1 = exploration_dict['exploration']['init_state_name']

        # Viewer gives 1st feedback
        self.post_json(
            '/explorehandler/give_feedback/%s' % exp_id, {
                'state_name': state_name_1,
                'feedback': 'This is a feedback message.',
            })

        # Viewer submits answer '0'
        result_dict = self.submit_answer(exp_id, state_name_1, '0')
        state_name_2 = result_dict['state_name']

        # Viewer gives 2nd feedback
        self.post_json(
            '/explorehandler/give_feedback/%s' % exp_id, {
                'state_name': state_name_2,
                'feedback': 'This is a 2nd feedback message.',
            })
        self.logout()
Example #13
0
    def post(self):
        """Handles POST requests."""
        try:
            if self.payload.get('action') == 'reload_exploration':
                exploration_id = self.payload.get('exploration_id')
                logging.info(
                    '[ADMIN] %s reloaded exploration %s' %
                    (self.user_id, exploration_id))
                exp_services.delete_demo(unicode(exploration_id))
                exp_services.load_demo(unicode(exploration_id))
            elif self.payload.get('action') == 'clear_search_index':
                exp_services.clear_search_index()
            elif self.payload.get('action') == 'save_config_properties':
                new_config_property_values = self.payload.get(
                    'new_config_property_values')
                logging.info('[ADMIN] %s saved config property values: %s' %
                             (self.user_id, new_config_property_values))
                for (name, value) in new_config_property_values.iteritems():
                    config_services.set_property(self.user_id, name, value)
            elif self.payload.get('action') == 'revert_config_property':
                config_property_id = self.payload.get('config_property_id')
                logging.info('[ADMIN] %s reverted config property: %s' %
                             (self.user_id, config_property_id))
                config_services.revert_property(
                    self.user_id, config_property_id)
            elif self.payload.get('action') == 'refresh_computed_property':
                computed_property_name = self.payload.get(
                    'computed_property_name')
                config_domain.Registry.get_config_property(
                    computed_property_name).refresh_default_value()
            elif self.payload.get('action') == 'start_new_job':
                for klass in jobs_registry.ONE_OFF_JOB_MANAGERS:
                    if klass.__name__ == self.payload.get('job_type'):
                        klass.enqueue(klass.create_new())
                        break
            elif self.payload.get('action') == 'cancel_job':
                job_id = self.payload.get('job_id')
                job_type = self.payload.get('job_type')
                for klass in jobs_registry.ONE_OFF_JOB_MANAGERS:
                    if klass.__name__ == job_type:
                        klass.cancel(job_id, self.user_id)
                        break
            elif self.payload.get('action') == 'start_computation':
                computation_type = self.payload.get('computation_type')
                for klass in jobs_registry.ALL_CONTINUOUS_COMPUTATION_MANAGERS:
                    if klass.__name__ == computation_type:
                        klass.start_computation()
                        break
            elif self.payload.get('action') == 'stop_computation':
                computation_type = self.payload.get('computation_type')
                for klass in jobs_registry.ALL_CONTINUOUS_COMPUTATION_MANAGERS:
                    if klass.__name__ == computation_type:
                        klass.stop_computation(self.user_id)
                        break

            self.render_json({})
        except Exception as e:
            self.render_json({'error': unicode(e)})
            raise
Example #14
0
    def setUp(self):
        super(AudioDevHandlerTest, self).setUp()
        exp_services.delete_demo('0')
        self.system_user = user_services.get_system_user()
        exp_services.load_demo('0')

        rights_manager.release_ownership_of_exploration(self.system_user, '0')
        self.signup(self.EDITOR_EMAIL, self.EDITOR_USERNAME)
Example #15
0
    def setUp(self):
        super(FeedbackThreadIntegrationTests, self).setUp()
        self.signup(self.EDITOR_EMAIL, self.EDITOR_USERNAME)
        self.EDITOR_ID = self.get_user_id_from_email(self.EDITOR_EMAIL)

        # Load exploration 0.
        exp_services.delete_demo(self.EXP_ID)
        exp_services.load_demo(self.EXP_ID)
Example #16
0
    def post(self):
        """Handles POST requests."""
        try:
            if self.payload.get('action') == 'reload_exploration':
                exploration_id = self.payload.get('exploration_id')
                logging.info('[ADMIN] %s reloaded exploration %s' %
                             (self.user_id, exploration_id))
                exp_services.delete_demo(unicode(exploration_id))
                exp_services.load_demo(unicode(exploration_id))
            elif self.payload.get('action') == 'clear_search_index':
                exp_services.clear_search_index()
            elif self.payload.get('action') == 'save_config_properties':
                new_config_property_values = self.payload.get(
                    'new_config_property_values')
                logging.info('[ADMIN] %s saved config property values: %s' %
                             (self.user_id, new_config_property_values))
                for (name, value) in new_config_property_values.iteritems():
                    config_services.set_property(self.user_id, name, value)
            elif self.payload.get('action') == 'revert_config_property':
                config_property_id = self.payload.get('config_property_id')
                logging.info('[ADMIN] %s reverted config property: %s' %
                             (self.user_id, config_property_id))
                config_services.revert_property(self.user_id,
                                                config_property_id)
            elif self.payload.get('action') == 'refresh_computed_property':
                computed_property_name = self.payload.get(
                    'computed_property_name')
                config_domain.Registry.get_config_property(
                    computed_property_name).refresh_default_value()
            elif self.payload.get('action') == 'start_new_job':
                for klass in jobs_registry.ONE_OFF_JOB_MANAGERS:
                    if klass.__name__ == self.payload.get('job_type'):
                        klass.enqueue(klass.create_new())
                        break
            elif self.payload.get('action') == 'cancel_job':
                job_id = self.payload.get('job_id')
                job_type = self.payload.get('job_type')
                for klass in jobs_registry.ONE_OFF_JOB_MANAGERS:
                    if klass.__name__ == job_type:
                        klass.cancel(job_id, self.user_id)
                        break
            elif self.payload.get('action') == 'start_computation':
                computation_type = self.payload.get('computation_type')
                for klass in jobs_registry.ALL_CONTINUOUS_COMPUTATION_MANAGERS:
                    if klass.__name__ == computation_type:
                        klass.start_computation()
                        break
            elif self.payload.get('action') == 'stop_computation':
                computation_type = self.payload.get('computation_type')
                for klass in jobs_registry.ALL_CONTINUOUS_COMPUTATION_MANAGERS:
                    if klass.__name__ == computation_type:
                        klass.stop_computation(self.user_id)
                        break

            self.render_json({})
        except Exception as e:
            self.render_json({'error': unicode(e)})
            raise
Example #17
0
    def setUp(self):
        """Load a demo exploration and register self.EDITOR_EMAIL."""
        super(ImageHandlerTest, self).setUp()

        exp_services.delete_demo('0')
        exp_services.load_demo('0')
        rights_manager.release_ownership_of_exploration(
            feconf.SYSTEM_COMMITTER_ID, '0')
        self.signup(self.EDITOR_EMAIL, self.EDITOR_USERNAME)
Example #18
0
    def get(self):
        """Handles GET requests."""
        if not exp_services.get_exploration_by_id('0', strict=False):
            exp_services.delete_demo('0')
            exp_services.load_demo('0')

        self.values.update({
            'gallery_login_url': user_services.create_login_url('/gallery'),
        })
        self.render_template('pages/index.html')
Example #19
0
    def setUp(self):
        """Load a demo exploration and register self.EDITOR_EMAIL."""
        super(AssetDevHandlerImageTests, self).setUp()

        exp_services.delete_demo('0')
        self.system_user = user_services.get_system_user()
        exp_services.load_demo('0')

        rights_manager.release_ownership_of_exploration(self.system_user, '0')
        self.signup(self.EDITOR_EMAIL, self.EDITOR_USERNAME)
Example #20
0
    def test_state_stats_for_default_exploration(self):
        exp_services.delete_demo('0')
        exp_services.load_demo('0')

        EXPLORATION_STATISTICS_URL = '/createhandler/statistics/0'

        # Check, from the editor perspective, that no stats have been recorded.
        self.register_editor('*****@*****.**')
        self.login('*****@*****.**')

        editor_exploration_dict = self.get_json(EXPLORATION_STATISTICS_URL)
        self.assertEqual(editor_exploration_dict['num_starts'], 0)
        self.assertEqual(editor_exploration_dict['num_completions'], 0)

        # Switch to the reader perspective. First submit the first
        # multiple-choice answer, then submit 'blah'.
        self.logout()
        exploration_dict = self.get_json(
            '%s/0' % feconf.EXPLORATION_INIT_URL_PREFIX)
        self.assertEqual(exploration_dict['title'], 'Welcome to Oppia!')

        state_name = exploration_dict['state_name']
        exploration_dict = self.post_json(
            '%s/0/%s' % (feconf.EXPLORATION_TRANSITION_URL_PREFIX, state_name),
            {
                'answer': '0', 'handler': 'submit',
                'state_history': exploration_dict['state_history'],
            }
        )
        state_name = exploration_dict['state_name']
        self.post_json(
            '%s/0/%s' % (feconf.EXPLORATION_TRANSITION_URL_PREFIX, state_name),
            {
                'answer': 'blah', 'handler': 'submit',
                'state_history': exploration_dict['state_history']
            }
        )
        # Ensure that all events get propagated.
        self.process_and_flush_pending_tasks()

        # Now switch back to the editor perspective.
        self.login('*****@*****.**')

        editor_exploration_dict = self.get_json(EXPLORATION_STATISTICS_URL)
        self.assertEqual(editor_exploration_dict['num_starts'], 1)
        self.assertEqual(editor_exploration_dict['num_completions'], 0)

        # TODO(sll): Add more checks here.

        self.logout()
Example #21
0
    def setUp(self):
        super(AssetDevHandlerAudioTest, self).setUp()
        exp_services.delete_demo('0')
        self.system_user = user_services.get_system_user()
        exp_services.load_demo('0')

        rights_manager.release_ownership_of_exploration(self.system_user, '0')
        self.signup(self.EDITOR_EMAIL, self.EDITOR_USERNAME)

        mock_accepted_audio_extensions = {
            'mp3': ['audio/mp3'],
            'flac': ['audio/flac']
        }

        self.accepted_audio_extensions_swap = self.swap(
            feconf, 'ACCEPTED_AUDIO_EXTENSIONS',
            mock_accepted_audio_extensions)
Example #22
0
    def get(self):
        if SPLASH_PAGE_EXPLORATION_ID.value:
            splash_exp_id = SPLASH_PAGE_EXPLORATION_ID.value
            if not exp_services.get_exploration_by_id(
                    splash_exp_id, strict=False):
                exp_services.delete_demo(splash_exp_id)
                exp_services.load_demo(splash_exp_id)

        self.values.update({
            'BANNER_ALT_TEXT': BANNER_ALT_TEXT.value,
            'SITE_FORUM_URL': SITE_FORUM_URL.value,
            'SITE_NAME': SITE_NAME.value,
            'SPLASH_PAGE_EXPLORATION_ID': SPLASH_PAGE_EXPLORATION_ID.value,
            'SPLASH_PAGE_EXPLORATION_VERSION': (
                SPLASH_PAGE_EXPLORATION_VERSION.value),
        })
        self.render_template('pages/splash.html')
Example #23
0
    def _get_splash_page(self):
        if SPLASH_PAGE_EXPLORATION_ID.value:
            splash_exp_id = SPLASH_PAGE_EXPLORATION_ID.value
            if not exp_services.get_exploration_by_id(
                    splash_exp_id, strict=False):
                exp_services.delete_demo(splash_exp_id)
                exp_services.load_demo(splash_exp_id)

        self.values.update({
            'BANNER_ALT_TEXT': BANNER_ALT_TEXT.value,
            'SITE_FORUM_URL': pages.SITE_FORUM_URL.value,
            'SITE_NAME': pages.SITE_NAME.value,
            'SPLASH_PAGE_EXPLORATION_ID': SPLASH_PAGE_EXPLORATION_ID.value,
            'SPLASH_PAGE_EXPLORATION_VERSION': (
                SPLASH_PAGE_EXPLORATION_VERSION.value),
        })
        self.render_template('pages/splash.html')
Example #24
0
    def test_give_feedback_handler(self):
        """Test giving feedback handler."""
        viewer_email = '*****@*****.**'

        # Load demo exploration
        EXP_ID = '0'
        exp_services.delete_demo('0')
        exp_services.load_demo('0')

        # Viewer opens exploration
        self.login(viewer_email)
        exploration_dict = self.get_json(
            '%s/%s' % (feconf.EXPLORATION_INIT_URL_PREFIX, EXP_ID))
        state_name_1 = exploration_dict['state_name']

        # Viewer gives 1st feedback
        self.post_json(
            '/explorehandler/give_feedback/%s' % EXP_ID,
            {
                'state_name': state_name_1,
                'feedback': 'This is a feedback message.',
            }
        )

        # Viewer submits answer '0'
        exploration_dict = self.post_json(
            '%s/%s/%s' % (feconf.EXPLORATION_TRANSITION_URL_PREFIX,
                          EXP_ID,
                          state_name_1),
            {
                'answer': '0', 'handler': 'submit',
                'state_history': exploration_dict['state_history']
            }
        )
        state_name_2 = exploration_dict['state_name']

        # Viewer gives 2nd feedback
        self.post_json(
            '/explorehandler/give_feedback/%s' % EXP_ID,
            {
                'state_name': state_name_2,
                'feedback': 'This is a 2nd feedback message.',
            }
        )
        self.logout()
Example #25
0
    def setUp(self):
        super(FeedbackThreadPermissionsTests, self).setUp()
        self.signup(self.EDITOR_EMAIL, self.EDITOR_USERNAME)
        # Load exploration 0.
        exp_services.delete_demo(self.EXP_ID)
        exp_services.load_demo(self.EXP_ID)

        # Get the CSRF token and create a single thread with a single message.
        # The corresponding user has already registered as an editor, and has a
        # username.
        self.login(self.EDITOR_EMAIL)
        self.csrf_token = self.get_new_csrf_token()
        self.post_json('%s/%s' % (
            feconf.FEEDBACK_THREADLIST_URL_PREFIX, self.EXP_ID
        ), {
            'subject': self._get_unicode_test_string('subject'),
            'text': self._get_unicode_test_string('text'),
        }, csrf_token=self.csrf_token)
        self.logout()
    def test_versioning_for_default_exploration(self):
        EXP_ID = '0'

        exp_services.delete_demo(EXP_ID)
        exp_services.load_demo(EXP_ID)

        # In version 2, change the initial state content.
        exploration = exp_services.get_exploration_by_id(EXP_ID)
        exp_services.update_exploration(
            '*****@*****.**', EXP_ID,
            [{
                'cmd': 'edit_state_property',
                'property_name': 'content',
                'state_name': exploration.init_state_name,
                'new_value': [{
                    'type': 'text',
                    'value': 'ABC'
                }],
            }], 'Change init state content')

        # The latest version contains 'ABC'.
        reader_dict = self.get_json(
            '%s/%s' % (feconf.EXPLORATION_INIT_URL_PREFIX, EXP_ID))
        self.assertIn('ABC', reader_dict['init_html'])
        self.assertNotIn('Hi, welcome to Oppia!', reader_dict['init_html'])

        # v1 contains 'Hi, welcome to Oppia!'.
        reader_dict = self.get_json(
            '%s/%s?v=1' % (feconf.EXPLORATION_INIT_URL_PREFIX, EXP_ID))
        self.assertIn('Hi, welcome to Oppia!', reader_dict['init_html'])
        self.assertNotIn('ABC', reader_dict['init_html'])

        # v2 contains 'ABC'.
        reader_dict = self.get_json(
            '%s/%s?v=2' % (feconf.EXPLORATION_INIT_URL_PREFIX, EXP_ID))
        self.assertIn('ABC', reader_dict['init_html'])
        self.assertNotIn('Hi, welcome to Oppia!', reader_dict['init_html'])

        # v3 does not exist.
        response = self.testapp.get(
            '%s/%s?v=3' % (feconf.EXPLORATION_INIT_URL_PREFIX, EXP_ID),
            expect_errors=True)
        self.assertEqual(response.status_int, 404)
Example #27
0
    def test_creation_of_state_classifier_mapping(self):
        super(ExplorationStateClassifierMappingTests, self).setUp()
        exploration_id = '15'

        self.login(self.VIEWER_EMAIL)
        self.signup(self.VIEWER_EMAIL, self.VIEWER_USERNAME)

        exp_services.delete_demo(exploration_id)
        # We enable ENABLE_ML_CLASSIFIERS so that the subsequent call to
        # save_exploration handles job creation for trainable states.
        # Since only one demo exploration has a trainable state, we modify our
        # values for MIN_ASSIGNED_LABELS and MIN_TOTAL_TRAINING_EXAMPLES to let
        # the classifier_demo_exploration.yaml be trainable. This is
        # completely for testing purposes.
        with self.swap(feconf, 'ENABLE_ML_CLASSIFIERS', True):
            with self.swap(feconf, 'MIN_TOTAL_TRAINING_EXAMPLES', 5):
                with self.swap(feconf, 'MIN_ASSIGNED_LABELS', 1):
                    exp_services.load_demo(exploration_id)

        # Retrieve job_id of created job (because of save_exp).
        all_jobs = classifier_models.ClassifierTrainingJobModel.get_all()
        self.assertEqual(all_jobs.count(), 1)
        for job in all_jobs:
            job_id = job.id

        classifier_services.store_classifier_data(job_id, {})

        expected_state_classifier_mapping = {
            'text': {
                'algorithm_id': 'LDAStringClassifier',
                'classifier_data': {},
                'data_schema_version': 1
            }
        }
        # Call the handler.
        exploration_dict = self.get_json(
            '%s/%s' % (feconf.EXPLORATION_INIT_URL_PREFIX, exploration_id))
        retrieved_state_classifier_mapping = exploration_dict[
            'state_classifier_mapping']

        self.assertEqual(expected_state_classifier_mapping,
                         retrieved_state_classifier_mapping)
Example #28
0
    def init_player(self, exploration_id, expected_title, expected_response):
        """Starts a reader session and gets the first state from the server.

        `expected_response` will be interpreted as a regex string.
        """
        exp_services.delete_demo(exploration_id)
        exp_services.load_demo(exploration_id)

        self.EXP_ID = exploration_id

        reader_dict = self.get_json(
            '%s/%s' % (feconf.EXPLORATION_INIT_URL_PREFIX, self.EXP_ID))

        self.last_params = reader_dict['params']
        self.last_state_name = reader_dict['state_name']
        self.state_history = [self.last_state_name]

        self.assertEqual(reader_dict['state_history'], self.state_history)
        self.assertRegexpMatches(reader_dict['init_html'], expected_response)
        self.assertEqual(reader_dict['title'], expected_title)
Example #29
0
    def init_player(self, exploration_id, expected_title, expected_response):
        """Starts a reader session and gets the first state from the server.

        `expected_response` will be interpreted as a regex string.
        """
        exp_services.delete_demo(exploration_id)
        exp_services.load_demo(exploration_id)

        self.exp_id = exploration_id  # pylint: disable=attribute-defined-outside-init

        reader_dict = self.get_json(
            '%s/%s' % (feconf.EXPLORATION_INIT_URL_PREFIX, self.exp_id))

        self.last_state_name = reader_dict['exploration']['init_state_name']  # pylint: disable=attribute-defined-outside-init
        init_state_data = (
            reader_dict['exploration']['states'][self.last_state_name])
        init_content = init_state_data['content'][0]['value']

        self.assertRegexpMatches(init_content, expected_response)
        self.assertEqual(reader_dict['exploration']['title'], expected_title)
Example #30
0
    def init_player(self, exploration_id, expected_title, expected_response):
        """Starts a reader session and gets the first state from the server.

        `expected_response` will be interpreted as a regex string.
        """
        exp_services.delete_demo(exploration_id)
        exp_services.load_demo(exploration_id)

        self.exp_id = exploration_id  # pylint: disable=attribute-defined-outside-init

        reader_dict = self.get_json(
            '%s/%s' % (feconf.EXPLORATION_INIT_URL_PREFIX, self.exp_id))

        self.last_state_name = reader_dict['exploration']['init_state_name']  # pylint: disable=attribute-defined-outside-init
        init_state_data = (
            reader_dict['exploration']['states'][self.last_state_name])
        init_content = init_state_data['content'][0]['value']

        self.assertRegexpMatches(init_content, expected_response)
        self.assertEqual(reader_dict['exploration']['title'], expected_title)
Example #31
0
    def test_editor_page(self):
        """Test access to editor pages for the sample exploration."""
        exp_services.delete_demo('0')
        exp_services.load_demo('0')

        # Check that non-editors cannot access the editor page.
        response = self.testapp.get('/create/0')
        self.assertEqual(response.status_int, 302)

        # Register and login as an admin.
        self.register_editor('*****@*****.**')
        self.login('*****@*****.**', is_admin=True)

        # Check that it is now possible to access the editor page.
        response = self.testapp.get('/create/0')
        self.assertEqual(response.status_int, 200)
        self.assertIn('Exploration Metadata', response.body)
        # Test that the value generator JS is included.
        self.assertIn('RandomSelector', response.body)

        self.logout()
Example #32
0
    def test_give_feedback_handler(self):
        """Test giving feedback handler."""
        self.signup(self.VIEWER_EMAIL, self.VIEWER_USERNAME)

        # Load demo exploration
        exp_id = "0"
        exp_services.delete_demo("0")
        exp_services.load_demo("0")

        # Viewer opens exploration
        self.login(self.VIEWER_EMAIL)
        exploration_dict = self.get_json("%s/%s" % (feconf.EXPLORATION_INIT_URL_PREFIX, exp_id))
        state_name_1 = exploration_dict["exploration"]["init_state_name"]

        # Viewer gives 1st feedback
        self.post_json(
            "/explorehandler/give_feedback/%s" % exp_id,
            {"state_name": state_name_1, "feedback": "This is a feedback message."},
        )

        self.logout()
Example #33
0
    def test_versioning_for_default_exploration(self):
        EXP_ID = '0'

        exp_services.delete_demo(EXP_ID)
        exp_services.load_demo(EXP_ID)

        # In version 2, change the initial state content.
        exploration = exp_services.get_exploration_by_id(EXP_ID)
        exp_services.update_exploration(
            '*****@*****.**', EXP_ID, [{
                'cmd': 'edit_state_property',
                'property_name': 'content',
                'state_name': exploration.init_state_name,
                'new_value': [{'type': 'text', 'value': 'ABC'}],
            }], 'Change init state content')

        # The latest version contains 'ABC'.
        reader_dict = self.get_json(
            '%s/%s' % (feconf.EXPLORATION_INIT_URL_PREFIX, EXP_ID))
        self.assertIn('ABC', reader_dict['init_html'])
        self.assertNotIn('Hi, welcome to Oppia!', reader_dict['init_html'])

        # v1 contains 'Hi, welcome to Oppia!'.
        reader_dict = self.get_json(
            '%s/%s?v=1' % (feconf.EXPLORATION_INIT_URL_PREFIX, EXP_ID))
        self.assertIn('Hi, welcome to Oppia!', reader_dict['init_html'])
        self.assertNotIn('ABC', reader_dict['init_html'])

        # v2 contains 'ABC'.
        reader_dict = self.get_json(
            '%s/%s?v=2' % (feconf.EXPLORATION_INIT_URL_PREFIX, EXP_ID))
        self.assertIn('ABC', reader_dict['init_html'])
        self.assertNotIn('Hi, welcome to Oppia!', reader_dict['init_html'])

        # v3 does not exist.
        response = self.testapp.get(
            '%s/%s?v=3' % (feconf.EXPLORATION_INIT_URL_PREFIX, EXP_ID),
            expect_errors=True)
        self.assertEqual(response.status_int, 404)
Example #34
0
    def test_user_banning(self):
        """Test that banned users are banned."""
        EXP_ID = '0'
        exp_services.delete_demo(EXP_ID)
        exp_services.load_demo(EXP_ID)

        # Sign-up new editors Joe and Sandra.
        self.signup('*****@*****.**', 'joe')
        self.signup('*****@*****.**', 'sandra')

        # Joe logs in.
        self.login('*****@*****.**')

        response = self.testapp.get(feconf.GALLERY_URL)
        self.assertEqual(response.status_int, 200)
        response = self.testapp.get('/create/%s' % EXP_ID)
        self.assertEqual(response.status_int, 200)
        self.assert_can_edit(response.body)

        # Ban joe.
        config_services.set_property(feconf.ADMIN_COMMITTER_ID,
                                     'banned_usernames', ['joe'])

        # Test that Joe is banned. (He can still access the gallery.)
        response = self.testapp.get(feconf.GALLERY_URL, expect_errors=True)
        self.assertEqual(response.status_int, 200)
        response = self.testapp.get('/create/%s' % EXP_ID, expect_errors=True)
        self.assertEqual(response.status_int, 200)
        self.assert_cannot_edit(response.body)

        # Joe logs out.
        self.logout()

        # Sandra logs in and is unaffected.
        self.login('*****@*****.**')
        response = self.testapp.get('/create/%s' % EXP_ID)
        self.assertEqual(response.status_int, 200)
        self.assert_can_edit(response.body)
        self.logout()
Example #35
0
    def test_give_feedback_handler(self):
        """Test giving feedback handler."""
        viewer_email = '*****@*****.**'

        # Load demo exploration
        EXP_ID = '0'
        exp_services.delete_demo('0')
        exp_services.load_demo('0')

        # Viewer opens exploration
        self.login(viewer_email)
        exploration_dict = self.get_json(
            '%s/%s' % (feconf.EXPLORATION_INIT_URL_PREFIX, EXP_ID))
        state_name_1 = exploration_dict['state_name']

        # Viewer gives 1st feedback
        self.post_json(
            '/explorehandler/give_feedback/%s' % EXP_ID, {
                'state_name': state_name_1,
                'feedback': 'This is a feedback message.',
            })

        # Viewer submits answer '0'
        exploration_dict = self.post_json(
            '%s/%s/%s' %
            (feconf.EXPLORATION_TRANSITION_URL_PREFIX, EXP_ID, state_name_1), {
                'answer': '0',
                'handler': 'submit',
                'state_history': exploration_dict['state_history']
            })
        state_name_2 = exploration_dict['state_name']

        # Viewer gives 2nd feedback
        self.post_json(
            '/explorehandler/give_feedback/%s' % EXP_ID, {
                'state_name': state_name_2,
                'feedback': 'This is a 2nd feedback message.',
            })
        self.logout()
    def test_editor_page(self):
        """Test access to editor pages for the sample exploration."""
        exp_services.delete_demo('0')
        exp_services.load_demo('0')

        # Check that non-editors cannot access the editor page.
        response = self.testapp.get('/create/0')
        self.assertEqual(response.status_int, 302)

        # Register and login as an editor.
        self.register_editor('*****@*****.**')
        self.login('*****@*****.**')

        # Check that it is now possible to access the editor page.
        response = self.testapp.get('/create/0')
        self.assertEqual(response.status_int, 200)
        self.assertIn('Stats', response.body)
        self.assertIn('History', response.body)
        # Test that the value generator JS is included.
        self.assertIn('RandomSelector', response.body)

        self.logout()
Example #37
0
    def test_user_banning(self):
        """Test that banned users are banned."""
        EXP_ID = '0'
        exp_services.delete_demo(EXP_ID)
        exp_services.load_demo(EXP_ID)

        # Register new editors Joe and Sandra.
        self.register_editor('*****@*****.**', username='******')
        self.register_editor('*****@*****.**', username='******')

        # Joe logs in.
        self.login('*****@*****.**')

        response = self.testapp.get('/contribute', expect_errors=True)
        self.assertEqual(response.status_int, 200)
        response = self.testapp.get('/create/%s' % EXP_ID)
        self.assertEqual(response.status_int, 200)
        self.assert_can_edit(response.body)

        # Ban joe.
        config_services.set_property(
            feconf.ADMIN_COMMITTER_ID, 'banned_usernames', ['joe'])

        # Test that Joe is banned.
        response = self.testapp.get('/contribute', expect_errors=True)
        self.assertEqual(response.status_int, 401)
        response = self.testapp.get('/create/%s' % EXP_ID, expect_errors=True)
        self.assertEqual(response.status_int, 200)
        self.assert_cannot_edit(response.body)

        # Joe logs out.
        self.logout()

        # Sandra logs in and is unaffected.
        self.login('*****@*****.**')
        response = self.testapp.get('/create/%s' % EXP_ID)
        self.assertEqual(response.status_int, 200)
        self.assert_can_edit(response.body)
        self.logout()
Example #38
0
    def setUp(self):
        super(FeedbackThreadPermissionsTests, self).setUp()
        self.signup(self.EDITOR_EMAIL, self.EDITOR_USERNAME)

        # Load exploration 0.
        exp_services.delete_demo(self.EXP_ID)
        exp_services.load_demo(self.EXP_ID)

        # Get the CSRF token and create a single thread with a single message.
        # The corresponding user has already registered as an editor, and has a
        # username.
        self.login(self.EDITOR_EMAIL)
        response = self.testapp.get('/create/%s' % self.EXP_ID)
        self.csrf_token = self.get_csrf_token_from_response(response)
        self.post_json('%s/%s' % (
            feconf.FEEDBACK_THREADLIST_URL_PREFIX, self.EXP_ID),
            {
                'state_name': self._get_unicode_test_string('statename'),
                'subject': self._get_unicode_test_string('subject'),
                'text': self._get_unicode_test_string('text'),
            }, self.csrf_token)
        self.logout()
Example #39
0
    def test_user_banning(self):
        """Test that banned users are banned."""
        EXP_ID = '0'
        exp_services.delete_demo(EXP_ID)
        exp_services.load_demo(EXP_ID)

        # Sign-up new editors Joe and Sandra.
        self.signup('*****@*****.**', 'joe')
        self.signup('*****@*****.**', 'sandra')

        # Joe logs in.
        self.login('*****@*****.**')

        response = self.testapp.get(feconf.GALLERY_URL)
        self.assertEqual(response.status_int, 200)
        response = self.testapp.get('/create/%s' % EXP_ID)
        self.assertEqual(response.status_int, 200)
        self.assert_can_edit(response.body)

        # Ban joe.
        config_services.set_property(
            feconf.SYSTEM_COMMITTER_ID, 'banned_usernames', ['joe'])

        # Test that Joe is banned. (He can still access the gallery.)
        response = self.testapp.get(feconf.GALLERY_URL, expect_errors=True)
        self.assertEqual(response.status_int, 200)
        response = self.testapp.get('/create/%s' % EXP_ID, expect_errors=True)
        self.assertEqual(response.status_int, 200)
        self.assert_cannot_edit(response.body)

        # Joe logs out.
        self.logout()

        # Sandra logs in and is unaffected.
        self.login('*****@*****.**')
        response = self.testapp.get('/create/%s' % EXP_ID)
        self.assertEqual(response.status_int, 200)
        self.assert_can_edit(response.body)
        self.logout()
Example #40
0
    def test_resolved_answers_handler(self):
        exp_services.delete_demo('0')
        exp_services.load_demo('0')

        # In the reader perspective, submit the first multiple-choice answer,
        # then submit 'blah' once, 'blah2' twice and 'blah3' three times.
        # TODO(sll): Use the ExplorationPlayer in reader_test for this.
        exploration_dict = self.get_json(
            '%s/0' % feconf.EXPLORATION_INIT_URL_PREFIX)
        self.assertEqual(
            exploration_dict['exploration']['title'], 'Welcome to Oppia!')

        state_name = exploration_dict['exploration']['init_state_name']
        result_dict = self.submit_answer('0', state_name, '0')

        state_name = result_dict['state_name']
        self.submit_answer('0', state_name, 'blah')
        for _ in range(2):
            self.submit_answer('0', state_name, 'blah2')
        for _ in range(3):
            self.submit_answer('0', state_name, 'blah3')

        # Log in as an editor.
        self.login(self.EDITOR_EMAIL)

        response = self.testapp.get('/create/0')
        csrf_token = self.get_csrf_token_from_response(response)
        url = str('/createhandler/resolved_answers/0/%s' % state_name)

        def _get_unresolved_answers():
            return stats_domain.StateRuleAnswerLog.get(
                '0', state_name, exp_domain.DEFAULT_RULESPEC_STR
            ).answers

        self.assertEqual(
            _get_unresolved_answers(), {'blah': 1, 'blah2': 2, 'blah3': 3})

        # An empty request should result in an error.
        response_dict = self.put_json(
            url, {'something_else': []}, csrf_token,
            expect_errors=True, expected_status_int=400)
        self.assertIn('Expected a list', response_dict['error'])

        # A request of the wrong type should result in an error.
        response_dict = self.put_json(
            url, {'resolved_answers': 'this_is_a_string'}, csrf_token,
            expect_errors=True, expected_status_int=400)
        self.assertIn('Expected a list', response_dict['error'])

        # Trying to remove an answer that wasn't submitted has no effect.
        response_dict = self.put_json(
            url, {'resolved_answers': ['not_submitted_answer']}, csrf_token)
        self.assertEqual(
            _get_unresolved_answers(), {'blah': 1, 'blah2': 2, 'blah3': 3})

        # A successful request should remove the answer in question.
        response_dict = self.put_json(
            url, {'resolved_answers': ['blah']}, csrf_token)
        self.assertEqual(
            _get_unresolved_answers(), {'blah2': 2, 'blah3': 3})

        # It is possible to remove more than one answer at a time.
        response_dict = self.put_json(
            url, {'resolved_answers': ['blah2', 'blah3']}, csrf_token)
        self.assertEqual(_get_unresolved_answers(), {})

        self.logout()
Example #41
0
 def _initialize(self):
     exp_services.delete_demo('0')
     exp_services.load_demo('0')
     self.register_editor(self.EDITOR_EMAIL)
Example #42
0
    def test_resolved_answers_handler(self):
        exp_services.delete_demo('0')
        exp_services.load_demo('0')

        # In the reader perspective, submit the first multiple-choice answer,
        # then submit 'blah' once, 'blah2' twice and 'blah3' three times.
        # TODO(sll): Use the ExplorationPlayer in reader_test for this.
        exploration_dict = self.get_json('%s/0' %
                                         feconf.EXPLORATION_INIT_URL_PREFIX)
        self.assertEqual(exploration_dict['exploration']['title'],
                         'Welcome to Oppia!')

        state_name = exploration_dict['exploration']['init_state_name']
        exploration_dict = self.submit_answer('0', state_name, '0')

        state_name = exploration_dict['state_name']
        self.submit_answer('0', state_name, 'blah')
        for _ in range(2):
            self.submit_answer('0', state_name, 'blah2')
        for _ in range(3):
            self.submit_answer('0', state_name, 'blah3')

        # Log in as an editor.
        self.login(self.EDITOR_EMAIL)

        response = self.testapp.get('/create/0')
        csrf_token = self.get_csrf_token_from_response(response)
        url = str('/createhandler/resolved_answers/0/%s' % state_name)

        def _get_unresolved_answers():
            return stats_domain.StateRuleAnswerLog.get(
                '0', state_name, feconf.SUBMIT_HANDLER_NAME,
                exp_domain.DEFAULT_RULESPEC_STR).answers

        self.assertEqual(_get_unresolved_answers(), {
            'blah': 1,
            'blah2': 2,
            'blah3': 3
        })

        # An empty request should result in an error.
        response_dict = self.put_json(url, {'something_else': []},
                                      csrf_token,
                                      expect_errors=True,
                                      expected_status_int=400)
        self.assertIn('Expected a list', response_dict['error'])

        # A request of the wrong type should result in an error.
        response_dict = self.put_json(url,
                                      {'resolved_answers': 'this_is_a_string'},
                                      csrf_token,
                                      expect_errors=True,
                                      expected_status_int=400)
        self.assertIn('Expected a list', response_dict['error'])

        # Trying to remove an answer that wasn't submitted has no effect.
        response_dict = self.put_json(
            url, {'resolved_answers': ['not_submitted_answer']}, csrf_token)
        self.assertEqual(_get_unresolved_answers(), {
            'blah': 1,
            'blah2': 2,
            'blah3': 3
        })

        # A successful request should remove the answer in question.
        response_dict = self.put_json(url, {'resolved_answers': ['blah']},
                                      csrf_token)
        self.assertEqual(_get_unresolved_answers(), {'blah2': 2, 'blah3': 3})

        # It is possible to remove more than one answer at a time.
        response_dict = self.put_json(url,
                                      {'resolved_answers': ['blah2', 'blah3']},
                                      csrf_token)
        self.assertEqual(_get_unresolved_answers(), {})

        self.logout()
Example #43
0
    def test_add_new_state_error_cases(self):
        """Test the error cases for adding a new state to an exploration."""
        exp_services.delete_demo('0')
        exp_services.load_demo('0')
        CURRENT_VERSION = 1

        self.login(self.EDITOR_EMAIL)
        response = self.testapp.get('/create/0')
        csrf_token = self.get_csrf_token_from_response(response)

        def _get_payload(new_state_name, version=None):
            result = {
                'change_list': [{
                    'cmd': 'add_state',
                    'state_name': new_state_name
                }],
                'commit_message': 'Add new state',
            }
            if version is not None:
                result['version'] = version
            return result

        def _put_and_expect_400_error(payload):
            return self.put_json('/createhandler/data/0',
                                 payload,
                                 csrf_token,
                                 expect_errors=True,
                                 expected_status_int=400)

        # A request with no version number is invalid.
        response_dict = _put_and_expect_400_error(_get_payload('New state'))
        self.assertIn('a version must be specified', response_dict['error'])

        # A request with the wrong version number is invalid.
        response_dict = _put_and_expect_400_error(
            _get_payload('New state', 123))
        self.assertIn('which is too old', response_dict['error'])

        # A request with an empty state name is invalid.
        response_dict = _put_and_expect_400_error(
            _get_payload('', CURRENT_VERSION))
        self.assertIn('should be between 1 and 50', response_dict['error'])

        # A request with a really long state name is invalid.
        response_dict = _put_and_expect_400_error(
            _get_payload('a' * 100, CURRENT_VERSION))
        self.assertIn('should be between 1 and 50', response_dict['error'])

        # A request with a state name containing invalid characters is
        # invalid.
        response_dict = _put_and_expect_400_error(
            _get_payload('[Bad State Name]', CURRENT_VERSION))
        self.assertIn('Invalid character [', response_dict['error'])

        # A request with a state name of feconf.END_DEST is invalid.
        response_dict = _put_and_expect_400_error(
            _get_payload(feconf.END_DEST, CURRENT_VERSION))
        self.assertIn('Invalid state name', response_dict['error'])

        # Even if feconf.END_DEST is mixed case, it is still invalid.
        response_dict = _put_and_expect_400_error(
            _get_payload('eNd', CURRENT_VERSION))
        self.assertEqual('eNd'.lower(), feconf.END_DEST.lower())
        self.assertIn('Invalid state name', response_dict['error'])

        # A name cannot have spaces at the front or back.
        response_dict = _put_and_expect_400_error(
            _get_payload('  aa', CURRENT_VERSION))
        self.assertIn('start or end with whitespace', response_dict['error'])
        response_dict = _put_and_expect_400_error(
            _get_payload('aa\t', CURRENT_VERSION))
        self.assertIn('end with whitespace', response_dict['error'])
        response_dict = _put_and_expect_400_error(
            _get_payload('\n', CURRENT_VERSION))
        self.assertIn('end with whitespace', response_dict['error'])

        # A name cannot have consecutive whitespace.
        response_dict = _put_and_expect_400_error(
            _get_payload('The   B', CURRENT_VERSION))
        self.assertIn('Adjacent whitespace', response_dict['error'])
        response_dict = _put_and_expect_400_error(
            _get_payload('The\t\tB', CURRENT_VERSION))
        self.assertIn('Adjacent whitespace', response_dict['error'])

        self.logout()
 def _initialize(self):
     exp_services.delete_demo('0')
     exp_services.load_demo('0')
     self.register_editor(self.EDITOR_EMAIL)
Example #45
0
 def setUp(self):
     super(RatingsIntegrationTests, self).setUp()
     self.EXP_ID = '0'
     exp_services.delete_demo('0')
     exp_services.load_demo('0')
Example #46
0
 def post(self):
     """Reloads the default explorations."""
     if self.payload.get('action') == 'reload_exploration':
         exploration_id = self.payload.get('explorationId')
         exp_services.delete_demo(str(exploration_id))
         exp_services.load_demo(str(exploration_id))
Example #47
0
    def setUp(self):
        super(SuggestionsIntegrationTests, self).setUp()

        # Register users.
        self.signup(self.OWNER_EMAIL, self.OWNER_USERNAME)
        self.signup(self.EDITOR_EMAIL, self.EDITOR_USERNAME)
        self.signup(self.VIEWER_EMAIL, self.VIEWER_USERNAME)
        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.viewer_id = self.get_user_id_from_email(self.VIEWER_EMAIL)

        # Load exploration 0.
        exp_services.delete_demo(self.EXP_ID)
        exp_services.load_demo(self.EXP_ID)

        # Login and create exploration and suggestions.
        self.login(self.EDITOR_EMAIL)

        # Create exploration.
        self.save_new_valid_exploration(
            self.EXP_ID,
            self.editor_id,
            title='Exploration for suggestions',
            category='This is just a test category',
            objective='Test a suggestion.')

        exploration = exp_services.get_exploration_by_id(self.EXP_ID)
        init_state = exploration.states[exploration.init_state_name]
        init_interaction = init_state.interaction
        init_interaction.default_outcome.dest = exploration.init_state_name
        exploration.add_states(['State A', 'State 2', 'State 3'])
        exploration.states['State A'].update_interaction_id('TextInput')
        exploration.states['State 2'].update_interaction_id('TextInput')
        exploration.states['State 3'].update_interaction_id('TextInput')
        exp_services._save_exploration(self.editor_id, exploration, '', [])  # pylint: disable=protected-access
        rights_manager.publish_exploration(self.editor_id, self.EXP_ID)
        rights_manager.assign_role_for_exploration(self.editor_id, self.EXP_ID,
                                                   self.owner_id,
                                                   rights_manager.ROLE_EDITOR)

        response = self.testapp.get('/explore/%s' % self.EXP_ID)
        csrf_token = self.get_csrf_token_from_response(response)

        # Create suggestions.
        self.post_json(
            '%s/%s' % (feconf.SUGGESTION_URL_PREFIX, self.EXP_ID), {
                'exploration_version': 3,
                'state_name': u'State A',
                'description': u'Suggestion for state A.',
                'suggestion_content': {
                    'type': 'text',
                    'value': u'new accepted suggestion for state A'
                },
            }, csrf_token)
        self.post_json(
            '%s/%s' % (feconf.SUGGESTION_URL_PREFIX, self.EXP_ID), {
                'exploration_version': 1,
                'state_name': u'State 2',
                'description': u'A new value.',
                'suggestion_content': {
                    'type': 'text',
                    'value': 'some new value'
                },
            }, csrf_token)
        self.post_json(
            '%s/%s' % (feconf.SUGGESTION_URL_PREFIX, self.EXP_ID), {
                'exploration_version': 2,
                'state_name': u'State 3',
                'description': u'Empty suggestion',
                'suggestion_content': {
                    'type': 'text',
                    'value': ''
                },
            }, csrf_token)
        self.post_json(
            '%s/%s' % (feconf.SUGGESTION_URL_PREFIX, self.EXP_ID), {
                'exploration_version': 2,
                'state_name': u'State A',
                'description': u'Just a space.',
                'suggestion_content': {
                    'type': 'text',
                    'value': ' '
                },
            }, csrf_token)
        self.post_json(
            '%s/%s' % (feconf.SUGGESTION_URL_PREFIX, self.EXP_ID), {
                'exploration_version': 1,
                'state_name': u'State 2',
                'description': u'Random characters.',
                'suggestion_content': {
                    'type': 'text',
                    'value': '#!$%'
                },
            }, csrf_token)
        self.post_json(
            '%s/%s' % (feconf.SUGGESTION_URL_PREFIX, self.EXP_ID), {
                'exploration_version': 2,
                'state_name': u'State 3',
                'description': u'Very bizarre characters.',
                'suggestion_content': {
                    'type': 'text',
                    'value': u'Ֆݓॵক'
                },
            }, csrf_token)
        self.logout()
Example #48
0
    def setUp(self):
        super(SuggestionsIntegrationTests, self).setUp()

        # Register users.
        self.signup(self.OWNER_EMAIL, self.OWNER_USERNAME)
        self.signup(self.EDITOR_EMAIL, self.EDITOR_USERNAME)
        self.signup(self.VIEWER_EMAIL, self.VIEWER_USERNAME)
        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.viewer_id = self.get_user_id_from_email(self.VIEWER_EMAIL)

        # Load exploration 0.
        exp_services.delete_demo(self.EXP_ID)
        exp_services.load_demo(self.EXP_ID)

        # Login and create exploration and suggestions.
        self.login(self.EDITOR_EMAIL)

        # Create exploration.
        self.save_new_valid_exploration(
            self.EXP_ID, self.editor_id,
            title='Exploration for suggestions',
            category='This is just a test category',
            objective='Test a suggestion.')

        exploration = exp_services.get_exploration_by_id(self.EXP_ID)
        init_state = exploration.states[exploration.init_state_name]
        init_interaction = init_state.interaction
        init_interaction.default_outcome.dest = exploration.init_state_name
        exploration.add_states(['State A', 'State 2', 'State 3'])
        exploration.states['State A'].update_interaction_id('TextInput')
        exploration.states['State 2'].update_interaction_id('TextInput')
        exploration.states['State 3'].update_interaction_id('TextInput')
        exp_services._save_exploration(self.editor_id, exploration, '', [])  # pylint: disable=protected-access
        rights_manager.publish_exploration(self.editor_id, self.EXP_ID)
        rights_manager.assign_role_for_exploration(
            self.editor_id, self.EXP_ID, self.owner_id,
            rights_manager.ROLE_EDITOR)

        response = self.testapp.get('/explore/%s' % self.EXP_ID)
        csrf_token = self.get_csrf_token_from_response(response)

        # Create suggestions.
        self.post_json(
            '%s/%s' % (feconf.SUGGESTION_URL_PREFIX, self.EXP_ID), {
                'exploration_version': 3,
                'state_name': u'State A',
                'description': u'Suggestion for state A.',
                'suggestion_content': {
                    'type': 'text',
                    'value': u'new accepted suggestion for state A'},
            }, csrf_token)
        self.post_json(
            '%s/%s' % (feconf.SUGGESTION_URL_PREFIX, self.EXP_ID), {
                'exploration_version': 1,
                'state_name': u'State 2',
                'description': u'A new value.',
                'suggestion_content': {
                    'type': 'text', 'value': 'some new value'},
            }, csrf_token)
        self.post_json(
            '%s/%s' % (feconf.SUGGESTION_URL_PREFIX, self.EXP_ID), {
                'exploration_version': 2,
                'state_name': u'State 3',
                'description': u'Empty suggestion',
                'suggestion_content': {'type': 'text', 'value': ''},
            }, csrf_token)
        self.post_json(
            '%s/%s' % (feconf.SUGGESTION_URL_PREFIX, self.EXP_ID), {
                'exploration_version': 2,
                'state_name': u'State A',
                'description': u'Just a space.',
                'suggestion_content': {'type': 'text', 'value': ' '},
            }, csrf_token)
        self.post_json(
            '%s/%s' % (feconf.SUGGESTION_URL_PREFIX, self.EXP_ID), {
                'exploration_version': 1,
                'state_name': u'State 2',
                'description': u'Random characters.',
                'suggestion_content': {'type': 'text', 'value': '#!$%'},
            }, csrf_token)
        self.post_json(
            '%s/%s' % (feconf.SUGGESTION_URL_PREFIX, self.EXP_ID), {
                'exploration_version': 2,
                'state_name': u'State 3',
                'description': u'Very bizarre characters.',
                'suggestion_content': {'type': 'text', 'value': u'Ֆݓॵক'},
            }, csrf_token)
        self.logout()
Example #49
0
 def setUp(self):
     super(RatingsIntegrationTests, self).setUp()
     self.EXP_ID = '0'
     exp_services.delete_demo('0')
     exp_services.load_demo('0')
Example #50
0
    def test_add_new_state_error_cases(self):
        """Test the error cases for adding a new state to an exploration."""
        exp_services.delete_demo('0')
        exp_services.load_demo('0')
        CURRENT_VERSION = 1

        self.login(self.EDITOR_EMAIL)
        response = self.testapp.get('/create/0')
        csrf_token = self.get_csrf_token_from_response(response)

        def _get_payload(new_state_name, version=None):
            result = {
                'change_list': [{
                    'cmd': 'add_state',
                    'state_name': new_state_name
                }],
                'commit_message': 'Add new state',
            }
            if version is not None:
                result['version'] = version
            return result

        def _put_and_expect_400_error(payload):
            return self.put_json(
                '/createhandler/data/0', payload, csrf_token,
                expect_errors=True, expected_status_int=400)

        # A request with no version number is invalid.
        response_dict = _put_and_expect_400_error(_get_payload('New state'))
        self.assertIn('a version must be specified', response_dict['error'])

        # A request with the wrong version number is invalid.
        response_dict = _put_and_expect_400_error(
            _get_payload('New state', 123))
        self.assertIn('which is too old', response_dict['error'])

        # A request with an empty state name is invalid.
        response_dict = _put_and_expect_400_error(
            _get_payload('', CURRENT_VERSION))
        self.assertIn('should be between 1 and 50', response_dict['error'])

        # A request with a really long state name is invalid.
        response_dict = _put_and_expect_400_error(
            _get_payload('a' * 100, CURRENT_VERSION))
        self.assertIn('should be between 1 and 50', response_dict['error'])

        # A request with a state name containing invalid characters is
        # invalid.
        response_dict = _put_and_expect_400_error(
            _get_payload('[Bad State Name]', CURRENT_VERSION))
        self.assertIn('Invalid character [', response_dict['error'])

        # A name cannot have spaces at the front or back.
        response_dict = _put_and_expect_400_error(
            _get_payload('  aa', CURRENT_VERSION))
        self.assertIn('start or end with whitespace', response_dict['error'])
        response_dict = _put_and_expect_400_error(
            _get_payload('aa\t', CURRENT_VERSION))
        self.assertIn('end with whitespace', response_dict['error'])
        response_dict = _put_and_expect_400_error(
            _get_payload('\n', CURRENT_VERSION))
        self.assertIn('end with whitespace', response_dict['error'])

        # A name cannot have consecutive whitespace.
        response_dict = _put_and_expect_400_error(
            _get_payload('The   B', CURRENT_VERSION))
        self.assertIn('Adjacent whitespace', response_dict['error'])
        response_dict = _put_and_expect_400_error(
            _get_payload('The\t\tB', CURRENT_VERSION))
        self.assertIn('Adjacent whitespace', response_dict['error'])

        self.logout()