Пример #1
0
    def test_no_username_shown_for_logged_out_learners(self):
        NEW_EXP_ID = 'new_eid'
        exploration = exp_domain.Exploration.create_default_exploration(
            NEW_EXP_ID, 'A title', 'A category')
        exp_services.save_new_exploration(self.EDITOR_ID, exploration)
        rights_manager.publish_exploration(self.EDITOR_ID, NEW_EXP_ID)

        response = self.testapp.get('/create/%s' % NEW_EXP_ID)
        csrf_token = self.get_csrf_token_from_response(response)
        self.post_json(
            '/explorehandler/give_feedback/%s' % NEW_EXP_ID,
            {
                'state_name': None,
                'subject': 'Test thread',
                'feedback': 'Test thread text',
                'include_author': False,
            }, csrf_token)

        response_dict = self.get_json(
            '%s/%s' % (feconf.FEEDBACK_THREADLIST_URL_PREFIX, NEW_EXP_ID))
        threadlist = response_dict['threads']
        self.assertIsNone(threadlist[0]['original_author_username'])

        response_dict = self.get_json('%s/%s/%s' % (
            feconf.FEEDBACK_THREAD_URL_PREFIX, NEW_EXP_ID,
            threadlist[0]['thread_id']))
        self.assertIsNone(response_dict['messages'][0]['author_username'])
Пример #2
0
    def save_new_valid_exploration(
            self, exploration_id, owner_id, title='A title',
            category='A category', objective='An objective',
            end_state_name=None):
        """Saves a new strictly-validated exploration.

        Returns the exploration domain object.
        """
        exploration = exp_domain.Exploration.create_default_exploration(
            exploration_id, title, category)
        exploration.states[exploration.init_state_name].update_interaction_id(
            'TextInput')
        exploration.objective = objective

        # If an end state name is provided, add terminal node with that name
        if end_state_name is not None:
            exploration.add_states([end_state_name])
            exploration.states[end_state_name].update_interaction_id(
                'EndExploration')
            # Link first state to ending state (to maintain validity)
            init_state = exploration.states[exploration.init_state_name]
            init_interaction = init_state.interaction
            init_interaction.handlers[0].rule_specs[0].dest = end_state_name

        exp_services.save_new_exploration(owner_id, exploration)
        return exploration
Пример #3
0
    def test_migration_job_does_not_convert_up_to_date_exp(self):
        """Tests that the exploration migration job does not convert an
        exploration that is already the latest states schema version.
        """
        # Create a new, default exploration that should not be affected by the
        # job.
        exploration = exp_domain.Exploration.create_default_exploration(
            self.VALID_EXP_ID, 'title', 'category')
        init_state = exploration.states[exploration.init_state_name]
        init_state.update_interaction_id('EndExploration')
        init_state.interaction.default_outcome = None
        exp_services.save_new_exploration(self.albert_id, exploration)
        self.assertEqual(
            exploration.states_schema_version,
            feconf.CURRENT_EXPLORATION_STATES_SCHEMA_VERSION)
        yaml_before_migration = exploration.to_yaml()

        # Start migration job on sample exploration.
        job_id = exp_jobs_one_off.ExplorationMigrationJobManager.create_new()
        exp_jobs_one_off.ExplorationMigrationJobManager.enqueue(job_id)
        self.process_and_flush_pending_tasks()

        # Verify the exploration is exactly the same after migration.
        updated_exp = exp_services.get_exploration_by_id(self.VALID_EXP_ID)
        self.assertEqual(
            updated_exp.states_schema_version,
            feconf.CURRENT_EXPLORATION_STATES_SCHEMA_VERSION)
        after_converted_yaml = updated_exp.to_yaml()
        self.assertEqual(after_converted_yaml, yaml_before_migration)
Пример #4
0
    def test_recording_answer_for_different_rules(self):
        exp = exp_domain.Exploration.create_default_exploration(
            'eid', 'title', 'category')
        exp_services.save_new_exploration('user_id', exp)

        rule = exp_domain.RuleSpec.from_dict({
            'rule_type': 'LessThan',
            'inputs': {'x': 5}
        })
        rule_str = rule.stringify_classified_rule()

        state_name = exp.init_state_name

        event_services.AnswerSubmissionEventHandler.record(
            'eid', 1, state_name, self.DEFAULT_RULESPEC_STR, 'answer1')
        event_services.AnswerSubmissionEventHandler.record(
            'eid', 1, state_name, rule_str, 'answer2')

        default_rule_answer_log = stats_domain.StateRuleAnswerLog.get(
            'eid', state_name, self.DEFAULT_RULESPEC_STR)
        self.assertEquals(default_rule_answer_log.answers, {'answer1': 1})
        self.assertEquals(default_rule_answer_log.total_answer_count, 1)

        other_rule_answer_log = stats_domain.StateRuleAnswerLog.get(
            'eid', state_name, rule_str)
        self.assertEquals(other_rule_answer_log.answers, {'answer2': 1})
        self.assertEquals(other_rule_answer_log.total_answer_count, 1)
Пример #5
0
    def test_incomplete_and_default_flags(self):
        exp = exp_domain.Exploration.create_default_exploration(
            'eid', 'A title', 'A category')
        exp_services.save_new_exploration('*****@*****.**', exp)
        state_name = exp.init_state_name

        # Hit the default rule once, and fail to answer twice. The result
        # should be classified as incomplete.
        for _ in range(3):
            event_services.StateHitEventHandler.record(
                'eid', state_name, True)
        event_services.AnswerSubmissionEventHandler.record(
            'eid', 1, state_name, self.SUBMIT_HANDLER,
            self.DEFAULT_RULESPEC, '1')
        self.assertEquals(stats_services.get_state_improvements('eid'), [{
            'rank': 2,
            'type': 'incomplete',
            'state_name': state_name
        }])

        # Now hit the default two more times. The result should be classified
        # as default.
        for i in range(2):
            event_services.StateHitEventHandler.record(
                'eid', state_name, True)
            event_services.AnswerSubmissionEventHandler.record(
                'eid', 1, state_name, self.SUBMIT_HANDLER,
                self.DEFAULT_RULESPEC, '1')
        self.assertEquals(stats_services.get_state_improvements('eid'), [{
            'rank': 3,
            'type': 'default',
            'state_name': state_name
        }])
Пример #6
0
    def test_adding_new_exploration_viewer_role_does_not_result_in_subscription(self):
        exploration = exp_domain.Exploration.create_default_exploration(EXP_ID, "Title", "Category")
        exp_services.save_new_exploration(self.owner_id, exploration)

        self.assertEqual(self._get_exploration_ids_subscribed_to(self.viewer_id), [])
        rights_manager.assign_role_for_exploration(self.owner_id, EXP_ID, self.viewer_id, rights_manager.ROLE_VIEWER)
        self.assertEqual(self._get_exploration_ids_subscribed_to(self.viewer_id), [])
Пример #7
0
    def test_deleting_exploration_does_not_delete_subscription(self):
        exploration = exp_domain.Exploration.create_default_exploration(EXP_ID, "Title", "Category")
        exp_services.save_new_exploration(self.owner_id, exploration)
        self.assertEqual(self._get_exploration_ids_subscribed_to(self.owner_id), [EXP_ID])

        exp_services.delete_exploration(self.owner_id, EXP_ID)
        self.assertEqual(self._get_exploration_ids_subscribed_to(self.owner_id), [EXP_ID])
 def test_creating_exploration_results_in_subscription(self):
     self.assertEqual(
         self._get_exploration_ids_subscribed_to(USER_ID), [])
     exp_services.save_new_exploration(
         USER_ID, exp_domain.Exploration.create_default_exploration(EXP_ID))
     self.assertEqual(
         self._get_exploration_ids_subscribed_to(USER_ID), [EXP_ID])
Пример #9
0
    def test_rating_assignation(self):
        """Check ratings are correctly assigned to an exploration"""

        self.exploration = exp_domain.Exploration.create_default_exploration(
            self.EXP_ID, 'A title', 'A category')
        exp_services.save_new_exploration(self.EXP_ID, self.exploration)

        self.assertEqual(
            rating_services.get_overall_ratings(self.EXP_ID),
            {'1': 0, '2': 0, '3': 0, '4': 0, '5': 0})

        self.assertEqual(
            rating_services.get_user_specific_rating(
                self.USER_ID_1, self.EXP_ID), None)

        rating_services.assign_rating(self.USER_ID_1, self.EXP_ID, 2)
        rating_services.assign_rating(self.USER_ID_2, self.EXP_ID, 4)
        rating_services.assign_rating(self.USER_ID_1, self.EXP_ID, 3)

        self.assertEqual(
            rating_services.get_user_specific_rating(
                self.USER_ID_1, self.EXP_ID), 3)
        self.assertEqual(
            rating_services.get_user_specific_rating(
                self.USER_ID_2, self.EXP_ID), 4)
        self.assertEqual(
            rating_services.get_overall_ratings(self.EXP_ID),
            {'1': 0, '2': 0, '3': 1, '4': 1, '5': 0})

        rating_services.assign_rating(self.USER_ID_1, self.EXP_ID, 4)

        self.assertEqual(
            rating_services.get_overall_ratings(self.EXP_ID),
            {'1': 0, '2': 0, '3': 0, '4': 2, '5': 0})
Пример #10
0
    def test_get_top_improvable_states(self):
        exp = exp_domain.Exploration.create_default_exploration(
            'eid', 'A title', 'A category')
        exp_services.save_new_exploration('*****@*****.**', exp)
        state_name = exp.init_state_name

        for _ in range(5):
            stats_services.EventHandler.record_state_hit(
                'eid', state_name, True)

        stats_services.EventHandler.record_answer_submitted(
            'eid', state_name, self.SUBMIT_HANDLER,
            self.DEFAULT_RULESPEC_STR, '1')
        for _ in range(2):
            stats_services.EventHandler.record_answer_submitted(
                'eid', state_name, self.SUBMIT_HANDLER,
                self.DEFAULT_RULESPEC_STR, '2')

        expected_top_state = {
            'exp_id': 'eid', 'type': 'default', 'rank': 3,
            'state_name': exp.init_state_name
        }

        states = stats_services.get_top_improvable_states(['eid'], 10)
        self.assertEquals(len(states), 1)
        self.assertDictContainsSubset(expected_top_state, states[0])
