def _test_reverted_task(self, task, iteration, num_iterations, task_status, latest_data, expected_audit, revert_before=False): response = self._revert_task( task, iteration, revert_before=revert_before, commit=False) self.assertEqual(response.status_code, 200) task.refresh_from_db() fake_audit = load_encoded_json(response.content) self.assertEqual(fake_audit, expected_audit) self.assertEqual(task.status, Task.Status.COMPLETE) self.assertEqual(task.assignments.count(), 2) for assignment in task.assignments.all(): self.assertEqual(assignment.iterations.count(), 2) response = self._revert_task( task, iteration, revert_before=revert_before, commit=True) self.assertEqual(response.status_code, 200) task.refresh_from_db() audit = load_encoded_json(response.content) self.assertEqual(audit, fake_audit) task.refresh_from_db() self.assertEqual(task.status, task_status) self.assertEqual( get_iteration_history(task).count(), num_iterations) verify_iterations(task.id) if num_iterations: self.assertEqual( current_assignment(task).in_progress_task_data, latest_data) verify_iterations(task.id)
def _test_reverted_task(self, task, iteration, num_iterations, task_status, latest_data, expected_audit, revert_before=False): response = self._revert_task( task, iteration, revert_before=revert_before, commit=False) self.assertEquals(response.status_code, 200) task.refresh_from_db() fake_audit = load_encoded_json(response.content) self.assertEqual(fake_audit, expected_audit) self.assertEquals(task.status, Task.Status.COMPLETE) self.assertEquals(task.assignments.count(), 2) for assignment in task.assignments.all(): self.assertEquals(assignment.iterations.count(), 2) response = self._revert_task( task, iteration, revert_before=revert_before, commit=True) self.assertEqual(response.status_code, 200) task.refresh_from_db() audit = load_encoded_json(response.content) self.assertEqual(audit, fake_audit) task.refresh_from_db() self.assertEqual(task.status, task_status) self.assertEqual( get_iteration_history(task).count(), num_iterations) verify_iterations(task.id) if num_iterations: self.assertEquals( current_assignment(task).in_progress_task_data, latest_data) verify_iterations(task.id)
def snapshots_to_iterations(apps, schema_editor): Iteration = apps.get_model('orchestra', 'Iteration') Task = apps.get_model('orchestra', 'Task') TaskAssignment = apps.get_model('orchestra', 'TaskAssignment') for task in Task.objects.all(): task_snapshots = get_ordered_snapshots(task) for task_snap_index, snapshot in enumerate(task_snapshots): assignment = snapshot['assignment'] iteration = Iteration.objects.create( assignment=assignment, end_datetime=parse(snapshot['datetime']), submitted_data=snapshot['data'], status=snapshot_type_to_iteration_status[snapshot['type']]) if snapshot['assignment_snap_index'] == 0: # Snapshot is the first for its assignment, so its start # datetime will be the same as its assignment # NOTE: This should cover the case where task_snap_index == 0 iteration.start_datetime = assignment.start_datetime else: iteration.start_datetime = (task_snapshots[task_snap_index - 1]['datetime']) iteration.save() processing_assignments = task.assignments.filter( status=AssignmentStatus.PROCESSING) if processing_assignments.exists(): if processing_assignments.count() > 1: logger.error( 'Task {} has too many processing assignments'.format( task.id)) else: # If task has a processing assignment, create a final # processing iteration processing_assignment = processing_assignments.first() if (not task_snapshots or not processing_assignment.iterations.exists()): final_start_datetime = processing_assignment.start_datetime else: final_start_datetime = task_snapshots[-1]['datetime'] iteration = Iteration.objects.create( assignment=processing_assignment, start_datetime=final_start_datetime, status=IterationStatus.PROCESSING) try: verify_iterations(task.id) except AssertionError: logger.error('Iterations invalid for task {}.'.format(task.id))
def snapshots_to_iterations(apps, schema_editor): Iteration = apps.get_model('orchestra', 'Iteration') Task = apps.get_model('orchestra', 'Task') TaskAssignment = apps.get_model('orchestra', 'TaskAssignment') for task in Task.objects.all(): task_snapshots = get_ordered_snapshots(task) for task_snap_index, snapshot in enumerate(task_snapshots): assignment = snapshot['assignment'] iteration = Iteration.objects.create( assignment=assignment, end_datetime=parse(snapshot['datetime']), submitted_data=snapshot['data'], status=snapshot_type_to_iteration_status[snapshot['type']]) if snapshot['assignment_snap_index'] == 0: # Snapshot is the first for its assignment, so its start # datetime will be the same as its assignment # NOTE: This should cover the case where task_snap_index == 0 iteration.start_datetime = assignment.start_datetime else: iteration.start_datetime = ( task_snapshots[task_snap_index - 1]['datetime']) iteration.save() processing_assignments = task.assignments.filter( status=AssignmentStatus.PROCESSING) if processing_assignments.exists(): if processing_assignments.count() > 1: logger.error( 'Task {} has too many processing assignments'.format( task.id)) else: # If task has a processing assignment, create a final # processing iteration processing_assignment = processing_assignments.first() if (not task_snapshots or not processing_assignment.iterations.exists()): final_start_datetime = processing_assignment.start_datetime else: final_start_datetime = task_snapshots[-1]['datetime'] iteration = Iteration.objects.create( assignment=processing_assignment, start_datetime=final_start_datetime, status=IterationStatus.PROCESSING) try: verify_iterations(task.id) except AssertionError: logger.error('Iterations invalid for task {}.'.format(task.id))
def setup_complete_task(test_case): # Microseconds are truncated when manually saving models test_start = timezone.now().replace(microsecond=0) times = { 'awaiting_pickup': test_start, 'entry_pickup': test_start + timedelta(hours=1), 'entry_submit': test_start + timedelta(hours=2), 'reviewer_pickup': test_start + timedelta(hours=3), 'reviewer_reject': test_start + timedelta(hours=4), 'entry_resubmit': test_start + timedelta(hours=5), 'reviewer_accept': test_start + timedelta(hours=6), } task = TaskFactory( project=test_case.projects['empty_project'], status=Task.Status.AWAITING_PROCESSING, step=test_case.test_step, start_datetime=times['awaiting_pickup']) workers = { 'entry': test_case.workers[0], 'reviewer': test_case.workers[1] } assign_task(workers['entry'].id, task.id) task.refresh_from_db() test_case.assertEqual(task.status, Task.Status.PROCESSING) submit_task( task.id, {'test': 'entry_submit'}, Iteration.Status.REQUESTED_REVIEW, workers['entry']) task.refresh_from_db() test_case.assertEqual(task.status, Task.Status.PENDING_REVIEW) assign_task(workers['reviewer'].id, task.id) reviewer_assignment = task.assignments.get( worker=workers['reviewer']) # Modify assignment with correct datetime reviewer_assignment.start_datetime = times['reviewer_pickup'] reviewer_assignment.save() task.refresh_from_db() test_case.assertEqual(task.status, Task.Status.REVIEWING) submit_task( task.id, {'test': 'reviewer_reject'}, Iteration.Status.PROVIDED_REVIEW, workers['reviewer']) task.refresh_from_db() test_case.assertEqual(task.status, Task.Status.POST_REVIEW_PROCESSING) submit_task( task.id, {'test': 'entry_resubmit'}, Iteration.Status.REQUESTED_REVIEW, workers['entry']) task.refresh_from_db() test_case.assertEqual(task.status, Task.Status.REVIEWING) with patch('orchestra.utils.task_lifecycle._is_review_needed', return_value=False): submit_task( task.id, {'test': 'reviewer_accept'}, Iteration.Status.REQUESTED_REVIEW, workers['reviewer']) task.refresh_from_db() test_case.assertEqual(task.status, Task.Status.COMPLETE) test_case.assertEqual(task.assignments.count(), 2) for assignment in task.assignments.all(): test_case.assertEqual( assignment.status, TaskAssignment.Status.SUBMITTED) test_case.assertEqual(assignment.iterations.count(), 2) # Modify assignments with correct datetime new_datetime_labels = ('entry_pickup', 'reviewer_pickup') for i, assignment in enumerate(assignment_history(task).all()): assignment.start_datetime = times[new_datetime_labels[i]] assignment.save() # Modify iterations with correct datetime new_datetime_labels = ( ('entry_pickup', 'entry_submit'), ('reviewer_pickup', 'reviewer_reject'), ('reviewer_reject', 'entry_resubmit'), ('entry_resubmit', 'reviewer_accept') ) new_datetimes = [ (times[start_label], times[end_label]) for start_label, end_label in new_datetime_labels] for i, iteration in enumerate(get_iteration_history(task)): iteration.start_datetime, iteration.end_datetime = new_datetimes[i] iteration.save() verify_iterations(task.id) return task
def _setup_tasks(test_case, tasks): # Create and assign tasks test_case.tasks = {} test_case.test_step = test_case.workflow_steps[ test_case.test_version_slug][test_case.test_step_slug] for task_slug, details in tasks.items(): task_pickup_time = BASE_DATETIME + timedelta(hours=1) task = TaskFactory( project=test_case.projects[details['project_name']], step=test_case.test_step, status=details['status'], start_datetime=task_pickup_time, ) test_case.tasks[task_slug] = task for i, (user_id, task_data, assignment_status) in enumerate(details['assignments']): assignment = TaskAssignmentFactory( worker=test_case.workers[user_id], task=task, status=assignment_status, assignment_counter=i, in_progress_task_data=task_data, start_datetime=_new_assignment_start_datetime(task)) # Each assignment must have at least one corresponding iteration Iteration.objects.create( assignment=assignment, start_datetime=assignment.start_datetime, end_datetime=assignment.start_datetime + ITERATION_DURATION, submitted_data=assignment.in_progress_task_data, status=Iteration.Status.REQUESTED_REVIEW) # Create time entry for each task. TimeEntryFactory(date='2016-04-04', time_worked=timedelta(minutes=30), assignment=assignment, worker=test_case.workers[user_id], description=( 'test description {}'.format(assignment.id))) cur_assignment = current_assignment(task) assignments = assignment_history(task).all() if cur_assignment and ( cur_assignment.status == TaskAssignment.Status.PROCESSING): # If there's a currently processing assignment, we'll need to # adjust the task's iteration sequence processing_counter = cur_assignment.assignment_counter if processing_counter != len(assignments) - 1: # If processing assignment is not the last in the hierarchy, we # need to reconstruct an iteration sequence: REQUESTED_REVIEW # up to the highest assignment counter, then PROVIDED_REVIEW # back down to the current assignment last_iteration = assignments.last().iterations.first() last_iteration.status = Iteration.Status.PROVIDED_REVIEW last_iteration.save() adjust_assignments = list(assignments)[processing_counter:-1] for assignment in reversed(adjust_assignments): last_iteration = get_iteration_history(task).last() Iteration.objects.create( assignment=assignment, start_datetime=last_iteration.end_datetime, end_datetime=( last_iteration.end_datetime + ITERATION_DURATION), submitted_data=assignment.in_progress_task_data, status=Iteration.Status.PROVIDED_REVIEW) # If there is a currently processing assignment, the task's last # iteration should still be processing last_iteration = get_iteration_history(task).last() last_iteration.end_datetime = None last_iteration.submitted_data = {} last_iteration.status = Iteration.Status.PROCESSING last_iteration.save() verify_iterations(task.id)
def test_submit_reviewer_task_assignment(self): data = {'submit_key1': 'submit_val1'} # user 1 is picking up a task as a reviewer response = (self.clients[1].get( '/orchestra/api/interface/new_task_assignment/reviewer/')) self.assertEqual(response.status_code, 200) returned = load_encoded_json(response.content) task_id = returned['id'] task = Task.objects.get(id=returned['id']) self.assertEqual(task.assignments.count(), 2) self.assertEqual(task_id, self.tasks['review_task'].id) verify_iterations(task.id) rejected_data = {'rejected_key': 'rejected_val'} # user 0 can retrieve data, but should see a read-only interface self._verify_good_task_assignment_information( self.clients[0], {'task_id': task.id}, task.project.short_description, 'Submitted', 'Reviewing', False, True, {'test_key': 'test_value'}, self.workers[0]) # user 1 should be able to review the post self._verify_good_task_assignment_information( self.clients[1], {'task_id': task.id}, task.project.short_description, 'Processing', 'Reviewing', True, False, {'test_key': 'test_value'}, self.workers[1]) # user 1 rejects a task response = self._submit_assignment(self.clients[1], task_id, data=rejected_data, command='reject') self.assertEqual(response.status_code, 200) verify_iterations(task.id) # user 0 should have the task back self._verify_good_task_assignment_information( self.clients[0], {'task_id': task.id}, task.project.short_description, 'Processing', 'Post-review Processing', False, False, rejected_data, self.workers[0]) # user 1 should no longer be able to modify the post self._verify_good_task_assignment_information( self.clients[1], {'task_id': task.id}, task.project.short_description, 'Submitted', 'Post-review Processing', True, True, rejected_data, self.workers[1]) # user 0 submits an updated data response = self._submit_assignment(self.clients[0], task_id, data=data) self.assertEqual(response.status_code, 200) verify_iterations(task.id) # check if the data is saved self._verify_good_task_assignment_information( self.clients[1], {'task_id': task.id}, task.project.short_description, 'Processing', 'Reviewing', True, False, data, self.workers[1]) accepted_data = {'accepted_key': 'accepted_val'} # user 1 accepts a task response = self._submit_assignment(self.clients[1], task_id, data=accepted_data, command='accept') self.assertEqual(response.status_code, 200) verify_iterations(task.id) # check if the accepted_data is saved # and task is pending for a second review. self._verify_good_task_assignment_information( self.clients[1], {'task_id': task.id}, task.project.short_description, 'Submitted', 'Pending Review', True, True, accepted_data, self.workers[1]) # make sure a task can't be submitted twice response = self._submit_assignment(self.clients[1], task_id, command='accept') self.assertEqual(response.status_code, 400) returned = load_encoded_json(response.content) self.assertEqual(returned['message'], 'Worker is not allowed to submit') # user 3 is picking up a task as a reviewer response = (self.clients[3].get( '/orchestra/api/interface/new_task_assignment/reviewer/')) self.assertEqual(response.status_code, 200) returned = load_encoded_json(response.content) self.assertEqual(returned['id'], task.id) verify_iterations(task.id) rejected_data = {'rejected_key': 'rejected_val'} # user 3 rejects a task response = self._submit_assignment(self.clients[3], task_id, data=rejected_data, command='reject') self.assertEqual(response.status_code, 200) returned = load_encoded_json(response.content) verify_iterations(task.id) # check if the rejected_data is saved self._verify_good_task_assignment_information( self.clients[3], {'task_id': task.id}, task.project.short_description, 'Submitted', 'Post-review Processing', True, True, rejected_data, self.workers[3]) # check client dashboards self._check_client_dashboard_state(self.clients[0], 'pending_review') self._check_client_dashboard_state(self.clients[1], 'returned') self._check_client_dashboard_state(self.clients[3], 'pending_processing') response = self._submit_assignment(self.clients[1], task.id) self.assertEqual(response.status_code, 200) verify_iterations(task.id) # check if client dashboards were updated self._check_client_dashboard_state(self.clients[0], 'pending_review') self._check_client_dashboard_state(self.clients[1], 'pending_review') self._check_client_dashboard_state(self.clients[3], 'in_progress') # check if the accepted_data is saved response = self._submit_assignment(self.clients[3], task_id, data=accepted_data, command='accept') self.assertEqual(response.status_code, 200) returned = load_encoded_json(response.content) verify_iterations(task.id) # check if task is complete self._verify_good_task_assignment_information( self.clients[3], {'task_id': task.id}, task.project.short_description, 'Submitted', 'Complete', True, True, accepted_data, self.workers[3]) # check that reviewer cannot reaccept task response = self._submit_assignment(self.clients[3], task_id, data=accepted_data, command='accept') self.assertEqual(response.status_code, 400) returned = load_encoded_json(response.content) self.assertEqual(returned['message'], 'Task already completed')
def test_submit_entry_level_task_assignment(self): # user 0 only has certification for entry level tasks response = (self.clients[0].get( '/orchestra/api/interface/new_task_assignment/entry_level/')) self.assertEqual(response.status_code, 200) returned = load_encoded_json(response.content) task = Task.objects.get(id=returned['id']) verify_iterations(task.id) # user is not assigned to a task response = self._submit_assignment(self.clients[1], task.id) self.assertEqual(response.status_code, 400) returned = load_encoded_json(response.content) self.assertEqual(returned['message'], 'Task assignment with worker is in broken state.') # task does not exist response = self._submit_assignment(self.clients[1], -1) self.assertEqual(response.status_code, 400) returned = load_encoded_json(response.content) self.assertEqual(returned['message'], 'No task for given id') # user 0 can only submit a task not reject response = self._submit_assignment(self.clients[0], task.id, command='reject') self.assertEqual(response.status_code, 400) returned = load_encoded_json(response.content) self.assertEqual(returned['message'], 'Task not in rejectable state.') # user 0 can't call illegal commands response = self._submit_assignment(self.clients[0], task.id, command='approve') self.assertEqual(response.status_code, 400) returned = load_encoded_json(response.content) self.assertEqual(returned['message'], 'Illegal command') data = {'submit_key1': 'submit_val1'} # user 0 can't submit a task if its submission prerequisites aren't # complete step = task.step step.submission_depends_on = [ Step.objects.create( workflow_version=step.workflow_version, slug='imaginary_test_step', is_human=True, ) ] step.save() response = self._submit_assignment(self.clients[0], task.id) self.assertEqual(response.status_code, 400) returned = load_encoded_json(response.content) self.assertEqual(returned['message'], 'Submission prerequisites are not complete.') step.submission_depends_on.set([]) step.save() data = {'submit_key1': 'submit_val1'} # user 0 submits a task response = self._submit_assignment(self.clients[0], task.id, data=data) self.assertEqual(response.status_code, 200) self._verify_good_task_assignment_information( self.clients[0], {'task_id': task.id}, task.project.short_description, 'Submitted', 'Pending Review', False, True, data, self.workers[0]) # Check that iteration has correct submitted state verify_iterations(task.id) # user cannot resubmit a task response = self._submit_assignment(self.clients[0], task.id) self.assertEqual(response.status_code, 400) returned = load_encoded_json(response.content) self.assertEqual(returned['message'], 'Worker is not allowed to submit')
def setup_complete_task(test_case): # Microseconds are truncated when manually saving models test_start = timezone.now().replace(microsecond=0) times = { 'awaiting_pickup': test_start, 'entry_pickup': test_start + timedelta(hours=1), 'entry_submit': test_start + timedelta(hours=2), 'reviewer_pickup': test_start + timedelta(hours=3), 'reviewer_reject': test_start + timedelta(hours=4), 'entry_resubmit': test_start + timedelta(hours=5), 'reviewer_accept': test_start + timedelta(hours=6), } task = TaskFactory( project=test_case.projects['empty_project'], status=Task.Status.AWAITING_PROCESSING, step=test_case.test_step, start_datetime=times['awaiting_pickup']) workers = { 'entry': test_case.workers[0], 'reviewer': test_case.workers[1] } assign_task(workers['entry'].id, task.id) task.refresh_from_db() test_case.assertEquals(task.status, Task.Status.PROCESSING) submit_task( task.id, {'test': 'entry_submit'}, Iteration.Status.REQUESTED_REVIEW, workers['entry']) task.refresh_from_db() test_case.assertEquals(task.status, Task.Status.PENDING_REVIEW) assign_task(workers['reviewer'].id, task.id) reviewer_assignment = task.assignments.get( worker=workers['reviewer']) # Modify assignment with correct datetime reviewer_assignment.start_datetime = times['reviewer_pickup'] reviewer_assignment.save() task.refresh_from_db() test_case.assertEquals(task.status, Task.Status.REVIEWING) submit_task( task.id, {'test': 'reviewer_reject'}, Iteration.Status.PROVIDED_REVIEW, workers['reviewer']) task.refresh_from_db() test_case.assertEquals(task.status, Task.Status.POST_REVIEW_PROCESSING) submit_task( task.id, {'test': 'entry_resubmit'}, Iteration.Status.REQUESTED_REVIEW, workers['entry']) task.refresh_from_db() test_case.assertEquals(task.status, Task.Status.REVIEWING) with patch('orchestra.utils.task_lifecycle._is_review_needed', return_value=False): submit_task( task.id, {'test': 'reviewer_accept'}, Iteration.Status.REQUESTED_REVIEW, workers['reviewer']) task.refresh_from_db() test_case.assertEquals(task.status, Task.Status.COMPLETE) test_case.assertEquals(task.assignments.count(), 2) for assignment in task.assignments.all(): test_case.assertEquals( assignment.status, TaskAssignment.Status.SUBMITTED) test_case.assertEquals(assignment.iterations.count(), 2) # Modify assignments with correct datetime new_datetime_labels = ('entry_pickup', 'reviewer_pickup') for i, assignment in enumerate(assignment_history(task).all()): assignment.start_datetime = times[new_datetime_labels[i]] assignment.save() # Modify iterations with correct datetime new_datetime_labels = ( ('entry_pickup', 'entry_submit'), ('reviewer_pickup', 'reviewer_reject'), ('reviewer_reject', 'entry_resubmit'), ('entry_resubmit', 'reviewer_accept') ) new_datetimes = [ (times[start_label], times[end_label]) for start_label, end_label in new_datetime_labels] for i, iteration in enumerate(get_iteration_history(task)): iteration.start_datetime, iteration.end_datetime = new_datetimes[i] iteration.save() verify_iterations(task.id) return task
def _setup_tasks(test_case, tasks): # Create and assign tasks test_case.tasks = {} test_case.test_step = test_case.workflow_steps[ test_case.test_version_slug][test_case.test_step_slug] for task_slug, details in tasks.items(): task_pickup_time = BASE_DATETIME + timedelta(hours=1) task = TaskFactory( project=test_case.projects[details['project_name']], step=test_case.test_step, status=details['status'], start_datetime=task_pickup_time, ) test_case.tasks[task_slug] = task for i, (user_id, task_data, assignment_status) in enumerate(details['assignments']): assignment = TaskAssignmentFactory( worker=test_case.workers[user_id], task=task, status=assignment_status, assignment_counter=i, in_progress_task_data=task_data, start_datetime=_new_assignment_start_datetime(task)) # Each assignment must have at least one corresponding iteration Iteration.objects.create( assignment=assignment, start_datetime=assignment.start_datetime, end_datetime=assignment.start_datetime + ITERATION_DURATION, submitted_data=assignment.in_progress_task_data, status=Iteration.Status.REQUESTED_REVIEW) # Create time entry for each task. TimeEntryFactory(date='2016-04-04', time_worked=timedelta(minutes=30), assignment=assignment, worker=test_case.workers[user_id], description=( 'test description {}'.format(assignment.id))) cur_assignment = current_assignment(task) assignments = assignment_history(task).all() if cur_assignment and ( cur_assignment.status == TaskAssignment.Status.PROCESSING): # If there's a currently processing assignment, we'll need to # adjust the task's iteration sequence processing_counter = cur_assignment.assignment_counter if processing_counter != len(assignments) - 1: # If processing assignment is not the last in the hierarchy, we # need to reconstruct an iteration sequence: REQUESTED_REVIEW # up to the highest assignment counter, then PROVIDED_REVIEW # back down to the current assignment last_iteration = assignments.last().iterations.first() last_iteration.status = Iteration.Status.PROVIDED_REVIEW last_iteration.save() adjust_assignments = list(assignments)[processing_counter:-1] for assignment in reversed(adjust_assignments): last_iteration = get_iteration_history(task).last() Iteration.objects.create( assignment=assignment, start_datetime=last_iteration.end_datetime, end_datetime=( last_iteration.end_datetime + ITERATION_DURATION), submitted_data=assignment.in_progress_task_data, status=Iteration.Status.PROVIDED_REVIEW) # If there is a currently processing assignment, the task's last # iteration should still be processing last_iteration = get_iteration_history(task).last() last_iteration.end_datetime = None last_iteration.submitted_data = {} last_iteration.status = Iteration.Status.PROCESSING last_iteration.save() verify_iterations(task.id)
def test_submit_reviewer_task_assignment(self): data = {'submit_key1': 'submit_val1'} # user 1 is picking up a task as a reviewer response = (self.clients[1].get( '/orchestra/api/interface/new_task_assignment/reviewer/')) self.assertEquals(response.status_code, 200) returned = load_encoded_json(response.content) task_id = returned['id'] task = Task.objects.get(id=returned['id']) self.assertEquals(task.assignments.count(), 2) self.assertEquals(task_id, self.tasks['review_task'].id) verify_iterations(task.id) rejected_data = {'rejected_key': 'rejected_val'} # user 0 can retrieve data, but should see a read-only interface self._verify_good_task_assignment_information( self.clients[0], {'task_id': task.id}, task.project.short_description, 'Submitted', 'Reviewing', False, True, {'test_key': 'test_value'}, self.workers[0]) # user 1 should be able to review the post self._verify_good_task_assignment_information( self.clients[1], {'task_id': task.id}, task.project.short_description, 'Processing', 'Reviewing', True, False, {'test_key': 'test_value'}, self.workers[1]) # user 1 rejects a task response = self._submit_assignment( self.clients[1], task_id, data=rejected_data, command='reject') self.assertEquals(response.status_code, 200) verify_iterations(task.id) # user 0 should have the task back self._verify_good_task_assignment_information( self.clients[0], {'task_id': task.id}, task.project.short_description, 'Processing', 'Post-review Processing', False, False, rejected_data, self.workers[0]) # user 1 should no longer be able to modify the post self._verify_good_task_assignment_information( self.clients[1], {'task_id': task.id}, task.project.short_description, 'Submitted', 'Post-review Processing', True, True, rejected_data, self.workers[1]) # user 0 submits an updated data response = self._submit_assignment( self.clients[0], task_id, data=data) self.assertEquals(response.status_code, 200) verify_iterations(task.id) # check if the data is saved self._verify_good_task_assignment_information( self.clients[1], {'task_id': task.id}, task.project.short_description, 'Processing', 'Reviewing', True, False, data, self.workers[1]) accepted_data = {'accepted_key': 'accepted_val'} # user 1 accepts a task response = self._submit_assignment( self.clients[1], task_id, data=accepted_data, command='accept') self.assertEquals(response.status_code, 200) verify_iterations(task.id) # check if the accepted_data is saved # and task is pending for a second review. self._verify_good_task_assignment_information( self.clients[1], {'task_id': task.id}, task.project.short_description, 'Submitted', 'Pending Review', True, True, accepted_data, self.workers[1]) # make sure a task can't be submitted twice response = self._submit_assignment( self.clients[1], task_id, command='accept') self.assertEquals(response.status_code, 400) returned = load_encoded_json(response.content) self.assertEquals(returned['message'], 'Worker is not allowed to submit') # user 3 is picking up a task as a reviewer response = (self.clients[3].get( '/orchestra/api/interface/new_task_assignment/reviewer/')) self.assertEquals(response.status_code, 200) returned = load_encoded_json(response.content) self.assertEquals(returned['id'], task.id) verify_iterations(task.id) rejected_data = {'rejected_key': 'rejected_val'} # user 3 rejects a task response = self._submit_assignment( self.clients[3], task_id, data=rejected_data, command='reject') self.assertEquals(response.status_code, 200) returned = load_encoded_json(response.content) verify_iterations(task.id) # check if the rejected_data is saved self._verify_good_task_assignment_information( self.clients[3], {'task_id': task.id}, task.project.short_description, 'Submitted', 'Post-review Processing', True, True, rejected_data, self.workers[3]) # check client dashboards self._check_client_dashboard_state(self.clients[0], 'pending_review') self._check_client_dashboard_state(self.clients[1], 'returned') self._check_client_dashboard_state(self.clients[3], 'pending_processing') response = self._submit_assignment( self.clients[1], task.id) self.assertEquals(response.status_code, 200) verify_iterations(task.id) # check if client dashboards were updated self._check_client_dashboard_state(self.clients[0], 'pending_review') self._check_client_dashboard_state(self.clients[1], 'pending_review') self._check_client_dashboard_state(self.clients[3], 'in_progress') # check if the accepted_data is saved response = self._submit_assignment( self.clients[3], task_id, data=accepted_data, command='accept') self.assertEquals(response.status_code, 200) returned = load_encoded_json(response.content) verify_iterations(task.id) # check if task is complete self._verify_good_task_assignment_information( self.clients[3], {'task_id': task.id}, task.project.short_description, 'Submitted', 'Complete', True, True, accepted_data, self.workers[3]) # check that reviewer cannot reaccept task response = self._submit_assignment( self.clients[3], task_id, data=accepted_data, command='accept') self.assertEquals(response.status_code, 400) returned = load_encoded_json(response.content) self.assertEquals(returned['message'], 'Task already completed')
def test_submit_entry_level_task_assignment(self): # user 0 only has certification for entry level tasks response = (self.clients[0].get( '/orchestra/api/interface/new_task_assignment/entry_level/')) self.assertEquals(response.status_code, 200) returned = load_encoded_json(response.content) task = Task.objects.get(id=returned['id']) verify_iterations(task.id) # user is not assigned to a task response = self._submit_assignment(self.clients[1], task.id) self.assertEquals(response.status_code, 400) returned = load_encoded_json(response.content) self.assertEquals(returned['message'], 'Task assignment with worker is in broken state.') # task does not exist response = self._submit_assignment(self.clients[1], -1) self.assertEquals(response.status_code, 400) returned = load_encoded_json(response.content) self.assertEquals(returned['message'], 'No task for given id') # user 0 can only submit a task not reject response = self._submit_assignment( self.clients[0], task.id, command='reject') self.assertEquals(response.status_code, 400) returned = load_encoded_json(response.content) self.assertEquals(returned['message'], 'Task not in rejectable state.') # user 0 can't call illegal commands response = self._submit_assignment( self.clients[0], task.id, command='approve') self.assertEquals(response.status_code, 400) returned = load_encoded_json(response.content) self.assertEquals(returned['message'], 'Illegal command') data = {'submit_key1': 'submit_val1'} # user 0 can't submit a task if its submission prerequisites aren't # complete step = task.step step.submission_depends_on = [ Step.objects.create( workflow_version=step.workflow_version, slug='imaginary_test_step', is_human=True, ) ] step.save() response = self._submit_assignment( self.clients[0], task.id) self.assertEquals(response.status_code, 400) returned = load_encoded_json(response.content) self.assertEquals(returned['message'], 'Submission prerequisites are not complete.') step.submission_depends_on = [] step.save() data = {'submit_key1': 'submit_val1'} # user 0 submits a task response = self._submit_assignment( self.clients[0], task.id, data=data) self.assertEquals(response.status_code, 200) self._verify_good_task_assignment_information( self.clients[0], {'task_id': task.id}, task.project.short_description, 'Submitted', 'Pending Review', False, True, data, self.workers[0]) # Check that iteration has correct submitted state verify_iterations(task.id) # user cannot resubmit a task response = self._submit_assignment( self.clients[0], task.id) self.assertEquals(response.status_code, 400) returned = load_encoded_json(response.content) self.assertEquals(returned['message'], 'Worker is not allowed to submit')