def test_is_entry_level(self): worker = WorkerFactory() WorkerCertificationFactory(worker=worker, certification=self.cert, role=WorkerCertification.Role.ENTRY_LEVEL) self.assertTrue(worker.is_entry_level(self.cert)) self.assertFalse(worker.is_reviewer(self.cert))
def test_send_staffing_request_priorities(self, mock_slack): worker2 = WorkerFactory() WorkerCertificationFactory(worker=worker2, staffing_priority=-1) CommunicationPreferenceFactory( worker=worker2, communication_type=(CommunicationPreference.CommunicationType. NEW_TASK_AVAILABLE.value)) worker3 = WorkerFactory() WorkerCertificationFactory(worker=worker3, staffing_priority=1) CommunicationPreferenceFactory( worker=worker3, communication_type=(CommunicationPreference.CommunicationType. NEW_TASK_AVAILABLE.value)) request = StaffBotRequestFactory() self.assertEqual(request.status, StaffBotRequest.Status.PROCESSING.value) # Workers should be contacted in priority order. excluded = [] for worker in (worker3, self.worker, worker2): send_staffing_requests(worker_batch_size=1, frequency=timedelta(minutes=0)) inquiries = (StaffingRequestInquiry.objects.filter( request=request).exclude( communication_preference__worker__in=excluded)) for inquiry in inquiries: self.assertEqual(worker.id, inquiry.communication_preference.worker.id) excluded.append(worker)
def test_is_entry_level(self): worker = WorkerFactory() WorkerCertificationFactory( worker=worker, certification=self.cert, role=WorkerCertification.Role.ENTRY_LEVEL) self.assertTrue(worker.is_entry_level(self.cert)) self.assertFalse(worker.is_reviewer(self.cert))
class AccountSettingsTest(OrchestraAuthenticatedTestCase): def setUp(self): super().setUp() self.request_client, self.user = self.authenticate_user() self.url = reverse('orchestra:account_settings') self.worker = WorkerFactory(user=self.user) def _get_account_settings_mock_data(self): return { 'first_name': 'Mock first', 'last_name': 'Mock last', 'slack_username': '******', 'phone_0': '+1', 'phone_1': '3477761527', } def test_get_form(self): response = self.request_client.get(self.url) self.assertEqual(response.status_code, 200) self.assertTemplateUsed(response, 'accounts/settings.html') @patch('orchestra.accounts.forms.get_slack_user_id') def test_change_all_fields(self, mock_get_slack_user_id): mock_get_slack_user_id.return_value = 'test_id' data = self._get_account_settings_mock_data() response = self.request_client.post(self.url, data) self.assertTrue(response.context['success']) self.user.refresh_from_db() self.assertEqual(self.user.first_name, data['first_name']) self.assertEqual(self.user.last_name, data['last_name']) self.worker.refresh_from_db() self.assertEqual(self.worker.slack_username, data['slack_username']) self.assertEqual(self.worker.phone, data['phone_0'] + data['phone_1']) self.assertEqual(self.worker.slack_user_id, 'test_id') @patch('orchestra.accounts.forms.get_slack_user_id') def test_missing_fields(self, mock_get_slack_user_id): mock_get_slack_user_id.return_value = 'test_id' required_fields = self._get_account_settings_mock_data().keys() for field in required_fields: data = self._get_account_settings_mock_data() data.pop(field) response = self.request_client.post(self.url, data) self.assertFalse(response.context['success'])
class AccountSettingsTest(OrchestraAuthenticatedTestCase): def setUp(self): super().setUp() self.user = self.authenticate_user() self.url = reverse('orchestra:account_settings') self.worker = WorkerFactory(user=self.user) def _get_account_settings_mock_data(self): return { 'first_name': 'Mock first', 'last_name': 'Mock last', 'slack_username': '******', 'phone_0': '+1', 'phone_1': '3477761527', } def test_get_form(self): response = self.request_client.get(self.url) self.assertEqual(response.status_code, 200) self.assertTemplateUsed(response, 'accounts/settings.html') @patch('orchestra.accounts.forms.get_slack_user_id') def test_change_all_fields(self, mock_get_slack_user_id): mock_get_slack_user_id.return_value = 'test_id' data = self._get_account_settings_mock_data() response = self.request_client.post(self.url, data) self.assertTrue(response.context['success']) self.user.refresh_from_db() self.assertEqual(self.user.first_name, data['first_name']) self.assertEqual(self.user.last_name, data['last_name']) self.worker.refresh_from_db() self.assertEqual(self.worker.slack_username, data['slack_username']) self.assertEqual(self.worker.phone, data['phone_0'] + data['phone_1']) self.assertEqual(self.worker.slack_user_id, 'test_id') @patch('orchestra.accounts.forms.get_slack_user_id') def test_missing_fields(self, mock_get_slack_user_id): mock_get_slack_user_id.return_value = 'test_id' required_fields = self._get_account_settings_mock_data().keys() for field in required_fields: data = self._get_account_settings_mock_data() data.pop(field) response = self.request_client.post(self.url, data) self.assertFalse(response.context['success'])
def setUp(self): super().setUp() user = UserFactory(username='******') self.worker = WorkerFactory(user=user) self.request_client.login(username=self.worker.user.username, password='******') self.time = timezone.now()
def test_address_staffing_requests_parameters(self, mock_slack): for idx in range(5): worker = WorkerFactory() CommunicationPreferenceFactory( worker=worker, communication_type=(CommunicationPreference.CommunicationType. NEW_TASK_AVAILABLE.value)) WorkerCertificationFactory(worker=worker, certification=self.certification) # Make a new request and turn off the global request, as the # global one has an inquiry on it already. request = StaffBotRequestFactory(task__step__is_human=True) request.task.step.required_certifications.add(self.certification) self.staffing_request_inquiry.request.status = ( StaffBotRequest.Status.DONE_SENDING_INQUIRIES) address_staffing_requests(worker_batch_size=1, frequency=timedelta(minutes=20)) # Inquiries increase by two because we send a Slack and an # email notification. `last_inquiry_sent` is None on new # tasks, so we send this batch regardless of frequency. self.assertEqual( StaffingRequestInquiry.objects.filter(request=request).count(), 2) address_staffing_requests(worker_batch_size=2, frequency=timedelta(minutes=20)) # Don't send more inquiries, since it hasn't been 20 minutes. self.assertEqual( StaffingRequestInquiry.objects.filter(request=request).count(), 2) request.last_inquiry_sent = timezone.now() - timedelta(minutes=21) request.save() address_staffing_requests(worker_batch_size=2, frequency=timedelta(minutes=20)) # Send two email and two slack inquiries since it's been 21 minutes. self.assertEqual( StaffingRequestInquiry.objects.filter(request=request).count(), 6) address_staffing_requests(worker_batch_size=10, frequency=timedelta(minutes=20)) # Don't send more inquiries, since it hasn't been 20 minutes. self.assertEqual( StaffingRequestInquiry.objects.filter(request=request).count(), 6) request.last_inquiry_sent = timezone.now() - timedelta(minutes=21) request.save() address_staffing_requests(worker_batch_size=10, frequency=timedelta(minutes=20)) # Send remaining inquiries, since enough time has passed. self.assertEqual( StaffingRequestInquiry.objects.filter(request=request).count(), 12) request.last_inquiry_sent = timezone.now() - timedelta(minutes=21) request.save() address_staffing_requests(worker_batch_size=10, frequency=timedelta(minutes=20)) # We're all out of workers to whom we'd like to send inquiries. self.assertEqual( StaffingRequestInquiry.objects.filter(request=request).count(), 12)
def test_mark_worker_as_winner(self): self.assertEqual(self.staffing_request_inquiry.responses.all().count(), 0) mark_worker_as_winner(self.worker, self.staffing_request_inquiry.request.task, 0, self.staffing_request_inquiry) staffbot_request = self.staffing_request_inquiry.request staffbot_request.refresh_from_db() self.assertEqual(staffbot_request.status, StaffBotRequest.Status.CLOSED.value) self.assertEqual(self.staffing_request_inquiry.responses.all().count(), 0) # Can't mark another worker as a winner for this request worker2 = WorkerFactory() inquiry2 = StaffingRequestInquiryFactory( communication_preference__worker=worker2, communication_preference__communication_type=( CommunicationPreference.CommunicationType.NEW_TASK_AVAILABLE. value), request__task__step__is_human=True, request=self.staffing_request_inquiry.request) mark_worker_as_winner(worker2, inquiry2.request.task, 0, inquiry2) self.assertEqual(inquiry2.responses.count(), 0)
def test_restaff_command_errors(self): """ Test that the staffing logic errors are raised during staff command. """ bot = StaffBot() command = 'restaff 999999999999 unknown' data = get_mock_slack_data( text=command, user_id=self.worker.slack_user_id) response = bot.dispatch(data) self.assertEqual(response.get('text'), command) self.assertEqual(response['attachments'][0]['text'], bot.worker_does_not_exist.format('unknown')) worker = WorkerFactory(user__username='******') data['text'] = 'restaff 999999999999 username' response = bot.dispatch(data) self.assertEqual(response['attachments'][0]['text'], bot.task_does_not_exist_error.format('999999999999')) # making sure it works with slack username as well. worker.slack_username = '******' worker.save() data['text'] = 'restaff 999999999999 slackusername' response = bot.dispatch(data) self.assertEqual(response['attachments'][0]['text'], bot.task_does_not_exist_error.format('999999999999')) data['text'] = 'restaff' response = bot.dispatch(data) self.assertTrue(bot.default_error_text in response.get('text')) task = TaskFactory(status=Task.Status.COMPLETE) command = 'restaff {} {}'.format(task.id, worker.user.username) data['text'] = command response = bot.dispatch(data) self.assertEquals(response['attachments'][0]['text'], (bot.task_assignment_does_not_exist_error .format(worker.user.username, task.id)))
def setUp(self): self.worker = WorkerFactory() self.staffing_request_inquiry = StaffingRequestInquiryFactory( communication_preference__worker=self.worker, communication_preference__communication_type=( CommunicationPreference.CommunicationType .NEW_TASK_AVAILABLE.value), request__task__step__is_human=True ) super().setUp()
def _create_worker(self, staffing_priority): worker = WorkerFactory() WorkerCertificationFactory(worker=worker, certification=self.certification, staffing_priority=staffing_priority) communication_preference = CommunicationPreferenceFactory( worker=worker, communication_type=(CommunicationPreference.CommunicationType. NEW_TASK_AVAILABLE.value)) return worker, communication_preference
def test_unauthenticated_request(self): new_worker = WorkerFactory() comm_pref = (self.staffing_response. request_inquiry.communication_preference) comm_pref.worker = new_worker comm_pref.save() response = self.request_client.get(self.url) self.assert_response(response, status_code=404, template='orchestra/error.html')
def test_send_staffing_requests(self, mock_slack): worker2 = WorkerFactory() CommunicationPreferenceFactory( worker=worker2, communication_type=( CommunicationPreference.CommunicationType .NEW_TASK_AVAILABLE.value)) WorkerCertificationFactory( worker=worker2, certification=self.certification ) request = StaffBotRequestFactory() request.task.step.required_certifications.add(self.certification) self.assertEqual(request.status, StaffBotRequest.Status.SENDING_INQUIRIES.value) send_staffing_requests(worker_batch_size=1, frequency=timedelta(minutes=0)) mock_slack.assert_not_called() request.refresh_from_db() self.assertEqual(request.status, StaffBotRequest.Status.SENDING_INQUIRIES.value) # Inquiries increase by two because we send a Slack and an # email notification. self.assertEqual( StaffingRequestInquiry.objects.filter(request=request).count(), 2) send_staffing_requests(worker_batch_size=1, frequency=timedelta(minutes=0)) self.assertEqual(mock_slack.call_count, 1) mock_slack.reset() request.refresh_from_db() self.assertEqual(request.status, StaffBotRequest.Status.SENDING_INQUIRIES.value) self.assertEqual( StaffingRequestInquiry.objects.filter(request=request).count(), 4) # marked as closed and no new request inquiries sent. send_staffing_requests(worker_batch_size=1, frequency=timedelta(minutes=0)) self.assertTrue(mock_slack.called) request.refresh_from_db() self.assertEqual(request.status, StaffBotRequest.Status.DONE_SENDING_INQUIRIES.value) self.assertEqual( StaffingRequestInquiry.objects.filter(request=request).count(), 4)
def setUp(self): super().setUp() setup_models(self) self.project_admin_group = Group.objects.create(name='project_admins') user = (UserFactory(username='******', first_name='project_management', last_name='project_management', password='******', email='*****@*****.**')) self.worker = WorkerFactory(user=user) user.groups.add(self.project_admin_group) self.api_client = Client() self.api_client.login(username='******', password='******')
def setUp(self): self.workflow_old = WorkflowFactory( slug='workflow_old', name='Old workflow', description='Old workflow to migrate certifications from.', code_directory='workflow_old') self.workflow_new = WorkflowFactory( slug='workflow_new', name='New workflow', description='New workflow to migrate certifications from.', code_directory='workflow_new') for workflow in (self.workflow_old, self.workflow_new): # Certifications must exist in both workflows for certification # to be migrated CertificationFactory( slug='certification1', name='Certification 1', description='First certification to migrate.', workflow=workflow) CertificationFactory( slug='certification2', name='Certification 2', description='Second certification to migrate.', workflow=workflow) user = (UserFactory(username='******', first_name='test', last_name='test', password='******', email='*****@*****.**')) self.worker = WorkerFactory(user=user) for certification in self.workflow_old.certifications.all(): # Worker certifications exist only for old workflow WorkerCertificationFactory( worker=self.worker, certification=certification, role=WorkerCertification.Role.ENTRY_LEVEL) WorkerCertificationFactory( worker=self.worker, certification=certification, role=WorkerCertification.Role.REVIEWER) super().setUp()
def test_handle_staffing_response_all_rejected(self, mock_slack): worker2 = WorkerFactory() CommunicationPreferenceFactory( worker=worker2, communication_type=(CommunicationPreference.CommunicationType. NEW_TASK_AVAILABLE.value)) response = handle_staffing_response(self.worker, self.staffing_request_inquiry.id, is_available=False) self.assertFalse(response.is_winner) self.assertEqual(response.request_inquiry.request.status, StaffBotRequest.Status.CLOSED.value) self.assertEqual(mock_slack.call_count, 1) mock_slack.reset() handle_staffing_response(worker2, self.staffing_request_inquiry.id, is_available=False) self.assertEqual(mock_slack.call_count, 1)
def test_handle_staffing_response_is_available(self): # Test StaffingResponse object creation old_count = StaffingResponse.objects.all().count() # assign task is called response = handle_staffing_response(self.worker, self.staffing_request_inquiry.id, is_available=True) self.assertTrue(response.is_winner) self.staffing_request_inquiry.refresh_from_db() self.assertEqual(response.request_inquiry.request.status, StaffBotRequest.Status.CLOSED.value) self.assertEqual(StaffingResponse.objects.all().count(), old_count + 1) task_assignment = (TaskAssignment.objects.get( worker=self.worker, task=self.staffing_request_inquiry.request.task)) self.assertEqual(task_assignment.status, TaskAssignment.Status.PROCESSING) self.staffing_request_inquiry.request.task.refresh_from_db() # Replay of same request response = handle_staffing_response(self.worker, self.staffing_request_inquiry.id, is_available=True) self.assertTrue(response.is_winner) self.assertEqual(response.request_inquiry.request.status, StaffBotRequest.Status.CLOSED.value) self.assertEqual(StaffingResponse.objects.all().count(), old_count + 1) # Change mind to `is_available=False` does not do anything with self.assertRaises(StaffingResponseException): response = handle_staffing_response( self.worker, self.staffing_request_inquiry.id, is_available=False) new_request_inquiry = StaffingRequestInquiryFactory( request__task__step__is_human=True) new_worker = new_request_inquiry.communication_preference.worker old_count = StaffingResponse.objects.all().count() response = handle_staffing_response(new_worker, new_request_inquiry.id, is_available=True) self.assertTrue(response.is_winner) self.assertEqual(response.request_inquiry.request.status, StaffBotRequest.Status.CLOSED.value) self.assertEqual(StaffingResponse.objects.all().count(), old_count + 1) task_assignment = (TaskAssignment.objects.get( worker=new_worker, task=new_request_inquiry.request.task)) self.assertEqual(task_assignment.status, TaskAssignment.Status.PROCESSING) # restaff response.is_winner = False response.save() worker2 = WorkerFactory() staffing_request_inquiry2 = StaffingRequestInquiryFactory( communication_preference__worker=worker2, request__task=new_request_inquiry.request.task) response = handle_staffing_response(worker2, staffing_request_inquiry2.id, is_available=True) self.assertTrue(response.is_winner) self.assertEqual(response.request_inquiry.request.status, StaffBotRequest.Status.CLOSED.value) task_assignment.refresh_from_db() self.assertEqual(task_assignment.worker, worker2)
def test_get_available_request(self, mock_slack): # Close all open requests so new worker doesn't receive them. address_staffing_requests(worker_batch_size=2, frequency=timedelta(minutes=0)) self.assertEqual(len(get_available_requests(self.worker)), 1) worker2 = WorkerFactory() CommunicationPreferenceFactory( worker=worker2, communication_type=(CommunicationPreference.CommunicationType. NEW_TASK_AVAILABLE.value)) WorkerCertificationFactory(worker=worker2, certification=self.certification) request1 = StaffBotRequestFactory(task__step__is_human=True) request1.task.step.required_certifications.add(self.certification) request2 = StaffBotRequestFactory(task__step__is_human=True) request2.task.step.required_certifications.add(self.certification) address_staffing_requests(worker_batch_size=2, frequency=timedelta(minutes=0)) inquiry1 = (StaffingRequestInquiry.objects.filter( communication_preference__worker=self.worker).filter( request=request1).first()) inquiry2 = (StaffingRequestInquiry.objects.filter( communication_preference__worker=worker2).filter( request=request2).first()) # `self.worker` now has three available tasks, whereas `worker2` # just has access to the two new tasks. available_requests = get_available_requests(self.worker) self.assertEqual(len(available_requests), 3) self.assertEqual(len(get_available_requests(worker2)), 2) # Tasks should be sorted by start_datetime in ascending order. first_available, second_available, third_available = ( available_requests[0]['available_datetime'], available_requests[1]['available_datetime'], available_requests[2]['available_datetime']) self.assertLess(first_available, second_available) self.assertLess(second_available, third_available) # `self.worker` will lose an available task (they accept it), # whereas `worker2` is unchanged. handle_staffing_response(self.worker, self.staffing_request_inquiry.id, is_available=True) self.assertEqual(len(get_available_requests(self.worker)), 2) self.assertEqual(len(get_available_requests(worker2)), 2) # `self.worker` will lose an available task (they ignore it), # whereas `worker2` is unchanged. handle_staffing_response(self.worker, inquiry1.id, is_available=False) self.assertEqual(len(get_available_requests(self.worker)), 1) self.assertEqual(len(get_available_requests(worker2)), 2) # `worker2` takes a task. handle_staffing_response(worker2, inquiry2.id, is_available=True) self.assertEqual(len(get_available_requests(self.worker)), 0) self.assertEqual(len(get_available_requests(worker2)), 1)
def setUp(self): self.user = UserFactory() self.worker = WorkerFactory(user=self.user) super().setUp()
def setUp(self): super().setUp() self.user = self.authenticate_user() self.url = reverse('orchestra:account_settings') self.worker = WorkerFactory(user=self.user)
def setUp(self): super().setUp() self.request_client, self.user = self.authenticate_user() self.url = reverse('orchestra:account_settings') self.worker = WorkerFactory(user=self.user)