Пример #11
0
    def save_new_valid_exploration(
            self, exploration_id, owner_id, title='A title',
            category='A category', objective='An objective',
            language_code=feconf.DEFAULT_LANGUAGE_CODE,
            end_state_name=None):
        """Saves a new strictly-validated exploration.

        Returns the exploration domain object.
        """
        exploration = exp_domain.Exploration.create_default_exploration(
            exploration_id, title=title, category=category,
            language_code=language_code)
        exploration.states[exploration.init_state_name].update_interaction_id(
            'TextInput')
        exploration.objective = objective

        # If an end state name is provided, add terminal node with that name
        if end_state_name is not None:
            exploration.add_states([end_state_name])
            end_state = exploration.states[end_state_name]
            end_state.update_interaction_id('EndExploration')
            end_state.interaction.default_outcome = None

            # Link first state to ending state (to maintain validity)
            init_state = exploration.states[exploration.init_state_name]
            init_interaction = init_state.interaction
            init_interaction.default_outcome.dest = end_state_name

        exp_services.save_new_exploration(owner_id, exploration)
        return exploration
    def test_no_improvement_flag_hit(self):
        exp = exp_domain.Exploration.create_default_exploration(
            'eid', 'A title', 'A category')
        exp_services.save_new_exploration('*****@*****.**', exp)

        not_default_rule_spec = exp_domain.RuleSpec({
            'rule_type': rule_domain.ATOMIC_RULE_TYPE,
            'name': 'NotDefault',
            'inputs': {},
            'subject': 'answer'
        }, exp.init_state_name, [], [], 'NormalizedString')
        default_rule_spec = exp_domain.RuleSpec.get_default_rule_spec(feconf.END_DEST, 'NormalizedString') 
        exp.init_state.widget.handlers[0].rule_specs = [
            not_default_rule_spec, default_rule_spec
        ]
        exp_services._save_exploration('*****@*****.**', exp, '', [])

        stats_services.EventHandler.record_state_hit(
            'eid', exp.init_state_name, True)
        stats_services.EventHandler.record_answer_submitted(
            'eid', 1, exp.init_state_name, self.SUBMIT_HANDLER,
            not_default_rule_spec, '1')

        states = stats_services.get_top_improvable_states(['eid'], 1)
        self.assertEquals(len(states), 0)
    def test_get_user_stats(self):
        exp0 = exp_domain.Exploration.create_default_exploration(
            'eid0', 'title0', 'category')
        exp_services.save_new_exploration('uid0', exp0)
        exp1 = exp_domain.Exploration.create_default_exploration(
            'eid1', 'title1', 'category')
        exp_services.save_new_exploration('uid0', exp1)

        f0 = stats_domain.FeedbackItem.create_feedback_for_state(
            'eid0', 'welcome', 'my feedback', None, 'uid0')
        f1 = stats_domain.FeedbackItem.create_feedback_for_exploration(
            'eid1', 'another feedback', None, 'uid0')

        # This should return the both the feedback.
        self.assertEquals(stats_services.get_user_stats('uid0'), {'feedback': {
            f0.id: {
                'content': 'my feedback',
                'exp_id': 'eid0',
                'exp_title': 'title0',
                'state_name': 'welcome',
                'status': 'new',
                'target_id': 'state:eid0.welcome',
            },
            f1.id: {
                'content': 'another feedback',
                'exp_id': 'eid1',
                'exp_title': 'title1',
                'state_name': None,
                'status': 'new',
                'target_id': 'exploration:eid1',
            },
        }})
        # uid1 does not have any feedbacks.
        self.assertEquals(stats_services.get_user_stats('uid1'),
            {'feedback':{}})
Пример #14
0
    def test_deletion_rights_for_published_exploration(self):
        """Test rights management for deletion of published explorations."""
        PUBLISHED_EXP_ID = "published_eid"
        exploration = exp_domain.Exploration.create_default_exploration(PUBLISHED_EXP_ID, "A title", "A category")
        exp_services.save_new_exploration(self.owner_id, exploration)

        rights_manager.assign_role(self.owner_id, PUBLISHED_EXP_ID, self.editor_id, rights_manager.ROLE_EDITOR)
        rights_manager.publish_exploration(self.owner_id, PUBLISHED_EXP_ID)

        self.login(self.EDITOR_EMAIL)
        response = self.testapp.delete("/createhandler/data/%s" % PUBLISHED_EXP_ID, expect_errors=True)
        self.assertEqual(response.status_int, 401)
        self.logout()

        self.login(self.VIEWER_EMAIL)
        response = self.testapp.delete("/createhandler/data/%s" % PUBLISHED_EXP_ID, expect_errors=True)
        self.assertEqual(response.status_int, 401)
        self.logout()

        self.login(self.OWNER_EMAIL)
        response = self.testapp.delete("/createhandler/data/%s" % PUBLISHED_EXP_ID, expect_errors=True)
        self.assertEqual(response.status_int, 401)
        self.logout()

        self.login(self.ADMIN_EMAIL)
        response = self.testapp.delete("/createhandler/data/%s" % PUBLISHED_EXP_ID)
        self.assertEqual(response.status_int, 200)
        self.logout()
Пример #15
0
    def test_recording_answer_for_different_rules(self):
        exp = exp_domain.Exploration.create_default_exploration(
            'eid', 'title', 'category')
        exp_services.save_new_exploration('user_id', exp)

        rule = exp_domain.RuleSpec.from_dict_and_obj_type({
            'definition':  {
                 'rule_type': 'atomic',
                 'name': 'LessThan',
                 'subject': 'answer',
                 'inputs': {'x': 5}
             },
             'dest': 'dest',
             'feedback': None,
             'param_changes': []
        }, 'Real')

        state_name = exp.init_state_name

        event_services.AnswerSubmissionEventHandler.record(
            'eid', 1, state_name, self.SUBMIT_HANDLER, self.DEFAULT_RULESPEC,
            'answer1')
        event_services.AnswerSubmissionEventHandler.record(
            'eid', 1, state_name, self.SUBMIT_HANDLER, rule,
            'answer2')

        default_rule_answer_log = stats_domain.StateRuleAnswerLog.get(
            'eid', state_name, self.SUBMIT_HANDLER, self.DEFAULT_RULESPEC_STR)
        self.assertEquals(default_rule_answer_log.answers, {'answer1': 1})
        self.assertEquals(default_rule_answer_log.total_answer_count, 1)

        other_rule_answer_log = stats_domain.StateRuleAnswerLog.get(
            'eid', state_name, self.SUBMIT_HANDLER, str(rule))
        self.assertEquals(other_rule_answer_log.answers, {'answer2': 1})
        self.assertEquals(other_rule_answer_log.total_answer_count, 1)
Пример #16
0
    def test_resolving_answers(self):
        exp = exp_domain.Exploration.create_default_exploration(
            'eid', 'title', 'category')
        exp_services.save_new_exploration('user_id', exp)

        state_name = exp.init_state_name

        answer_log = stats_domain.StateRuleAnswerLog.get(
            'eid', state_name, self.DEFAULT_RULESPEC_STR)
        self.assertEquals(answer_log.answers, {})

        event_services.AnswerSubmissionEventHandler.record(
            'eid', 1, state_name, self.DEFAULT_RULESPEC_STR, 'answer1')
        event_services.AnswerSubmissionEventHandler.record(
            'eid', 1, state_name, self.DEFAULT_RULESPEC_STR, 'answer1')
        event_services.AnswerSubmissionEventHandler.record(
            'eid', 1, state_name, self.DEFAULT_RULESPEC_STR, 'answer2')

        answer_log = stats_domain.StateRuleAnswerLog.get(
            'eid', state_name, self.DEFAULT_RULESPEC_STR)
        self.assertEquals(answer_log.answers, {'answer1': 2, 'answer2': 1})
        self.assertEquals(answer_log.total_answer_count, 3)

        event_services.DefaultRuleAnswerResolutionEventHandler.record(
            'eid', state_name, ['answer1'])

        answer_log = stats_domain.StateRuleAnswerLog.get(
            'eid', state_name, self.DEFAULT_RULESPEC_STR)
        self.assertEquals(answer_log.answers, {'answer2': 1})
        self.assertEquals(answer_log.total_answer_count, 1)
Пример #17
0
    def test_deletion_rights_for_published_exploration(self):
        """Test rights management for deletion of published explorations."""
        published_exp_id = 'published_eid'
        exploration = exp_domain.Exploration.create_default_exploration(
            published_exp_id, 'A title', 'A category')
        exp_services.save_new_exploration(self.owner_id, exploration)

        rights_manager.assign_role_for_exploration(
            self.owner_id, published_exp_id, self.editor_id,
            rights_manager.ROLE_EDITOR)
        rights_manager.publish_exploration(self.owner_id, published_exp_id)

        self.login(self.EDITOR_EMAIL)
        response = self.testapp.delete(
            '/createhandler/data/%s' % published_exp_id, expect_errors=True)
        self.assertEqual(response.status_int, 401)
        self.logout()

        self.login(self.VIEWER_EMAIL)
        response = self.testapp.delete(
            '/createhandler/data/%s' % published_exp_id, expect_errors=True)
        self.assertEqual(response.status_int, 401)
        self.logout()

        self.login(self.OWNER_EMAIL)
        response = self.testapp.delete(
            '/createhandler/data/%s' % published_exp_id, expect_errors=True)
        self.assertEqual(response.status_int, 401)
        self.logout()

        self.login(self.ADMIN_EMAIL)
        response = self.testapp.delete(
            '/createhandler/data/%s' % published_exp_id)
        self.assertEqual(response.status_int, 200)
        self.logout()
Пример #18
0
    def setUp(self):
        """Create an exploration and register the event listener manually."""
        super(ContinuousComputationTests, self).setUp()

        exploration = exp_domain.Exploration.create_default_exploration(
            self.EXP_ID, 'title', 'A category')
        exp_services.save_new_exploration('owner_id', exploration)
