Exemple #1
0
    def test_put_for_task_entries_which_do_not_exist_creates_new_models(self):
        open_task = self._new_open_task(state_name='Start')
        obsolete_task = self._new_obsolete_task(state_name='Middle')
        resolved_task = self._new_resolved_task(state_name='End')

        improvements_services.put_tasks(
            [open_task, obsolete_task, resolved_task])

        open_task_model = (improvements_models.TaskEntryModel.get_by_id(
            open_task.task_id))
        obsolete_task_model = (improvements_models.TaskEntryModel.get_by_id(
            obsolete_task.task_id))
        resolved_task_model = (improvements_models.TaskEntryModel.get_by_id(
            resolved_task.task_id))

        self.assertEqual(
            open_task.to_dict(),
            improvements_services.get_task_entry_from_model(
                open_task_model).to_dict())
        self.assertEqual(
            obsolete_task.to_dict(),
            improvements_services.get_task_entry_from_model(
                obsolete_task_model).to_dict())
        self.assertEqual(
            resolved_task.to_dict(),
            improvements_services.get_task_entry_from_model(
                resolved_task_model).to_dict())
Exemple #2
0
 def post(self, exploration_id):
     task_entries = self.payload.get('task_entries', None)
     if task_entries is None:
         raise self.InvalidInputException('No task_entries provided')
     task_entries_to_put = []
     for task_entry in task_entries:
         entity_version = task_entry.get('entity_version', None)
         if entity_version is None:
             raise self.InvalidInputException('No entity_version provided')
         task_type = task_entry.get('task_type', None)
         if task_type is None:
             raise self.InvalidInputException('No task_type provided')
         target_id = task_entry.get('target_id', None)
         if target_id is None:
             raise self.InvalidInputException('No target_id provided')
         status = task_entry.get('status', None)
         if status is None:
             raise self.InvalidInputException('No status provided')
         # The issue_description is allowed to be None.
         issue_description = task_entry.get('issue_description', None)
         task_entries_to_put.append(
             improvements_domain.TaskEntry(
                 improvements_models.TASK_ENTITY_TYPE_EXPLORATION,
                 exploration_id,
                 entity_version,
                 task_type,
                 improvements_models.TASK_TARGET_TYPE_STATE,
                 target_id,
                 issue_description,
                 status,
                 self.user_id,
                 datetime.datetime.utcnow()))
     improvements_services.put_tasks(task_entries_to_put)
     self.render_json({})
Exemple #3
0
    def test_put_for_updated_task_entries_without_changing_last_updated(self):
        task_entry = self._new_open_task()
        created_on = datetime.datetime(2020, 6, 15, 5)
        updated_on = created_on + datetime.timedelta(minutes=5)

        with self.mock_datetime_utcnow(created_on):
            improvements_services.put_tasks([task_entry])

        model = improvements_models.TaskEntryModel.get_by_id(
            task_entry.task_id)
        self.assertEqual(model.resolver_id, None)
        self.assertEqual(model.created_on, created_on)
        self.assertEqual(model.last_updated, created_on)

        task_entry = self._new_resolved_task()

        with self.mock_datetime_utcnow(updated_on):
            improvements_services.put_tasks([task_entry],
                                            update_last_updated_time=False)

        model = improvements_models.TaskEntryModel.get_by_id(
            task_entry.task_id)
        self.assertEqual(model.resolver_id, self.owner_id)
        self.assertEqual(model.created_on, created_on)
        self.assertEqual(model.last_updated, created_on)
