def test_historic_badges(self): officer = OfficerFactory() expect(officer.historic_badges).to.be.empty() OfficerBadgeNumberFactory(officer=officer, star='000', current=True) OfficerBadgeNumberFactory(officer=officer, star='123', current=False) OfficerBadgeNumberFactory(officer=officer, star='456', current=False) expect(list(officer.historic_badges)).to.eq(['123', '456'])
def test_current_badge(self): officer_1 = OfficerFactory() officer_2 = OfficerFactory() OfficerBadgeNumberFactory(officer=officer_1, star='123', current=True) OfficerBadgeNumberFactory(officer=officer_2, current=False) officer_cache_manager.build_cached_columns() officer_1.refresh_from_db() expect(officer_1.current_badge).to.eq('123') expect(officer_2.current_badge).to.eq(None)
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_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_extract_info(self): officer = OfficerFactory(id=123, first_name='Alex', last_name='Mack', rank='5', race='White', gender='M', appointed_date=date(2017, 2, 27), resignation_date=date(2017, 12, 27), active='Yes', birth_year=1910, complaint_percentile=99.8, honorable_mention_percentile=98, tags=['Jason VanDyke']) TRRFactory(officer=officer, trr_datetime=datetime(2002, 9, 29, tzinfo=pytz.utc)) SalaryFactory(officer=officer, salary=9000) AwardFactory(officer=officer, award_type='Honorable Mention') AwardFactory(officer=officer, award_type='Complimentary Letter') AwardFactory(officer=officer, award_type='Honored Police Star') AwardFactory(officer=officer, award_type='Lambert Tree') OfficerHistoryFactory(officer=officer, unit__id=1001, unit__unit_name='001', unit__description='Hyde Park D', effective_date=date(2010, 1, 1), end_date=date(2011, 1, 1)) OfficerHistoryFactory(officer=officer, unit__id=1002, unit__unit_name='002', unit__description='Tactical', effective_date=date(2011, 1, 2)) OfficerBadgeNumberFactory(officer=officer, star='123456', current=True) OfficerBadgeNumberFactory(officer=officer, star='123', current=False) OfficerBadgeNumberFactory(officer=officer, star='456', current=False) allegation = AllegationFactory( incident_date=datetime(2000, 4, 26, tzinfo=pytz.utc)) OfficerAllegationFactory( officer=officer, final_finding='SU', start_date=date(2000, 1, 1), allegation_category__category='Illegal Search', allegation=allegation, disciplined=True) ComplainantFactory(allegation=allegation, race='White', age=18, gender='M') rows = self.extract_data() expect(rows).to.have.length(1) expect(rows[0]).to.eq({ 'id': 123, 'full_name': 'Alex Mack', 'unit': { 'id': 1002, 'unit_name': '002', 'description': 'Tactical', 'long_unit_name': 'Unit 002' }, 'rank': '5', 'race': 'White', 'badge': '123456', 'badge_keyword': '123456', 'historic_badges': ['123', '456'], 'historic_badges_keyword': ['123', '456'], 'historic_units': [{ 'id': 1002, 'unit_name': '002', 'description': 'Tactical', 'long_unit_name': 'Unit 002', }, { 'id': 1001, 'unit_name': '001', 'description': 'Hyde Park D', 'long_unit_name': 'Unit 001', }], 'gender': 'Male', 'date_of_appt': '2017-02-27', 'date_of_resignation': '2017-12-27', 'active': 'Active', 'birth_year': 1910, 'complaint_records': { 'count': 1, 'sustained_count': 1, 'items': [{ 'year': 2000, 'count': 1, 'sustained_count': 1 }], 'facets': [{ 'name': 'category', 'entries': [{ 'name': 'Illegal Search', 'count': 1, 'sustained_count': 1, 'items': [{ 'year': 2000, 'name': 'Illegal Search', 'count': 1, 'sustained_count': 1 }] }] }, { 'name': 'complainant race', 'entries': [{ 'name': 'White', 'count': 1, 'sustained_count': 1, 'items': [{ 'year': 2000, 'name': 'White', 'count': 1, 'sustained_count': 1 }] }] }, { 'name': 'complainant age', 'entries': [{ 'name': '<20', 'count': 1, 'sustained_count': 1, 'items': [{ 'year': 2000, 'name': '<20', 'count': 1, 'sustained_count': 1 }] }] }, { 'name': 'complainant gender', 'entries': [{ 'name': 'Male', 'count': 1, 'sustained_count': 1, 'items': [{ 'year': 2000, 'name': 'Male', 'count': 1, 'sustained_count': 1 }] }] }] }, 'allegation_count': 1, 'complaint_percentile': Decimal('99.8'), 'honorable_mention_count': 1, 'honorable_mention_percentile': 98, 'has_visual_token': False, 'sustained_count': 1, 'discipline_count': 1, 'civilian_compliment_count': 1, 'trr_count': 1, 'major_award_count': 2, 'tags': ['Jason VanDyke'], 'to': '/officer/123/alex-mack/', 'url': 'http://test.com/officer/alex-mack/123', 'current_salary': 9000, 'unsustained_count': 0, 'coaccusals': [], 'current_allegation_percentile': None, 'percentiles': [], 'cr_incident_dates': ['2000-04-26'], 'trr_datetimes': ['2002-09-29'], 'internal_allegation_percentile': None, 'trr_percentile': None, 'civilian_allegation_percentile': None, })
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_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): unit = PoliceUnitFactory( id=4, unit_name='004', description='District 004', ) old_unit = PoliceUnitFactory( id=5, unit_name='005', description='District 005', ) officer = OfficerFactory(id=123, first_name='Michael', last_name='Flynn', last_unit=unit, appointed_date=date(2000, 1, 2), resignation_date=date(2010, 2, 3), active='Yes', rank='Sergeant', race='Black', gender='F', current_badge='456', birth_year=1950, current_salary=10000, has_unique_name=False) OfficerBadgeNumberFactory(officer=officer, current=False, star='789') OfficerBadgeNumberFactory(officer=officer, current=True, star='456') OfficerHistoryFactory(officer=officer, unit=old_unit, effective_date=date(2002, 1, 2)) OfficerHistoryFactory(officer=officer, unit=unit, effective_date=date(2004, 1, 2)) expect(OfficerSummarySerializer(officer).data).to.eq({ 'id': 123, 'unit': { 'id': 4, 'unit_name': '004', 'description': 'District 004', 'long_unit_name': 'Unit 004', }, 'date_of_appt': '2000-01-02', 'date_of_resignation': '2010-02-03', 'active': 'Active', 'rank': 'Sergeant', 'full_name': 'Michael Flynn', 'race': 'Black', 'badge': '456', 'historic_badges': ['789'], 'historic_units': [{ 'id': 4, 'unit_name': '004', 'description': 'District 004', 'long_unit_name': 'Unit 004', }, { 'id': 5, 'unit_name': '005', 'description': 'District 005', 'long_unit_name': 'Unit 005', }], 'gender': 'Female', 'birth_year': 1950, 'current_salary': 10000, 'has_unique_name': False, })
def test_serialization(self, _): unit = PoliceUnitFactory( id=4, unit_name='004', description='District 004', ) old_unit = PoliceUnitFactory( id=5, unit_name='005', description='District 005', ) officer = OfficerFactory(id=123, tags=['tag1', 'tag2'], first_name='Michael', last_name='Flynn', last_unit=unit, appointed_date=date(2000, 1, 2), resignation_date=date(2010, 2, 3), active='Yes', rank='Sergeant', race='Black', gender='F', current_badge='456', birth_year=1950, current_salary=10000, allegation_count=20, complaint_percentile='99.9900', honorable_mention_count=3, sustained_count=4, unsustained_count=5, discipline_count=6, civilian_compliment_count=2, trr_count=7, major_award_count=8, honorable_mention_percentile='88.8800', has_unique_name=True) OfficerBadgeNumberFactory(officer=officer, current=False, star='789') OfficerBadgeNumberFactory(officer=officer, current=True, star='456') OfficerHistoryFactory(officer=officer, unit=old_unit, effective_date=date(2002, 1, 2)) OfficerHistoryFactory(officer=officer, unit=unit, effective_date=date(2004, 1, 2)) OfficerYearlyPercentileFactory(id=285, officer=officer, year=2002, percentile_trr='99.88', percentile_allegation=None, percentile_allegation_civilian='77.66', percentile_allegation_internal='66.55') OfficerYearlyPercentileFactory(id=286, officer=officer, year=2003, percentile_trr='99.99', percentile_allegation='88.88', percentile_allegation_civilian='77.77', percentile_allegation_internal='66.66') expect(OfficerInfoSerializer(officer).data).to.eq({ 'id': 123, 'unit': { 'id': 4, 'unit_name': '004', 'description': 'District 004', 'long_unit_name': 'Unit 004', }, 'date_of_appt': '2000-01-02', 'date_of_resignation': '2010-02-03', 'active': 'Active', 'rank': 'Sergeant', 'full_name': 'Michael Flynn', 'has_unique_name': True, 'race': 'Black', 'badge': '456', 'historic_badges': ['789'], 'historic_units': [{ 'id': 4, 'unit_name': '004', 'description': 'District 004', 'long_unit_name': 'Unit 004', }, { 'id': 5, 'unit_name': '005', 'description': 'District 005', 'long_unit_name': 'Unit 005', }], 'gender': 'Female', 'birth_year': 1950, 'current_salary': 10000, 'allegation_count': 20, 'percentile_allegation': '99.9900', 'honorable_mention_count': 3, 'sustained_count': 4, 'unsustained_count': 5, 'discipline_count': 6, 'civilian_compliment_count': 2, 'trr_count': 7, 'major_award_count': 8, 'honorable_mention_percentile': '88.8800', 'to': '/officer/123/michael-flynn/', 'url': f'{settings.V1_URL}/officer/michael-flynn/123', 'tags': ['tag1', 'tag2'], 'coaccusals': [{ 'id': 789, 'coaccusal_count': 10 }], 'percentiles': [ { 'id': 285, 'year': 2002, 'percentile_trr': '99.8800', 'percentile_allegation_civilian': '77.6600', 'percentile_allegation_internal': '66.5500', }, { 'id': 286, 'year': 2003, 'percentile_trr': '99.9900', 'percentile_allegation': '88.8800', 'percentile_allegation_civilian': '77.7700', 'percentile_allegation_internal': '66.6600', }, ] })
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_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)