Пример #19
0
    def test_request_new_state_template(self):
        """Test requesting a new state template when adding a new state."""
        # Register and log in as an admin.
        self.register_editor('*****@*****.**')
        self.login('*****@*****.**')

        EXP_ID = 'eid'
        exploration = exp_domain.Exploration.create_default_exploration(
            EXP_ID, 'A title', 'A category')
        exploration.states[exploration.init_state_name].widget.handlers[
            0].rule_specs[0].dest = feconf.END_DEST
        exp_services.save_new_exploration(
            self.get_current_logged_in_user_id(), exploration)

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

        # Add a new state called 'New valid state name'.
        response_dict = self.post_json(
            '/createhandler/new_state_template/%s' % EXP_ID, {
                'state_name': 'New valid state name'
            }, csrf_token)

        self.assertDictContainsSubset({
            'content': [{'type': 'text', 'value': ''}],
            'unresolved_answers': {}
        }, response_dict['new_state'])
        self.assertTrue('widget' in response_dict['new_state'])

        self.logout()
Пример #20
0
    def test_no_username_shown_for_nonregistered_users(self):
        NEW_EXP_ID = 'new_eid'
        exploration = exp_domain.Exploration.create_default_exploration(
            NEW_EXP_ID, 'A title', 'A category')
        exp_services.save_new_exploration(self.EDITOR_ID, exploration)
        rights_manager.publish_exploration(self.EDITOR_ID, NEW_EXP_ID)

        self.login('*****@*****.**')
        response = self.testapp.get('/create/%s' % NEW_EXP_ID)
        csrf_token = self.get_csrf_token_from_response(response)
        self.post_json(
            '%s/%s' % (feconf.FEEDBACK_THREADLIST_URL_PREFIX, NEW_EXP_ID),
            {
                'state_name': None,
                'subject': 'Test thread',
                'text': 'Test thread text',
            }, csrf_token)

        response_dict = self.get_json(
            '%s/%s' % (feconf.FEEDBACK_THREADLIST_URL_PREFIX, NEW_EXP_ID))
        threadlist = response_dict['threads']
        self.assertIsNone(threadlist[0]['original_author_username'])

        response_dict = self.get_json('%s/%s/%s' % (
            feconf.FEEDBACK_THREAD_URL_PREFIX, NEW_EXP_ID,
            threadlist[0]['thread_id']))
        self.assertIsNone(response_dict['messages'][0]['author_username'])

        self.logout()
Пример #21
0
    def test_get_state_improvements(self):
        exp = exp_domain.Exploration.create_default_exploration(
            'eid', 'A title', 'A category')
        exp_services.save_new_exploration('*****@*****.**', exp)

        for ind in range(5):
            event_services.StartExplorationEventHandler.record(
                'eid', 1, exp.init_state_name, 'session_id_%s' % ind,
                {}, feconf.PLAY_TYPE_NORMAL)
            event_services.StateHitEventHandler.record(
                'eid', 1, exp.init_state_name, 'session_id_%s' % ind,
                {}, feconf.PLAY_TYPE_NORMAL)
        event_services.AnswerSubmissionEventHandler.record(
            'eid', 1, exp.init_state_name, self.DEFAULT_RULESPEC_STR, '1')
        for _ in range(2):
            event_services.AnswerSubmissionEventHandler.record(
                'eid', 1, exp.init_state_name, self.DEFAULT_RULESPEC_STR, '2')
        ModifiedStatisticsAggregator.start_computation()
        self.process_and_flush_pending_tasks()
        with self.swap(stats_jobs.StatisticsAggregator, 'get_statistics',
                       ModifiedStatisticsAggregator.get_statistics):
            self.assertEquals(
                stats_services.get_state_improvements('eid', 1), [{
                    'type': 'default',
                    'rank': 3,
                    'state_name': exp.init_state_name
                }])
Пример #22
0
    def test_deletion_rights_for_published_exploration(self):
        """Test rights management for deletion of published explorations."""
        PUBLISHED_EXP_ID = 'published_eid'
        exploration = exp_domain.Exploration.create_default_exploration(
            PUBLISHED_EXP_ID, 'A title', 'A category')
        exp_services.save_new_exploration(self.owner_id, exploration)

        rights_manager.assign_role(
            self.owner_id, PUBLISHED_EXP_ID, self.editor_id,
            rights_manager.ROLE_EDITOR)
        rights_manager.publish_exploration(self.owner_id, PUBLISHED_EXP_ID)

        self.login(self.editor_email)
        response = self.testapp.delete(
            '/createhandler/data/%s' % PUBLISHED_EXP_ID, expect_errors=True)
        self.assertEqual(response.status_int, 401)
        self.logout()

        self.login(self.viewer_email)
        response = self.testapp.delete(
            '/createhandler/data/%s' % PUBLISHED_EXP_ID, expect_errors=True)
        self.assertEqual(response.status_int, 401)
        self.logout()

        self.login(self.owner_email)
        response = self.testapp.delete(
            '/createhandler/data/%s' % PUBLISHED_EXP_ID, expect_errors=True)
        self.assertEqual(response.status_int, 401)
        self.logout()

        self.login(self.admin_email)
        response = self.testapp.delete(
            '/createhandler/data/%s' % PUBLISHED_EXP_ID)
        self.assertEqual(response.status_int, 200)
        self.logout()
Пример #23
0
 def setUp(self):
     """Create an exploration so that there is something to count."""
     super(MapReduceJobIntegrationTests, self).setUp()
     exploration = exp_domain.Exploration.create_default_exploration(
         'exp_id')
     exp_services.save_new_exploration('owner_id', exploration)
     self.process_and_flush_pending_tasks()
Пример #24
0
    def test_newly_created_exploration(self):
        exp = exp_domain.Exploration.create_default_exploration(
            self.EXP_ID, 'A title', 'A category')
        exp_services.save_new_exploration(self.user_id_a, exp)

        self.assertTrue(
            rights_manager.Actor(self.user_id_a).can_view(self.EXP_ID))
        self.assertTrue(
            rights_manager.Actor(self.user_id_a).can_edit(self.EXP_ID))
        self.assertTrue(
            rights_manager.Actor(self.user_id_a).can_delete(self.EXP_ID))

        self.assertTrue(
            rights_manager.Actor(self.user_id_admin).can_view(self.EXP_ID))
        self.assertFalse(
            rights_manager.Actor(self.user_id_admin).can_edit(self.EXP_ID))
        self.assertFalse(
            rights_manager.Actor(self.user_id_admin).can_delete(self.EXP_ID))

        self.assertFalse(
            rights_manager.Actor(self.user_id_b).can_view(self.EXP_ID))
        self.assertFalse(
            rights_manager.Actor(self.user_id_b).can_edit(self.EXP_ID))
        self.assertFalse(
            rights_manager.Actor(self.user_id_b).can_delete(self.EXP_ID))
Пример #25
0
    def test_inviting_playtester(self):
        exp = exp_domain.Exploration.create_default_exploration(
            self.EXP_ID, 'A title', 'A category')
        exp_services.save_new_exploration(self.user_id_a, exp)

        self.assertFalse(
            rights_manager.Actor(self.user_id_b).can_play(self.EXP_ID))
        self.assertFalse(
            rights_manager.Actor(self.user_id_b).can_view(self.EXP_ID))
        self.assertFalse(
            rights_manager.Actor(self.user_id_b).can_edit(self.EXP_ID))
        self.assertFalse(
            rights_manager.Actor(self.user_id_b).can_delete(self.EXP_ID))

        rights_manager.assign_role(
            self.user_id_a, self.EXP_ID, self.user_id_b,
            rights_manager.ROLE_VIEWER)

        self.assertTrue(
            rights_manager.Actor(self.user_id_b).can_play(self.EXP_ID))
        self.assertTrue(
            rights_manager.Actor(self.user_id_b).can_view(self.EXP_ID))
        self.assertFalse(
            rights_manager.Actor(self.user_id_b).can_edit(self.EXP_ID))
        self.assertFalse(
            rights_manager.Actor(self.user_id_b).can_delete(self.EXP_ID))
Пример #26
0
    def test_resolving_answers(self):
        exp = exp_domain.Exploration.create_default_exploration(
            'eid', 'title', 'category')
        exp_services.save_new_exploration('user_id', exp)

        state_name = exp.init_state_name

        answer_log = stats_domain.StateRuleAnswerLog.get(
            'eid', state_name, self.SUBMIT_HANDLER, self.DEFAULT_RULESPEC_STR)
        self.assertEquals(answer_log.answers, {})

        stats_services.EventHandler.record_answer_submitted(
            'eid', state_name, self.SUBMIT_HANDLER,
            self.DEFAULT_RULESPEC_STR, 'answer1')
        stats_services.EventHandler.record_answer_submitted(
            'eid', state_name, self.SUBMIT_HANDLER,
            self.DEFAULT_RULESPEC_STR, 'answer1')
        stats_services.EventHandler.record_answer_submitted(
            'eid', state_name, self.SUBMIT_HANDLER,
            self.DEFAULT_RULESPEC_STR, 'answer2')

        answer_log = stats_domain.StateRuleAnswerLog.get(
            'eid', state_name, self.SUBMIT_HANDLER, self.DEFAULT_RULESPEC_STR)
        self.assertEquals(answer_log.answers, {'answer1': 2, 'answer2': 1})
        self.assertEquals(answer_log.total_answer_count, 3)

        stats_services.EventHandler.resolve_answers_for_default_rule(
            'eid', state_name, self.SUBMIT_HANDLER, ['answer1'])

        answer_log = stats_domain.StateRuleAnswerLog.get(
            'eid', state_name, self.SUBMIT_HANDLER, self.DEFAULT_RULESPEC_STR)
        self.assertEquals(answer_log.answers, {'answer2': 1})
        self.assertEquals(answer_log.total_answer_count, 1)
Пример #27
0
    def test_inviting_playtester_to_exploration(self):
        exp = exp_domain.Exploration.create_default_exploration(self.EXP_ID)
        exp_services.save_new_exploration(self.user_id_a, exp)

        self.assertFalse(
            rights_manager.Actor(self.user_id_b).can_play(
                rights_manager.ACTIVITY_TYPE_EXPLORATION, self.EXP_ID))
        self.assertFalse(
            rights_manager.Actor(self.user_id_b).can_view(
                rights_manager.ACTIVITY_TYPE_EXPLORATION, self.EXP_ID))
        self.assertFalse(
            rights_manager.Actor(self.user_id_b).can_edit(
                rights_manager.ACTIVITY_TYPE_EXPLORATION, self.EXP_ID))
        self.assertFalse(
            rights_manager.Actor(self.user_id_b).can_delete(
                rights_manager.ACTIVITY_TYPE_EXPLORATION, self.EXP_ID))

        rights_manager.assign_role_for_exploration(
            self.user_id_a, self.EXP_ID, self.user_id_b,
            rights_manager.ROLE_VIEWER)

        self.assertTrue(
            rights_manager.Actor(self.user_id_b).can_play(
                rights_manager.ACTIVITY_TYPE_EXPLORATION, self.EXP_ID))
        self.assertTrue(
            rights_manager.Actor(self.user_id_b).can_view(
                rights_manager.ACTIVITY_TYPE_EXPLORATION, self.EXP_ID))
        self.assertFalse(
            rights_manager.Actor(self.user_id_b).can_edit(
                rights_manager.ACTIVITY_TYPE_EXPLORATION, self.EXP_ID))
        self.assertFalse(
            rights_manager.Actor(self.user_id_b).can_delete(
                rights_manager.ACTIVITY_TYPE_EXPLORATION, self.EXP_ID))