Exemple #4
0
    def test_fetch_identifies_the_resolved_tasks_of_each_state(self):
        tasks = [
            self._new_resolved_task(
                state_name='A',
                task_type=improvements_models.TASK_TYPE_HIGH_BOUNCE_RATE),
            self._new_resolved_task(
                state_name='B',
                task_type=improvements_models.TASK_TYPE_HIGH_BOUNCE_RATE),
            self._new_resolved_task(
                state_name='B',
                task_type=(
                    improvements_models.TASK_TYPE_NEEDS_GUIDING_RESPONSES)),
            self._new_resolved_task(
                state_name='C',
                task_type=(
                    improvements_models.TASK_TYPE_INEFFECTIVE_FEEDBACK_LOOP)),
            self._new_resolved_task(
                state_name='D',
                task_type=improvements_models.TASK_TYPE_HIGH_BOUNCE_RATE),
            self._new_resolved_task(
                state_name='D',
                task_type=(
                    improvements_models.TASK_TYPE_NEEDS_GUIDING_RESPONSES)),
            self._new_resolved_task(
                state_name='D',
                task_type=(
                    improvements_models.TASK_TYPE_INEFFECTIVE_FEEDBACK_LOOP)),
            self._new_resolved_task(
                state_name='D',
                task_type=(improvements_models.
                           TASK_TYPE_SUCCESSIVE_INCORRECT_ANSWERS))
        ]
        improvements_services.put_tasks(tasks)
        open_tasks, resolved_task_types_by_state_name = (
            improvements_services.fetch_exploration_tasks(self.exp))

        self.assertEqual(open_tasks, [])
        self.assertItemsEqual(list(resolved_task_types_by_state_name.keys()), [
            'A',
            'B',
            'C',
            'D',
        ])
        self.assertItemsEqual(resolved_task_types_by_state_name['A'],
                              ['high_bounce_rate'])
        self.assertItemsEqual(resolved_task_types_by_state_name['B'], [
            'high_bounce_rate',
            'needs_guiding_responses',
        ])
        self.assertItemsEqual(resolved_task_types_by_state_name['C'], [
            'ineffective_feedback_loop',
        ])
        self.assertItemsEqual(resolved_task_types_by_state_name['D'], [
            'high_bounce_rate',
            'needs_guiding_responses',
            'ineffective_feedback_loop',
            'successive_incorrect_answers',
        ])
Exemple #5
0
    def test_returns_false_when_task_is_equalivalent_to_model(self):
        task_entry = self._new_open_task()
        improvements_services.put_tasks([task_entry])
        task_entry_model = (improvements_models.TaskEntryModel.get_by_id(
            task_entry.task_id))

        self.assertFalse(
            improvements_services.apply_changes_to_model(
                task_entry, task_entry_model))
Exemple #6
0
    def test_passing_mismatching_task_entries_raises_an_exception(self):
        task_entry = self._new_open_task()
        improvements_services.put_tasks([task_entry])
        task_entry_model = (improvements_models.TaskEntryModel.get_by_id(
            task_entry.task_id))
        task_entry.target_id = 'Different State'

        with self.assertRaisesRegex(Exception, 'Wrong model provided'):
            improvements_services.apply_changes_to_model(
                task_entry, task_entry_model)
Exemple #7
0
    def test_get_returns_open_tasks(self):
        task_entries = [
            self._new_open_task(state_name=name) for name in ['A', 'B', 'C']]
        improvements_services.put_tasks(task_entries)

        with self.login_context(self.OWNER_EMAIL):
            self.assertEqual(self.get_json(self.get_url()), {
                'open_tasks': [t.to_dict() for t in task_entries],
                'resolved_task_types_by_state_name': {},
            })
Exemple #8
0
    def test_fetch_ignores_obsolete_tasks(self):
        tasks = [
            self._new_obsolete_task(state_name='State %d' % (i, ))
            for i in range(50)
        ]
        improvements_services.put_tasks(tasks)
        open_tasks, resolved_task_types_by_state_name = (
            improvements_services.fetch_exploration_tasks(self.exp))

        self.assertEqual(open_tasks, [])
        self.assertEqual(resolved_task_types_by_state_name, {})
Exemple #9
0
    def test_fetch_when_number_of_open_tasks_exceed_single_fetch_limit(self):
        tasks = [
            self._new_open_task(state_name='State %d' % (i, ))
            for i in range(int(feconf.MAX_TASK_MODELS_PER_FETCH * 2.5))
        ]
        improvements_services.put_tasks(tasks)
        open_tasks, resolved_task_types_by_state_name = (
            improvements_services.fetch_exploration_tasks(self.exp))

        self.assertEqual(resolved_task_types_by_state_name, {})
        self.assertItemsEqual([t.to_dict() for t in tasks],
                              [t.to_dict() for t in open_tasks])
Exemple #10
0
    def test_makes_changes_when_issue_description_is_different(self):
        task_entry = self._new_open_task()
        improvements_services.put_tasks([task_entry])
        task_entry_model = (improvements_models.TaskEntryModel.get_by_id(
            task_entry.task_id))
        task_entry.issue_description = 'new issue description'

        self.assertTrue(
            improvements_services.apply_changes_to_model(
                task_entry, task_entry_model))
        self.assertEqual(task_entry_model.issue_description,
                         'new issue description')
