def setUp(self): self.rank = 'SGT' self.star = '823' self.unit = '001' self.gender = 'M' self.crid_1 = '1234' self.crid_2 = '2345' self.crid_3 = '3456' police_unit = PoliceUnitFactory(unit_name=self.unit) self.officer = OfficerFactory(rank=self.rank, star=self.star, unit=police_unit, gender=self.gender) self.involved_officer = OfficerFactory() self.witness_officer = OfficerFactory() allegation_1 = AllegationFactory(crid=self.crid_1) OfficerAllegationFactory(officer=self.officer, allegation=allegation_1) allegation_2 = AllegationFactory(crid=self.crid_2) OfficerAllegationFactory(officer=self.officer, allegation=allegation_2) OfficerAllegationFactory( officer=self.officer, allegation=AllegationFactory(crid=self.crid_3)) OfficerAllegationFactory(officer=self.involved_officer, allegation=allegation_1) PoliceWitnessFactory(officer=self.witness_officer, crid=self.crid_2, allegation=allegation_2) self.setting = self.get_admin_settings()
def test_merge_officer_allegations(self): officer_1 = OfficerFactory() officer_2 = OfficerFactory() oa_list_1 = OfficerAllegationFactory.create_batch(2, officer=officer_1) oa_list_2 = OfficerAllegationFactory.create_batch(2, officer=officer_2) allegation = AllegationFactory() oa_1 = OfficerAllegationFactory(allegation=allegation, officer=officer_1, cat=None, recc_finding=None, recc_outcome=None, final_outcome=None, final_outcome_class=None, start_date=None, end_date=None, final_finding=None) oa_2 = OfficerAllegationFactory(allegation=allegation, officer=officer_2) merge_officer_allegation(officer_1, officer_2) oa_1.refresh_from_db() set(oa.pk for oa in officer_1.officerallegation_set.all()).should.equal( set(oa.pk for oa in oa_list_1 + oa_list_2 + [oa_1])) for field in [ 'cat', 'recc_finding', 'recc_outcome', 'final_finding', 'final_outcome', 'final_outcome_class', 'start_date', 'end_date' ]: getattr(oa_1, field).should.equal(getattr(oa_2, field))
def test_merge_officer_history(self): officer_1 = OfficerFactory() officer_2 = OfficerFactory() officer_histories_1 = OfficerHistoryFactory.create_batch( 2, officer=officer_1) officer_histories_2 = OfficerHistoryFactory.create_batch( 2, officer=officer_1, effective_date=None, end_date=None) officer_histories_3 = OfficerHistoryFactory.create_batch( 2, officer=officer_2) intersect_effective_date = datetime.date.today() - datetime.timedelta( days=1) intersect_end_date = datetime.date.today() oh_1 = OfficerHistoryFactory(officer=officer_1, effective_date=intersect_effective_date, unit=None, rank=None, star=None, end_date=intersect_end_date) oh_2 = OfficerHistoryFactory(officer=officer_2, effective_date=intersect_effective_date, end_date=intersect_end_date) merge_officer_history(officer_1, officer_2) oh_1.refresh_from_db() set(officer_1.officerhistory_set.all()).should.equal( set(officer_histories_1 + officer_histories_2 + officer_histories_3 + [oh_1])) for field in ['unit', 'rank', 'star']: getattr(oh_1, field).should.equal(getattr(oh_2, field))
def test_age_range(self): age_values = [20, 25, 31, 41, 51, 61] expect_officer_age = { '20-30': 2, '31-40': 1, '41-50': 1, '51-60': 1, '61+': 1, } expected_witness_age = { '<20': 1, '21-30': 1, '31-40': 1, '41-50': 1, '51+': 2 } for val in age_values: allegation = AllegationFactory(incident_date=datetime(2000, 1, 1)) OfficerAllegationFactory(officer=OfficerFactory(birth_year=2000 - val), allegation=allegation) ComplainingWitnessFactory(age=val, allegation=allegation) allegation = AllegationFactory() OfficerAllegationFactory(officer=OfficerFactory(birth_year=None), allegation=allegation) ComplainingWitnessFactory(age=None, allegation=allegation) response, data = self.get_race_gender_info() response.status_code.should.equal(status.HTTP_200_OK) data['officers']['age'].should.equal(expect_officer_age) data['complaining_witness']['age'].should.equal(expected_witness_age)
def test_get_related_officer_in_police_witness_info(self): no_disp_code = '600' allegation1 = AllegationFactory() allegation2 = AllegationFactory() officer = OfficerFactory() OfficerAllegationFactory( allegation=allegation1, officer=officer, final_outcome=no_disp_code) OfficerAllegationFactory( allegation=allegation2, officer=officer) witness = OfficerFactory() PoliceWitnessFactory( crid=allegation1.crid, allegation=allegation1, officer=witness) OfficerAllegationFactory( allegation=allegation2, officer=witness, final_outcome=no_disp_code) result = self.client.get('/api/police-witness/', { 'crid': allegation1.crid}) data = json.loads(result.content.decode()) officers = data['police_witness'][0]['officers'] len(officers).should.equal(1) officers[0]['num_complaints'].should.equal(2) officers[0]['no_action_taken'].should.equal(2)
def test_officer_detail_when_successfully_call_the_api(self): officer = OfficerFactory() co_accused_officer = OfficerFactory() witness_officer = OfficerFactory() officer_allegation = OfficerAllegationFactory(officer=officer) PoliceWitnessFactory(crid=officer_allegation.allegation.crid, officer=witness_officer, allegation=officer_allegation.allegation) OfficerAllegationFactory(allegation=officer_allegation.allegation, officer=co_accused_officer) response, data = self.call_related_officer_api({'pk': officer.pk}) response.status_code.should.equal(HTTP_200_OK) detail = data['detail'] complaints = data['complaints'] detail['id'].should.be.equal(officer.id) detail['appt_date'].should.be.equal(officer.appt_date) detail['unit'].should.be.equal(officer.unit.unit_name) detail['gender'].should.be.equal(officer.gender) detail['rank'].should.be.equal(officer.rank) detail['race'].should.be.equal(officer.race) detail['officer_first'].should.be.equal(officer.officer_first) detail['officer_last'].should.be.equal(officer.officer_last) len(complaints).should.be(1) complaints[0]['crid'].should.be.equal(str(officer_allegation.allegation.crid)) len(complaints[0]['officer_allegation_set']).should.be.equal(2) len(data['co_accused']).should.be.equal(1) data.should.contain('distribution')
def test_get_distribution(self): OfficerFactory(allegations_count=1) OfficerFactory.create_batch(2, allegations_count=3) distribution = OfficerDistributionService.get_distribution() distribution.should.be.equal([1, 0, 2])
def test_filter_by_one_graph_does_not_change_others(self): officer_1 = OfficerFactory(race='black', gender='M') officer_2 = OfficerFactory(race='white', gender='F') officer_allegation_1 = OfficerAllegationFactory(officer=officer_1) officer_allegation_2 = OfficerAllegationFactory(officer=officer_2) ComplainingWitnessFactory(race='black', crid=officer_allegation_1.allegation.crid, gender='M', allegation=officer_allegation_1.allegation) ComplainingWitnessFactory(race='white', crid=officer_allegation_2.allegation.crid, gender='F', allegation=officer_allegation_2.allegation) response, data = self.get_race_gender_info(officer__gender='F') data['officers']['gender']['M'].should.equal(1) data['officers']['gender']['F'].should.equal(1) data['officers']['race'].shouldnt.contain('black') data['officers']['race']['white'].should.equal(1) data['complaining_witness']['gender'].shouldnt.contain('M') data['complaining_witness']['gender']['F'].should.equal(1) data['complaining_witness']['race'].shouldnt.contain('black') data['complaining_witness']['race']['white'].should.equal(1)
def test_less_data_information_officer(self): # no data, race is keep here to make summary section not to be hidden officer = OfficerFactory(gender='', rank=None, appt_date=None, unit=None, race='Hispanic') OfficerAllegationFactory(officer=officer) self.visit_officer_page(officer.id) self.until(lambda: self.find('.officer-summary-section')) officer_summary = self.find('.officer-summary-section').text officer_summary.shouldnt.contain('Rank') officer_summary.shouldnt.contain('Unit') officer_summary.shouldnt.contain('Joined Date') officer_summary.shouldnt.contain('Sex') # Invalid units and no race data other_officer_unit = PoliceUnitFactory(unit_name='999') other_officer = OfficerFactory(gender='M', rank=None, appt_date=None, unit=other_officer_unit, race='') OfficerAllegationFactory(officer=other_officer) self.visit_officer_page(other_officer.id) self.until(lambda: self.find('.officer-summary-section')) officer_summary = self.find('.officer-summary-section').text officer_summary.shouldnt.contain('Unit') officer_summary.shouldnt.contain('Unit')
def setUp(self): first_name = 'First' last_name = 'Last' self.display_name = '{first_name} {last_name}'.format( first_name=first_name, last_name=last_name) self.officer = OfficerFactory(officer_first=first_name, officer_last=last_name) self.officer_id = self.officer.id
def test_copy_missing_officer_fields(self): officer_1 = OfficerFactory(gender=None, race=None, birth_year=None, active=ACTIVE_UNKNOWN_CHOICE) officer_2 = OfficerFactory(active=ACTIVE_YES_CHOICE) copy_missing_officer_fields(officer_1, officer_2) officer_1.refresh_from_db() officer_1.gender.should.equal(officer_2.gender) officer_1.race.should.equal(officer_2.race) officer_1.birth_year.should.equal(officer_2.birth_year) officer_1.active.should.equal(officer_2.active)
def test_merge_officers(self): officer_1 = OfficerFactory() officer_2 = OfficerFactory() officer_2_pk = officer_2.pk merge_officers(officer_1, officer_2) OfficerAlias.objects.filter( new_officer=officer_1, old_officer_id=officer_2_pk).exists().should.be.true Officer.objects.filter(id=officer_2_pk).exists().should.be.false
def test_suggest_officer_name(self): officer = OfficerFactory(officer_first='Test', officer_last='Name') OfficerFactory(officer_first='Other', officer_last='Bad') query_for_first_name = officer.officer_first[0:2] query_for_last_name = officer.officer_last[0:2] non_matched = 'nonmatchquery' len(suggest_officer_name(query_for_first_name)).should.equal(1) len(suggest_officer_name(query_for_last_name)).should.equal(1) len(suggest_officer_name(non_matched)).should.equal(0)
def test_officer_discipline_count(self): expected_allegations = [ OfficerAllegationFactory( officer=OfficerFactory(discipline_count=11))] OfficerAllegationFactory(officer=OfficerFactory(discipline_count=10)) OfficerAllegationFactory(officer=OfficerFactory(discipline_count=9)) query_string = 'officer__discipline_count__gt=10' expected_ids = [allegation.id for allegation in expected_allegations] self.check_built_query(query_string, expected_ids)
def test_officer_age_filter(self): incident_date = datetime.datetime(2000, 1, 1) allegation = AllegationFactory(incident_date=incident_date) officers = [ OfficerFactory(birth_year=incident_date.year - 34), OfficerFactory(birth_year=incident_date.year - 56)] oas = [OfficerAllegationFactory(allegation=allegation, officer=officer) for officer in officers] self.check_built_query('officer_age=30-40', [oas[0].id]) self.check_built_query('officer_age=<40', [oas[0].id]) self.check_built_query('officer_age=>35', [oas[1].id])
def test_suggest_officer_badge(self): officer = OfficerFactory(star=19663) OfficerFactory(star=17489) star = str(officer.star) partial_query = star[0:2] bad_query = 'bad-query' suggest_officer_star(partial_query).should.equal([]) suggest_officer_star(bad_query).should.equal([]) suggest_officer_star(star).should.equal( [officer.as_suggestion_entry()])
def test_suggest_officer_badge(self): officer = OfficerFactory(star=19663) OfficerFactory(star=17489) star = str(officer.star) partial_query = star[0:2] bad_query = 'bad-query' suggest_officer_star(partial_query).should.equal([]) suggest_officer_star(bad_query).should.equal([]) suggest_officer_star(star).should.equal( [officer.as_suggestion_entry()])
def test_officer_names(self): expected_allegations = [ OfficerAllegationFactory(officer=OfficerFactory( officer_first='First', officer_last='Last')), OfficerAllegationFactory(officer=OfficerFactory( officer_first='Alpha', officer_last='Omega'))] OfficerAllegationFactory(officer=OfficerFactory( officer_first='Name1', officer_last='Name2')) query_string = 'officer_name=First&officer_name=Omega' expected_ids = [allegation.id for allegation in expected_allegations] self.check_built_query(query_string, expected_ids)
def test_copy_missing_officer_fields(self): officer_1 = OfficerFactory(gender=None, race=None, birth_year=None, active=ACTIVE_UNKNOWN_CHOICE) officer_2 = OfficerFactory(active=ACTIVE_YES_CHOICE) copy_missing_officer_fields(officer_1, officer_2) officer_1.refresh_from_db() officer_1.gender.should.equal(officer_2.gender) officer_1.race.should.equal(officer_2.race) officer_1.birth_year.should.equal(officer_2.birth_year) officer_1.active.should.equal(officer_2.active)
def test_co_accused(self): officer = OfficerFactory() co_accused_officer = OfficerFactory() officer_allegation = OfficerAllegationFactory(officer=officer) OfficerAllegationFactory(officer=co_accused_officer, allegation=officer_allegation.allegation) co_accused_officers = RelatedOfficerService.co_accused_officers( officer.id) SqlHelper.len_of_raw_queryset(co_accused_officers).should.be.equal(1) co_accused_officers[0].id.should.be.equal(co_accused_officer.id) co_accused_officers[0].num_allegations.should.be.equal(1)
def test_query_for_repeaters(self): normal = OfficerFactory() repeater = OfficerFactory() OfficerAllegationFactory(officer=normal) OfficerAllegationFactory.create_batch(10, officer=repeater) management.call_command('calculate_allegations_count') response = self.client.get( '/api/officer-allegations/officers/?officer__allegations_count__gt=9' ) data = json.loads(response.content.decode()) any([officer['id'] == repeater.id for officer in data['officers']])\ .should.be.true
def test_order_officer_by_number_of_complaints(self): officer_name = 'matched' officer_1 = OfficerFactory(officer_first=officer_name, allegations_count=1) officer_2 = OfficerFactory(officer_first=officer_name, allegations_count=3) officer_3 = OfficerFactory(officer_first=officer_name, allegations_count=2) officers = suggest_officer_name(officer_name) ordered_officer_keys = [officer_2.pk, officer_3.pk, officer_1.pk] officer_allegation_counts = [x['resource_key'] for x in officers] officer_allegation_counts.should.equal(ordered_officer_keys)
class TestOfficerProfileLink(SimpleTestCase): def setUp(self): Officer.objects.all().delete() self.officer = OfficerFactory(officer_first="First", officer_last="Last", id=1000) def tearDown(self): self.officer.delete() def test_officer_profile_link(self): expected_result = 'http://cpdb.co/officer/first-last/1000' with open('/tmp/command_output', 'w') as f: management.call_command('build_google_sitemap', stdout=f) with open('/tmp/command_output', 'r') as f: f.readline().strip().should.equal(expected_result)
def test_race_gender_api_that_complaint_doesnt_contain_in_allegations( self): OfficerFactory(race='black', gender='M') OfficerFactory(race='white', gender='F') ComplainingWitnessFactory(race='black', gender='M') ComplainingWitnessFactory(race='white', gender='F') response, data = self.get_race_gender_info() response.status_code.should.equal(status.HTTP_200_OK) for x in ['officers', 'complaining_witness']: data[x]['gender'].shouldnt.contain('M') data[x]['gender'].shouldnt.contain('F') data[x]['race'].shouldnt.contain('black') data[x]['race'].shouldnt.contain('white')
def test_correct_obrien(self): officer = OfficerFactory(officer_first='tommy', officer_last='obrien') management.call_command('capitalize_officer_name') officer = Officer.objects.get(pk=officer.pk) officer.officer_first.should.equal('Tommy') officer.officer_last.should.equal("O'Brien")
def test_circle_color_of_involved_officers(self): crid = '1234' category = AllegationCategoryFactory() allegation = AllegationFactory(crid=crid) allegations_count_color_map = { 'circle-0': 21, 'circle-1': 11, 'circle-2': 4, 'circle-3': 2, 'circle-4': 1 } officers = {} for circle_class, allegations_count in \ allegations_count_color_map.items(): officer = OfficerFactory(allegations_count=allegations_count) officers[circle_class] = officer OfficerAllegationFactory(allegation=allegation, officer=officer, cat=category) self.visit_complaint_page(allegation.crid, category.id) self.until(lambda: self.should_not_see_text(allegation.crid)) for circle_class, allegations_count in \ allegations_count_color_map.items(): selector = '.officer-card.officer-{id} .{circle_class}'.format( id=officers[circle_class].id, circle_class=circle_class ) self.find_all(selector).should.have.length_of(1)
def test_officer_sheet(self, mock_workbook): allegation = AllegationFactory() officer = OfficerFactory() officer_allegation = OfficerAllegationFactory(allegation=allegation, officer=officer) allegation_download = AllegationsDownload(DownloadFactory().id) allegation_download.officer_allegations = [officer_allegation] allegation_download.update_crids() allegation_download.write_headers = MagicMock() with patch('allegation.services.download_allegations.os'): allegation_download.init_workbook() mock_worksheet = MagicMock() allegation_download.workbook.add_worksheet = MagicMock( return_value=mock_worksheet) allegation_download.write_officer_profile() (sheet, columns), _ = allegation_download.write_headers.call_args sheet.should.equal(mock_worksheet) columns.should.equal([ 'OfficerID', 'OfficerFirst', 'OfficerLast', 'Gender', 'Race', 'ApptDate', 'Unit', 'Rank', 'Star', 'Age' ]) mock_worksheet.write.assert_any_call(1, 0, officer.id) mock_worksheet.write.assert_any_call(1, 1, officer.officer_first) mock_worksheet.write.assert_any_call(1, 2, officer.officer_last) mock_worksheet.write.assert_any_call(1, 3, officer.gender) mock_worksheet.write.assert_any_call(1, 4, officer.race) mock_worksheet.write.assert_any_call(1, 5, officer.appt_date) mock_worksheet.write.assert_any_call(1, 6, officer.unit.unit_name) mock_worksheet.write.assert_any_call(1, 7, officer.rank) mock_worksheet.write.assert_any_call(1, 8, officer.star) mock_worksheet.write.assert_any_call(1, 9, officer.age)
def test_detect_suggest_type_officer_badge_number(self): OfficerFactory(star=123456) rebuild_index() data = self.get_suggestion('12') data.should.contain('Badge number')
def test_detect_suggest_type_officer_name(self): OfficerFactory(officer_first='Jerry', officer_last="Dao") rebuild_index() [self.get_suggestion(term).should.contain('Officer') for term in ['je', 'je da']] [self.get_suggestion(term).shouldnt.contain('Officer') for term in ['genie', 'je e']]
def test_session_build_from_suggestion(self): officer = OfficerFactory() rebuild_index() suggestions = UrlMediatorSuggestionService().make_suggestion(officer.officer_first) session = Builder( FilterTags( FromSuggestions(suggestions=suggestions) )).build() officer_name = "{officer_first} {officer_last}".format( officer_first=officer.officer_first, officer_last=officer.officer_last ) session.should.have.length_of(1) session.should.be.equal({ 'filters': { 'officer': [{ 'category': 'officer', 'displayCategory': "Officer", 'displayValue': officer_name, 'pinned': False, 'value': officer.pk }] } })
def test_correct_last_name_suffix(self): OfficerFactory(officer_first='Jr., paul', officer_last='Wiechert') management.call_command('clean_officer_names') officer = Officer.objects.all()[0] officer.officer_first.should.equal('paul') officer.officer_last.should.equal('Wiechert Jr.')
def test_display_suggestions_upon_typing(self): officer = OfficerFactory(officer_first='Jerry') OfficerFactory(officer_first='Jee') rebuild_index() self.visit('/?no_disclaimer=1#!/data-tools') search_text = 'Je' self.until( lambda: self.find('.ui-autocomplete-input').send_keys(search_text)) self.until(lambda: self.should_see_text(search_text)) self.until(lambda: self.should_see_text(officer.officer_last)) self.find('.ui-autocomplete-input').send_keys(Keys.ARROW_DOWN) self.find('.ui-autocomplete-input').get_attribute( 'value').should.equal(search_text)
class MobileSuggestibleOfficerTest(TestCase): def setUp(self): first_name = 'First' last_name = 'Last' self.display_name = '{first_name} {last_name}'.format(first_name=first_name, last_name=last_name) self.officer = OfficerFactory(officer_first=first_name, officer_last=last_name) self.officer_id = self.officer.id def test_suggestion_entry(self): expected_entry = { 'text': self.display_name, 'resource': 'officer', 'resource_key': self.officer_id, 'meta': { 'officer': self.officer } } self.officer.as_suggestion_entry().should.be.equal(expected_entry)
def setUp(self): Officer.objects.all().delete() self.officer = OfficerFactory(officer_first="First", officer_last="Last", id=1000)
def setUp(self): first_name = 'First' last_name = 'Last' self.display_name = '{first_name} {last_name}'.format(first_name=first_name, last_name=last_name) self.officer = OfficerFactory(officer_first=first_name, officer_last=last_name) self.officer_id = self.officer.id