Пример #28
0
    def test_setting_rights_of_exploration(self):
        exp = exp_domain.Exploration.create_default_exploration(self.EXP_ID)
        exp_services.save_new_exploration(self.user_id_a, exp)

        rights_manager.assign_role_for_exploration(
            self.user_id_a, self.EXP_ID, self.user_id_b,
            rights_manager.ROLE_VIEWER)

        with self.assertRaisesRegexp(Exception, 'Could not assign new role.'):
            rights_manager.assign_role_for_exploration(
                self.user_id_b, self.EXP_ID, self.user_id_c,
                rights_manager.ROLE_VIEWER)

        rights_manager.assign_role_for_exploration(
            self.user_id_a, self.EXP_ID, self.user_id_b,
            rights_manager.ROLE_EDITOR)

        with self.assertRaisesRegexp(Exception, 'Could not assign new role.'):
            rights_manager.assign_role_for_exploration(
                self.user_id_b, self.EXP_ID, self.user_id_c,
                rights_manager.ROLE_VIEWER)

        rights_manager.assign_role_for_exploration(
            self.user_id_a, self.EXP_ID, self.user_id_b,
            rights_manager.ROLE_OWNER)

        rights_manager.assign_role_for_exploration(
            self.user_id_b, self.EXP_ID, self.user_id_c,
            rights_manager.ROLE_OWNER)
        rights_manager.assign_role_for_exploration(
            self.user_id_b, self.EXP_ID, self.user_id_d,
            rights_manager.ROLE_EDITOR)
        rights_manager.assign_role_for_exploration(
            self.user_id_b, self.EXP_ID, self.user_id_e,
            rights_manager.ROLE_VIEWER)
Пример #29
0
    def test_changing_viewability_of_exploration(self):
        exp = exp_domain.Exploration.create_default_exploration(
            self.EXP_ID, title='A title', category='A category')
        exp_services.save_new_exploration(self.user_id_a, exp)

        self.assertFalse(
            rights_manager.Actor(self.user_id_b).can_view(
                rights_manager.ACTIVITY_TYPE_EXPLORATION, self.EXP_ID))

        self.assertTrue(rights_manager.Actor(
            self.user_id_a).can_change_private_viewability(
                rights_manager.ACTIVITY_TYPE_EXPLORATION, self.EXP_ID))
        self.assertFalse(rights_manager.Actor(
            self.user_id_b).can_change_private_viewability(
                rights_manager.ACTIVITY_TYPE_EXPLORATION, self.EXP_ID))
        self.assertTrue(rights_manager.Actor(
            self.user_id_admin).can_change_private_viewability(
                rights_manager.ACTIVITY_TYPE_EXPLORATION, self.EXP_ID))

        with self.assertRaisesRegexp(Exception, 'already the current value'):
            rights_manager.set_private_viewability_of_exploration(
                self.user_id_a, self.EXP_ID, False)
        with self.assertRaisesRegexp(Exception, 'cannot be changed'):
            rights_manager.set_private_viewability_of_exploration(
                self.user_id_b, self.EXP_ID, True)

        rights_manager.set_private_viewability_of_exploration(
            self.user_id_a, self.EXP_ID, True)
        self.assertTrue(
            rights_manager.Actor(self.user_id_a).can_view(
                rights_manager.ACTIVITY_TYPE_EXPLORATION, self.EXP_ID))
        self.assertTrue(
            rights_manager.Actor(self.user_id_b).can_view(
                rights_manager.ACTIVITY_TYPE_EXPLORATION, self.EXP_ID))

        rights_manager.set_private_viewability_of_exploration(
            self.user_id_a, self.EXP_ID, False)
        self.assertTrue(
            rights_manager.Actor(self.user_id_a).can_view(
                rights_manager.ACTIVITY_TYPE_EXPLORATION, self.EXP_ID))
        self.assertFalse(
            rights_manager.Actor(self.user_id_b).can_view(
                rights_manager.ACTIVITY_TYPE_EXPLORATION, self.EXP_ID))

        rights_manager.publish_exploration(self.user_id_a, self.EXP_ID)
        self.assertFalse(rights_manager.Actor(
            self.user_id_a).can_change_private_viewability(
                rights_manager.ACTIVITY_TYPE_EXPLORATION, self.EXP_ID))

        rights_manager.unpublish_exploration(self.user_id_admin, self.EXP_ID)
        self.assertTrue(rights_manager.Actor(
            self.user_id_a).can_change_private_viewability(
                rights_manager.ACTIVITY_TYPE_EXPLORATION, self.EXP_ID))
        self.assertFalse(rights_manager.Actor(
            self.user_id_b).can_change_private_viewability(
                rights_manager.ACTIVITY_TYPE_EXPLORATION, self.EXP_ID))
        self.assertTrue(rights_manager.Actor(
            self.user_id_admin).can_change_private_viewability(
                rights_manager.ACTIVITY_TYPE_EXPLORATION, self.EXP_ID))
Пример #30
0
    def reduce(exp_id, list_of_exps):
        from core.domain import exp_services
        from core.domain import rights_manager

        for stringified_exp in list_of_exps:
            exploration = exp_domain.Exploration.from_yaml(exp_id, "Copy", "Copies", stringified_exp)
            exp_services.save_new_exploration(feconf.SYSTEM_COMMITTER_ID, exploration)
            rights_manager.publish_exploration(feconf.SYSTEM_COMMITTER_ID, exp_id)
Пример #31
0
    def test_get_user_stats(self):
        exp0 = exp_domain.Exploration.create_default_exploration(
            'eid0', 'title0', 'category')
        exp_services.save_new_exploration('uid0', exp0)
        exp1 = exp_domain.Exploration.create_default_exploration(
            'eid1', 'title1', 'category')
        exp_services.save_new_exploration('uid0', exp1)

        f0 = stats_domain.FeedbackItem.create_feedback_for_state(
            'eid0', 'welcome', 'my feedback', None, 'uid0')
        f1 = stats_domain.FeedbackItem.create_feedback_for_exploration(
            'eid1', 'another feedback', None, 'uid0')

        # This should return the both the feedback.
        self.assertEquals(
            stats_services.get_user_stats('uid0'), {
                'feedback': {
                    f0.id: {
                        'content': 'my feedback',
                        'exp_id': 'eid0',
                        'exp_title': 'title0',
                        'state_name': 'welcome',
                        'status': 'new',
                        'target_id': 'state:eid0.welcome',
                    },
                    f1.id: {
                        'content': 'another feedback',
                        'exp_id': 'eid1',
                        'exp_title': 'title1',
                        'state_name': None,
                        'status': 'new',
                        'target_id': 'exploration:eid1',
                    },
                }
            })
        # uid1 does not have any feedbacks.
        self.assertEquals(stats_services.get_user_stats('uid1'),
                          {'feedback': {}})
Пример #32
0
    def test_publishing_and_unpublishing_exploration(self):
        exp = exp_domain.Exploration.create_default_exploration(
            self.EXP_ID, 'A title', 'A category')
        exp_services.save_new_exploration(self.user_id_a, exp)

        self.assertFalse(
            rights_manager.Actor(self.user_id_b).can_play(
                rights_manager.ACTIVITY_TYPE_EXPLORATION, self.EXP_ID))
        self.assertFalse(
            rights_manager.Actor(self.user_id_b).can_view(
                rights_manager.ACTIVITY_TYPE_EXPLORATION, self.EXP_ID))

        rights_manager.publish_exploration(self.user_id_a, self.EXP_ID)

        self.assertTrue(
            rights_manager.Actor(self.user_id_b).can_play(
                rights_manager.ACTIVITY_TYPE_EXPLORATION, self.EXP_ID))
        self.assertTrue(
            rights_manager.Actor(self.user_id_b).can_view(
                rights_manager.ACTIVITY_TYPE_EXPLORATION, self.EXP_ID))
        self.assertFalse(
            rights_manager.Actor(self.user_id_a).can_unpublish(
                rights_manager.ACTIVITY_TYPE_EXPLORATION, self.EXP_ID))

        rights_manager.unpublish_exploration(self.user_id_admin, self.EXP_ID)

        self.assertTrue(
            rights_manager.Actor(self.user_id_a).can_play(
                rights_manager.ACTIVITY_TYPE_EXPLORATION, self.EXP_ID))
        self.assertTrue(
            rights_manager.Actor(self.user_id_a).can_view(
                rights_manager.ACTIVITY_TYPE_EXPLORATION, self.EXP_ID))
        self.assertFalse(
            rights_manager.Actor(self.user_id_b).can_play(
                rights_manager.ACTIVITY_TYPE_EXPLORATION, self.EXP_ID))
        self.assertFalse(
            rights_manager.Actor(self.user_id_b).can_view(
                rights_manager.ACTIVITY_TYPE_EXPLORATION, self.EXP_ID))
