def test_search_with_apostrophe(self): allegation_category = AllegationCategoryFactory(category='Use of Force') allegation_1 = AllegationFactory( crid='C12345', incident_date=datetime(2007, 1, 1, tzinfo=pytz.utc), most_common_category=allegation_category, ) allegation_2 = AllegationFactory( crid='C12346', incident_date=datetime(2007, 1, 1, tzinfo=pytz.utc), most_common_category=allegation_category, ) allegation_3 = AllegationFactory( crid='C12347', incident_date=datetime(2007, 1, 1, tzinfo=pytz.utc), most_common_category=allegation_category, ) allegation_4 = AllegationFactory( crid='C12348', incident_date=datetime(2007, 1, 1, tzinfo=pytz.utc), most_common_category=allegation_category, ) AttachmentFileFactory(text_content='Name: OBrien', allegation=allegation_1) AttachmentFileFactory(text_content='Name: O\'Brien', allegation=allegation_2) AttachmentFileFactory(text_content='Name: O Brien', allegation=allegation_3) AttachmentFileFactory(text_content='Name: Jim', allegation=allegation_4) self.rebuild_index() self.refresh_index() response = self.client.get(reverse('api:suggestion-list'), { 'term': 'O\'Brien', }) sorted_cr_results = list(sorted(response.data['CR'], key=lambda cr: cr['crid'])) print(sorted_cr_results) expect(len(sorted_cr_results)).to.eq(3) expect(sorted_cr_results[0]['crid']).to.eq('C12345') expect(sorted_cr_results[0]['highlight']['text_content']).to.eq(['Name: O<em>Brien</em>']) expect(sorted_cr_results[1]['crid']).to.eq('C12346') expect(sorted_cr_results[1]['highlight']['text_content']).to.eq(['Name: O\'<em>Brien</em>']) expect(sorted_cr_results[2]['crid']).to.eq('C12347') expect(sorted_cr_results[2]['highlight']['text_content']).to.eq(['Name: O <em>Brien</em>'])
def test_complaint_category_aggregation(self): officer = OfficerFactory() allegation_category = AllegationCategoryFactory( category='Use of Force') OfficerAllegationFactory(officer=officer, allegation=AllegationFactory(), allegation_category=allegation_category, start_date=None, final_finding='NS') OfficerAllegationFactory(officer=officer, allegation=AllegationFactory(), allegation_category=allegation_category, start_date=date(2010, 1, 1), final_finding='NS') OfficerAllegationFactory(officer=officer, allegation=AllegationFactory(), allegation_category=allegation_category, start_date=date(2011, 1, 1), final_finding='SU') expect(officer.complaint_category_aggregation).to.eq([{ 'name': 'Use of Force', 'count': 3, 'sustained_count': 1, 'items': [{ 'year': 2010, 'count': 1, 'sustained_count': 0, 'name': 'Use of Force' }, { 'year': 2011, 'count': 1, 'sustained_count': 1, 'name': 'Use of Force' }] }])
def test_complaint_category_aggregation_with_duplicated_allegation(self): unit = PoliceUnitFactory() officer1 = OfficerFactory() officer2 = OfficerFactory() allegation = AllegationFactory() allegation_category = AllegationCategoryFactory( category='Use of Force') OfficerHistoryFactory(officer=officer1, unit=unit) OfficerHistoryFactory(officer=officer2, unit=unit) OfficerAllegationFactory(officer=officer1, allegation=allegation, allegation_category=allegation_category, final_finding='NS') OfficerAllegationFactory(officer=officer2, allegation=allegation, allegation_category=allegation_category, final_finding='NS') expect(unit.complaint_category_aggregation).to.eq([{ 'name': 'Use of Force', 'count': 1, 'sustained_count': 0 }])
def test_retrieve_recent_search_items(self): OfficerFactory(id=8562, first_name='Jerome', last_name='Finnigan', current_badge='123456') allegation_category = AllegationCategoryFactory( category='Use of Force') AllegationFactory( crid='C12345', incident_date=datetime(2007, 1, 1, tzinfo=pytz.utc), most_common_category=allegation_category, ) TRRFactory(id=123) url = reverse('api-v2:search-mobile-recent-search-items') response = self.client.get(url, { 'officer_ids[]': 8562, 'crids[]': 'C12345', 'trr_ids[]': 123, }) expect(response.status_code).to.eq(status.HTTP_200_OK) expect(response.data).to.eq([{ 'id': 8562, 'name': 'Jerome Finnigan', 'badge': '123456', 'type': 'OFFICER', }, { 'id': 'C12345', 'crid': 'C12345', 'incident_date': '2007-01-01', 'category': 'Use of Force', 'type': 'CR', }, { 'id': 123, 'type': 'TRR', }])
def test_serialization(self): category = AllegationCategoryFactory(category='Use of Force', allegation_name='Subcategory') allegation = AllegationFactory( crid=123, old_complaint_address='16XX N TALMAN AVE, CHICAGO IL', most_common_category=category, incident_date=datetime(2002, 1, 1, tzinfo=pytz.utc), coaccused_count=12, point=Point(-35.5, 68.9), ) expect(AllegationMobileSerializer(allegation).data).to.eq({ 'crid': '123', 'category': 'Use of Force', 'incident_date': '2002-01-01', 'point': { 'lon': -35.5, 'lat': 68.9 }, })
def test_request_complaint_summary(self): allegation = AllegationFactory(crid='11', incident_date=datetime(2002, 2, 28, tzinfo=pytz.utc), summary='Summary') category = AllegationCategoryFactory(category='Use of Force') OfficerAllegationFactory( allegation=allegation, officer=OfficerFactory(appointed_date=date(2001, 1, 1)), start_date=date(2003, 2, 28), end_date=date(2004, 4, 28), allegation_category=category) OfficerAllegationFactory( allegation=allegation, officer=OfficerFactory(appointed_date=date(2001, 1, 1)), start_date=date(2003, 2, 28), end_date=date(2004, 4, 28), allegation_category=None) officer_cache_manager.build_cached_yearly_percentiles() officer_cache_manager.build_cached_columns() allegation_cache_manager.cache_data() response = self.client.get(reverse('api-v2:cr-complaint-summaries')) expect(response.status_code).to.eq(status.HTTP_200_OK) expect(response.data).to.eq([{ 'crid': '11', 'category_names': ['Unknown', 'Use of Force'], 'incident_date': '2002-02-28', 'summary': 'Summary' }])
def test_serialization(self): category = AllegationCategoryFactory(category='Use of Force', allegation_name='Subcategory') allegation = AllegationFactory( crid=123, old_complaint_address='16XX N TALMAN AVE, CHICAGO IL', most_common_category=category, incident_date=datetime(2002, 1, 1, tzinfo=pytz.utc), coaccused_count=12, point=Point(-35.5, 68.9), ) VictimFactory( gender='M', race='Black', age=35, allegation=allegation ) expect(AllegationSerializer(allegation).data).to.eq({ 'crid': '123', 'address': '16XX N TALMAN AVE, CHICAGO IL', 'category': 'Use of Force', 'incident_date': '2002-01-01', 'victims': [ { 'gender': 'Male', 'race': 'Black', 'age': 35 } ], 'point': { 'lon': -35.5, 'lat': 68.9 }, 'to': '/complaint/123/', 'sub_category': 'Subcategory', })
def test_cr_new_documents(self): allegation_1 = AllegationFactory(crid='123', incident_date=datetime( 2001, 2, 28, tzinfo=pytz.utc)) allegation_2 = AllegationFactory(crid='456', incident_date=datetime( 2002, 2, 28, tzinfo=pytz.utc)) allegation_3 = AllegationFactory(crid='789', incident_date=datetime( 2003, 2, 28, tzinfo=pytz.utc)) allegation_4 = AllegationFactory(crid='321', incident_date=datetime( 2004, 2, 28, tzinfo=pytz.utc)) allegation_5 = AllegationFactory(crid='987', incident_date=datetime( 2005, 2, 28, tzinfo=pytz.utc)) allegation_category_1 = AllegationCategoryFactory( id=1, category='Category 1') allegation_category_12 = AllegationCategoryFactory( id=2, category='Category 2') OfficerAllegationFactory(allegation=allegation_1, allegation_category=allegation_category_1) OfficerAllegationFactory(allegation=allegation_1, allegation_category=allegation_category_1) OfficerAllegationFactory(allegation=allegation_1, allegation_category=allegation_category_12) AttachmentFileFactory(allegation=allegation_1, title='CR document 1', id=1, tag='CR', url='http://cr-document.com/1', file_type=MEDIA_TYPE_DOCUMENT, preview_image_url='http://preview.com/url1', external_created_at=datetime(2019, 1, 19, 12, 1, 1, tzinfo=pytz.utc)) AttachmentFileFactory(allegation=allegation_1, title='CR document 2', id=2, tag='CR', url='http://cr-document.com/2', file_type=MEDIA_TYPE_DOCUMENT, external_created_at=datetime(2019, 1, 14, 10, 12, 1, tzinfo=pytz.utc)) AttachmentFileFactory(allegation=allegation_2, title='CR document 3', id=3, tag='CR', url='http://cr-document.com/3', file_type=MEDIA_TYPE_DOCUMENT, preview_image_url='http://preview.com/url3', external_created_at=datetime(2019, 1, 15, 9, 3, 1, tzinfo=pytz.utc)) AttachmentFileFactory(allegation=allegation_2, title='CR document 4', id=4, tag='OCIR', url='http://cr-document.com/4', file_type=MEDIA_TYPE_DOCUMENT, preview_image_url='http://preview.com/url4', external_created_at=datetime(2019, 1, 19, 17, 12, 5, tzinfo=pytz.utc)) with freeze_time(datetime(2019, 1, 20, 13, 2, 15, tzinfo=pytz.utc)): AttachmentFileFactory(allegation=allegation_2, title='CR document 5', id=5, tag='AR', url='http://cr-document.com/5', file_type=MEDIA_TYPE_DOCUMENT, preview_image_url='http://preview.com/url5', external_created_at=None) AttachmentFileFactory(allegation=allegation_3, title='CR document 6', id=6, tag='CR', url='http://cr-document.com/6', file_type=MEDIA_TYPE_AUDIO, preview_image_url='http://preview.com/url6', external_created_at=datetime(2019, 1, 21, 6, 4, 12, tzinfo=pytz.utc)) AttachmentFileFactory(allegation=allegation_3, title='CR document 7', id=7, tag='CR', url='http://cr-document.com/7', file_type=MEDIA_TYPE_VIDEO, preview_image_url='http://preview.com/url7', external_created_at=datetime(2019, 1, 22, 4, 9, 12, tzinfo=pytz.utc)) attachment_file_1 = AttachmentFileFactory( title='Tracking document 1', id=8, tag='CR', url='http://cr-document.com/8', file_type=MEDIA_TYPE_DOCUMENT, preview_image_url='http://preview.com/url8', allegation=allegation_4, external_created_at=datetime(2014, 9, 14, 12, 0, 1, tzinfo=pytz.utc)) attachment_file_2 = AttachmentFileFactory( title='Tracking document 2', id=9, tag='CR', url='http://cr-document.com/9', file_type=MEDIA_TYPE_DOCUMENT, preview_image_url='http://preview.com/url9', allegation=allegation_4, external_created_at=datetime(2015, 9, 14, 12, 0, 1, tzinfo=pytz.utc)) AttachmentFileFactory(title='Not appear attachment', id=10, tag='CR', url='http://cr-document.com/10', file_type=MEDIA_TYPE_DOCUMENT, preview_image_url='http://preview.com/url10', allegation=allegation_4, external_created_at=datetime(2015, 6, 13, 12, 0, 1, tzinfo=pytz.utc)) attachment_file_3 = AttachmentFileFactory( title='Tracking document 3', id=11, tag='CR', url='http://cr-document.com/11', file_type=MEDIA_TYPE_DOCUMENT, preview_image_url='http://preview.com/url11', allegation=allegation_5, external_created_at=datetime(2015, 9, 14, 12, 0, 1, tzinfo=pytz.utc)) AttachmentFileFactory(allegation=allegation_1, title='CR document 12', id=12, tag='CR', url='http://cr-document.com/12', file_type=MEDIA_TYPE_DOCUMENT, preview_image_url='http://preview.com/url12', external_created_at=datetime(2015, 9, 14, 12, 0, 1, tzinfo=pytz.utc), show=False) attachment_file_4 = AttachmentFileFactory( title='Attachment not appear because is download event', id=13, tag='CR', url='http://cr-document.com/13', file_type=MEDIA_TYPE_DOCUMENT, preview_image_url='http://preview.com/url13', allegation=allegation_4, external_created_at=datetime(2015, 7, 13, 12, 0, 1, tzinfo=pytz.utc)) with freeze_time(datetime(2019, 1, 17, 12, 0, 1, tzinfo=pytz.utc)): AttachmentTrackingFactory(attachment_file=attachment_file_1) with freeze_time(datetime(2019, 1, 18, 12, 0, 1, tzinfo=pytz.utc)): AttachmentTrackingFactory(attachment_file=attachment_file_2) with freeze_time(datetime(2019, 1, 12, 12, 0, 1, tzinfo=pytz.utc)): AttachmentTrackingFactory(attachment_file=attachment_file_3) with freeze_time(datetime(2019, 10, 14, 12, 0, 1, tzinfo=pytz.utc)): AttachmentTrackingFactory(attachment_file=attachment_file_4, kind=constants.DOWNLOAD_EVENT_TYPE) allegation_cache_manager.cache_data() response = self.client.get(reverse('api-v2:cr-list-by-new-document'), {'limit': 5}) expect(response.status_code).to.eq(status.HTTP_200_OK) expect(len(response.data)).to.eq(4) expect(response.data).to.eq([ { 'crid': '123', 'latest_document': { 'id': '1', 'title': 'CR document 1', 'url': 'http://cr-document.com/1', 'preview_image_url': 'http://preview.com/url1', 'file_type': 'document' }, 'incident_date': '2001-02-28', 'category': 'Category 1' }, { 'crid': '321', 'latest_document': { 'id': '9', 'title': 'Tracking document 2', 'url': 'http://cr-document.com/9', 'preview_image_url': 'http://preview.com/url9', 'file_type': 'document' }, 'incident_date': '2004-02-28', }, { 'crid': '456', 'latest_document': { 'id': '3', 'title': 'CR document 3', 'url': 'http://cr-document.com/3', 'preview_image_url': 'http://preview.com/url3', 'file_type': 'document' }, 'incident_date': '2002-02-28', }, { 'crid': '987', 'latest_document': { 'id': '11', 'title': 'Tracking document 3', 'url': 'http://cr-document.com/11', 'preview_image_url': 'http://preview.com/url11', 'file_type': 'document' }, 'incident_date': '2005-02-28', }, ])
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_serialization(self): category = AllegationCategoryFactory(category='Use of Force', allegation_name='Subcategory') category2 = AllegationCategoryFactory(category='Verbal Abuse', allegation_name='Miscellaneous') allegation = AllegationFactory( crid=123, old_complaint_address='16XX N TALMAN AVE, CHICAGO IL', most_common_category=category, incident_date=datetime(2002, 1, 1, tzinfo=pytz.utc), coaccused_count=12, point=Point(-35.5, 68.9), ) VictimFactory(gender='M', race='Black', age=35, allegation=allegation) coaccused = OfficerFactory(id=2, first_name='Walter', last_name='White', allegation_count=6, sustained_count=5, birth_year=1940, race='White', gender='M', rank='Sergeant of Police', complaint_percentile=0.0, civilian_allegation_percentile=1.1, internal_allegation_percentile=2.2, trr_percentile=3.3, resignation_date=date(2015, 4, 14)) OfficerAllegationFactory( officer=coaccused, allegation=allegation, recc_outcome='11 Day Suspension', final_outcome='Separation', final_finding='SU', allegation_category=category2, disciplined=True, ) expect(PinnedAllegationSerializer(allegation).data).to.eq({ 'crid': '123', 'address': '16XX N TALMAN AVE, CHICAGO IL', 'category': 'Use of Force', 'incident_date': '2002-01-01', 'victims': [{ 'gender': 'Male', 'race': 'Black', 'age': 35 }], 'point': { 'lon': -35.5, 'lat': 68.9 }, 'to': '/complaint/123/', 'sub_category': 'Subcategory', 'coaccused': [{ 'id': 2, 'full_name': 'Walter White', 'complaint_count': 6, 'sustained_count': 5, 'birth_year': 1940, 'recommended_outcome': '11 Day Suspension', 'final_outcome': 'Separation', 'final_finding': 'Sustained', 'category': 'Verbal Abuse', 'disciplined': True, 'race': 'White', 'gender': 'Male', 'rank': 'Sergeant of Police', 'percentile_trr': '3.3000', 'percentile_allegation': '0.0000', 'percentile_allegation_civilian': '1.1000', 'percentile_allegation_internal': '2.2000' }], })
def test_execute(self): allegation_1 = AllegationFactory(crid='123') allegation_2 = AllegationFactory(crid='456') allegation_3 = AllegationFactory(crid='789') allegation_4 = AllegationFactory(crid='321') allegation_5 = AllegationFactory(crid='987') allegation_category_1 = AllegationCategoryFactory(id=1) allegation_category_12 = AllegationCategoryFactory(id=2) OfficerAllegationFactory(allegation=allegation_1, allegation_category=allegation_category_1) OfficerAllegationFactory(allegation=allegation_1, allegation_category=allegation_category_1) OfficerAllegationFactory(allegation=allegation_1, allegation_category=allegation_category_12) attachment_file_1 = AttachmentFileFactory( allegation=allegation_1, title='CR document 1', id=1, tag='CR', url='http://cr-document.com/1', file_type=MEDIA_TYPE_DOCUMENT, preview_image_url='http://preview.com/url1', external_created_at=datetime(2019, 1, 19, 12, 1, 1, tzinfo=pytz.utc)) AttachmentFileFactory(allegation=allegation_1, title='CR document 2', id=2, tag='CR', url='http://cr-document.com/2', file_type=MEDIA_TYPE_DOCUMENT, external_created_at=datetime(2019, 1, 14, 10, 12, 1, tzinfo=pytz.utc)) attachment_file_2 = AttachmentFileFactory( allegation=allegation_2, title='CR document 3', id=3, tag='CR', url='http://cr-document.com/3', file_type=MEDIA_TYPE_DOCUMENT, preview_image_url='http://preview.com/url3', external_created_at=datetime(2019, 1, 15, 9, 3, 1, tzinfo=pytz.utc)) AttachmentFileFactory(allegation=allegation_2, title='CR document 4', id=4, tag='OCIR', url='http://cr-document.com/4', file_type=MEDIA_TYPE_DOCUMENT, preview_image_url='http://preview.com/url4', external_created_at=datetime(2019, 1, 19, 17, 12, 5, tzinfo=pytz.utc)) with freeze_time(datetime(2019, 1, 20, 13, 2, 15, tzinfo=pytz.utc)): AttachmentFileFactory(allegation=allegation_2, title='CR document 5', id=5, tag='AR', url='http://cr-document.com/5', file_type=MEDIA_TYPE_DOCUMENT, preview_image_url='http://preview.com/url5', external_created_at=None) AttachmentFileFactory(allegation=allegation_3, title='CR document 6', id=6, tag='CR', url='http://cr-document.com/6', file_type=MEDIA_TYPE_AUDIO, preview_image_url='http://preview.com/url6', external_created_at=datetime(2019, 1, 21, 6, 4, 12, tzinfo=pytz.utc)) AttachmentFileFactory(allegation=allegation_3, title='CR document 7', id=7, tag='CR', url='http://cr-document.com/7', file_type=MEDIA_TYPE_VIDEO, preview_image_url='http://preview.com/url7', external_created_at=datetime(2019, 1, 22, 4, 9, 12, tzinfo=pytz.utc)) attachment_file_3 = AttachmentFileFactory( title='Tracking document 1', id=8, tag='CR', url='http://cr-document.com/8', file_type=MEDIA_TYPE_DOCUMENT, preview_image_url='http://preview.com/url8', allegation=allegation_4, external_created_at=datetime(2014, 9, 14, 12, 0, 1, tzinfo=pytz.utc)) attachment_file_4 = AttachmentFileFactory( title='Tracking document 2', id=9, tag='CR', url='http://cr-document.com/9', file_type=MEDIA_TYPE_DOCUMENT, preview_image_url='http://preview.com/url9', allegation=allegation_4, external_created_at=datetime(2015, 9, 14, 12, 0, 1, tzinfo=pytz.utc)) AttachmentFileFactory(title='Not appear attachment', id=10, tag='CR', url='http://cr-document.com/10', file_type=MEDIA_TYPE_DOCUMENT, preview_image_url='http://preview.com/url10', allegation=allegation_4, external_created_at=datetime(2015, 6, 13, 12, 0, 1, tzinfo=pytz.utc)) attachment_file_5 = AttachmentFileFactory( title='Tracking document 3', id=11, tag='CR', url='http://cr-document.com/11', file_type=MEDIA_TYPE_DOCUMENT, preview_image_url='http://preview.com/url11', allegation=allegation_5, external_created_at=datetime(2015, 9, 14, 12, 0, 1, tzinfo=pytz.utc)) # Should not have this in result because show = False AttachmentFileFactory(allegation=allegation_1, title='CR document 12', id=12, tag='CR', url='http://cr-document.com/12', file_type=MEDIA_TYPE_DOCUMENT, preview_image_url='http://preview.com/url12', external_created_at=datetime(2015, 9, 14, 12, 0, 1, tzinfo=pytz.utc), show=False) # Should still count but not 1st row because is attached to a download event attachment_file_6 = AttachmentFileFactory( title='Attachment not appear because is download event', id=13, tag='CR', url='http://cr-document.com/13', file_type=MEDIA_TYPE_DOCUMENT, preview_image_url='http://preview.com/url13', allegation=allegation_4, external_created_at=datetime(2015, 7, 13, 12, 0, 1, tzinfo=pytz.utc)) with freeze_time(datetime(2019, 1, 17, 12, 0, 1, tzinfo=pytz.utc)): AttachmentTrackingFactory(attachment_file=attachment_file_3) with freeze_time(datetime(2019, 1, 18, 12, 0, 1, tzinfo=pytz.utc)): AttachmentTrackingFactory(attachment_file=attachment_file_4) with freeze_time(datetime(2019, 1, 12, 12, 0, 1, tzinfo=pytz.utc)): AttachmentTrackingFactory(attachment_file=attachment_file_5) with freeze_time(datetime(2019, 10, 14, 12, 0, 1, tzinfo=pytz.utc)): AttachmentTrackingFactory(attachment_file=attachment_file_6, kind=constants.DOWNLOAD_EVENT_TYPE) allegation_cache_manager.cache_data() results = LatestDocumentsQuery.execute(5) expected_results = [ { 'id': attachment_file_1.id, 'allegation_id': '123', 'last_active_at': datetime(2019, 1, 19, 12, 1, 1, tzinfo=pytz.utc), }, { 'id': attachment_file_4.id, 'allegation_id': '321', 'last_active_at': datetime(2019, 1, 18, 12, 0, 1, tzinfo=pytz.utc), }, { 'id': attachment_file_2.id, 'allegation_id': '456', 'last_active_at': datetime(2019, 1, 15, 9, 3, 1, tzinfo=pytz.utc), }, { 'id': attachment_file_5.id, 'allegation_id': '987', 'last_active_at': datetime(2019, 1, 12, 12, 0, 1, tzinfo=pytz.utc), }, ] expect(len(results)).to.eq(len(expected_results)) for index, attachment_data in enumerate(results): expected_attachment_data = expected_results[index] expect(attachment_data.id).to.eq(expected_attachment_data['id']) expect(attachment_data.allegation_id).to.eq( expected_attachment_data['allegation_id']) expect(attachment_data.last_active_at).to.eq( expected_attachment_data['last_active_at'])
def test_serialization(self): category = AllegationCategoryFactory( category='Use of Force', allegation_name='Improper Search Of Person') allegation = AllegationFactory( crid='123', is_officer_complaint=True, incident_date=datetime(2005, 12, 31, tzinfo=pytz.utc), most_common_category=category, old_complaint_address='34XX Douglas Blvd', ) attachment = AttachmentFileFactory(tag='TRR', allegation=allegation, title='CR document', id='123456', url='http://cr-document.com/', file_type=MEDIA_TYPE_DOCUMENT) officer = OfficerFactory(id=8562, first_name='Jerome', last_name='Finnigan', allegation_count=5, trr_percentile=80, complaint_percentile=85, civilian_allegation_percentile=90, internal_allegation_percentile=95) officer_allegation = OfficerAllegationFactory( id=1, officer=officer, allegation=allegation, recc_outcome='10 Day Suspension', final_finding='SU', final_outcome='Separation', disciplined=True, allegation_category=category) VictimFactory(gender='M', race='Black', age=35, allegation=allegation) setattr(allegation, 'prefetch_filtered_attachment_files', [attachment]) allegation.officerallegation_set.set([officer_allegation]) expect(SocialGraphCRDetailSerializer(allegation).data).to.eq({ 'kind': 'CR', 'crid': '123', 'to': '/complaint/123/', 'category': 'Use of Force', 'subcategory': 'Improper Search Of Person', 'incident_date': '2005-12-31', 'address': '34XX Douglas Blvd', 'victims': [{ 'gender': 'Male', 'race': 'Black', 'age': 35 }], 'coaccused': [{ 'id': 8562, 'full_name': 'Jerome Finnigan', 'allegation_count': 5, 'percentile_allegation': '85.0000', 'percentile_allegation_civilian': '90.0000', 'percentile_allegation_internal': '95.0000', 'percentile_trr': '80.0000', }], 'attachments': [{ 'id': '123456', 'title': 'CR document', 'url': 'http://cr-document.com/', 'file_type': MEDIA_TYPE_DOCUMENT, }], 'officer_ids': [8562], })
def test_export_xlsx(self): 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) officer = OfficerFactory( id=8562, first_name='Jerome', last_name='Finnigan', middle_initial='A', middle_initial2=None, suffix_name=None, ) 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, ) writer = AccusedXlsxWriter(officer, self.test_output_dir) writer.export_xlsx() self.covert_xlsx_to_csv('accused.xlsx') self.assert_csv_files_equal('accused_8562', [ 'Allegation', 'Coaccused Officer', 'Beat', 'Police Witness', 'Victim' ])
def test_query(self): allegation_officer1, allegation_officer2 = OfficerFactory.create_batch( 2) trr_officer1, trr_officer2 = OfficerFactory.create_batch(2) pinboard_officer1, pinboard_officer2 = OfficerFactory.create_batch(2) other_officer = OfficerFactory() pinboard_allegation1, pinboard_allegation2 = AllegationFactory.create_batch( 2) allegation1, allegation2, allegation3, allegation4 = AllegationFactory.create_batch( 4) trr1 = TRRFactory(officer=trr_officer1) trr2 = TRRFactory(officer=trr_officer2) allegation_category1 = AllegationCategoryFactory( category='Operation/Personnel Violations', ) allegation_category2 = AllegationCategoryFactory( category='Illegal Search', ) allegation_category3 = AllegationCategoryFactory( category='Verbal Abuse', ) OfficerAllegationFactory(allegation=pinboard_allegation1, officer=allegation_officer1, allegation_category=allegation_category1) OfficerAllegationFactory(allegation=pinboard_allegation2, officer=allegation_officer1, allegation_category=allegation_category2) OfficerAllegationFactory(allegation=pinboard_allegation1, officer=allegation_officer2, allegation_category=allegation_category3) OfficerAllegationFactory(allegation=pinboard_allegation2, officer=allegation_officer2, allegation_category=allegation_category3) OfficerAllegationFactory(allegation=allegation3, officer=trr_officer1, allegation_category=None) OfficerAllegationFactory(allegation=allegation4, officer=trr_officer1, allegation_category=allegation_category1) OfficerAllegationFactory(allegation=pinboard_allegation1, officer=trr_officer1, allegation_category=None) OfficerAllegationFactory(allegation=pinboard_allegation2, officer=trr_officer2, allegation_category=None) OfficerAllegationFactory(allegation=pinboard_allegation2, officer=trr_officer2, allegation_category=allegation_category1) OfficerAllegationFactory(allegation=allegation1, officer=pinboard_officer1, allegation_category=None) OfficerAllegationFactory(allegation=allegation2, officer=pinboard_officer1, allegation_category=allegation_category2) OfficerAllegationFactory(allegation=allegation1, officer=other_officer, allegation_category=allegation_category2) pinboard = PinboardFactory(trrs=(trr1, trr2), allegations=(pinboard_allegation1, pinboard_allegation2), officers=(pinboard_officer1, pinboard_officer2)) expect(list(ComplaintSummaryQuery(pinboard).query())).to.eq([{ 'category': None, 'count': 4 }, { 'category': 'Operation/Personnel Violations', 'count': 3 }, { 'category': 'Illegal Search', 'count': 2 }, { 'category': 'Verbal Abuse', 'count': 2 }])
def test_new_timeline_item(self): officer = OfficerFactory(id=123, appointed_date=date(2000, 1, 1), rank='Police Officer') unit1 = PoliceUnitFactory(unit_name='001', description='unit_001') unit2 = PoliceUnitFactory(unit_name='002', description='unit_002') OfficerHistoryFactory(officer=officer, unit=unit1, effective_date=date(2010, 1, 1), end_date=date(2011, 12, 31)) OfficerHistoryFactory(officer=officer, unit=unit2, effective_date=date(2012, 1, 1), end_date=None) AwardFactory(officer=officer, start_date=date(2011, 3, 23), award_type='Honorable Mention') AwardFactory(officer=officer, start_date=date(2015, 3, 23), award_type='Complimentary Letter') AwardFactory(officer=officer, start_date=date(2011, 3, 23), award_type='Life Saving Award') allegation = AllegationFactory( crid='123456', coaccused_count=4, incident_date=datetime(2011, 8, 23, tzinfo=pytz.utc) ) VictimFactory(allegation=allegation, gender='M', race='White', age=34) OfficerAllegationFactory( final_finding='UN', final_outcome='Unknown', officer=officer, allegation=allegation, allegation_category=AllegationCategoryFactory(category='category', allegation_name='sub category') ) OfficerAllegationFactory.create_batch(3, allegation=allegation) allegation2 = AllegationFactory( crid='654321', point=Point(35.5, 68.9), coaccused_count=1, incident_date=datetime(2015, 8, 23, tzinfo=pytz.utc) ) OfficerAllegationFactory( final_finding='UN', final_outcome='9 Day Suspension', officer=officer, allegation=allegation2, allegation_category=AllegationCategoryFactory(category='Use of Force', allegation_name='sub category') ) trr2011 = TRRFactory( officer=officer, trr_datetime=datetime(2011, 9, 23, tzinfo=pytz.utc), taser=True, firearm_used=False ) trr2015 = TRRFactory( officer=officer, trr_datetime=datetime(2015, 9, 23, tzinfo=pytz.utc), taser=False, firearm_used=False ) SalaryFactory(officer=officer, year=2001, rank='Police Officer', spp_date=date(2001, 9, 23)) SalaryFactory(officer=officer, year=2000, rank='Junior Police Officer', spp_date=date(2000, 1, 1)) cache_managers.cache_all() response = self.client.get(reverse('api-v2:officers-new-timeline-items', kwargs={'pk': 123})) expect(response.status_code).to.eq(status.HTTP_200_OK) expect(response.data).to.eq([ { 'trr_id': trr2015.id, 'date': '2015-09-23', 'kind': 'FORCE', 'taser': False, 'firearm_used': False, 'unit_name': '002', 'unit_description': 'unit_002', 'rank': 'Police Officer', }, { 'date': '2015-08-23', 'kind': 'CR', 'crid': '654321', 'category': 'Use of Force', 'subcategory': 'sub category', 'finding': 'Unfounded', 'outcome': '9 Day Suspension', 'coaccused': 1, 'unit_name': '002', 'unit_description': 'unit_002', 'rank': 'Police Officer', 'point': { 'lon': 35.5, 'lat': 68.9 }, 'victims': [], 'attachments': [] }, { 'date': '2012-01-01', 'kind': 'UNIT_CHANGE', 'unit_name': '002', 'unit_description': 'unit_002', 'rank': 'Police Officer', }, { 'trr_id': trr2011.id, 'date': '2011-09-23', 'kind': 'FORCE', 'taser': True, 'firearm_used': False, 'unit_name': '001', 'unit_description': 'unit_001', 'rank': 'Police Officer', }, { 'date': '2011-08-23', 'kind': 'CR', 'crid': '123456', 'category': 'category', 'subcategory': 'sub category', 'finding': 'Unfounded', 'outcome': 'Unknown', 'coaccused': 4, 'unit_name': '001', 'unit_description': 'unit_001', 'rank': 'Police Officer', 'victims': [ { 'race': 'White', 'age': 34, 'gender': 'Male', } ], 'attachments': [], }, { 'date': '2011-03-23', 'kind': 'AWARD', 'award_type': 'Life Saving Award', 'unit_name': '001', 'unit_description': 'unit_001', 'rank': 'Police Officer', }, { 'date': '2010-01-01', 'kind': 'UNIT_CHANGE', 'unit_name': '001', 'unit_description': 'unit_001', 'rank': 'Police Officer', }, { 'date': '2001-09-23', 'kind': 'RANK_CHANGE', 'unit_name': '', 'unit_description': '', 'rank': 'Police Officer', }, { 'date': '2000-01-01', 'kind': 'JOINED', 'unit_name': '', 'unit_description': '', 'rank': 'Junior Police Officer', }, ])
def test_extract_datum(self): allegation = AllegationFactory( crid='123456', incident_date=datetime(2017, 7, 27, tzinfo=pytz.utc), summary='abc', add1='3000', add2='Michigan Ave', city='Chicago IL' ) officer = OfficerFactory( id=10, first_name='Luke', last_name='Skywalker', allegation_count=4, complaint_percentile='99.70', trr_percentile='99.88', civilian_allegation_percentile='77.66', internal_allegation_percentile='66.55' ) officer2 = OfficerFactory( id=11, first_name='John', last_name='Doe', allegation_count=2, complaint_percentile='70.33', trr_percentile='66.88', civilian_allegation_percentile='33.66', internal_allegation_percentile='22.55' ) OfficerAllegationFactory(allegation=allegation, officer=officer) category1 = AllegationCategoryFactory( category='Operation/Personnel Violations', allegation_name='Secondary/Special Employment' ) category2 = AllegationCategoryFactory(category='Use of Force', allegation_name='sub category') OfficerAllegationFactory(allegation=allegation, allegation_category=category2, officer=officer2) OfficerAllegationFactory.create_batch(2, allegation=allegation, allegation_category=category1, officer=None) OfficerAllegationFactory.create_batch(3, allegation=allegation, allegation_category=None, officer=None) VictimFactory(allegation=allegation, gender='F', race='Black', age=25) VictimFactory(allegation=allegation, gender='', race='Black', age=25) VictimFactory(allegation=allegation, gender='F', race='Black', age=None) AttachmentFileFactory(id=1, allegation=allegation, text_content='') AttachmentFileFactory( id=2, allegation=allegation, show=False, text_content="CHICAGO POLICE DEPARTMENT RD I HT334604" ) AttachmentFileFactory(id=3, allegation=allegation, text_content='CHICAGO POLICE DEPARTMENT RD I HT334604') setattr(allegation, 'investigator_names', ['Jerome Finnigan']) allegation_cache_manager.cache_data() allegation.refresh_from_db() datum = CrIndexer().extract_datum(allegation) datum['victims'] = sorted( datum['victims'], key=lambda victim: (victim['gender'], victim['race'], victim.get('age', 0)) ) expect(datum).to.eq({ 'crid': '123456', 'category': 'Operation/Personnel Violations', 'sub_category': 'Secondary/Special Employment', 'incident_date': '2017-07-27', 'address': '3000 Michigan Ave, Chicago IL', 'summary': 'abc', 'to': '/complaint/123456/', 'investigator_names': ['Jerome Finnigan'], 'victims': [ {'gender': '', 'race': 'Black', 'age': 25}, {'gender': 'Female', 'race': 'Black'}, {'gender': 'Female', 'race': 'Black', 'age': 25}, ], 'coaccused': [ { 'id': 10, 'full_name': 'Luke Skywalker', 'allegation_count': 4, 'percentile_allegation': '99.7000', 'percentile_allegation_civilian': '77.6600', 'percentile_allegation_internal': '66.5500', 'percentile_trr': '99.8800', }, { 'id': 11, 'full_name': 'John Doe', 'allegation_count': 2, 'percentile_allegation': '70.3300', 'percentile_allegation_civilian': '33.6600', 'percentile_allegation_internal': '22.5500', 'percentile_trr': '66.8800', } ], 'attachment_files': [ {'id': 3, 'text_content': 'CHICAGO POLICE DEPARTMENT RD I HT334604'} ] })
def test_serialization(self): category = AllegationCategoryFactory(category='Use of Force', allegation_name='Subcategory') allegation = AllegationFactory( crid=123, incident_date=datetime(2002, 1, 1, tzinfo=pytz.utc), most_common_category=category, coaccused_count=12, point=Point(-35.5, 68.9), old_complaint_address='34XX Douglas Blvd' ) officer = OfficerFactory( id=1, first_name='Jerome', last_name='Finnigan', allegation_count=20, trr_percentile=80, complaint_percentile=85, civilian_allegation_percentile=90, internal_allegation_percentile=95 ) OfficerAllegationFactory( officer=officer, allegation=allegation, recc_outcome='Separation', final_outcome='30 Day Suspension', final_finding='UN', allegation_category=category, disciplined=True ) VictimFactory( gender='M', race='Black', age=35, allegation=allegation ) expected_data = { 'incident_date': '2002-01-01', 'crid': '123', 'category': 'Use of Force', 'subcategory': 'Subcategory', 'kind': 'CR', 'address': '34XX Douglas Blvd', 'to': '/complaint/123/', 'victims': [ { 'gender': 'Male', 'race': 'Black', 'age': 35, } ], 'coaccused': [ { 'id': 1, 'full_name': 'Jerome Finnigan', 'allegation_count': 20, 'percentile_trr': '80.0000', 'percentile_allegation': '85.0000', 'percentile_allegation_civilian': '90.0000', 'percentile_allegation_internal': '95.0000', } ] } expect(CRDetailSerializer(allegation).data).to.eq(expected_data)
def test_serialization(self): pinned_officer = OfficerFactory( id=1, rank='Police Officer', first_name='Jerome', last_name='Finnigan', trr_percentile='11.11', complaint_percentile='22.22', civilian_allegation_percentile='33.33', internal_allegation_percentile='44.44', allegation_count=2, ) relevant_allegation = AllegationFactory( crid='1', incident_date=datetime(2002, 2, 21, tzinfo=pytz.utc), most_common_category=AllegationCategoryFactory( category='Operation/Personnel Violations', allegation_name='Subcategory' ), point=Point([0.01, 0.02]) ) VictimFactory( gender='M', race='Black', age=35, allegation=relevant_allegation ) pinboard = PinboardFactory( id='66ef1560', title='Test pinboard', description='Test description', ) pinboard.officers.set([pinned_officer]) OfficerAllegationFactory(officer=pinned_officer, allegation=relevant_allegation) expect(pinboard.relevant_complaints.count()).to.eq(1) expect(AllegationSerializer(pinboard.relevant_complaints.first()).data).to.eq({ 'crid': '1', 'address': '', 'category': 'Operation/Personnel Violations', 'incident_date': '2002-02-21', 'victims': [{ 'gender': 'Male', 'race': 'Black', 'age': 35 }], 'point': { 'lon': 0.01, 'lat': 0.02 }, 'to': '/complaint/1/', 'sub_category': 'Subcategory', 'coaccused': [{ 'id': 1, 'rank': 'Police Officer', 'full_name': 'Jerome Finnigan', 'percentile_allegation': '22.2200', 'percentile_allegation_civilian': '33.3300', 'percentile_allegation_internal': '44.4400', 'percentile_trr': '11.1100', 'allegation_count': 2, }], })
def test_retrieve_recent_search_items(self): OfficerFactory(id=8562, first_name='Jerome', last_name='Finnigan', current_badge='123456', allegation_count=20, sustained_count=5, birth_year=1980, race='White', gender='M', rank='Police Officer') allegation_category = AllegationCategoryFactory( category='Use of Force') AllegationFactory( crid='C12345', incident_date=datetime(2007, 1, 1, tzinfo=pytz.utc), most_common_category=allegation_category, ) trr = TRRFactory(id=123, trr_datetime=datetime(2007, 1, 1, tzinfo=pytz.utc)) ActionResponseFactory(trr=trr, force_type='Physical Force - Stunning', action_sub_category='4') ActionResponseFactory(trr=trr, force_type='Taser', action_sub_category='5.1') ActionResponseFactory(trr=trr, force_type='Impact Weapon', action_sub_category='5.2') ActionResponseFactory(trr=trr, force_type='Taser Display', action_sub_category='3') url = reverse('api:suggestion-recent-search-items') response = self.client.get(url, { 'officer_ids[]': 8562, 'crids[]': 'C12345', 'trr_ids[]': 123, }) expect(response.status_code).to.eq(status.HTTP_200_OK) expect(response.data).to.eq([{ 'id': 8562, 'name': 'Jerome Finnigan', 'race': 'White', 'gender': 'Male', 'rank': 'Police Officer', 'allegation_count': 20, 'sustained_count': 5, 'birth_year': 1980, 'type': 'OFFICER', }, { 'id': 'C12345', 'crid': 'C12345', 'category': 'Use of Force', 'incident_date': '2007-01-01', 'type': 'CR', }, { 'id': 123, 'trr_datetime': '2007-01-01', 'force_type': 'Impact Weapon', 'type': 'TRR', }])
def test_crawl_and_update_attachments(self, aws_mock, crawl_copa, _): logger = logging.getLogger('crawler.crawl_copa_data') crawl_copa.return_value = [{ 'allegation': { 'crid': '123', 'incident_date': datetime(2013, 4, 30, 21, 30, tzinfo=pytz.utc), 'attachment_files': [{ 'file_type': 'audio', 'title': 'Audio Clip', 'url': 'http://chicagocopa.org/audio_link.mp3', 'original_url': 'http://chicagocopa.org/audio_link.mp3', 'tag': 'Audio', 'source_type': 'PORTAL_COPA', 'external_last_updated': datetime(2018, 10, 30, 15, 0, 3, tzinfo=pytz.utc), }, { 'file_type': 'document', 'title': 'Document', 'url': 'http://chicagocopa.org/document.pdf', 'original_url': 'http://chicagocopa.org/document.pdf', 'tag': 'Document', 'source_type': 'PORTAL_COPA', 'external_last_updated': datetime(2017, 10, 30, 15, 0, 3, tzinfo=pytz.utc), }], 'subjects': ['Subject', '', 'Unknown'], }, 'allegation_category': { 'category': 'Incident', 'allegation_name': 'Allegation Name' }, 'police_shooting': True }, { 'allegation': { 'crid': '456', 'incident_date': datetime(2013, 4, 30, 21, 30, tzinfo=pytz.utc), 'attachment_files': [{ 'file_type': 'document', 'title': 'Document', 'url': 'http://chicagocopa.org/other.pdf', 'original_url': 'http://chicagocopa.org/other.pdf', 'tag': 'Document', 'source_type': 'PORTAL_COPA', 'external_last_updated': datetime(2017, 10, 30, 15, 0, 3, tzinfo=pytz.utc), }], 'subjects': ['Subject 2'], }, 'allegation_category': { 'category': 'Incident', 'allegation_name': 'Allegation Name' }, 'police_shooting': True }] AllegationCategoryFactory(category='Incident', allegation_name='Allegation Name') allegation = AllegationFactory(crid='123') attachment_file = AttachmentFileFactory( allegation=allegation, source_type='', external_id='document.pdf', original_url='http://chicagocopa.org/document.pdf') expect(DocumentCrawler.objects.count()).to.eq(0) expect(Allegation.objects.count()).to.eq(1) expect(Allegation.objects.get( crid='123').attachment_files.count()).to.eq(1) with freeze_time(datetime(2018, 4, 4, 12, 0, 1, tzinfo=pytz.utc)): new_attachments = CopaPortalAttachmentImporter( logger).crawl_and_update_attachments() expect(Allegation.objects.count()).to.eq(1) expect(Allegation.objects.get(crid='123').subjects).to.eq(['Subject']) expect(AttachmentFile.objects.filter( allegation=allegation).count()).to.eq(2) expect(AttachmentFile.objects.get( pk=attachment_file.pk).source_type).to.eq( AttachmentSourceType.PORTAL_COPA) expect(DocumentCrawler.objects.count()).to.eq(1) crawler_log = DocumentCrawler.objects.first() expect(crawler_log.source_type).to.eq(AttachmentSourceType.PORTAL_COPA) expect(crawler_log.num_documents).to.eq(2) expect(crawler_log.num_new_documents).to.eq(1) expect(crawler_log.num_updated_documents).to.eq(1) expect(new_attachments).to.have.length(1) expect(new_attachments[0].title).to.eq('Audio Clip') expect(new_attachments[0].url).to.eq( 'http://chicagocopa.org/audio_link.mp3') log_content = b'Creating 1 attachments' \ b'\nUpdating 1 attachments' \ b'\nCurrent Total portal_copa attachments: 2' \ b'\nDone importing!' log_args = aws_mock.s3.put_object.call_args[1] expect(len(log_args)).to.eq(4) expect(log_args['Body']).to.contain(log_content) expect(log_args['Bucket']).to.eq('crawler_logs_bucket') expect(log_args['Key']).to.eq( 'portal_copa/portal-copa-2018-04-04-120001.txt') expect(log_args['ContentType']).to.eq('text/plain')
def test_serialization(self): pinned_officer = OfficerFactory( id=1, rank='Police Officer', first_name='Jerome', last_name='Finnigan', allegation_count=10, trr_percentile='99.99', complaint_percentile='88.88', civilian_allegation_percentile='77.77', internal_allegation_percentile='66.66', ) relevant_allegation = AllegationFactory( crid='1', incident_date=datetime(2002, 2, 21, tzinfo=pytz.utc), most_common_category=AllegationCategoryFactory( category='Operation/Personnel Violations'), point=Point([0.01, 0.02]), ) AttachmentFileFactory( id=1, file_type='document', title='relevant document 1', allegation=relevant_allegation, show=True, preview_image_url= "https://assets.documentcloud.org/CRID-1-CR-p1-normal.gif", url='http://cr-1-document.com/', ) pinboard = PinboardFactory( id='66ef1560', title='Test pinboard', description='Test description', ) pinboard.officers.set([pinned_officer]) OfficerAllegationFactory(officer=pinned_officer, allegation=relevant_allegation) expect(pinboard.relevant_documents.count()).to.eq(1) expect( AllegationSerializer( pinboard.relevant_documents[0].allegation).data).to.eq({ 'crid': '1', 'category': 'Operation/Personnel Violations', 'incident_date': '2002-02-21', 'coaccused': [{ 'id': 1, 'rank': 'Police Officer', 'full_name': 'Jerome Finnigan', 'percentile_allegation': '88.8800', 'percentile_allegation_civilian': '77.7700', 'percentile_allegation_internal': '66.6600', 'percentile_trr': '99.9900', 'allegation_count': 10, }], 'point': { 'lon': 0.01, 'lat': 0.02, }, }) expect(DocumentSerializer( pinboard.relevant_documents.first()).data).to.eq({ 'id': 1, 'preview_image_url': "https://assets.documentcloud.org/CRID-1-CR-p1-normal.gif", 'url': 'http://cr-1-document.com/', 'allegation': { 'crid': '1', 'category': 'Operation/Personnel Violations', 'incident_date': '2002-02-21', 'coaccused': [{ 'id': 1, 'rank': 'Police Officer', 'full_name': 'Jerome Finnigan', 'allegation_count': 10, 'percentile_allegation': '88.8800', 'percentile_allegation_civilian': '77.7700', 'percentile_allegation_internal': '66.6600', 'percentile_trr': '99.9900', }], 'point': { 'lon': 0.01, 'lat': 0.02, }, } })
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_summary(self): officer = OfficerFactory( tags=[], first_name='Kevin', last_name='Kerl', id=123, race='White', gender='M', appointed_date=date(2017, 2, 27), rank='PO', resignation_date=date(2017, 12, 27), active=ACTIVE_YES_CHOICE, birth_year=1910, complaint_percentile=32.5, sustained_count=1, allegation_count=1, discipline_count=1, trr_count=1, civilian_compliment_count=1, honorable_mention_count=1, major_award_count=1, last_unit_id=1, current_badge='123456', current_salary=90000, has_unique_name=True ) allegation = AllegationFactory() allegation_category = AllegationCategoryFactory(category='Use of Force') OfficerHistoryFactory(officer=officer, unit=PoliceUnitFactory(id=1, unit_name='CAND', description='')) ComplainantFactory(allegation=allegation, race='White', age=18, gender='F') OfficerBadgeNumberFactory(officer=officer, star='123456', current=True) OfficerAllegationFactory( officer=officer, allegation=allegation, allegation_category=allegation_category, final_finding='SU', start_date=date(2000, 1, 1), disciplined=True ) AwardFactory(officer=officer, award_type='Complimentary Letter') AwardFactory(officer=officer, award_type='Honored Police Star') AwardFactory(officer=officer, award_type='Honorable Mention') SalaryFactory(officer=officer, salary=50000, year=2015) SalaryFactory(officer=officer, salary=90000, year=2017) TRRFactory(officer=officer) officer_cache_manager.build_cached_columns() allegation_cache_manager.cache_data() response = self.client.get(reverse('api-v2:officers-summary', kwargs={'pk': 123})) expect(response.status_code).to.eq(status.HTTP_200_OK) expected_data = { 'id': 123, 'unit': { 'id': 1, 'unit_name': 'CAND', 'description': '', 'long_unit_name': 'Unit CAND', }, 'date_of_appt': '2017-02-27', 'date_of_resignation': '2017-12-27', 'active': 'Active', 'rank': 'PO', 'full_name': 'Kevin Kerl', 'race': 'White', 'badge': '123456', 'historic_units': [{ 'id': 1, 'unit_name': 'CAND', 'description': '', 'long_unit_name': 'Unit CAND' }], 'gender': 'Male', 'birth_year': 1910, 'sustained_count': 1, 'civilian_compliment_count': 1, 'allegation_count': 1, 'discipline_count': 1, 'honorable_mention_count': 1, 'to': '/officer/123/kevin-kerl/', 'url': 'http://cpdb.lvh.me/officer/kevin-kerl/123', 'current_salary': 90000, 'trr_count': 1, 'major_award_count': 1, 'unsustained_count': 0, 'percentile_allegation': '32.5000', 'coaccusals': [], 'percentiles': [], 'tags': [], 'historic_badges': [], 'has_unique_name': True } expect(response.data).to.eq(expected_data)
def test_serialization(self): officer = OfficerFactory(id=123) allegation = AllegationFactory( crid='CR123', incident_date=datetime(2002, 2, 3, tzinfo=pytz.utc), coaccused_count=3, point=Point([0.01, 0.02]), ) allegation_category = AllegationCategoryFactory( category='some category', allegation_name='some sub category') officer_allegation = OfficerAllegationFactory( officer=officer, allegation=allegation, start_date=date(2002, 2, 3), allegation_category=allegation_category, final_finding='SU', final_outcome='9 Day Suspension') attachment = AttachmentFileFactory( tag='Other', allegation=allegation, title='title', id='123456', url='url', preview_image_url='preview_image_url', file_type='document') VictimFactory(allegation=allegation, gender='M', race='Black', age=30) setattr(officer_allegation, 'unit_name', 'Unit 001') setattr(officer_allegation, 'unit_description', 'District 001') setattr(officer_allegation, 'rank_name', 'Police Officer') setattr(allegation, 'prefetch_filtered_attachments', [attachment]) expect(CRNewTimelineSerializer(officer_allegation).data).to.eq({ 'unit_name': 'Unit 001', 'unit_description': 'District 001', 'rank': 'Police Officer', 'priority_sort': 30, 'kind': 'CR', 'date_sort': date(2002, 2, 3), 'date': '2002-02-03', 'crid': 'CR123', 'category': 'some category', 'subcategory': 'some sub category', 'finding': 'Sustained', 'outcome': '9 Day Suspension', 'coaccused': 3, 'attachments': [{ 'title': 'title', 'url': 'url', 'preview_image_url': 'preview_image_url', 'file_type': 'document', 'id': '123456', }], 'point': { 'lon': 0.01, 'lat': 0.02 }, 'victims': [{ 'gender': 'Male', 'race': 'Black', 'age': 30 }] })
def test_serialization(self): with freeze_time(datetime(2018, 4, 3, 12, 0, 10, tzinfo=pytz.utc)): officer_1 = OfficerFactory( first_name='Jerome', last_name='Finnigan', allegation_count=0, complaint_percentile='0.0000', trr_percentile='0.0000', civilian_allegation_percentile='0.0000', internal_allegation_percentile='0.0000', ) officer_2 = OfficerFactory( first_name='Joe', last_name='Parker', allegation_count=5, complaint_percentile='50.0000', trr_percentile='50.0000', civilian_allegation_percentile='50.0000', internal_allegation_percentile='50.0000', ) officer_3 = OfficerFactory( first_name='John', last_name='Hurley', allegation_count=10, complaint_percentile='99.9999', trr_percentile='99.9999', civilian_allegation_percentile='99.9999', internal_allegation_percentile='99.9999', ) allegation_1 = AllegationFactory( crid='111111', most_common_category=AllegationCategoryFactory( category='Use Of Force'), incident_date=datetime(2001, 1, 1, tzinfo=pytz.utc), ) allegation_2 = AllegationFactory( crid='222222', incident_date=datetime(2002, 2, 2, tzinfo=pytz.utc), ) trr_1 = TRRFactory(id='111', trr_datetime=datetime(2001, 1, 1, tzinfo=pytz.utc)) ActionResponseFactory(trr=trr_1, force_type='Use Of Force') trr_2 = TRRFactory(id='222', trr_datetime=datetime(2002, 2, 2, tzinfo=pytz.utc)) pinboard = PinboardFactory( id='aaaa1111', title='Pinboard 1', description='Pinboard description 1', officers=[officer_1, officer_2, officer_3], allegations=[allegation_1, allegation_2], trrs=[trr_1, trr_2], ) setattr(pinboard, 'child_pinboard_count', 2) expect(PinboardSerializer(pinboard).data).to.eq({ 'id': 'aaaa1111', 'title': 'Pinboard 1', 'description': 'Pinboard description 1', 'created_at': '2018-04-03T12:00:10Z', 'officers_count': 3, 'allegations_count': 2, 'trrs_count': 2, 'child_pinboard_count': 2, 'officers': [ { 'id': officer_3.id, 'name': 'John Hurley', 'count': 10, 'percentile_allegation': '99.9999', 'percentile_trr': '99.9999', 'percentile_allegation_civilian': '99.9999', 'percentile_allegation_internal': '99.9999', }, { 'id': officer_2.id, 'name': 'Joe Parker', 'count': 5, 'percentile_allegation': '50.0000', 'percentile_trr': '50.0000', 'percentile_allegation_civilian': '50.0000', 'percentile_allegation_internal': '50.0000', }, { 'id': officer_1.id, 'name': 'Jerome Finnigan', 'count': 0, 'percentile_allegation': '0.0000', 'percentile_trr': '0.0000', 'percentile_allegation_civilian': '0.0000', 'percentile_allegation_internal': '0.0000', }, ], 'allegations': [ { 'crid': '222222', 'category': 'Unknown', 'incident_date': '2002-02-02', }, { 'crid': '111111', 'category': 'Use Of Force', 'incident_date': '2001-01-01', }, ], 'trrs': [{ 'id': 222, 'trr_datetime': '2002-02-02', 'category': 'Unknown', }, { 'id': 111, 'trr_datetime': '2001-01-01', 'category': 'Use Of Force', }], })
def test_summary(self): unit = PoliceUnitFactory(unit_name='123', description='foo') officer = OfficerFactory(race='White', gender='F', birth_year='1980') OfficerHistoryFactory(unit=unit, officer=officer, end_date=None) allegation = AllegationFactory() allegation_category = AllegationCategoryFactory( category='Use of Force') OfficerAllegationFactory(officer=officer, allegation=allegation, allegation_category=allegation_category, final_finding='SU') ComplainantFactory(allegation=allegation, race='Black', age=25, gender='M') self.refresh_index() response = self.client.get( reverse('api-v2:units-summary', kwargs={'pk': '123'})) expect(response.data).to.be.eq({ 'unit_name': '123', 'description': 'foo', 'member_records': { 'active_members': 1, 'total': 1, 'facets': [{ 'name': 'race', 'entries': [{ 'name': 'White', 'count': 1 }] }, { 'name': 'age', 'entries': [{ 'name': '31-40', 'count': 1 }] }, { 'name': 'gender', 'entries': [{ 'name': 'Female', 'count': 1 }] }] }, 'complaint_records': { 'count': 1, 'sustained_count': 1, 'facets': [{ 'name': 'category', 'entries': [{ 'name': 'Use of Force', 'count': 1, 'sustained_count': 1 }] }, { 'name': 'race', 'entries': [{ 'name': 'Black', 'count': 1, 'sustained_count': 1 }] }, { 'name': 'age', 'entries': [{ 'name': '21-30', 'count': 1, 'sustained_count': 1 }] }, { 'name': 'gender', 'entries': [{ 'name': 'Male', 'count': 1, 'sustained_count': 1 }] }] } })
def test_crawl_and_update_attachments(self, aws_mock, crawl_copa, _): logger = logging.getLogger('crawler.crawl_copa_data') crawl_copa.return_value = [{ 'allegation': { 'crid': '123', 'incident_date': datetime(2013, 4, 30, 21, 30, tzinfo=pytz.utc), 'attachment_files': [{ 'file_type': 'document', 'title': 'Some Document', 'url': 'http://chicagocopa.org/document_link.pdf', 'original_url': 'http://chicagocopa.org/document_link.pdf', 'tag': 'Document', 'source_type': 'SUMMARY_REPORTS_COPA', 'external_last_updated': datetime(2018, 10, 30, 15, 0, 3, tzinfo=pytz.utc), }, { 'file_type': 'document', 'title': 'Some Document', 'url': 'http://chicagocopa.org/document.pdf', 'original_url': 'http://chicagocopa.org/document.pdf', 'tag': 'Document', 'source_type': 'SUMMARY_REPORTS_COPA', 'external_last_updated': datetime(2017, 10, 30, 15, 0, 3, tzinfo=pytz.utc), }], 'subjects': ['Subject1', 'Unknown'] }, 'allegation_category': { 'category': 'Incident', 'allegation_name': 'Allegation Name' }, 'police_shooting': True }, { 'allegation': { 'crid': '456', 'incident_date': datetime(2013, 4, 30, 21, 30, tzinfo=pytz.utc), 'attachment_files': [{ 'file_type': 'document', 'title': 'Some PDF', 'url': 'http://chicagocopa.org/other.pdf', 'original_url': 'http://chicagocopa.org/other.pdf', 'tag': 'Document', 'source_type': 'SUMMARY_REPORTS_COPA', 'external_last_updated': datetime(2017, 10, 30, 15, 0, 3, tzinfo=pytz.utc), }], 'subjects': ['Subject1', 'Unknown'] }, 'allegation_category': { 'category': 'Incident', 'allegation_name': 'Allegation Name' }, 'police_shooting': True }] AllegationCategoryFactory(category='Incident', allegation_name='Allegation Name') with freeze_time(datetime(2018, 4, 2, 12, 0, 1, tzinfo=pytz.utc)): DocumentCrawlerFactory( source_type=AttachmentSourceType.SUMMARY_REPORTS_COPA, status=DOCUMENT_CRAWLER_SUCCESS, num_documents=5, num_new_documents=1, num_updated_documents=4, num_successful_run=1, ) with freeze_time(datetime(2018, 4, 3, 12, 0, 1, tzinfo=pytz.utc)): DocumentCrawlerFactory( source_type=AttachmentSourceType.SUMMARY_REPORTS_COPA, status=DOCUMENT_CRAWLER_FAILED, num_successful_run=1, ) allegation = AllegationFactory(crid='123') attachment_file = AttachmentFileFactory( allegation=allegation, source_type='', external_id='document.pdf', original_url='http://chicagocopa.org/document.pdf') expect(expect(DocumentCrawler.objects.count())).to.eq(2) expect(Allegation.objects.count()).to.eq(1) expect(Allegation.objects.get( crid='123').attachment_files.count()).to.eq(1) with freeze_time(datetime(2018, 4, 4, 12, 0, 1, tzinfo=pytz.utc)): new_attachments = CopaSummaryReportsAttachmentImporter( logger).crawl_and_update_attachments() expect(Allegation.objects.count()).to.eq(1) expect(AttachmentFile.objects.filter( allegation=allegation).count()).to.eq(2) expect(AttachmentFile.objects.get( pk=attachment_file.pk).source_type).to.eq( AttachmentSourceType.SUMMARY_REPORTS_COPA) expect(DocumentCrawler.objects.count()).to.eq(3) crawler_log = DocumentCrawler.objects.order_by('-created_at').first() expect(crawler_log.source_type).to.eq( AttachmentSourceType.SUMMARY_REPORTS_COPA) expect(crawler_log.status).to.eq(DOCUMENT_CRAWLER_SUCCESS) expect(crawler_log.num_documents).to.eq(2) expect(crawler_log.num_new_documents).to.eq(1) expect(crawler_log.num_updated_documents).to.eq(1) expect(crawler_log.num_successful_run).to.eq(2) expect(new_attachments).to.have.length(1) expect(new_attachments[0].url).to.eq( 'http://chicagocopa.org/document_link.pdf') log_content = b'\nCreating 1 attachments' \ b'\nUpdating 1 attachments' \ b'\nCurrent Total summary_reports_copa attachments: 2' \ b'\nDone importing!' log_args = aws_mock.s3.put_object.call_args[1] expect(len(log_args)).to.eq(4) expect(log_args['Body']).to.contain(log_content) expect(log_args['Bucket']).to.contain('crawler_logs_bucket') expect(log_args['Key']).to.contain( 'summary_reports_copa/summary-reports-copa-2018-04-04-120001.txt') expect(log_args['ContentType']).to.eq('text/plain')
def test_retrieve_data_range_too_small_cause_no_percentiles(self): officer = OfficerFactory( tags=[], first_name='Kevin', last_name='Kerl', id=123, race='White', gender='M', appointed_date=date(2002, 2, 27), rank='PO', resignation_date=date(2017, 12, 27), active=ACTIVE_YES_CHOICE, birth_year=1960, complaint_percentile=32.5, sustained_count=1, allegation_count=2, discipline_count=1, trr_count=1, civilian_compliment_count=1, honorable_mention_count=1, major_award_count=1, last_unit_id=1, current_badge='123456' ) allegation = AllegationFactory(incident_date=datetime(2002, 3, 1, tzinfo=pytz.utc)) internal_allegation = AllegationFactory( incident_date=datetime(2002, 4, 1, tzinfo=pytz.utc), is_officer_complaint=True ) allegation_category = AllegationCategoryFactory(category='Use of Force') OfficerHistoryFactory( officer=officer, effective_date=datetime(2002, 2, 27, tzinfo=pytz.utc), unit=PoliceUnitFactory(id=1, unit_name='CAND', description='') ) ComplainantFactory(allegation=allegation, race='White', age=18, gender='F') OfficerBadgeNumberFactory(officer=officer, star='123456', current=True) OfficerBadgeNumberFactory(officer=officer, star='789', current=False) OfficerAllegationFactory( officer=officer, allegation=allegation, allegation_category=allegation_category, final_finding='SU', start_date=date(2002, 3, 2), disciplined=True ) OfficerAllegationFactory( officer=officer, allegation=internal_allegation, final_finding='NS', start_date=date(2002, 3, 2), disciplined=False ) AwardFactory(officer=officer, award_type='Complimentary Letter', start_date=date(2014, 5, 1)) AwardFactory(officer=officer, award_type='Honored Police Star', start_date=date(2014, 6, 1)) AwardFactory(officer=officer, award_type='Honorable Mention', start_date=date(2014, 7, 1)) SalaryFactory(officer=officer, salary=50000, year=2002) SalaryFactory(officer=officer, salary=90000, year=2017) TRRFactory(officer=officer, trr_datetime=datetime(2002, 3, 1, tzinfo=pytz.utc)) second_officer = OfficerFactory( tags=[], first_name='Kevin', last_name='Osborn', id=456, race='Black', gender='M', appointed_date=date(2002, 1, 27), resignation_date=date(2017, 12, 27), rank='PO', active=ACTIVE_YES_CHOICE, birth_year=1970 ) TRRFactory(officer=second_officer, trr_datetime=datetime(2002, 5, 1, tzinfo=pytz.utc)) TRRFactory(officer=second_officer, trr_datetime=datetime(2002, 12, 1, tzinfo=pytz.utc)) OfficerFactory( tags=[], first_name='Kevin', last_name='Edward', id=789, race='Black', gender='M', appointed_date=date(2002, 3, 27), resignation_date=date(2017, 12, 27), rank='PO', active=ACTIVE_YES_CHOICE, birth_year=1970 ) officer_cache_manager.build_cached_columns() allegation_cache_manager.cache_data() response = self.client.get(reverse('api-v2:officers-mobile-detail', kwargs={'pk': 123})) expected_response = { 'officer_id': 123, 'unit': { 'unit_id': 1, 'unit_name': 'CAND', 'description': '', }, 'date_of_appt': '2002-02-27', 'date_of_resignation': '2017-12-27', 'active': 'Active', 'rank': 'PO', 'full_name': 'Kevin Kerl', 'race': 'White', 'badge': '123456', 'historic_badges': ['789'], 'gender': 'Male', 'birth_year': 1960, 'sustained_count': 1, 'unsustained_count': 1, 'civilian_compliment_count': 1, 'allegation_count': 2, 'discipline_count': 1, 'honorable_mention_count': 1, 'trr_count': 1, 'major_award_count': 1, 'percentile_allegation': '32.5000', 'percentiles': [] } expect(response.data).to.eq(expected_response)