def test_get_involvements(self, police_witness_serializer_mock, investigator_allegation_serializer_mock): allegation = AllegationFactory() officer_1 = OfficerFactory() officer_2 = OfficerFactory() PoliceWitnessFactory(officer=officer_1, allegation=allegation) PoliceWitnessFactory(officer=officer_2, allegation=allegation) OfficerBadgeNumberFactory(officer=officer_1, star='456789') investigator_1 = InvestigatorFactory(officer=officer_1) investigator_2 = InvestigatorFactory(officer=officer_2) investigator_3 = InvestigatorFactory() investigator_allegation_1 = InvestigatorAllegationFactory(allegation=allegation, investigator=investigator_1) investigator_allegation_2 = InvestigatorAllegationFactory(allegation=allegation, investigator=investigator_2) investigator_allegation_3 = InvestigatorAllegationFactory(allegation=allegation, investigator=investigator_3) investigator_allegations = [investigator_allegation_1, investigator_allegation_2, investigator_allegation_3] expected_has_badge_numbers = { investigator_allegation_1.id: True, investigator_allegation_2.id: False, investigator_allegation_3.id: False, } result = CRSerializer(allegation).data investigator_allegations_arg = investigator_allegation_serializer_mock.call_args[0][0] police_witnesses_arg = police_witness_serializer_mock.call_args[0][0] expect(set(investigator_allegations_arg)).to.eq(set(investigator_allegations)) for obj in investigator_allegations_arg: expect(obj.has_badge_number).to.eq(expected_has_badge_numbers[obj.id]) expect(set(police_witnesses_arg)).to.eq(set([officer_1, officer_2])) expect(result['involvements']).to.eq( [{'officer_id': 1}, {'officer_id': 2}, {'officer_id': 4}, {'officer_id': 3}] )
def test_search_investigator_cr_results(self): allegation_1 = AllegationFactory(crid='123456', incident_date=datetime( 2002, 2, 3, tzinfo=pytz.utc)) allegation_2 = AllegationFactory(crid='654321', incident_date=datetime( 2005, 2, 3, tzinfo=pytz.utc)) officer = OfficerFactory(id=123, first_name='Edward', last_name='May') investigator_1 = InvestigatorFactory(first_name='Jerome', last_name='Finnigan') investigator_2 = InvestigatorFactory(officer=officer) InvestigatorAllegationFactory(investigator=investigator_1, allegation=allegation_1) InvestigatorAllegationFactory(investigator=investigator_2, allegation=allegation_1) InvestigatorAllegationFactory(investigator=investigator_1, allegation=allegation_2) self.rebuild_index() self.refresh_index() url = reverse('api:suggestion-list') response = self.client.get(url, { 'term': 'Jerome', }) results = response.data['INVESTIGATOR > CR'] expect(results).to.have.length(2) expected_results = { '123456': { 'id': '123456', 'crid': '123456', 'to': '/complaint/123456/', 'incident_date': '2002-02-03', 'category': 'Unknown', 'sub_category': 'Unknown', 'address': '', 'victims': [], 'coaccused': [] }, '654321': { 'id': '654321', 'crid': '654321', 'to': '/complaint/654321/', 'incident_date': '2005-02-03', 'category': 'Unknown', 'sub_category': 'Unknown', 'address': '', 'victims': [], 'coaccused': [] } } for cr_data in results: expect(cr_data).to.eq(expected_results[cr_data['id']])
def test_search_investigator_cr_results(self): allegation_1 = AllegationFactory(crid='123456', incident_date=datetime( 2002, 2, 3, tzinfo=pytz.utc)) allegation_2 = AllegationFactory(crid='654321', incident_date=datetime( 2005, 2, 3, tzinfo=pytz.utc)) officer = OfficerFactory(id=123, first_name='Edward', last_name='May') investigator_1 = InvestigatorFactory(first_name='Jerome', last_name='Finnigan') investigator_2 = InvestigatorFactory(officer=officer) InvestigatorAllegationFactory(investigator=investigator_1, allegation=allegation_1) InvestigatorAllegationFactory(investigator=investigator_2, allegation=allegation_1) InvestigatorAllegationFactory(investigator=investigator_1, allegation=allegation_2) OfficerAllegationFactory( allegation=allegation_1, allegation_category__category='Illegal Search') OfficerAllegationFactory(allegation=allegation_2, allegation_category__category='') allegation_cache_manager.cache_data() self.rebuild_index() self.refresh_index() url = reverse('api-v2:search-mobile-list') response = self.client.get(url, { 'term': 'Jerome', }) results = response.data['INVESTIGATOR > CR'] expect(results).to.have.length(2) expected_results = { '123456': { 'id': '123456', 'crid': '123456', 'category': 'Illegal Search', 'incident_date': '2002-02-03' }, '654321': { 'id': '654321', 'crid': '654321', 'category': 'Unknown', 'incident_date': '2005-02-03' } } for cr_data in results: expect(cr_data).to.eq(expected_results[cr_data['id']])
def test_upload_cr_attachment_request_to_foia_with_cpd_after_2006_has_badge_number( self, airtable_mock): airtable_mock.insert.return_value = {'id': 'some_airtable_record_id'} allegation = AllegationFactory(crid='123456', incident_date=datetime(2007, 12, 31, tzinfo=pytz.utc)) attachment_request = AttachmentRequestFactory( allegation=allegation, email='*****@*****.**') officer_1 = OfficerFactory(id=1, first_name='Marry', last_name='Jane') officer_2 = OfficerFactory(id=2, first_name='John', last_name='Henry') OfficerBadgeNumberFactory(officer=officer_1, star='12345') OfficerBadgeNumberFactory(officer=officer_2, star='56789') investigator_1 = InvestigatorFactory(officer=officer_1) investigator_2 = InvestigatorFactory(officer=officer_1) InvestigatorAllegationFactory(allegation=allegation, current_star=None, investigator=investigator_1) InvestigatorAllegationFactory(allegation=allegation, current_star=None, investigator=investigator_2) OfficerAllegationFactory(allegation=allegation, officer=officer_1) OfficerAllegationFactory(allegation=allegation, officer=officer_2) expected_airtable_data = { 'Explanation': 'Officers: John Henry(ID 2), Marry Jane(ID 1)', 'Project': ['CPDP'], 'Agency': ['CPD_AGENCY_ID'], 'Requested For': 'CR 123456', 'Requestor': [{ 'id': 'usrGiZFcyZ6wHTYWd', 'email': '*****@*****.**', 'name': 'Rajiv Sinclair' }], 'Date requested by user': attachment_request.created_at.strftime('%Y-%m-%d'), 'Requester Email': '*****@*****.**' } CRRequestAirTableUploader.upload() attachment_request.refresh_from_db() airtable_mock.insert.assert_called_with(expected_airtable_data) expect( attachment_request.airtable_id).to.be.eq('some_airtable_record_id')
def test_invoke_create_zip(self, aws_mock): exception = botocore.exceptions.ClientError( error_response={'Error': { 'Code': 'NoSuchKey' }}, operation_name='get_object') aws_mock.s3.get_object.side_effect = exception allegation = AllegationFactory(crid='1') allegation_456 = AllegationFactory(crid='456') AttachmentFileFactory(allegation=allegation, source_type='DOCUMENTCLOUD', external_id='ABC', title='allegation 1 attachment') AttachmentFileFactory(allegation=allegation, source_type='COPA') AttachmentFileFactory(allegation=allegation_456, source_type='DOCUMENTCLOUD') AttachmentFileFactory(allegation=allegation_456, source_type='PORTAL_COPA_DOCUMENTCLOUD') officer = OfficerFactory(id=1, first_name='Jerome', last_name='Finnigan') OfficerAllegationFactory(officer=officer, allegation=allegation) allegation_2 = AllegationFactory(crid='2') allegation_789 = AllegationFactory(crid='789') AttachmentFileFactory(allegation=allegation_2, source_type='DOCUMENTCLOUD', external_id='XYZ', title='allegation 2 attachment') AttachmentFileFactory(allegation=allegation_2, source_type='COPA') AttachmentFileFactory(allegation=allegation_789, source_type='DOCUMENTCLOUD') AttachmentFileFactory(allegation=allegation_789, source_type='PORTAL_COPA_DOCUMENTCLOUD') investigator = InvestigatorFactory(officer=officer) InvestigatorAllegationFactory(allegation=allegation_2, investigator=investigator) officer.invoke_create_zip(with_docs=True) expect(aws_mock.s3.get_object).to.be.called_with( Bucket='officer_content_bucket', Key='zip_with_docs/Jerome_Finnigan_with_docs.zip') _, kwargs = aws_mock.lambda_client.invoke_async.call_args expect(kwargs['FunctionName']).to.eq('createOfficerZipFileTest') expect(json.loads(kwargs['InvokeArgs'])).to.eq({ 'key': 'zip_with_docs/Jerome_Finnigan_with_docs.zip', 'bucket': 'officer_content_bucket', 'file_map': { 'xlsx/1/accused.xlsx': 'accused.xlsx', 'xlsx/1/use_of_force.xlsx': 'use_of_force.xlsx', 'xlsx/1/investigator.xlsx': 'investigator.xlsx', 'xlsx/1/documents.xlsx': 'documents.xlsx', 'pdf/ABC': f'documents/allegation 1 attachment.pdf', 'pdf/XYZ': f'investigators/allegation 2 attachment.pdf' } })
def test_investigator_attachments(self): allegation = AllegationFactory(crid='123') allegation_456 = AllegationFactory(crid='456') attachment_1 = AttachmentFileFactory(allegation=allegation, source_type='DOCUMENTCLOUD') attachment_2 = AttachmentFileFactory( allegation=allegation, source_type='PORTAL_COPA_DOCUMENTCLOUD') AttachmentFileFactory(allegation=allegation, source_type='PORTAL_COPA_DOCUMENTCLOUD', show=False) AttachmentFileFactory(allegation=allegation, source_type='COPA') AttachmentFileFactory(allegation=allegation, source_type='COPA', show=False) AttachmentFileFactory(allegation=allegation_456, source_type='DOCUMENTCLOUD') AttachmentFileFactory(allegation=allegation_456, source_type='PORTAL_COPA_DOCUMENTCLOUD') AttachmentFileFactory(allegation=allegation_456, source_type='PORTAL_COPA_DOCUMENTCLOUD', show=False) investigator = InvestigatorFactory(officer=OfficerFactory(id=1)) InvestigatorAllegationFactory(allegation=allegation, investigator=investigator) expect({ attachment.id for attachment in investigator.officer.investigator_attachments }).to.eq({attachment_1.id, attachment_2.id})
def test_extract_investigator_multiple_cases(self): investigator = InvestigatorFactory(first_name='Luke', last_name='Skywalker') InvestigatorAllegationFactory.create_batch(3, investigator=investigator) rows = self.extract_data() expect(rows).to.have.length(3) for row in rows: expect(row['involvements']).to.have.length(1) expect(row['involvements'][0]['full_name']).to.eq('Luke Skywalker')
def test_investigator_num_cases(self): investigator = InvestigatorFactory() InvestigatorAllegationFactory.create_batch(3, investigator=investigator) allegation = AllegationFactory() InvestigatorAllegationFactory(investigator=investigator, allegation=allegation) rows = self.extract_data() expect(rows).to.have.length(4) expect(rows[-1]['involvements']).to.have.length(1) expect(rows[-1]['involvements'][0]['num_cases']).to.eq(4)
def test_investigator_names(self): allegation = AllegationFactory() investigator = InvestigatorFactory(first_name='Jerome', last_name='Finnigan') InvestigatorAllegationFactory(allegation=allegation, investigator=investigator) attachment_request = AttachmentRequestFactory(allegation=allegation) expect( attachment_request.investigator_names()).to.eq('Jerome Finnigan')
def test_search(self): allegation_1 = AllegationFactory(crid='123456') allegation_2 = AllegationFactory(crid='654321') officer = OfficerFactory(id=123, first_name='Edward', last_name='May') investigator_1 = InvestigatorFactory(first_name='Jerome', last_name='Finnigan') investigator_2 = InvestigatorFactory(officer=officer) InvestigatorAllegationFactory(investigator=investigator_1, allegation=allegation_1) InvestigatorAllegationFactory(investigator=investigator_2, allegation=allegation_2) self.rebuild_index() self.refresh_index() response_1 = InvestigatorCRWorker().search(term='Jerome') response_2 = InvestigatorCRWorker().search(term='May') expect(response_1.hits.total).to.eq(1) expect(response_1.hits[0].investigator_names).to.eq(['Jerome Finnigan']) expect(response_2.hits.total).to.eq(1) expect(response_2.hits[0].investigator_names).to.eq(['Edward May'])
def test_get_queryset(self): expect(CrIndexer().get_queryset().count()).to.eq(0) allegation = AllegationFactory(crid='123456', incident_date=datetime(2017, 7, 27, tzinfo=pytz.utc)) officer = OfficerFactory() OfficerAllegationFactory(allegation=allegation, officer=officer) investigator = InvestigatorFactory(first_name='Jerome', last_name='Finnigan') InvestigatorAllegationFactory(investigator=investigator, allegation=allegation) querysets = CrIndexer().get_queryset() expect(querysets.count()).to.eq(1) allegation = querysets[0] expect(allegation.crid).to.eq('123456') expect(allegation.investigator_names).to.eq(['Jerome Finnigan'])
def test_get_queryset_with_investigator_is_officer(self): allegation = AllegationFactory( crid='654321', incident_date=datetime(2009, 7, 27, tzinfo=pytz.utc), summary='abc') officer = OfficerFactory(id=10, first_name='Edward', last_name='May') OfficerAllegationFactory(allegation=allegation, officer=officer) investigator = InvestigatorFactory(officer=officer) InvestigatorAllegationFactory(investigator=investigator, allegation=allegation) querysets = CrIndexer().get_queryset() expect(querysets.count()).to.eq(1) allegation = querysets[0] expect(allegation.crid).to.eq('654321') expect(allegation.investigator_names).to.eq(['Edward May'])
def test_create_zip_file_already_exist(self, aws_mock): aws_mock.s3.get_object.return_value = {} allegation = AllegationFactory(crid='1') allegation_456 = AllegationFactory(crid='456') AttachmentFileFactory( allegation=allegation, source_type='DOCUMENTCLOUD', external_id='ABC', title='allegation 1 attachment' ) AttachmentFileFactory(allegation=allegation, source_type='COPA') AttachmentFileFactory(allegation=allegation_456, source_type='DOCUMENTCLOUD') AttachmentFileFactory(allegation=allegation_456, source_type='PORTAL_COPA_DOCUMENTCLOUD') officer = OfficerFactory(id=1, first_name='Jerome', last_name='Finnigan') OfficerAllegationFactory(officer=officer, allegation=allegation) allegation_2 = AllegationFactory(crid='2') allegation_789 = AllegationFactory(crid='789') AttachmentFileFactory( allegation=allegation_2, source_type='DOCUMENTCLOUD', external_id='XYZ', title='allegation 2 attachment' ) AttachmentFileFactory(allegation=allegation_2, source_type='COPA') AttachmentFileFactory(allegation=allegation_789, source_type='DOCUMENTCLOUD') AttachmentFileFactory(allegation=allegation_789, source_type='PORTAL_COPA_DOCUMENTCLOUD') investigator = InvestigatorFactory(officer=officer) InvestigatorAllegationFactory(allegation=allegation_2, investigator=investigator) self.client.get(reverse('api-v2:officers-create-zip-file', kwargs={'pk': 1})) aws_mock.s3.get_object.assert_any_call( Bucket='officer_content_bucket', Key='zip_with_docs/Jerome_Finnigan_with_docs.zip' ) aws_mock.s3.get_object.assert_any_call( Bucket='officer_content_bucket', Key='zip/Jerome_Finnigan.zip' ) expect(aws_mock.lambda_client.invoke_async.called).to.be.false()
def test_AirTableUploader_raise_NotImplementedError(self, airtable_mock): airtable_mock.insert.return_value = {'id': 'some_airtable_record_id'} allegation123 = AllegationFactory(crid='123', incident_date=datetime( 2010, 1, 1, tzinfo=pytz.utc)) officer_1 = OfficerFactory(id=1, first_name='Marry', last_name='Jane') officer_2 = OfficerFactory(id=2, first_name='John', last_name='Henry') OfficerAllegationFactory(allegation=allegation123, officer=officer_1) OfficerAllegationFactory(allegation=allegation123, officer=officer_2) investigator = InvestigatorFactory(officer=officer_1) InvestigatorAllegationFactory(allegation=allegation123, investigator=investigator) cr_request_1 = AttachmentRequestFactory(allegation=allegation123, email='*****@*****.**', airtable_id='') allegation456 = AllegationFactory(crid='456') officer_3 = OfficerFactory(id=3, first_name='Marry', last_name='Jane') officer_4 = OfficerFactory(id=4, first_name='John', last_name='Henry') OfficerAllegationFactory(allegation=allegation456, officer=officer_3) OfficerAllegationFactory(allegation=allegation456, officer=officer_4) cr_request_2 = AttachmentRequestFactory(allegation=allegation456, email='*****@*****.**', airtable_id='') expect(AirTableUploader.upload).to.throw(NotImplementedError) with patch( 'airtable_integration.services.document_request_service.AirTableUploader._get_uploaded_objects', return_value=[cr_request_1, cr_request_2]): expect(AirTableUploader.upload).to.throw(NotImplementedError) with patch( 'airtable_integration.services.document_request_service.' 'AirTableUploader._build_data', return_value=('', '', [])): expect(AirTableUploader.upload).to.throw(NotImplementedError) with patch( 'airtable_integration.services.document_request_service.' 'AirTableUploader._post_handle'): AirTableUploader.upload()
def test_request_download(self, aws_mock): aws_mock.s3.get_object.return_value = {} aws_mock.s3.generate_presigned_url.return_value = 'presigned_url' officer = OfficerFactory(id=123, first_name='Jerome', last_name='Finnigan') allegation1 = AllegationFactory() OfficerAllegationFactory(officer=officer, allegation=allegation1) AttachmentFileFactory(allegation=allegation1, id=321, source_type='DOCUMENTCLOUD') investigator = InvestigatorFactory(officer=officer) allegation2 = AllegationFactory() InvestigatorAllegationFactory(investigator=investigator, allegation=allegation2) AttachmentFileFactory(allegation=allegation2, id=322, source_type='PORTAL_COPA_DOCUMENTCLOUD') base_url = reverse('api-v2:officers-request-download', kwargs={'pk': 123}) query = urlencode({'with-docs': 'true'}) response = self.client.get(f'{base_url}?{query}') expect(response.status_code).to.eq(status.HTTP_200_OK) expect(response.data).to.eq('presigned_url') aws_mock.s3.get_object.assert_called_with( Bucket='officer_content_bucket', Key='zip_with_docs/Jerome_Finnigan_with_docs.zip' ) aws_mock.s3.generate_presigned_url.assert_called_with( ClientMethod='get_object', Params={ 'Bucket': 'officer_content_bucket', 'Key': 'zip_with_docs/Jerome_Finnigan_with_docs.zip', } ) events = AttachmentTracking.objects.filter(kind=constants.DOWNLOAD_EVENT_TYPE) expect(events.count()).to.eq(2) expect(set([event.attachment_file.id for event in events])).to.eq(set([321, 322]))
def test_full_name(self): investigator = InvestigatorFactory(first_name='John', last_name='Doe') expect(investigator.full_name).to.eq('John Doe')
def test_Airtable_insert_raise_HTTPError(self, airtable_mock): AirTableUploader._get_foia_airtable().insert = Mock( side_effect=[{ 'id': 'some_airtable_record_id' }, HTTPError]) allegation123 = AllegationFactory(crid='123', incident_date=datetime( 2005, 1, 1, tzinfo=pytz.utc)) officer_1 = OfficerFactory(id=1, first_name='Marry', last_name='Jane') officer_2 = OfficerFactory(id=2, first_name='John', last_name='Henry') OfficerAllegationFactory(allegation=allegation123, officer=officer_1) OfficerAllegationFactory(allegation=allegation123, officer=officer_2) investigator = InvestigatorFactory(officer=officer_1) InvestigatorAllegationFactory(allegation=allegation123, investigator=investigator) attachment_request_1 = AttachmentRequestFactory( allegation=allegation123, email='*****@*****.**') allegation456 = AllegationFactory(crid='456', incident_date=datetime( 2011, 1, 1, tzinfo=pytz.utc)) officer_3 = OfficerFactory(id=3, first_name='Marry', last_name='Jane') officer_4 = OfficerFactory(id=4, first_name='John', last_name='Henry') OfficerAllegationFactory(allegation=allegation456, officer=officer_3) OfficerAllegationFactory(allegation=allegation456, officer=officer_4) attachment_request_2 = AttachmentRequestFactory( allegation=allegation456, email='*****@*****.**') expect(attachment_request_1.airtable_id).to.eq('') expect(attachment_request_2.airtable_id).to.eq('') CRRequestAirTableUploader.upload() attachment_request_1.refresh_from_db() attachment_request_2.refresh_from_db() expected_calls = [ call({ 'Explanation': 'Officers: John Henry(ID 2), Marry Jane(ID 1)', 'Project': ['CPDP'], 'Agency': ['CPD_AGENCY_ID'], 'Requested For': 'CR 123', 'Requestor': [{ 'id': 'usrGiZFcyZ6wHTYWd', 'email': '*****@*****.**', 'name': 'Rajiv Sinclair' }], 'Date requested by user': attachment_request_1.created_at.strftime('%Y-%m-%d'), 'Requester Email': '*****@*****.**' }), call({ 'Explanation': 'Officers: John Henry(ID 4), Marry Jane(ID 3)', 'Project': ['CPDP'], 'Agency': ['COPA_AGENCY_ID'], 'Requested For': 'CR 456', 'Requestor': [{ 'id': 'usrGiZFcyZ6wHTYWd', 'email': '*****@*****.**', 'name': 'Rajiv Sinclair' }], 'Date requested by user': attachment_request_2.created_at.strftime('%Y-%m-%d'), 'Requester Email': '*****@*****.**' }) ] airtable_mock.insert.assert_has_calls(expected_calls, any_order=True) expect( attachment_request_1.airtable_id).to.eq('some_airtable_record_id') expect(attachment_request_2.airtable_id).to.eq('')
def test_abbr_name(self): investigator = InvestigatorFactory(first_name='John', last_name='Doe') expect(investigator.abbr_name).to.eq('J. Doe')
def test_annotate_investigated_by_cpd(self): allegation_1 = AllegationFactory(crid='001', incident_date=datetime( 2005, 12, 31, tzinfo=pytz.utc)) allegation_2 = AllegationFactory(crid='002', incident_date=datetime( 2007, 12, 31, tzinfo=pytz.utc)) allegation_3 = AllegationFactory(crid='003', incident_date=datetime( 2007, 12, 31, tzinfo=pytz.utc)) allegation_4 = AllegationFactory(crid='004', incident_date=datetime( 2007, 12, 31, tzinfo=pytz.utc)) allegation_5 = AllegationFactory(crid='005', incident_date=datetime( 2007, 12, 31, tzinfo=pytz.utc)) allegation_6 = AllegationFactory(crid='006', incident_date=datetime( 2007, 12, 31, tzinfo=pytz.utc)) attachment_request_1 = AttachmentRequestFactory( allegation=allegation_1) attachment_request_2 = AttachmentRequestFactory( allegation=allegation_2) attachment_request_3 = AttachmentRequestFactory( allegation=allegation_3) attachment_request_4 = AttachmentRequestFactory( allegation=allegation_4) attachment_request_5 = AttachmentRequestFactory( allegation=allegation_5) attachment_request_6 = AttachmentRequestFactory( allegation=allegation_6) officer_1 = OfficerFactory() officer_2 = OfficerFactory() OfficerBadgeNumberFactory(officer=officer_2, star='12345') investigator_1 = InvestigatorFactory(officer=officer_1) investigator_2 = InvestigatorFactory(officer=officer_2) InvestigatorAllegationFactory(allegation=allegation_3, current_star='123456') InvestigatorAllegationFactory(allegation=allegation_5, current_star=None, investigator=investigator_1) InvestigatorAllegationFactory(allegation=allegation_6, current_star=None, investigator=investigator_2) expected_results = { attachment_request_1.id: True, attachment_request_2.id: False, attachment_request_3.id: True, attachment_request_4.id: False, attachment_request_5.id: False, attachment_request_6.id: True, } for attachment_request in AttachmentRequest.objects.annotate_investigated_by_cpd( ): expect(attachment_request.investigated_by_cpd).to.be.eq( expected_results[attachment_request.id])
def test_export_xlsx(self): allegation = AllegationFactory(crid='123') AttachmentFileFactory( allegation=allegation, source_type='DOCUMENTCLOUD', title='CRID 1045950 CR Original Case Incident Report 1 of 5', url='https://assets.documentcloud.org/documents/5679592/CRID.pdf', external_created_at=datetime(2019, 1, 9, 9, 11, 38, 41928, tzinfo=pytz.utc), text_content='CHICAGO POLICE DEPARTMENT RD I HT334604', ) AttachmentFileFactory( allegation=allegation, source_type='PORTAL_COPA_DOCUMENTCLOUD', title='CRID 1045950 CR Original Case Incident Report 2 of 5', url='https://assets.documentcloud.org/documents/5678901/CRID.pdf', external_created_at=datetime(2019, 1, 9, 9, 11, 38, 41929, tzinfo=pytz.utc), text_content='CHICAGO POLICE DEPARTMENT RD I HT334604', ) AttachmentFileFactory(allegation=allegation, source_type='COPA') AttachmentFileFactory(source_type='DOCUMENTCLOUD') officer = OfficerFactory(id=1) OfficerAllegationFactory(officer=officer, allegation=allegation) allegation456 = AllegationFactory(crid='456') AttachmentFileFactory( allegation=allegation456, source_type='DOCUMENTCLOUD', title='CRID 1041253 CR Original Case Incident Report 1 of 5', url='https://assets.documentcloud.org/documents/1041253/CRID.pdf', external_created_at=datetime(2019, 1, 8, 9, 11, 38, 41928, tzinfo=pytz.utc), text_content='CHICAGO POLICE DEPARTMENT RD I HT334111', ) AttachmentFileFactory( allegation=allegation456, source_type='PORTAL_COPA_DOCUMENTCLOUD', title='CRID 1041253 CR Original Case Incident Report 2 of 5', url='https://assets.documentcloud.org/documents/1041253/CRID.pdf', external_created_at=datetime(2019, 1, 8, 9, 11, 38, 41927, tzinfo=pytz.utc), text_content='CHICAGO POLICE DEPARTMENT RD I HT334111', ) AttachmentFileFactory(allegation=allegation456, source_type='COPA') AttachmentFileFactory(source_type='DOCUMENTCLOUD') AttachmentFileFactory(source_type='PORTAL_COPA_DOCUMENTCLOUD') investigator = InvestigatorFactory(officer=officer) InvestigatorAllegationFactory(allegation=allegation456, investigator=investigator) writer = DocumentsXlsxWriter(officer, self.test_output_dir) writer.export_xlsx() self.covert_xlsx_to_csv('documents.xlsx') self.assert_csv_files_equal( 'documents_1', ['Complaint Documents', 'Investigation Documents'])
def test_retrieve(self): area = AreaFactory(name='Lincoln Square') officer1 = OfficerFactory( id=123, first_name='Mr', last_name='Foo', gender='M', race='White', rank='Officer', appointed_date=date(2001, 1, 1), birth_year=1993, complaint_percentile=4.4, civilian_allegation_percentile=1.1, internal_allegation_percentile=2.2, trr_percentile=3.3, allegation_count=1, sustained_count=1, ) OfficerBadgeNumberFactory(officer=officer1, star='12345', current=True) allegation = AllegationFactory(crid='12345', point=Point(12, 21), incident_date=datetime(2002, 2, 28, tzinfo=pytz.utc), add1=3510, add2='Michigan Ave', city='Chicago', location='Police Communications System', beat=area, is_officer_complaint=False, summary='Summary', first_start_date=date(2003, 3, 20), first_end_date=date(2006, 5, 26)) ComplainantFactory(allegation=allegation, gender='M', race='Black', age='18') VictimFactory(allegation=allegation, gender='M', race='Black', age=53) OfficerAllegationFactory( officer=officer1, allegation=allegation, final_finding='SU', disciplined=True, final_outcome='Separation', recc_outcome='10 Day Suspension', start_date=date(2003, 3, 20), end_date=date(2006, 5, 26), allegation_category=AllegationCategoryFactory( category='Operation/Personnel Violations', allegation_name='Secondary/Special Employment')) officer = OfficerFactory( id=3, first_name='Raymond', last_name='Piwinicki', appointed_date=date(2001, 5, 1), complaint_percentile=4.4, trr_percentile=5.5, allegation_count=1, sustained_count=1, ) OfficerAllegationFactory(officer=officer, final_finding='SU', start_date=date(2003, 2, 28), allegation__incident_date=datetime( 2002, 2, 28, tzinfo=pytz.utc), allegation__is_officer_complaint=False) PoliceWitnessFactory(officer=officer, allegation=allegation) investigator = OfficerFactory( id=1, first_name='Ellis', last_name='Skol', appointed_date=date(2001, 5, 1), complaint_percentile=6.6, civilian_allegation_percentile=7.7, internal_allegation_percentile=8.8, allegation_count=1, sustained_count=0, ) OfficerAllegationFactory(officer=investigator, final_finding='NS', start_date=date(2003, 2, 28), allegation__incident_date=datetime( 2002, 2, 28, tzinfo=pytz.utc), allegation__is_officer_complaint=False) investigator = InvestigatorFactory(officer=investigator) InvestigatorAllegationFactory(allegation=allegation, investigator=investigator, current_rank='IPRA investigator') AttachmentFileFactory(tag='TRR', allegation=allegation, title='CR document', id='123456', url='http://cr-document.com/', file_type=MEDIA_TYPE_DOCUMENT) AttachmentFileFactory(tag='TRR', allegation=allegation, title='CR arrest report document', url='http://cr-document.com/', file_type=MEDIA_TYPE_DOCUMENT) AttachmentFileFactory(tag='AR', allegation=allegation, title='CR document 2', id='654321', url='http://AR-document.com/', file_type=MEDIA_TYPE_DOCUMENT) officer_cache_manager.build_cached_columns() allegation_cache_manager.cache_data() response = self.client.get( reverse('api-v2:cr-detail', kwargs={'pk': '12345'})) expect(response.status_code).to.eq(status.HTTP_200_OK) expect(dict(response.data)).to.eq({ 'crid': '12345', 'most_common_category': { 'category': 'Operation/Personnel Violations', 'allegation_name': 'Secondary/Special Employment' }, 'coaccused': [{ 'id': 123, 'full_name': 'Mr Foo', 'gender': 'Male', 'race': 'White', 'rank': 'Officer', 'birth_year': 1993, 'recommended_outcome': '10 Day Suspension', 'final_outcome': 'Separation', 'final_finding': 'Sustained', 'category': 'Operation/Personnel Violations', 'complaint_count': 1, 'sustained_count': 1, 'percentile_allegation': '4.4000', 'percentile_allegation_civilian': '1.1000', 'percentile_allegation_internal': '2.2000', 'percentile_trr': '3.3000', 'disciplined': True }], 'complainants': [{ 'race': 'Black', 'gender': 'Male', 'age': 18 }], 'victims': [{ 'race': 'Black', 'gender': 'Male', 'age': 53 }], 'point': { 'lon': 12.0, 'lat': 21.0 }, 'summary': 'Summary', 'incident_date': '2002-02-28', 'start_date': '2003-03-20', 'end_date': '2006-05-26', 'address': '3510 Michigan Ave, Chicago', 'location': 'Police Communications System', 'beat': 'Lincoln Square', 'involvements': [{ 'involved_type': 'investigator', 'officer_id': 1, 'full_name': 'Ellis Skol', 'badge': 'CPD', 'percentile_allegation': '6.6000', 'percentile_allegation_civilian': '7.7000', 'percentile_allegation_internal': '8.8000', }, { 'involved_type': 'police_witness', 'officer_id': 3, 'full_name': 'Raymond Piwinicki', 'allegation_count': 1, 'sustained_count': 1, 'percentile_trr': '5.5000', 'percentile_allegation': '4.4000', }], 'attachments': [{ 'title': 'CR document', 'file_type': 'document', 'url': 'http://cr-document.com/', 'id': '123456', }] })
def test_emit_correct_format(self): allegation = AllegationFactory( crid='12345', summary='Summary', point=Point(12, 21), incident_date=datetime(2002, 2, 28, tzinfo=pytz.utc), add1='3510', add2='Michigan Ave', city='Chicago', location='Police Building', beat=AreaFactory(name='23'), is_officer_complaint=False, first_start_date=date(2003, 3, 28), first_end_date=date(2003, 4, 28), ) coaccused = OfficerFactory( id=1, first_name='Foo', last_name='Bar', gender='M', race='White', birth_year=1986, appointed_date=date(2001, 1, 1), rank='Officer', complaint_percentile=Decimal(0), civilian_allegation_percentile=Decimal(1.1), internal_allegation_percentile=Decimal(2.2), trr_percentile=Decimal(3.3), allegation_count=1, sustained_count=1, ) OfficerAllegationFactory( officer=coaccused, allegation=allegation, final_finding='SU', recc_outcome='Separation', final_outcome='Reprimand', start_date=date(2003, 3, 28), end_date=date(2003, 4, 28), allegation_category=AllegationCategoryFactory( category='Operation/Personnel Violations', allegation_name='NEGLECT OF DUTY/CONDUCT UNBECOMING - ON DUTY' ), disciplined=True ) ComplainantFactory(allegation=allegation, gender='M', race='White', age=30) ComplainantFactory(allegation=allegation, gender='F', race='Black', age=25) VictimFactory(allegation=allegation, gender='F', race='Black', age=25) VictimFactory(allegation=allegation, gender='M', race='Hispanic', age=40) officer = OfficerFactory( id=2, first_name='Jerome', last_name='Finnigan', gender='M', appointed_date=date(2001, 5, 1), complaint_percentile=4.4, trr_percentile=5.5, allegation_count=1, sustained_count=1, ) OfficerAllegationFactory( officer=officer, final_finding='SU', start_date=date(2003, 2, 28), allegation__incident_date=datetime(2002, 2, 28, tzinfo=pytz.utc), allegation__is_officer_complaint=False ) PoliceWitnessFactory(officer=officer, allegation=allegation) investigator = OfficerFactory( id=3, first_name='German', last_name='Lauren', appointed_date=date(2001, 5, 1), complaint_percentile=6.6, civilian_allegation_percentile=7.7, internal_allegation_percentile=8.8, allegation_count=1, sustained_count=0, ) OfficerAllegationFactory( officer=investigator, final_finding='NS', start_date=date(2003, 2, 28), allegation__incident_date=datetime(2002, 2, 28, tzinfo=pytz.utc), allegation__is_officer_complaint=False ) investigator = InvestigatorFactory(officer=investigator) InvestigatorAllegationFactory( allegation=allegation, investigator=investigator, current_rank='IPRA investigator' ) AttachmentFileFactory( tag='Other', allegation=allegation, file_type='document', title='CR document', url='http://foo.com/', preview_image_url='http://web.com/image', ) AttachmentFileFactory( tag='Other', allegation=allegation, file_type='document', title='CR document', url='http://foo.com/', preview_image_url='http://web.com/image', show=False ) AttachmentFileFactory( allegation=allegation, file_type='document', tag='OCIR', title='CR document', url='http://foo.com/', preview_image_url='http://web.com/image', ) indexer = CRIndexer() rows = list(indexer.get_queryset()) row = [obj for obj in rows if obj['crid'] == '12345'][0] result = indexer.extract_datum(row) expect(dict(result)).to.eq({ 'crid': '12345', 'most_common_category': { 'category': 'Operation/Personnel Violations', 'allegation_name': 'NEGLECT OF DUTY/CONDUCT UNBECOMING - ON DUTY' }, 'category_names': ['Operation/Personnel Violations'], 'coaccused': [ { 'id': 1, 'full_name': 'Foo Bar', 'abbr_name': 'F. Bar', 'gender': 'Male', 'race': 'White', 'rank': 'Officer', 'final_finding': 'Sustained', 'recc_outcome': 'Separation', 'final_outcome': 'Reprimand', 'category': 'Operation/Personnel Violations', 'subcategory': 'NEGLECT OF DUTY/CONDUCT UNBECOMING - ON DUTY', 'start_date': '2003-03-28', 'end_date': '2003-04-28', 'age': 32, 'allegation_count': 1, 'sustained_count': 1, 'percentile_allegation': Decimal('0'), 'percentile_allegation_civilian': Decimal('1.1'), 'percentile_allegation_internal': Decimal('2.2'), 'percentile_trr': Decimal('3.3'), 'disciplined': True } ], 'complainants': [ {'gender': 'Male', 'race': 'White', 'age': 30}, {'gender': 'Female', 'race': 'Black', 'age': 25} ], 'victims': [ {'gender': 'Female', 'race': 'Black', 'age': 25}, {'gender': 'Male', 'race': 'Hispanic', 'age': 40} ], 'summary': 'Summary', 'point': {'lon': 12.0, 'lat': 21.0}, 'incident_date': '2002-02-28', 'start_date': '2003-03-28', 'end_date': '2003-04-28', 'address': '3510 Michigan Ave, Chicago', 'location': 'Police Building', 'beat': '23', 'involvements': [ { 'involved_type': 'investigator', 'officer_id': 3, 'full_name': 'German Lauren', 'abbr_name': 'G. Lauren', 'num_cases': 1, 'current_rank': 'IPRA investigator', 'percentile_allegation': Decimal('6.6000'), 'percentile_allegation_civilian': Decimal('7.7000'), 'percentile_allegation_internal': Decimal('8.8000'), 'percentile_trr': None }, { 'involved_type': 'police_witness', 'officer_id': 2, 'full_name': 'Jerome Finnigan', 'abbr_name': 'J. Finnigan', 'gender': 'Male', 'race': 'White', 'allegation_count': 1, 'sustained_count': 1, 'percentile_allegation': Decimal('4.4000'), 'percentile_allegation_civilian': None, 'percentile_allegation_internal': None, 'percentile_trr': Decimal('5.5000') } ], 'attachments': [ { 'title': 'CR document', 'file_type': 'document', 'url': 'http://foo.com/', 'preview_image_url': 'http://web.com/image' } ] })
def test_export_officer_xlsx_investigator(self): investigator = InvestigatorFactory(officer=OfficerFactory(id=1234)) allegation = AllegationFactory( crid='1009678', location='Tavern/Liquor Store', add1='37XX', add2='W 63RD ST', city='CHICAGO IL', old_complaint_address=None, incident_date=datetime(2007, 9, 28, 0, 0, tzinfo=pytz.utc), beat=AreaFactory(name='0823'), is_officer_complaint=True, coaccused_count=19 ) allegation1 = AllegationFactory( crid='1012803', location='Public Way - Other', add1='31XX', add2='N NEWCASTLE AVE', city='CHICAGO IL', old_complaint_address=None, incident_date=datetime(2005, 11, 1, 0, 0, tzinfo=pytz.utc), beat=AreaFactory(name='2511'), is_officer_complaint=False, coaccused_count=9 ) InvestigatorAllegationFactory(investigator=investigator, allegation=allegation) InvestigatorAllegationFactory(investigator=investigator, allegation=allegation1) officer = OfficerFactory( first_name='Jerome', last_name='Finnigan', middle_initial='A', middle_initial2=None, suffix_name=None, gender='M', race='White', appointed_date=date(1988, 12, 5), resignation_date=date(2008, 8, 5), rank='Police Officer', birth_year=1963, active='No', complaint_percentile=Decimal('99.9751'), civilian_allegation_percentile=Decimal('99.9778'), internal_allegation_percentile=Decimal('99.8056'), trr_percentile=Decimal('64.3694'), honorable_mention_percentile=Decimal('0.0000'), allegation_count=175, sustained_count=6, honorable_mention_count=1, unsustained_count=112, discipline_count=2, civilian_compliment_count=0, trr_count=1, major_award_count=0, current_badge='5167', last_unit=PoliceUnitFactory(unit_name='003'), current_salary=73116, ) officer1 = OfficerFactory( first_name='Jeffery', last_name='Aaron', middle_initial='M', middle_initial2=None, suffix_name=None, gender='M', race='White', appointed_date=date(2005, 9, 26), resignation_date=None, rank='Sergeant of Police', birth_year=1971, active='Yes', complaint_percentile=Decimal('61.2357'), civilian_allegation_percentile=Decimal('61.2069'), internal_allegation_percentile=Decimal('76.9384'), trr_percentile=Decimal('79.8763'), honorable_mention_percentile=Decimal('94.8669'), allegation_count=6, sustained_count=0, honorable_mention_count=61, unsustained_count=0, discipline_count=0, civilian_compliment_count=4, trr_count=7, major_award_count=0, current_badge='1424', last_unit=PoliceUnitFactory(unit_name='003'), current_salary=101442, ) officer2 = OfficerFactory( first_name='Karina', last_name='Aaron', middle_initial=None, middle_initial2=None, suffix_name=None, gender='F', race='Hispanic', appointed_date=date(2005, 9, 26), resignation_date=None, rank='Police Officer', birth_year=1980, active='Yes', complaint_percentile=Decimal('72.0378'), civilian_allegation_percentile=Decimal('76.4252'), internal_allegation_percentile=Decimal('0.0000'), trr_percentile=Decimal('67.4458'), honorable_mention_percentile=Decimal('96.0992'), allegation_count=8, sustained_count=0, honorable_mention_count=71, unsustained_count=2, discipline_count=0, civilian_compliment_count=2, trr_count=4, major_award_count=0, current_badge='20373', last_unit=PoliceUnitFactory(unit_name='001'), current_salary=94122, ) allegation_category = AllegationCategoryFactory( category='Illegal Search', allegation_name='Improper Search Of Person', ) allegation_category1 = AllegationCategoryFactory( category='False Arrest', allegation_name='Illegal Arrest / False Arrest', ) OfficerAllegationFactory( officer=officer, allegation=allegation, allegation_category=allegation_category, start_date=date(2007, 9, 28), end_date=None, recc_finding='', recc_outcome='Unknown', final_finding='', final_outcome='Unknown', disciplined=None, ) OfficerAllegationFactory( officer=officer, allegation=allegation1, allegation_category=allegation_category1, start_date=date(2007, 12, 21), end_date=date(2008, 5, 29), recc_finding='', recc_outcome='Unknown', final_finding='', final_outcome='Unknown', disciplined=None, ) OfficerAllegationFactory( officer=officer1, allegation=allegation, allegation_category=allegation_category, start_date=date(1967, 10, 21), end_date=date(1980, 8, 1), recc_finding='', recc_outcome='Unknown', final_finding='SU', final_outcome='30 Day Suspension', disciplined=True, ) OfficerAllegationFactory( officer=officer2, allegation=allegation, allegation_category=allegation_category, start_date=date(1970, 8, 13), end_date=date(1973, 9, 15), recc_finding='', recc_outcome='Unknown', final_finding='SU', final_outcome='Suspended Over 30 Days', final_outcome_class='', disciplined=True, ) VictimFactory( allegation=allegation, gender='M', race='Hispanic', birth_year=1973, ) VictimFactory( allegation=allegation1, gender='', race='', birth_year=None, ) witness = OfficerFactory( first_name='Jeffery', last_name='Aaron', middle_initial='M', middle_initial2=None, suffix_name=None, gender='M', race='White', appointed_date=date(2005, 9, 26), resignation_date=None, rank='Sergeant of Police', birth_year=1971, active='Yes', complaint_percentile=Decimal('61.2357'), civilian_allegation_percentile=Decimal('61.2069'), internal_allegation_percentile=Decimal('76.9384'), trr_percentile=Decimal('79.8763'), honorable_mention_percentile=Decimal('94.8669'), allegation_count=6, sustained_count=0, honorable_mention_count=61, unsustained_count=0, discipline_count=0, civilian_compliment_count=4, trr_count=7, major_award_count=0, current_badge='1424', last_unit=PoliceUnitFactory(unit_name='003'), current_salary=101442, ) PoliceWitnessFactory( officer=witness, allegation=allegation, ) export_officer_xlsx(investigator.officer, self.test_output_dir) self.covert_xlsx_to_csv('investigator.xlsx') self.assert_csv_files_equal( expectation_dir='investigator_1234', sheet_names=['Allegation', 'Accused Officer', 'Beat', 'Police Witness', 'Victim'] )
def test_num_cases(self): investigator = InvestigatorFactory() InvestigatorAllegationFactory(investigator=investigator) expect(investigator.num_cases).to.eq(1)
def test_upload_document_requests(self, airtable_mock): airtable_mock.insert.return_value = {'id': 'airtable_id'} allegation123 = AllegationFactory(crid='123', incident_date=datetime(2005, 1, 1, tzinfo=pytz.utc)) officer_1 = OfficerFactory(id=1, first_name='Marry', last_name='Jane') officer_2 = OfficerFactory(id=2, first_name='John', last_name='Henry') OfficerAllegationFactory(allegation=allegation123, officer=officer_1) OfficerAllegationFactory(allegation=allegation123, officer=officer_2) investigator = InvestigatorFactory(officer=officer_1) InvestigatorAllegationFactory(allegation=allegation123, investigator=investigator) cr_request_1 = AttachmentRequestFactory( allegation=allegation123, email='*****@*****.**', airtable_id='') AttachmentRequestFactory( allegation=allegation123, email='*****@*****.**', airtable_id='cr2222') allegation456 = AllegationFactory(crid='456', incident_date=datetime(2010, 1, 1, tzinfo=pytz.utc)) officer_3 = OfficerFactory(id=3, first_name='Marry', last_name='Jane') officer_4 = OfficerFactory(id=4, first_name='John', last_name='Henry') OfficerAllegationFactory(allegation=allegation456, officer=officer_3) OfficerAllegationFactory(allegation=allegation456, officer=officer_4) cr_request_2 = AttachmentRequestFactory( allegation=allegation456, email='*****@*****.**', airtable_id='') AttachmentRequestFactory( allegation=allegation456, email='*****@*****.**', airtable_id='cr4444') trr = TRRFactory(id='123456', officer=officer_1) trr_request = TRRAttachmentRequestFactory( trr=trr, email='*****@*****.**', airtable_id='') TRRAttachmentRequestFactory( trr=trr, email='*****@*****.**', airtable_id='trr2222') expect(AttachmentRequest.objects.filter(airtable_id='').count()).to.eq(2) expect(TRRAttachmentRequest.objects.filter(airtable_id='').count()).to.eq(1) management.call_command('upload_document_requests') expected_calls = [ call({ 'Explanation': 'Officers: John Henry(ID 2), Marry Jane(ID 1)', 'Project': [ 'CPDP' ], 'Agency': ['CPD_AGENCY_ID'], 'Requested For': 'CR 123', 'Requestor': [ { 'id': 'usrGiZFcyZ6wHTYWd', 'email': '*****@*****.**', 'name': 'Rajiv Sinclair' } ], 'Date requested by user': cr_request_1.created_at.strftime('%Y-%m-%d'), 'Requester Email': '*****@*****.**', }), call({ 'Explanation': 'Officers: John Henry(ID 4), Marry Jane(ID 3)', 'Project': [ 'CPDP' ], 'Agency': ['COPA_AGENCY_ID'], 'Requested For': 'CR 456', 'Requestor': [ { 'id': 'usrGiZFcyZ6wHTYWd', 'email': '*****@*****.**', 'name': 'Rajiv Sinclair' } ], 'Date requested by user': cr_request_2.created_at.strftime('%Y-%m-%d'), 'Requester Email': '*****@*****.**', }), call({ 'Explanation': 'Officer: Marry Jane(ID 1)', 'Project': [ 'CPDP' ], 'Agency': [], 'Requested For': 'TRR 123456', 'Requestor': [ { 'id': 'usrGiZFcyZ6wHTYWd', 'email': '*****@*****.**', 'name': 'Rajiv Sinclair' } ], 'Date requested by user': trr_request.created_at.strftime('%Y-%m-%d'), 'Requester Email': '*****@*****.**', }) ] airtable_mock.insert.assert_has_calls(expected_calls, any_order=True) expect(AttachmentRequest.objects.filter(airtable_id='').count()).to.eq(0) expect(TRRAttachmentRequest.objects.filter(airtable_id='').count()).to.eq(0)