Пример #33
0
    def test_newly_created_exploration(self):
        exp = exp_domain.Exploration.create_default_exploration(self.EXP_ID)
        exp_services.save_new_exploration(self.user_id_a, exp)
        exp_rights = rights_manager.get_exploration_rights(self.EXP_ID)

        self.assertTrue(
            rights_manager.check_can_access_activity(self.user_a, exp_rights))
        self.assertTrue(
            rights_manager.check_can_edit_activity(self.user_a, exp_rights))
        self.assertTrue(
            rights_manager.check_can_delete_activity(self.user_a, exp_rights))

        self.assertTrue(
            rights_manager.check_can_access_activity(self.user_admin,
                                                     exp_rights))
        self.assertTrue(
            rights_manager.check_can_edit_activity(self.user_admin,
                                                   exp_rights))
        self.assertTrue(
            rights_manager.check_can_delete_activity(self.user_admin,
                                                     exp_rights))

        self.assertTrue(
            rights_manager.check_can_access_activity(self.user_moderator,
                                                     exp_rights))
        self.assertFalse(
            rights_manager.check_can_edit_activity(self.user_moderator,
                                                   exp_rights))
        self.assertFalse(
            rights_manager.check_can_delete_activity(self.user_moderator,
                                                     exp_rights))

        self.assertFalse(
            rights_manager.check_can_access_activity(self.user_b, exp_rights))
        self.assertFalse(
            rights_manager.check_can_edit_activity(self.user_b, exp_rights))
        self.assertFalse(
            rights_manager.check_can_delete_activity(self.user_b, exp_rights))
Пример #34
0
    def setUp(self):
        super(OpportunityServicesIntegrationTest, self).setUp()
        self.signup(self.ADMIN_EMAIL, self.ADMIN_USERNAME)
        self.signup(self.OWNER_EMAIL, self.OWNER_USERNAME)

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

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

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

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

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

        story = story_domain.Story.create_default_story(
            self.STORY_ID,
            title='A story',
            corresponding_topic_id=self.TOPIC_ID)
        story_services.save_new_story(self.owner_id, story)
        topic_services.add_canonical_story(self.owner_id, self.TOPIC_ID,
                                           self.STORY_ID)
Пример #35
0
    def test_migration_job_detects_invalid_exploration(self):
        exploration = exp_domain.Exploration.create_default_exploration(
            self.VALID_EXP_ID, title='title', category='category')
        exp_services.save_new_exploration(self.albert_id, exploration)

        exploration_model = exp_models.ExplorationModel.get(self.VALID_EXP_ID)
        exploration_model.language_code = 'invalid_language_code'
        exploration_model.commit(self.albert_id, 'Changed language_code.', [])
        caching_services.delete_multi(
            caching_services.CACHE_NAMESPACE_EXPLORATION, None,
            [self.VALID_EXP_ID])

        job_id = exp_jobs_one_off.ExpSnapshotsMigrationJob.create_new()
        exp_jobs_one_off.ExpSnapshotsMigrationJob.enqueue(job_id)
        self.process_and_flush_pending_mapreduce_tasks()

        actual_output = (
            exp_jobs_one_off.ExpSnapshotsMigrationJob.get_output(job_id))
        expected_output_message = (
            '[u\'INFO - Exploration %s-1 failed non-strict validation\', '
            '[u\'Invalid language_code: invalid_language_code\']]' %
            self.VALID_EXP_ID)
        self.assertIn(expected_output_message, actual_output)
Пример #36
0
    def test_time_of_ratings_recorded(self):
        """Check that the time a rating is given is recorded correctly."""

        time_allowed_for_computation = datetime.timedelta(seconds=10)

        exp_services.save_new_exploration(
            self.EXP_ID,
            exp_domain.Exploration.create_default_exploration(self.EXP_ID))

        rating_services.assign_rating_to_exploration(
            self.USER_ID_1, self.EXP_ID, 1)
        first_rating_time = rating_services.get_when_exploration_rated(
            self.USER_ID_1, self.EXP_ID)
        rating_services.assign_rating_to_exploration(
            self.USER_ID_1, self.EXP_ID, 3)
        second_rating_time = rating_services.get_when_exploration_rated(
            self.USER_ID_1, self.EXP_ID)

        self.assertLess(
            datetime.datetime.utcnow(),
            first_rating_time + time_allowed_for_computation)
        self.assertLess(first_rating_time, second_rating_time)
        self.assertLess(second_rating_time, datetime.datetime.utcnow())
Пример #37
0
    def test_get_state_improvements(self):
        exp = exp_domain.Exploration.create_default_exploration(
            'eid', 'A title', 'A category')
        exp_services.save_new_exploration('*****@*****.**', exp)

        for _ in range(5):
            event_services.StateHitEventHandler.record('eid',
                                                       exp.init_state_name,
                                                       True)

        event_services.AnswerSubmissionEventHandler.record(
            'eid', 1, exp.init_state_name, self.SUBMIT_HANDLER,
            self.DEFAULT_RULESPEC, '1')
        for _ in range(2):
            event_services.AnswerSubmissionEventHandler.record(
                'eid', 1, exp.init_state_name, self.SUBMIT_HANDLER,
                self.DEFAULT_RULESPEC, '2')
        self.assertEquals(stats_services.get_state_improvements('eid'),
                          [{
                              'type': 'default',
                              'rank': 3,
                              'state_name': exp.init_state_name
                          }])
Пример #38
0
    def test_inviting_playtester_to_exploration(self):
        exp = exp_domain.Exploration.create_default_exploration(self.EXP_ID)
        exp_services.save_new_exploration(self.user_id_a, exp)
        exp_rights = rights_manager.get_exploration_rights(self.EXP_ID)

        self.assertFalse(rights_manager.check_can_access_activity(
            self.user_b, exp_rights))
        self.assertFalse(rights_manager.check_can_edit_activity(
            self.user_b, exp_rights))
        self.assertFalse(rights_manager.check_can_delete_activity(
            self.user_b, exp_rights))

        rights_manager.assign_role_for_exploration(
            self.user_a, self.EXP_ID, self.user_id_b,
            rights_manager.ROLE_VIEWER)
        exp_rights = rights_manager.get_exploration_rights(self.EXP_ID)

        self.assertTrue(rights_manager.check_can_access_activity(
            self.user_b, exp_rights))
        self.assertFalse(rights_manager.check_can_edit_activity(
            self.user_b, exp_rights))
        self.assertFalse(rights_manager.check_can_delete_activity(
            self.user_b, exp_rights))
Пример #39
0
    def test_single_default_rule_hit(self):
        exp = exp_domain.Exploration.create_default_exploration(
            'eid', 'A title', 'A category')
        exp_services.save_new_exploration('*****@*****.**', exp)
        state_name = exp.init_state_name

        event_services.StartExplorationEventHandler.record(
            'eid', 1, state_name, 'session_id', {}, feconf.PLAY_TYPE_NORMAL)
        event_services.StateHitEventHandler.record(
            'eid', 1, state_name, 'session_id', {},
            feconf.PLAY_TYPE_NORMAL)
        event_services.AnswerSubmissionEventHandler.record(
            'eid', 1, state_name, self.DEFAULT_RULESPEC_STR, '1')
        ModifiedStatisticsAggregator.start_computation()
        self.process_and_flush_pending_tasks()

        with self._get_swap_context():
            self.assertEquals(
                stats_services.get_state_improvements('eid', 1), [{
                    'type': 'default',
                    'rank': 1,
                    'state_name': exp.init_state_name
                }])
Пример #40
0
    def post(self):
        """Handles POST requests."""
        title = self.payload.get('title')
        category = self.payload.get('category')
        objective = self.payload.get('objective')
        language_code = self.payload.get('language_code')

        if not title:
            raise self.InvalidInputException('No title supplied.')
        if not category:
            raise self.InvalidInputException('No category chosen.')
        if not language_code:
            raise self.InvalidInputException('No language chosen.')

        new_exploration_id = exp_services.get_new_exploration_id()
        exploration = exp_domain.Exploration.create_default_exploration(
            new_exploration_id, title, category,
            objective=objective, language_code=language_code)
        exp_services.save_new_exploration(self.user_id, exploration)

        self.render_json({
            EXPLORATION_ID_KEY: new_exploration_id
        })
Пример #41
0
    def test_recording_answer_for_different_rules(self):
        exp = exp_domain.Exploration.create_default_exploration(
            'eid', 'title', 'category')
        exp_services.save_new_exploration('user_id', exp)

        rule = exp_domain.RuleSpec.from_dict_and_obj_type(
            {
                'definition': {
                    'rule_type': 'atomic',
                    'name': 'LessThan',
                    'subject': 'answer',
                    'inputs': {
                        'x': 5
                    }
                },
                'dest': 'dest',
                'feedback': None,
                'param_changes': []
            }, 'Real')

        state_name = exp.init_state_name

        event_services.AnswerSubmissionEventHandler.record(
            'eid', 1, state_name, self.SUBMIT_HANDLER, self.DEFAULT_RULESPEC,
            'answer1')
        event_services.AnswerSubmissionEventHandler.record(
            'eid', 1, state_name, self.SUBMIT_HANDLER, rule, 'answer2')

        default_rule_answer_log = stats_domain.StateRuleAnswerLog.get(
            'eid', state_name, self.SUBMIT_HANDLER, self.DEFAULT_RULESPEC_STR)
        self.assertEquals(default_rule_answer_log.answers, {'answer1': 1})
        self.assertEquals(default_rule_answer_log.total_answer_count, 1)

        other_rule_answer_log = stats_domain.StateRuleAnswerLog.get(
            'eid', state_name, self.SUBMIT_HANDLER, str(rule))
        self.assertEquals(other_rule_answer_log.answers, {'answer2': 1})
        self.assertEquals(other_rule_answer_log.total_answer_count, 1)
Пример #42
0
    def test_incomplete_and_default_flags(self):
        exp = exp_domain.Exploration.create_default_exploration(
            'eid', 'A title', 'A category')
        exp_services.save_new_exploration('*****@*****.**', exp)

        state_name = exp.init_state_name

        # Hit the default rule once, and fail to answer twice. The result
        # should be classified as incomplete.

        for _ in range(3):
            stats_services.EventHandler.record_state_hit(
                'eid', state_name, True)

        stats_services.EventHandler.record_answer_submitted(
            'eid', 1, state_name, self.SUBMIT_HANDLER, self.DEFAULT_RULESPEC,
            '1')

        states = stats_services.get_top_improvable_states(['eid'], 2)
        self.assertEquals(len(states), 1)
        self.assertEquals(states[0]['rank'], 2)
        self.assertEquals(states[0]['type'], 'incomplete')

        # Now hit the default two more times. The result should be classified
        # as default.

        for i in range(2):
            stats_services.EventHandler.record_state_hit(
                'eid', state_name, True)
            stats_services.EventHandler.record_answer_submitted(
                'eid', 1, state_name, self.SUBMIT_HANDLER,
                self.DEFAULT_RULESPEC, '1')

        states = stats_services.get_top_improvable_states(['eid'], 2)
        self.assertEquals(len(states), 1)
        self.assertEquals(states[0]['rank'], 3)
        self.assertEquals(states[0]['type'], 'default')