Exemple #11
0
    def setUp(self) -> None:
        super(FetchExplorationTaskHistoryPageTests, self).setUp()
        task_entries = []
        for i in range(1, 26):
            task_entry = self._new_resolved_task(state_name='State %d' % (i, ),
                                                 exploration_version=i)
            task_entry.resolved_on = (self.MOCK_DATE +
                                      datetime.timedelta(minutes=5 * i))

            task_entries.append(task_entry)
        improvements_services.put_tasks(task_entries,
                                        update_last_updated_time=False)
    def test_no_changes_made_if_only_resolved_on_is_different(self):
        task_entry = self._new_open_task()
        improvements_services.put_tasks([task_entry])
        task_entry_model = (improvements_models.TaskEntryModel.get_by_id(
            task_entry.task_id))
        task_entry.resolved_on = self.owner_id

        self.assertFalse(
            improvements_services.apply_changes_to_model(
                task_entry, task_entry_model))
        self.assertEqual(task_entry_model.status, constants.TASK_STATUS_OPEN)
        self.assertIsNone(task_entry_model.resolved_on)
        self.assertIsNone(task_entry_model.resolved_on)
Exemple #13
0
 def setUp(self):
     super(FetchExplorationTaskHistoryPageTests, self).setUp()
     task_entries = []
     for i in range(1, 26):
         task_entry = self._new_resolved_task(state_name='State %d' % (i, ),
                                              exploration_version=i)
         task_entry.resolved_on = (self.MOCK_DATE +
                                   datetime.timedelta(minutes=5 * i))
         # last_updated of tasks are descending to ensure that the tasks
         # returned are ordered by resolved_on instead.
         task_entry.last_updated = (self.MOCK_DATE -
                                    datetime.timedelta(minutes=5 * i))
         task_entries.append(task_entry)
     improvements_services.put_tasks(task_entries,
                                     update_last_updated_time=False)
Exemple #14
0
    def test_makes_changes_to_status_related_fields_if_status_is_different(
            self):
        task_entry = self._new_open_task()
        improvements_services.put_tasks([task_entry])
        task_entry_model = (improvements_models.TaskEntryModel.get_by_id(
            task_entry.task_id))
        task_entry = self._new_resolved_task()

        self.assertTrue(
            improvements_services.apply_changes_to_model(
                task_entry, task_entry_model))
        self.assertEqual(task_entry_model.status,
                         improvements_models.TASK_STATUS_RESOLVED)
        self.assertEqual(task_entry_model.resolver_id, self.owner_id)
        self.assertEqual(task_entry_model.resolved_on, self.MOCK_DATE)
Exemple #15
0
 def test_get_with_cursor_as_none_returns_first_page(self):
     task_entries = [
         self._new_resolved_task(
             state_name='State %d' % i,
             resolved_on=self.MOCK_DATE + datetime.timedelta(minutes=i * 5))
         for i in python_utils.RANGE(1, 26)]
     improvements_services.put_tasks(task_entries)
     with self.login_context(self.OWNER_EMAIL):
         json_response = self.get_json(self.get_url(cursor=None))
     self.assertEqual(
         [t['target_id'] for t in json_response['results']], [
             'State 25', 'State 24', 'State 23', 'State 22', 'State 21',
             'State 20', 'State 19', 'State 18', 'State 17', 'State 16',
         ])
     self.assertIsNotNone(json_response['cursor'])
     self.assertTrue(json_response['more'])
Exemple #16
0
    def test_get_returns_resolved_tasks(self):
        task_entries = [
            self._new_resolved_task(
                state_name=name,
                task_type=improvements_models.TASK_TYPE_HIGH_BOUNCE_RATE)
            for name in ['A', 'B', 'C']]
        improvements_services.put_tasks(task_entries)

        with self.login_context(self.OWNER_EMAIL):
            self.assertEqual(self.get_json(self.get_url()), {
                'open_tasks': [],
                'resolved_task_types_by_state_name': {
                    'A': ['high_bounce_rate'],
                    'B': ['high_bounce_rate'],
                    'C': ['high_bounce_rate'],
                },
            })