Пример #43
0
    def test_deletion_rights_for_published_exploration(self):
        """Test rights management for deletion of published explorations."""
        PUBLISHED_EXP_ID = 'published_eid'
        exploration = exp_domain.Exploration.create_default_exploration(
            PUBLISHED_EXP_ID, 'A title', 'A category')
        exp_services.save_new_exploration(self.owner_id, exploration)

        rights_manager.assign_role(self.owner_id, PUBLISHED_EXP_ID,
                                   self.editor_id, rights_manager.ROLE_EDITOR)
        rights_manager.publish_exploration(self.owner_id, PUBLISHED_EXP_ID)

        self.login(self.EDITOR_EMAIL)
        response = self.testapp.delete('/createhandler/data/%s' %
                                       PUBLISHED_EXP_ID,
                                       expect_errors=True)
        self.assertEqual(response.status_int, 401)
        self.logout()

        self.login(self.VIEWER_EMAIL)
        response = self.testapp.delete('/createhandler/data/%s' %
                                       PUBLISHED_EXP_ID,
                                       expect_errors=True)
        self.assertEqual(response.status_int, 401)
        self.logout()

        self.login(self.OWNER_EMAIL)
        response = self.testapp.delete('/createhandler/data/%s' %
                                       PUBLISHED_EXP_ID,
                                       expect_errors=True)
        self.assertEqual(response.status_int, 401)
        self.logout()

        self.login(self.ADMIN_EMAIL)
        response = self.testapp.delete('/createhandler/data/%s' %
                                       PUBLISHED_EXP_ID)
        self.assertEqual(response.status_int, 200)
        self.logout()
Пример #44
0
    def test_rating_assignations_do_not_conflict(self):
        """Check that ratings of different explorations are independant."""

        EXP_ID_A = 'exp_id_A'
        EXP_ID_B = 'exp_id_B'

        self.exploration = exp_domain.Exploration.create_default_exploration(
            EXP_ID_A, 'A title', 'A category')
        exp_services.save_new_exploration(EXP_ID_A, self.exploration)
        self.exploration = exp_domain.Exploration.create_default_exploration(
            EXP_ID_B, 'A title', 'A category')
        exp_services.save_new_exploration(EXP_ID_B, self.exploration)

        rating_services.assign_rating(self.USER_ID_1, EXP_ID_A, 1)
        rating_services.assign_rating(self.USER_ID_1, EXP_ID_B, 3)
        rating_services.assign_rating(self.USER_ID_2, EXP_ID_A, 2)
        rating_services.assign_rating(self.USER_ID_2, EXP_ID_B, 5)

        self.assertEqual(
            rating_services.get_user_specific_rating(
                self.USER_ID_1, EXP_ID_A), 1)
        self.assertEqual(
            rating_services.get_user_specific_rating(
                self.USER_ID_1, EXP_ID_B), 3)
        self.assertEqual(
            rating_services.get_user_specific_rating(
                self.USER_ID_2, EXP_ID_A), 2)
        self.assertEqual(
            rating_services.get_user_specific_rating(
                self.USER_ID_2, EXP_ID_B), 5)

        self.assertEqual(
            rating_services.get_overall_ratings(EXP_ID_A),
            {'1': 1, '2': 1, '3': 0, '4': 0, '5': 0})
        self.assertEqual(
            rating_services.get_overall_ratings(EXP_ID_B),
            {'1': 0, '2': 0, '3': 1, '4': 0, '5': 1})
Пример #45
0
    def test_migration_job_skips_deleted_explorations(self):
        """Tests that the exploration migration job skips deleted explorations
        and does not attempt to migrate.
        """
        swap_states_schema_41 = self.swap(feconf,
                                          'CURRENT_STATE_SCHEMA_VERSION', 41)
        swap_exp_schema_46 = self.swap(exp_domain.Exploration,
                                       'CURRENT_EXP_SCHEMA_VERSION', 46)
        with swap_states_schema_41, swap_exp_schema_46:
            exploration = exp_domain.Exploration.create_default_exploration(
                self.NEW_EXP_ID, title=self.EXP_TITLE)
            exp_services.save_new_exploration(self.albert_id, exploration)

        # Note: This creates a summary based on the upgraded model (which is
        # fine). A summary is needed to delete the exploration.
        exp_services.regenerate_exploration_and_contributors_summaries(
            self.NEW_EXP_ID)

        # Delete the exploration before migration occurs.
        exp_services.delete_exploration(self.albert_id, self.NEW_EXP_ID)

        # Ensure the exploration is deleted.
        with self.assertRaisesRegexp(Exception, 'Entity .* not found'):
            exp_fetchers.get_exploration_by_id(self.NEW_EXP_ID)

        # Start migration job on sample exploration.
        job_id = exp_jobs_one_off.ExplorationMigrationJobManager.create_new()
        exp_jobs_one_off.ExplorationMigrationJobManager.enqueue(job_id)

        # This running without errors indicates the deleted exploration is
        # being ignored, since otherwise exp_fetchers.get_exploration_by_id
        # (used within the job) will raise an error.
        self.process_and_flush_pending_mapreduce_tasks()

        # Ensure the exploration is still deleted.
        with self.assertRaisesRegexp(Exception, 'Entity .* not found'):
            exp_fetchers.get_exploration_by_id(self.NEW_EXP_ID)
Пример #46
0
    def test_no_action_is_performed_for_deleted_exploration(self):
        """Test that no action is performed on deleted explorations."""

        exploration = exp_domain.Exploration.create_default_exploration(
            self.VALID_EXP_ID, title='title', category='category')

        exploration.add_states(['State1'])

        state1 = exploration.states['State1']

        state1.update_interaction_id('ItemSelectionInput')

        customization_args_dict = {
            'minAllowableSelectionCount': {
                'value': '1b'
            },
            'maxAllowableSelectionCount': {
                'value': 1
            },
            'choices': {
                'value': [{
                    'html': '<p>This is value1 for ItemSelection</p>',
                    'content_id': 'ca_choices_0'
                }]
            },
        }

        state1.update_interaction_customization_args(customization_args_dict)

        exp_services.save_new_exploration(self.albert_id, exploration)

        exp_services.delete_exploration(self.albert_id, self.VALID_EXP_ID)

        run_job_for_deleted_exp(
            self, interaction_jobs_one_off.
            InteractionCustomizationArgsValidationOneOffJob)
Пример #47
0
    def test_setting_rights_of_exploration(self):
        exp = exp_domain.Exploration.create_default_exploration(
            self.EXP_ID, 'A title', 'A category')
        exp_services.save_new_exploration(self.user_id_a, exp)

        rights_manager.assign_role_for_exploration(
            self.user_id_a, self.EXP_ID, self.user_id_b,
            rights_manager.ROLE_VIEWER)

        with self.assertRaisesRegexp(Exception, 'Could not assign new role.'):
            rights_manager.assign_role_for_exploration(
                self.user_id_b, self.EXP_ID, self.user_id_c,
                rights_manager.ROLE_VIEWER)

        rights_manager.assign_role_for_exploration(
            self.user_id_a, self.EXP_ID, self.user_id_b,
            rights_manager.ROLE_EDITOR)

        with self.assertRaisesRegexp(Exception, 'Could not assign new role.'):
            rights_manager.assign_role_for_exploration(
                self.user_id_b, self.EXP_ID, self.user_id_c,
                rights_manager.ROLE_VIEWER)

        rights_manager.assign_role_for_exploration(
            self.user_id_a, self.EXP_ID, self.user_id_b,
            rights_manager.ROLE_OWNER)

        rights_manager.assign_role_for_exploration(
            self.user_id_b, self.EXP_ID, self.user_id_c,
            rights_manager.ROLE_OWNER)
        rights_manager.assign_role_for_exploration(
            self.user_id_b, self.EXP_ID, self.user_id_d,
            rights_manager.ROLE_EDITOR)
        rights_manager.assign_role_for_exploration(
            self.user_id_b, self.EXP_ID, self.user_id_e,
            rights_manager.ROLE_VIEWER)
Пример #48
0
    def test_exploration_migration_job_output(self):
        """Test that Exploration Migration job output is correct."""
        exploration = exp_domain.Exploration.create_default_exploration(
            self.VALID_EXP_ID, title='title', category='category')
        exp_services.save_new_exploration(self.albert_id, exploration)

        swap_states_schema_41 = self.swap(feconf,
                                          'CURRENT_STATE_SCHEMA_VERSION', 41)
        swap_exp_schema_46 = self.swap(exp_domain.Exploration,
                                       'CURRENT_EXP_SCHEMA_VERSION', 46)
        with swap_states_schema_41, swap_exp_schema_46:
            exploration = exp_domain.Exploration.create_default_exploration(
                self.NEW_EXP_ID, title=self.EXP_TITLE)
            exp_services.save_new_exploration(self.albert_id, exploration)

        # Start migration job on sample exploration.
        job_id = exp_jobs_one_off.ExplorationMigrationJobManager.create_new()
        exp_jobs_one_off.ExplorationMigrationJobManager.enqueue(job_id)
        self.process_and_flush_pending_mapreduce_tasks()

        actual_output = (
            exp_jobs_one_off.ExplorationMigrationJobManager.get_output(job_id))
        expected_output = ['[u\'SUCCESS\', 1]']
        self.assertEqual(actual_output, expected_output)
Пример #49
0
    def test_publishing_and_unpublishing_exploration(self):
        exp = exp_domain.Exploration.create_default_exploration(
            self.EXP_ID, title='A title', category='A category')
        exp_services.save_new_exploration(self.user_id_a, exp)
        exp_rights = rights_manager.get_exploration_rights(self.EXP_ID)

        self.assertFalse(rights_manager.check_can_access_activity(
            self.user_b, exp_rights))

        rights_manager.publish_exploration(self.user_a, self.EXP_ID)
        exp_rights = rights_manager.get_exploration_rights(self.EXP_ID)

        self.assertTrue(rights_manager.check_can_access_activity(
            self.user_b, exp_rights))
        self.assertFalse(rights_manager.check_can_unpublish_activity(
            self.user_a, exp_rights))

        rights_manager.unpublish_exploration(self.user_admin, self.EXP_ID)
        exp_rights = rights_manager.get_exploration_rights(self.EXP_ID)

        self.assertTrue(rights_manager.check_can_access_activity(
            self.user_a, exp_rights))
        self.assertFalse(rights_manager.check_can_access_activity(
            self.user_b, exp_rights))
Пример #50
0
    def test_stop_computation_with_finished_jobs(self):
        self.login(self.ADMIN_EMAIL, is_super_admin=True)

        exploration = exp_domain.Exploration.create_default_exploration(
            'exp_id')
        exp_services.save_new_exploration('owner_id', exploration)

        self.assertEqual(
            jobs_test.StartExplorationEventCounter.get_count('exp_id'), 0)

        jobs_test.StartExplorationEventCounter.start_computation()

        self.process_and_flush_pending_tasks()
        status = jobs_test.StartExplorationEventCounter.get_status_code()

        self.assertEqual(
            status, job_models.CONTINUOUS_COMPUTATION_STATUS_CODE_RUNNING)

        with self.swap(
            jobs_registry, 'ALL_CONTINUOUS_COMPUTATION_MANAGERS',
            [jobs_test.StartExplorationEventCounter]):

            self.get_json('/adminhandler')
            csrf_token = self.get_new_csrf_token()

            self.post_json(
                '/adminhandler', {
                    'action': 'stop_computation',
                    'computation_type': 'StartExplorationEventCounter'
                }, csrf_token=csrf_token)

        status = jobs_test.StartExplorationEventCounter.get_status_code()
        self.assertEqual(
            status, job_models.CONTINUOUS_COMPUTATION_STATUS_CODE_IDLE)

        self.logout()
Пример #51
0
    def save_new_valid_exploration(self,
                                   exploration_id,
                                   owner_id,
                                   title='A title',
                                   category='A category',
                                   objective='An objective',
                                   language_code=feconf.DEFAULT_LANGUAGE_CODE,
                                   end_state_name=None,
                                   interaction_id='TextInput'):
        """Saves a new strictly-validated exploration.

        Returns the exploration domain object.
        """
        exploration = exp_domain.Exploration.create_default_exploration(
            exploration_id,
            title=title,
            category=category,
            language_code=language_code)
        exploration.states[exploration.init_state_name].update_interaction_id(
            interaction_id)
        exploration.objective = objective

        # If an end state name is provided, add terminal node with that name
        if end_state_name is not None:
            exploration.add_states([end_state_name])
            end_state = exploration.states[end_state_name]
            end_state.update_interaction_id('EndExploration')
            end_state.interaction.default_outcome = None

            # Link first state to ending state (to maintain validity)
            init_state = exploration.states[exploration.init_state_name]
            init_interaction = init_state.interaction
            init_interaction.default_outcome.dest = end_state_name

        exp_services.save_new_exploration(owner_id, exploration)
        return exploration
    def test_fixes_invalid_unicode_translations(self):
        exp_id = 'EXP_ID'
        exploration = exp_domain.Exploration.create_default_exploration(
            exp_id, title='title', category='category', language_code='bn')
        self.set_interaction_for_state(
            exploration.states[exploration.init_state_name], 'Continue')
        exp_services.save_new_exploration(self.albert_id, exploration)
        add_translation_change_dict = {
            'cmd': exp_domain.CMD_ADD_WRITTEN_TRANSLATION,
            'state_name': 'Introduction',
            'content_id': 'ca_buttonText_0',
            'language_code': 'bn',
            'content_html': 'Continue',
            'translation_html': '<p>চালিয়ে যান</p>',
            'data_format': 'html'
        }

        invalid_suggestion = suggestion_services.create_suggestion(
            feconf.SUGGESTION_TYPE_TRANSLATE_CONTENT,
            feconf.ENTITY_TYPE_EXPLORATION, exp_id, exploration.version,
            self.albert_id, add_translation_change_dict, 'test description')
        self.assertEqual(invalid_suggestion.change.data_format, 'html')
        self.assertEqual(invalid_suggestion.change.translation_html,
                         '<p>চালিয়ে যান</p>')

        expected_output = [
            u'[u\'UPDATED\', [u\'%s | ca_buttonText_0\']]' %
            invalid_suggestion.suggestion_id, u'[u\'PROCESSED\', 1]'
        ]
        self._run_job_and_verify_output(expected_output)

        valid_suggestion = suggestion_services.get_suggestion_by_id(
            invalid_suggestion.suggestion_id)
        self.assertEqual(valid_suggestion.change.data_format, 'unicode')
        self.assertEqual(valid_suggestion.change.translation_html,
                         'চালিয়ে যান')
Пример #53
0
    def test_for_customization_arg_validation_job(self):
        """Check that expected errors are produced for invalid
        customization args.
        """

        exploration = exp_domain.Exploration.create_default_exploration(
            self.VALID_EXP_ID, title='title', category='category')

        exploration.add_states(['State1', 'State2'])

        state1 = exploration.states['State1']
        state2 = exploration.states['State2']

        state1.update_interaction_id('ItemSelectionInput')

        customization_args_dict1 = {
            'minAllowableSelectionCount': {'value': 1},
            'maxAllowableSelectionCount': {'value': 1},
            'choices': {'value': [{
                'html': '<p>This is value1 for ItemSelection</p>',
                'content_id': 'ca_choices_0'
            }]},
        }

        state1.update_interaction_customization_args(customization_args_dict1)
        exp_services.save_new_exploration(self.albert_id, exploration)

        # Start ItemSelectionInteractionOneOff job on sample exploration.
        job_id = (
            interaction_jobs_one_off
            .InteractionCustomizationArgsValidationOneOffJob.create_new())
        (
            interaction_jobs_one_off
            .InteractionCustomizationArgsValidationOneOffJob.enqueue(job_id))
        self.process_and_flush_pending_mapreduce_tasks()

        actual_output = (
            interaction_jobs_one_off
            .InteractionCustomizationArgsValidationOneOffJob.get_output(job_id))
        self.assertEqual(actual_output, [])

        customization_args_dict2 = {
            'minAllowableSelectionCount': {'value': '1bθ'},
            'maxAllowableSelectionCount': {'value': 1},
            'choices': {'value': [{
                'html': '<p>This is value1 for ItemSelection</p>',
                'content_id': 'ca_choices_0'
            }]},
        }
        state2.update_interaction_id('ItemSelectionInput')
        state2.update_interaction_customization_args(customization_args_dict2)

        exp_services.save_new_exploration(self.albert_id, exploration)

        # Start ItemSelectionInteractionOneOff job on sample exploration.
        job_id = (
            interaction_jobs_one_off
            .InteractionCustomizationArgsValidationOneOffJob.create_new())
        (
            interaction_jobs_one_off
            .InteractionCustomizationArgsValidationOneOffJob.enqueue(job_id))
        self.process_and_flush_pending_mapreduce_tasks()

        actual_output = (
            interaction_jobs_one_off
            .InteractionCustomizationArgsValidationOneOffJob.get_output(job_id))
        expected_output = [(
            u'[u\'Failed customization args validation for exp id exp_id0\', '
            '[u\'ItemSelectionInput: Could not convert unicode to int: '
            '1b\\u03b8\']]')]
        self.assertEqual(actual_output, expected_output)
Пример #54
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 = [exp_domain.Exploration.create_default_exploration(
            '%s' % i,
            title='title %d' % i,
            category='category%d' % i,
        ) for i in python_utils.RANGE(2)]

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

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

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

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

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

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

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

        self.expected_opportunity_dict_2 = {
            'id': '1',
            'topic_name': 'topic',
            'story_title': 'title 1',
            'chapter_title': 'Node1',
            'content_count': 2,
            'translation_counts': {}
        }