Exemple #17
0
    def test_get_can_build_full_task_list_after_enough_fetches(self):
        task_entries = [
            self._new_resolved_task(state_name='State %d' % i,
                                    resolved_on=self.MOCK_DATE +
                                    datetime.timedelta(minutes=i * 5))
            for i in range(1, 26)
        ]
        improvements_services.put_tasks(task_entries)

        with self.login_context(self.OWNER_EMAIL):
            all_results, cursor, more = [], None, True
            while more:
                json_response = self.get_json(self.get_url(cursor=cursor))
                all_results.extend(json_response['results'])
                cursor = json_response['cursor']
                more = json_response['more']
        self.assertEqual([t['target_id'] for t in all_results], [
            'State 25',
            'State 24',
            'State 23',
            'State 22',
            'State 21',
            'State 20',
            'State 19',
            'State 18',
            'State 17',
            'State 16',
            'State 15',
            'State 14',
            'State 13',
            'State 12',
            'State 11',
            'State 10',
            'State 9',
            'State 8',
            'State 7',
            'State 6',
            'State 5',
            'State 4',
            'State 3',
            'State 2',
            'State 1',
        ])
Exemple #18
0
 def post(self, exploration_id):
     task_entries = self.normalized_payload.get('task_entries')
     task_entries_to_put = []
     for task_entry in task_entries:
         entity_version = task_entry['entity_version']
         task_type = task_entry['task_type']
         target_id = task_entry['target_id']
         status = task_entry['status']
         # The issue_description is allowed to be None.
         issue_description = task_entry.get('issue_description', None)
         task_entries_to_put.append(
             improvements_domain.TaskEntry(
                 constants.TASK_ENTITY_TYPE_EXPLORATION, exploration_id,
                 entity_version, task_type,
                 constants.TASK_TARGET_TYPE_STATE, target_id,
                 issue_description, status, self.user_id,
                 datetime.datetime.utcnow()))
     improvements_services.put_tasks(task_entries_to_put)
     self.render_json({})
Exemple #19
0
    def test_fetch_only_returns_tasks_for_the_given_exploration_version(self):
        tasks = [
            # Version 1 tasks.
            self._new_open_task(
                state_name='A',
                task_type=improvements_models.TASK_TYPE_HIGH_BOUNCE_RATE,
                exploration_version=1),
            self._new_open_task(
                state_name='B',
                task_type=improvements_models.TASK_TYPE_HIGH_BOUNCE_RATE,
                exploration_version=1),
            self._new_open_task(
                state_name='C',
                task_type=improvements_models.TASK_TYPE_NEEDS_GUIDING_RESPONSES,
                exploration_version=1),
            # Version 2 tasks.
            self._new_open_task(
                state_name='A',
                task_type=improvements_models.TASK_TYPE_HIGH_BOUNCE_RATE,
                exploration_version=2),
            self._new_resolved_task(
                state_name='B',
                task_type=improvements_models.TASK_TYPE_HIGH_BOUNCE_RATE,
                exploration_version=2),
            self._new_resolved_task(
                state_name='C',
                task_type=improvements_models.TASK_TYPE_NEEDS_GUIDING_RESPONSES,
                exploration_version=2),
        ]
        improvements_services.put_tasks(tasks)

        self.exp.version = 2
        open_tasks, resolved_task_types_by_state_name = (
            improvements_services.fetch_exploration_tasks(self.exp))

        self.assertItemsEqual(
            [t.to_dict() for t in open_tasks], [tasks[3].to_dict()])
        self.assertEqual(
            resolved_task_types_by_state_name, {
                'B': ['high_bounce_rate'],
                'C': ['needs_guiding_responses'],
            })
Exemple #20
0
    def test_put_for_task_entries_that_are_not_changing_does_nothing(
            self) -> None:
        task_entry = self._new_resolved_task()
        created_on = datetime.datetime(2020, 6, 15, 5)
        updated_on = created_on + datetime.timedelta(minutes=5)

        with self.mock_datetime_utcnow(created_on):
            improvements_services.put_tasks([task_entry])

        model = improvements_models.TaskEntryModel.get_by_id(
            task_entry.task_id)
        self.assertEqual(model.resolver_id, self.owner_id)
        self.assertEqual(model.created_on, created_on)
        self.assertEqual(model.last_updated, created_on)

        with self.mock_datetime_utcnow(updated_on):
            improvements_services.put_tasks([task_entry])

        model = improvements_models.TaskEntryModel.get_by_id(
            task_entry.task_id)
        self.assertEqual(model.resolver_id, self.owner_id)
        self.assertEqual(model.created_on, created_on)
        self.assertEqual(model.last_updated, created_on)