Пример #55
0
    def test_exp_state_pairs_are_produced_for_item_selection_interactions(self):
        """Checks (exp, state) pairs are produced correctly for ItemSelection
        interactions.
        """
        owner = user_services.get_user_actions_info(self.albert_id)
        exploration = exp_domain.Exploration.create_default_exploration(
            self.VALID_EXP_ID, title='title', category='category')

        exploration.add_states(['State1', 'State2'])

        state1 = exploration.states['State1']
        state2 = exploration.states['State2']

        customization_args_dict1 = {
            'choices': {'value': [{
                'html': '<p>This is value1 for ItemSelection</p>',
                'content_id': 'ca_choices_0'
            }, {
                'html': '<p>This is value2 for ItemSelection</p>',
                'content_id': 'ca_choices_1'
            }]},
            'minAllowableSelectionCount': {'value': 0},
            'maxAllowableSelectionCount': {'value': 1}
        }

        state_answer_group_list1 = [state_domain.AnswerGroup(
            state_domain.Outcome(
                'Introduction', state_domain.SubtitledHtml(
                    'feedback', '<p>Outcome for state1</p>'),
                False, [], None, None),
            [
                state_domain.RuleSpec(
                    'Equals',
                    {
                        'x': ['<p>This is value1 for ItemSelection</p>']
                    }),
                state_domain.RuleSpec(
                    'Equals',
                    {
                        'x': ['<p>This is value2 for ItemSelection</p>']
                    })
            ],
            [],
            None
        )]

        solution1 = state_domain.Solution.from_dict('ItemSelectionInput', {
            'answer_is_exclusive': True,
            'correct_answer': ['<p>This is value2 for DragAndDropSort</p>'],
            'explanation': {
                'content_id': 'solution',
                'html': ''
            }
        })

        hint_list1 = [state_domain.Hint.from_dict({
            'hint_content': {
                'content_id': 'hint_0',
                'html': ''
            }
        })]

        state1.update_interaction_id('ItemSelectionInput')
        state1.update_interaction_customization_args(customization_args_dict1)
        state1.update_next_content_id_index(2)
        state1.update_interaction_answer_groups(state_answer_group_list1)
        exp_services.save_new_exploration(self.albert_id, exploration)
        state1.update_interaction_solution(solution1)
        state1.update_interaction_hints(hint_list1)

        # Start RuleInputToCustomizationArgsMappingOneOffJob job on sample
        # exploration.
        job_id = (
            interaction_jobs_one_off
            .RuleInputToCustomizationArgsMappingOneOffJob.create_new())
        (
            interaction_jobs_one_off
            .RuleInputToCustomizationArgsMappingOneOffJob.enqueue(job_id))
        self.process_and_flush_pending_mapreduce_tasks()

        actual_output = (
            interaction_jobs_one_off
            .RuleInputToCustomizationArgsMappingOneOffJob.get_output(job_id))
        self.assertEqual(actual_output, [])

        customization_args_dict2 = {
            'choices': {'value': [{
                'html': '<p>This is value1 for ItemSelection</p>',
                'content_id': 'ca_choices_0'
            }, {
                'html': '<p>This is value2 for ItemSelection</p>',
                'content_id': 'ca_choices_1'
            }]},
            'minAllowableSelectionCount': {'value': 0},
            'maxAllowableSelectionCount': {'value': 1}
        }

        state_answer_group_list2 = [state_domain.AnswerGroup(
            state_domain.Outcome(
                'State1', state_domain.SubtitledHtml(
                    'feedback', '<p>Outcome for state2</p>'),
                False, [], None, None),
            [
                state_domain.RuleSpec(
                    'Equals',
                    {
                        'x': ['<p>This is value1 for ItemSelection</p>']
                    }),
                state_domain.RuleSpec(
                    'Equals',
                    {
                        'x': ['<p>This is value3 for ItemSelection</p>']
                    })
            ],
            [],
            None
        )]

        solution2 = state_domain.Solution.from_dict('ItemSelectionInput', {
            'answer_is_exclusive': True,
            'correct_answer': ['<p>This is value3 for DragAndDropSort</p>'],
            'explanation': {
                'content_id': 'solution',
                'html': ''
            }
        })

        hint_list2 = [state_domain.Hint.from_dict({
            'hint_content': {
                'content_id': 'hint_0',
                'html': ''
            }
        })]

        state2.update_interaction_id('ItemSelectionInput')
        state2.update_interaction_customization_args(customization_args_dict2)
        state2.update_next_content_id_index(2)
        state2.update_interaction_answer_groups(state_answer_group_list2)
        state2.update_interaction_solution(solution2)
        state2.update_interaction_hints(hint_list2)

        exp_services.save_new_exploration(self.albert_id, exploration)
        rights_manager.publish_exploration(owner, self.VALID_EXP_ID)

        # Start ItemSelectionInteractionOneOff job on sample exploration.
        job_id = (
            interaction_jobs_one_off
            .RuleInputToCustomizationArgsMappingOneOffJob.create_new())
        (
            interaction_jobs_one_off
            .RuleInputToCustomizationArgsMappingOneOffJob.enqueue(job_id))
        self.process_and_flush_pending_mapreduce_tasks()

        actual_output = (
            interaction_jobs_one_off
            .RuleInputToCustomizationArgsMappingOneOffJob.get_output(job_id))
        expected_output = [(
            u'[u\'exp_id0\', [u"<ItemSelectionInput Answer> State: State2, '
            'Invalid Values: [\'<p>This is value3 for DragAndDropSort</p>\']"'
            ', u"<ItemSelectionInput Rule> State: State2, '
            'Answer Group Index: 0, Invalid Values: [u\'<p>This is value3 '
            'for ItemSelection</p>\']", u"<ItemSelectionInput Answer> State: '
            'State1, Invalid Values: [\'<p>This is value2 for '
            'DragAndDropSort</p>\']"]]'
        )]

        self.assertEqual(actual_output, expected_output)
 def _create_exploration(self, exp_id, user_id):
     exploration = exp_domain.Exploration.create_default_exploration(
         exp_id, 'A title', 'A category')
     exp_services.save_new_exploration(user_id, exploration)
     return exploration
Пример #57
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)
Пример #58
0
    def setUp(self):
        super(ExplorationOpportunitySummaryModelRegenerationJobTest,
              self).setUp()
        self.signup(self.OWNER_EMAIL, self.OWNER_USERNAME)

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

        self.topic_id_1 = 'topic1'
        self.topic_id_2 = 'topic2'

        story_id_1 = 'story1'
        story_id_2 = 'story2'

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

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

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

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

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

        story_services.save_new_story(self.owner_id, story_1)
        story_services.save_new_story(self.owner_id, story_2)
        topic_services.add_canonical_story(self.owner_id, self.topic_id_1,
                                           story_id_1)
        topic_services.add_canonical_story(self.owner_id, self.topic_id_2,
                                           story_id_2)
        story_services.update_story(self.owner_id, story_id_1, [
            story_domain.StoryChange({
                'cmd': 'add_story_node',
                'node_id': 'node_1',
                'title': 'Node1',
            }),
            story_domain.StoryChange({
                'cmd': 'update_story_node_property',
                'property_name': 'exploration_id',
                'node_id': 'node_1',
                'old_value': None,
                'new_value': '0'
            })
        ], 'Changes.')
        story_services.update_story(self.owner_id, story_id_2, [
            story_domain.StoryChange({
                'cmd': 'add_story_node',
                'node_id': 'node_1',
                'title': 'Node1',
            }),
            story_domain.StoryChange({
                'cmd': 'update_story_node_property',
                'property_name': 'exploration_id',
                'node_id': 'node_1',
                'old_value': None,
                'new_value': '1'
            })
        ], 'Changes.')
Пример #59
0
    def test_for_validation_job(self):
        """Tests that the exploration validation job validates the content
        without skipping any tags.
        """
        exploration = exp_domain.Exploration.create_default_exploration(
            self.VALID_EXP_ID, title='title', category='category')
        exploration.add_states(['State1', 'State2'])
        state1 = exploration.states['State1']
        state2 = exploration.states['State2']
        content1_dict = {
            'html': '''<blockquote><div><p>Hello, this <i>is</i> state1
                </p> </div> </blockquote> <pre>I'm looking for a particular
                <b>Hello Oppia</b> message</pre>. <p> Don't you want to
                say hello? You can learn more about oppia
                <oppia-noninteractive-link url-with-value="&amp;quot;
                https://www.example.com&amp;quot;" text-with-value="&amp;quot;
                here&amp;quot;"></oppia-noninteractive-link></p>''',
            'audio_translations': {}
        }
        content2_dict = {
            'html': '''<pre>Hello, this is state2.</pre> <blockquote>
                <ol> <li>item1</li> <li>item2</li> </ol> </blockquote>.<p>
                You can see this equation <b> <oppia-noninteractive-math
                raw_latex-with-value="&amp;quot;\\frac{x}{y}&amp;
                quot;"></oppia-noninteractive-math></b></p>
                ''',
            'audio_translations': {}
        }
        state1.update_content(content1_dict)
        state2.update_content(content2_dict)
        exp_services.save_new_exploration(self.albert_id, exploration)

        # Start validation job on sample exploration.
        job_id = exp_jobs_one_off.ExplorationContentValidationJob.create_new()
        exp_jobs_one_off.ExplorationContentValidationJob.enqueue(job_id)
        self.process_and_flush_pending_tasks()

        actual_output = (exp_jobs_one_off.ExplorationContentValidationJob.
                         get_output(job_id))
        expected_output = [u"[u'Errors', [u'{}']]"]

        self.assertEqual(actual_output, expected_output)

        default_outcome_dict = {
            'dest': 'State2',
            'feedback': {
                'html': '''<p>Sorry, it doesn't look like your <span>program
                </span>prints any output</p>.<p> <blockquote> Could you get
                it to print something?</blockquote> You can do this by using a
                statement like print</p>. <br> You can ask any doubt if you have
                <oppia-noninteractive-link url-with-value="&amp;quot;
                https://www.example.com&amp;quot;" text-with-value="
                &amp;quot;Here&amp;quot;"></oppia-noninteractive-link>.
                ''',
                'audio_translations': {}
            },
            'labelled_as_correct': False,
            'param_changes': [],
            'refresher_exploration_id': None
        }

        state1.update_interaction_default_outcome(default_outcome_dict)
        exp_services.save_new_exploration(self.albert_id, exploration)

        job_id = exp_jobs_one_off.ExplorationContentValidationJob.create_new()
        exp_jobs_one_off.ExplorationContentValidationJob.enqueue(job_id)
        self.process_and_flush_pending_tasks()

        actual_output = (exp_jobs_one_off.ExplorationContentValidationJob.
                         get_output(job_id))
        expected_output = [u'[u\'Errors\', [u"{\'invalidTags\': [u\'span\'], u\'oppia-noninteractive-link\': [u\'[document]\'], u\'br\': [u\'[document]\']}"]]']  # pylint: disable=line-too-long

        self.assertEqual(actual_output, expected_output)
Пример #60
0
    def test_rating_assignation(self):
        """Check ratings are correctly assigned to an exploration."""

        exp_services.save_new_exploration(
            self.EXP_ID,
            exp_domain.Exploration.create_default_exploration(self.EXP_ID))

        self.assertEqual(
            rating_services.get_overall_ratings_for_exploration(self.EXP_ID), {
                '1': 0,
                '2': 0,
                '3': 0,
                '4': 0,
                '5': 0
            })

        exp_summary = exp_fetchers.get_exploration_summary_by_id(self.EXP_ID)
        self.assertEqual(exp_summary.scaled_average_rating, 0)

        self.assertEqual(
            rating_services.get_user_specific_rating_for_exploration(
                self.USER_ID_1, self.EXP_ID), None)

        rating_services.assign_rating_to_exploration(self.USER_ID_1,
                                                     self.EXP_ID, 2)
        rating_services.assign_rating_to_exploration(self.USER_ID_2,
                                                     self.EXP_ID, 4)
        rating_services.assign_rating_to_exploration(self.USER_ID_1,
                                                     self.EXP_ID, 3)

        exp_summary = exp_fetchers.get_exploration_summary_by_id(self.EXP_ID)
        self.assertAlmostEqual(exp_summary.scaled_average_rating,
                               1.5667471839848,
                               places=4)

        self.assertEqual(
            rating_services.get_user_specific_rating_for_exploration(
                self.USER_ID_1, self.EXP_ID), 3)
        self.assertEqual(
            rating_services.get_user_specific_rating_for_exploration(
                self.USER_ID_2, self.EXP_ID), 4)
        self.assertEqual(
            rating_services.get_overall_ratings_for_exploration(self.EXP_ID), {
                '1': 0,
                '2': 0,
                '3': 1,
                '4': 1,
                '5': 0
            })

        rating_services.assign_rating_to_exploration(self.USER_ID_1,
                                                     self.EXP_ID, 4)

        self.assertEqual(
            rating_services.get_overall_ratings_for_exploration(self.EXP_ID), {
                '1': 0,
                '2': 0,
                '3': 0,
                '4': 2,
                '5': 0
            })