Beispiel #1
0
    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()
Beispiel #2
0
    def test_complaint_detail_summary(self):
        allegation = AllegationFactory()
        officer_allegation = OfficerAllegationFactory(
            allegation=allegation,
            final_finding='UN'
            )

        self.visit_home()
        self.find('.officer.active .checkmark').click()

        self.until_ajax_complete()

        self.find('.complaint-row > .row').click()
        self.element_exist('.complaint_detail').should.be.true

        # Verify content in expanded view are correct
        self.should_see_text('Final Outcome\n{final_outcome}'.format(
            final_outcome=officer_allegation.get_final_outcome_display()
            )
        )
        self.should_see_text('CRID {crid}'.format(crid=allegation.crid))
        self.should_see_text(officer_allegation.cat.category)
        self.should_see_text(officer_allegation.cat.allegation_name)
        self.should_see_text('Final Finding\n{final_finding}'.format(
            final_finding=officer_allegation.get_final_finding_display()
            )
        )
    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)
Beispiel #4
0
    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 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_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)
Beispiel #7
0
    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')
Beispiel #8
0
    def test_update_officer_allegation_session(self):
        ids_to_update = [(OfficerAllegationFactory().id,
                          OfficerAllegationFactory().id) for i in range(2)]
        session_1 = SessionFactory(
            query={'filters': {
                'id': [{
                    'value': ids_to_update[0][0]
                }]
            }})
        SessionFactory(
            query={'filters': {
                'def': [{
                    'value': ids_to_update[0][0]
                }]
            }})
        session_2 = SessionFactory(query={
            'activeComplaints': [ids_to_update[1][0], ids_to_update[1][0]]
        })
        SessionFactory(query={'abc': ids_to_update[1][0]})

        update_officer_allegation_session(ids_to_update)

        session_1.refresh_from_db()
        session_1.query['filters']['id'][0]['value'].should.equal(
            ids_to_update[0][1])

        session_2.refresh_from_db()
        session_2.query['activeComplaints'].should.equal([ids_to_update[1][1]])
Beispiel #9
0
    def test_null_last_order_by(self):
        OfficerAllegationFactory(start_date=datetime.datetime(2010, 11, 1))
        OfficerAllegationFactory(start_date=None)

        [
            o.start_date
            for o in OfficerAllegation.objects.all().order_by('-start_date')
        ].index(None).should.equal(1)
        [
            o.start_date
            for o in OfficerAllegation.objects.all().order_by('start_date')
        ].index(None).should.equal(0)

        OfficerAllegation.objects.all().delete()

        OfficerAllegationFactory(allegation=AllegationFactory(
            incident_date=datetime.datetime(2011, 10, 1)))
        OfficerAllegationFactory(allegation=AllegationFactory(
            incident_date=None))

        [
            o.allegation.incident_date
            for o in OfficerAllegation.objects.all().order_by(
                '-allegation__incident_date')
        ].index(None).should.equal(1)
        [
            o.allegation.incident_date
            for o in OfficerAllegation.objects.all().order_by(
                'allegation__incident_date')
        ].index(None).should.equal(0)
    def test_filter_by_has_address(self):
        data = self.fetch_officer_allegations(has_address='true')
        len(data).should.equal(0)

        allegation1 = AllegationFactory(add1=123)
        OfficerAllegationFactory(allegation=allegation1)
        allegation2 = AllegationFactory(add2='456')
        OfficerAllegationFactory(allegation=allegation2)
        allegation3 = AllegationFactory(add1=789, add2='abc')
        OfficerAllegationFactory(allegation=allegation3)
        result_count = 3

        data = self.fetch_officer_allegations(has_address='true')
        len(data).should.equal(result_count)
        any([
            data[i]['allegation']['id'] == allegation1.id
            for i in range(result_count)
        ]).should.be.true
        any([
            data[i]['allegation']['id'] == allegation2.id
            for i in range(result_count)
        ]).should.be.true
        any([
            data[i]['allegation']['id'] == allegation3.id
            for i in range(result_count)
        ]).should.be.true
    def test_categories_replacement_logic(self):
        category = self.allegation_category.category
        other_category = AllegationCategoryFactory()
        sub_category = AllegationCategoryFactory(category=category)
        OfficerAllegationFactory(cat=other_category)
        OfficerAllegationFactory(cat=sub_category)

        self.filter_complaint_type()
        self.link(category).click()
        self.until_ajax_complete()
        self.element_by_classname_and_text('filter-name',
                                           category).should.be.ok

        self.link(sub_category.allegation_name).click()
        self.until_ajax_complete()
        self.element_by_classname_and_text(
            'filter-name', sub_category.allegation_name).should.be.ok
        self.element_by_classname_and_text('filter-name',
                                           category).should.be.false

        self.link(other_category.category).click()
        self.until_ajax_complete()
        self.element_by_classname_and_text(
            'filter-name', other_category.category).should.be.ok
        self.element_by_classname_and_text(
            'filter-name', sub_category.allegation_name).should.be.false
Beispiel #12
0
 def setUp(self):
     base = datetime.now()
     self.dates = [(base + timedelta(days=x)).date() for x in range(0, 2)]
     OfficerAllegationFactory(allegation=AllegationFactory(
         incident_date_only=self.dates[1]))
     allegation = AllegationFactory(incident_date_only=None)
     OfficerAllegationFactory(allegation=allegation,
                              start_date=self.dates[0])
Beispiel #13
0
 def test_create_officer_allegation_with_officer_age(self):
     officer = OfficerFactory(birth_year=1984)
     allegation = AllegationFactory(
         incident_date=datetime.datetime(2010, 1, 1))
     officer_allegation = OfficerAllegationFactory(officer=officer,
                                                   allegation=allegation)
     officer_allegation.officer_age.should.equal(26)
     OfficerAllegationFactory(allegation=AllegationFactory(
         incident_date=None)).officer_age.should.be.none
Beispiel #14
0
    def test_allegation_category_on_duty(self):
        expected_allegations = [
            OfficerAllegationFactory(cat=AllegationCategoryFactory(
                on_duty=True))]
        OfficerAllegationFactory()

        query_string = 'cat__on_duty=true'
        expected_ids = [allegation.id for allegation in expected_allegations]

        self.check_built_query(query_string, expected_ids)
Beispiel #15
0
    def test_incident_date_time_of_day(self):
        self.clean_db()
        oa1 = OfficerAllegationFactory(allegation=AllegationFactory(
            incident_date=datetime.datetime(2007, 12, 16, 7, 30, 30)
        ))
        OfficerAllegationFactory(allegation=AllegationFactory(
            incident_date=datetime.datetime(2007, 12, 16, 16, 30, 30)
        ))

        self.check_built_query('incident_date_time_of_day=morning', [oa1.id])
Beispiel #16
0
    def test_has_summary(self):
        expected_allegations = [
            OfficerAllegationFactory(
                allegation=AllegationFactory(summary='Some summary'))]
        OfficerAllegationFactory()

        query_string = 'has_summary=true'
        expected_ids = [allegation.id for allegation in expected_allegations]

        self.check_built_query(query_string, expected_ids)
Beispiel #17
0
    def test_has_address(self):
        expected_allegations = [
            OfficerAllegationFactory(allegation=AllegationFactory(add1=100)),
            OfficerAllegationFactory(allegation=AllegationFactory(add2='100'))]
        OfficerAllegationFactory()

        query_string = 'has_address=true'
        expected_ids = [allegation.id for allegation in expected_allegations]

        self.check_built_query(query_string, expected_ids)
Beispiel #18
0
    def test_outcome_30_more_days(self):
        expected_allegations = [
            OfficerAllegationFactory(final_outcome=code)
            for code in ["045", "060", "090", "180", "200"]]
        OfficerAllegationFactory(final_outcome='ZZ')

        query_string = 'outcome_text=30 more days'
        expected_ids = [allegation.id for allegation in expected_allegations]

        self.check_built_query(query_string, expected_ids)
Beispiel #19
0
    def test_has_identified(self):
        expected_allegations = [
            OfficerAllegationFactory()]
        OfficerAllegationFactory(
            officer=None)

        query_string = 'has_identified=true'
        expected_ids = [allegation.id for allegation in expected_allegations]

        self.check_built_query(query_string, expected_ids)
Beispiel #20
0
    def test_has_investigator(self):
        expected_allegations = [
            OfficerAllegationFactory()]
        OfficerAllegationFactory(
            allegation=AllegationFactory(investigator=None))

        query_string = 'has_investigator=true'
        expected_ids = [allegation.id for allegation in expected_allegations]

        self.check_built_query(query_string, expected_ids)
Beispiel #21
0
    def test_adhoc_queries(self):
        expected_allegations = [
            OfficerAllegationFactory(
                allegation=AllegationFactory(crid='1'), final_outcome='ZZ')]
        OfficerAllegationFactory(allegation=AllegationFactory(crid='1'))

        query_string = 'final_outcome=ZZ&allegation__crid=1'
        expected_ids = [allegation.id for allegation in expected_allegations]

        self.check_built_query(query_string, expected_ids)
Beispiel #22
0
    def test_lookup_by_allegation_crid_with_one_officerallegation_but_same_category(self):
        allegation = AllegationFactory(crid='12345')
        category = AllegationCategoryFactory(pk=456123, category='category name')
        OfficerAllegationFactory.create_batch(2, allegation=allegation, cat=category)
        expected_url = '/complaint/12345/category-name/J84Lyq78'

        response = self.client.get('/lookup/{query}'.format(query=allegation.crid))

        response.status_code.should.equals(HTTP_301_MOVED_PERMANENTLY)
        response.url.should.contain(expected_url)
Beispiel #23
0
    def test_has_location(self):
        expected_allegations = [
            OfficerAllegationFactory(
                allegation=AllegationFactory(location='4 Privet Drive'))]
        OfficerAllegationFactory()

        query_string = 'has_location=true'
        expected_ids = [allegation.id for allegation in expected_allegations]

        self.check_built_query(query_string, expected_ids)
Beispiel #24
0
    def test_has_document(self):
        document = DocumentFactory(documentcloud_id=1)

        expected_allegations = [OfficerAllegationFactory(allegation=document.allegation)]
        OfficerAllegationFactory()

        query_string = 'has_document=true'
        expected_ids = [allegation.id for allegation in expected_allegations]

        self.check_built_query(query_string, expected_ids)
Beispiel #25
0
    def test_unsustained_final_finding(self):
        expected_allegations = [
            OfficerAllegationFactory(final_finding=code)
            for code in ['DS', 'EX', 'NA', 'NC', 'NS', 'UN', 'ZZ']]
        OfficerAllegationFactory(final_finding='SU')

        query_string = 'final_finding_text=unsustained'
        expected_ids = [allegation.id for allegation in expected_allegations]

        self.check_built_query(query_string, expected_ids)
Beispiel #26
0
    def test_outcome_no_discipline(self):
        expected_allegations = [
            OfficerAllegationFactory(final_finding='SU', final_outcome=code)
            for code in NO_DISCIPLINE_CODES + (None,)]
        OfficerAllegationFactory(final_finding='SU', final_outcome='ZZ')

        query_string = 'outcome_text=no discipline'
        expected_ids = [allegation.id for allegation in expected_allegations]

        self.check_built_query(query_string, expected_ids)
Beispiel #27
0
    def _test_investigator_agency_iad(self):
        expected_allegations = [
            OfficerAllegationFactory(allegation=AllegationFactory(
                investigator=InvestigatorFactory(agency='IAD')))]
        OfficerAllegationFactory(allegation=AllegationFactory(
            investigator=InvestigatorFactory(agency='IPRA')))

        query_string = 'allegation__investigator__agency=IAD'
        expected_ids = [allegation.id for allegation in expected_allegations]

        self.check_built_query(query_string, expected_ids)
    def test_has_map(self):
        expected_allegations = [
            OfficerAllegationFactory()]
        allegation = OfficerAllegationFactory().allegation
        allegation.point = None
        allegation.save()

        query_string = 'has_map=true'
        expected_ids = [o.id for o in expected_allegations]

        self.check_built_query(query_string, expected_ids)
Beispiel #29
0
    def test_complainant_age_filter(self):
        allegation_1 = AllegationFactory()
        allegation_2 = AllegationFactory()
        ComplainingWitnessFactory(age=36, allegation=allegation_1)
        ComplainingWitnessFactory(age=23, allegation=allegation_2)
        oa_1 = OfficerAllegationFactory(allegation=allegation_1)
        oa_2 = OfficerAllegationFactory(allegation=allegation_2)

        self.check_built_query('complainant_age=30-40', [oa_1.id])
        self.check_built_query('complainant_age=<30', [oa_2.id])
        self.check_built_query('complainant_age=>35', [oa_1.id])
Beispiel #30
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 setUp(self):
     Allegation.objects.all().delete()
     today = datetime.datetime.now().strftime(DATE_ONLY_FORMAT)
     self.foia = AllegationFactory(
         incident_date=generate_random_date(FOIA_START_DATE, today))
     OfficerAllegationFactory(allegation=self.foia)
     self.pre_foia = AllegationFactory(incident_date=generate_random_date(
         START_UNIX_TIME_DATE, FOIA_START_DATE))
     OfficerAllegationFactory(allegation=self.pre_foia,
                              start_date=generate_random_date(
                                  START_UNIX_TIME_DATE, FOIA_START_DATE))
Beispiel #32
0
    def setUp(self):
        super(OfficerOutcomeFilterTestCase, self).setUp()

        officer_allegation = OfficerAllegationFactory(
            final_outcome_class='disciplined', final_finding='SU')
        self.officer = officer_allegation.officer

        final_findings = ['DS', 'EX', 'NA', 'NC', 'NS', 'UN', 'ZZ']
        [
            OfficerAllegationFactory(officer=self.officer, final_finding=code)
            for code in final_findings
        ]
    def test_redirect_allegation_crid_sesstion_multiple_officer_allegation_but_one_category(self):
        crid = '12345'
        expected_url = '/complaint/12345/no-category/r9ME4Vao'
        allegation = AllegationFactory(crid=crid)
        OfficerAllegationFactory.create_batch(2, allegation=allegation, cat=None)

        filters = {
            'allegation__crid': [{'value': allegation.crid, 'category': 'allegation__crid'}]
        }

        urls = self.redirect_allegation_id_only_session(filters)
        urls.should.be.equal([expected_url])
Beispiel #34
0
    def test_lookup_by_multiple_categories_officerallegation(self):
        allegation = AllegationFactory()
        cat1 = AllegationCategoryFactory()
        cat2 = AllegationCategoryFactory()
        OfficerAllegationFactory(allegation=allegation, cat=cat1)
        OfficerAllegationFactory(allegation=allegation, cat=cat2)

        response = self.client.get(
            '/lookup/{query}'.format(query=allegation.crid))

        response.status_code.should.equals(HTTP_301_MOVED_PERMANENTLY)
        response.url.should.contain('/s/{query}'.format(query=allegation.crid))
    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_latlng(self):
        expected_allegations = OfficerAllegationFactory.create_batch(2)
        for i in range(len(expected_allegations)):
            allegation = expected_allegations[i].allegation
            allegation.point = Point(0 + i/1000, 0 + 1/1000)
            allegation.save()
        allegation = OfficerAllegationFactory().allegation
        allegation.point = Point(650, 650)
        allegation.save()

        query_string = 'latlng=0,0&radius=500'
        expected_ids = [o.id for o in expected_allegations]

        self.check_built_query(query_string, expected_ids)
    def test_query_for_discipline_count(self):
        officer_1 = OfficerFactory()
        officer_2 = OfficerFactory()
        OfficerAllegationFactory(officer=officer_1)
        OfficerAllegationFactory.create_batch(
            10, officer=officer_2, final_outcome_class='disciplined')

        management.call_command('calculate_allegations_count')

        response = self.client.get(
            '/api/officer-allegations/officers/?officer__discipline_count__gt=9')
        data = json.loads(response.content.decode())
        returned_officer = data['officers'][0]
        officer_2.id.should.equal(returned_officer['id'])

        len(data['officers']).should.equal(1)
    def test_get_allegations_with_good_information(self):
        crid = 'crid1'
        other_crid = 'crid2'
        officer = OfficerFactory()
        other_officer = OfficerFactory()

        allegation = AllegationFactory(crid=crid)
        OfficerAllegationFactory.create_batch(
            2, allegation=allegation, officer=officer)

        allegation = AllegationFactory(crid=other_crid)
        OfficerAllegationFactory.create_batch(
            1, allegation=allegation, officer=other_officer)

        result = self.call_get_allegations(officer_id=officer.id)
        len(result).should.equal(2)
        result[0].crid.should.equal(str(crid))
Beispiel #39
0
    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))
Beispiel #40
0
    def test_sunburst_remove_tag(self):
        us = 'Unsustained'
        ns = 'Not Sustained'

        self.officer_allegation = OfficerAllegationFactory(
            cat=self.allegation_category, final_outcome='300')
        self.visit_home()
        self.click_active_tab("Outcomes")

        self.until(lambda: self.should_see_text('Officers (2)'))

        self.click_sunburst_legend(us)
        self.click_sunburst_legend(ns)
        self.until(lambda: self.element_by_classname_and_text('filter-name', ns))

        self.find(".tag .remove").click()
        self.until(lambda: self.element_by_classname_and_text('filter-name', us))
        self.should_see_text('Officers (1)')
class DataToolCategoriesTabTestCase(BaseLiveTestCase):
    def setUp(self):
        self.allegation_category = AllegationCategoryFactory()
        self.officer_allegation = OfficerAllegationFactory(
            cat=self.allegation_category, final_finding='NS')

    def tearDown(self):
        super(DataToolCategoriesTabTestCase, self).tearDown()
        self.allegation_category.delete()
        if self.officer_allegation.officer:
            self.officer_allegation.officer.delete()
        else:
            self.officer_allegation.delete()

    # Helper methods
    def filter_complaint_type(self):
        self.visit_home()
        self.link("Categories").click()
        self.until_ajax_complete()

    def check_number_officer(self, num):
        self.until(lambda: self.number_of_officers().should.equal(num))

    def number_of_active_subcategories(self):
        active_subcategories = self.find_all(
            '.child-rows .category-name.active')
        return len(active_subcategories)

    def number_of_officers(self):
        officers = self.find_all('.officer')
        return len(officers)

    # Tests
    def test_click_on_category_only_show_allegation_belong_to_it(self):
        other_category = AllegationCategoryFactory()
        OfficerAllegationFactory(cat=other_category)
        self.filter_complaint_type()

        self.check_number_officer(2)

        self.until(
            lambda:
            self.link(self.allegation_category.category).is_displayed())
        self.link(self.allegation_category.category).click()

        self.check_number_officer(1)

    def test_click_on_officer_will_show_compliant(self):
        self.filter_complaint_type()

        self.check_number_officer(1)

        self.browser.refresh()

        self.find('.checkmark').click()
        self.until(lambda: self.element_exist('.complaint-list'))
        self.find('.complaint-row > .row').click()

        self.element_exist('.complaint_detail').should.equal(True)

    def test_all_subcategories_should_be_selected(self):
        category = self.allegation_category.category
        allegation_category = AllegationCategoryFactory(category=category)
        OfficerAllegationFactory(cat=allegation_category)

        # First, we click a category, we should see the arrow beside the category
        self.filter_complaint_type()
        with self.browser_no_wait():
            self.element_exist('.row .arrow-container').should.equal(False)

        self.until(
            lambda: self.link(self.allegation_category.category).click())
        # TODO: We should have another test to check which main category this arrow belong to?
        self.element_exist('.row .arrow-container').should.equal(True)

        # And it should have a an arrow on the category
        self.until(
            lambda: self.number_of_active_subcategories().should.equal(2))
        self.until(
            lambda:
            self.should_see_text(self.allegation_category.allegation_name))
        self.link(self.allegation_category.allegation_name).click()
        self.until(
            lambda: self.number_of_active_subcategories().should.equal(1))

    def test_categories_replacement_logic(self):
        category = self.allegation_category.category
        other_category = AllegationCategoryFactory()
        sub_category = AllegationCategoryFactory(category=category)
        OfficerAllegationFactory(cat=other_category)
        OfficerAllegationFactory(cat=sub_category)

        self.filter_complaint_type()
        self.link(category).click()
        self.until_ajax_complete()
        self.element_by_classname_and_text('filter-name', category).should.be.ok

        self.link(sub_category.allegation_name).click()
        self.until_ajax_complete()
        self.element_by_classname_and_text('filter-name', sub_category.allegation_name).should.be.ok
        self.element_by_classname_and_text('filter-name', category).should.be.false

        self.link(other_category.category).click()
        self.until_ajax_complete()
        self.element_by_classname_and_text('filter-name', other_category.category).should.be.ok
        self.element_by_classname_and_text('filter-name', sub_category.allegation_name).should.be.false
 def setUp(self):
     self.officer_allegations = OfficerAllegationFactory.create_batch(3)
Beispiel #43
0
class HomePageTestCase(AutocompleteTestHelperMixin, BaseLiveTestCase):
    def setUp(self):
        self.allegation_category = AllegationCategoryFactory()
        self.officer_allegation = OfficerAllegationFactory(
            cat=self.allegation_category, final_finding='NS')

    def tearDown(self):
        super(HomePageTestCase, self).tearDown()
        self.allegation_category.delete()
        if self.officer_allegation.officer:
            self.officer_allegation.officer.delete()
        else:
            self.officer_allegation.delete()

    def test_start_new_session_on_click_logo(self):
        Session.objects.all().count().should.equal(0)
        self.visit_home(fresh=True)
        self.link("Categories").click()
        self.find(".category-name-wrapper a").click()
        self.until_ajax_complete()
        Session.objects.all().count().should.equal(1)

        url = self.browser.current_url
        self.find("#logo_link img").click()
        self.until(lambda: self.browser.current_url != url)

        Session.objects.all().count().should.equal(2)
        session = Session.objects.all()[1]
        self.browser.current_url.should.contain(session.hash_id)

    def test_see_tabs(self):
        self.visit_home()
        links = self.find_all('.chart-row .nav a')
        link_texts = [x.text for x in links]
        link_texts.should.contain('Outcomes')
        link_texts.should.contain('Categories')
        link_texts.should.contain('Complainants')
        link_texts.should.contain('Accused')

    def test_close_disclaimer(self):
        self.visit_home()
        self.link('About the data').click()
        self.until(lambda: self.button('I UNDERSTAND').click())
        self.until(lambda: self.should_not_see_text('I UNDERSTAND'))

    def test_see_session_query_on_reload(self):
        self.visit_home()
        officer = self.officer_allegation.officer

        rebuild_index()

        self.until(
            lambda:
            self.fill_in('.ui-autocomplete-input', officer.officer_first))
        self.until_ajax_complete()
        self.until(lambda: self.find(".autocomplete-officer").is_displayed())
        self.find(".autocomplete-officer").click()

        self.should_see_text(officer.officer_first)
        self.should_see_text(officer.officer_last)

        self.browser.refresh()
        self.until(self.ajax_complete)
        self.until(lambda: self.should_see_text(officer.officer_first))
        self.should_see_text(officer.officer_last)

    def test_complaint_detail_without_investigator(self):
        self.officer_allegation.investigator = None
        self.officer_allegation.save()

        self.visit_home()
        self.link('Categories').click()
        self.find('.category-name').click()
        self.find('.complaint-row .cursor').click()
        officers_divs = self.find_all('.officers > div')

        len(officers_divs).should.equal(1)
        officers_divs[0].has_class('col-md-10')

    def click_sunburst_legend(self, text):
        self.element_by_tagname_and_text('td', text).click()
        self.sleep(0.75)
        self.until(
            lambda:
            self.element_by_classname_and_text('filter-name', text)
                .should.be.ok)

    def test_sunburst(self):
        us = 'Unsustained'
        ns = 'Not Sustained'

        self.visit_home()
        self.click_active_tab("Outcomes")
        with self.browser_no_wait():
            self.element_by_classname_and_text('filter-name', us)\
                .shouldnt.be.ok
            self.element_by_classname_and_text('filter-name', ns)\
                .shouldnt.be.ok

        self.click_sunburst_legend(us)

        with self.browser_no_wait():
            self.element_by_classname_and_text('filter-name', ns)\
                .shouldnt.be.ok

        sunburst_legend_root_text = self.find('#sunburst-legend .root').text
        url = self.browser.current_url
        with self.open_new_browser():
            self.visit(url)

            self.until_ajax_complete()
            self.sleep(0.75)  # sunburst zoom time

            with self.browser_no_wait():  # same state with above
                self.find('#sunburst-legend .root')\
                    .text.should.equal(sunburst_legend_root_text)

        self.click_sunburst_legend(ns)
        with self.browser_no_wait():
            self.element_by_classname_and_text(
                'filter-name', us).shouldnt.be.ok

        self.click_sunburst_legend(us)
        with self.browser_no_wait():
            self.element_by_classname_and_text(
                'filter-name', ns).shouldnt.be.ok

        self.find(".tag .remove").click()
        with self.browser_no_wait():
            self.element_by_tagname_and_text('td', ns).shouldnt.be.ok

    def test_sunburst_remove_tag(self):
        us = 'Unsustained'
        ns = 'Not Sustained'

        self.officer_allegation = OfficerAllegationFactory(
            cat=self.allegation_category, final_outcome='300')
        self.visit_home()
        self.click_active_tab("Outcomes")

        self.until(lambda: self.should_see_text('Officers (2)'))

        self.click_sunburst_legend(us)
        self.click_sunburst_legend(ns)
        self.until(lambda: self.element_by_classname_and_text('filter-name', ns))

        self.find(".tag .remove").click()
        self.until(lambda: self.element_by_classname_and_text('filter-name', us))
        self.should_see_text('Officers (1)')

    def test_replace_old_filter_in_same_category(self):
        officer_allegation = OfficerAllegationFactory()

        rebuild_index()

        self.visit_home()
        self.search_officer(officer_allegation.officer)
        self.should_see_text(officer_allegation.officer.display_name)

        self.search_officer(self.officer_allegation.officer)
        self.should_see_text(self.officer_allegation.officer.display_name)
        self.should_not_see_text(officer_allegation.officer.display_name)

    @retry_random_fail
    def test_pin_tag(self):
        officer_allegation = OfficerAllegationFactory()
        another = OfficerAllegationFactory()

        rebuild_index()

        self.visit_home()
        self.search_officer(officer_allegation.officer)
        self.should_see_text(officer_allegation.officer.display_name)

        self.find('.tag > .pin').click()
        self.until(
            lambda:
            self.find('.tag').get_attribute('class').should.contain('pinned'))

        self.search_officer(self.officer_allegation.officer)
        self.should_see_text(self.officer_allegation.officer.display_name)
        self.should_see_text(officer_allegation.officer.display_name)

        self.search_officer(another.officer)
        self.should_see_text(another.officer.display_name)
        self.should_see_text(officer_allegation.officer.display_name)
        self.should_not_see_text(self.officer_allegation.officer.display_name)

    def test_unpin_tag(self):
        officer_allegation = OfficerAllegationFactory()
        another = OfficerAllegationFactory()

        rebuild_index()

        self.visit_home()
        self.search_officer(officer_allegation.officer)
        self.should_see_text(officer_allegation.officer.display_name)

        self.find('.tag > .pin').click()
        self.search_officer(self.officer_allegation.officer)
        self.should_see_text(self.officer_allegation.officer.display_name)
        self.should_see_text(officer_allegation.officer.display_name)

        element = self.find('.pinned')
        element.find('.pin').click()
        self.until(
            lambda: element.get_attribute('class').shouldnt.contain('pinned'))

        self.search_officer(another.officer)
        self.should_see_text(another.officer.display_name)
        self.should_not_see_text(officer_allegation.officer.display_name)
        self.should_not_see_text(self.officer_allegation.officer.display_name)

    def test_default_site_title_from_settings(self):
        setting = self.get_admin_settings()
        setting.default_site_title = 'New title'
        setting.save()

        self.visit_home(fresh=True)
        self.browser.title.should.equal(setting.default_site_title)

    def test_share_button(self):
        self.visit_home(fresh=True)
        self.find('.share-button button').click()
        self.find('.share-bar').is_displayed()
        self.find('.share-bar-content-wrapper input').get_attribute('value').should_not.equal(self.browser.current_url)
        self.find('.share-button button').click()
        with self.browser_no_wait():
            self.element_exist('.share-bar').should.be.false

    def test_no_disclaimer_when_search_engine(self):
        profile = webdriver.FirefoxProfile()
        profile.set_preference(
            "general.useragent.override",
            "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)"
        )
        browser = WebDriver(profile)
        browser.implicitly_wait(10)
        browser.set_window_size(width=1200, height=1200)

        old_browser = self.browser

        self.set_browser(browser)
        try:
            self.visit_home()
            self.find('#disclaimer').get_attribute('class').should.contain('fade')
        finally:
            browser.close()
            self.set_browser(old_browser)
            self.set_default_window_size()
            self.try_to_revive_browser()

    def create_glossary_page(self, rows):
        HomePage.get_tree().all().delete()
        root = HomePage.add_root(instance=HomePageFactory.build(
            title='Root', slug='root'))
        glossary_page = root.add_child(
            instance=GlossaryPageFactory.build(
                title='Glossary', glossary_table_rows=rows, slug='glossary', subtitle='sub-title'))
        Site.objects.create(
            is_default_site=True, root_page=root, hostname='localhost')

        return glossary_page

    def visit_glossary_page(self):
        nav_link = [el for el in self.find_all('.nav-link') if el.text == 'Glossary']
        nav_link[0].find('a').click()

    def glossary_rows_content(self):
        return [
            [el.find('.%s' % cls_name).text for cls_name in ['term', 'definition', 'category']]
            for el in self.find_all('table.glossary-table tr')]

    def test_glossary_page(self):
        rows = [
            GlossaryTableRowFactory.build(sort_order=3),
            GlossaryTableRowFactory.build(sort_order=1),
            GlossaryTableRowFactory.build(sort_order=2)
            ]
        glossary_page = self.create_glossary_page(rows)

        self.visit_home(fresh=True)
        self.visit_glossary_page()

        self.find('.glossary-page .glossary-title').text.should.equal(glossary_page.title)
        self.find('.glossary-page .glossary-subtitle').text.should.equal(glossary_page.subtitle)

        self.glossary_rows_content().should.equal([
            [rows[1].term, rows[1].definition, rows[1].category_text],
            [rows[2].term, rows[2].definition, rows[2].category_text],
            [rows[0].term, rows[0].definition, rows[0].category_text]
            ])

    def test_share_bar_facebook_share(self):
        title = 'Donald Duck'

        self.visit_home()
        self.find('.share-button button').click()
        self.until_ajax_complete()
        self.fill_in('.site-title-input', title)
        shared_hash_id = re.findall(
            r'data/([^/]+)', self.find('.share-bar-content-wrapper input').get_attribute('value'))[0]
        self.find('.share-bar-facebook-link').click()
        self.until_ajax_complete()

        with switch_to_popup(self.browser):
            ('https://www.facebook.com' in self.browser.current_url).should.be.true

        self.find('.share-button button').click()

        session_id = Session.id_from_hash(shared_hash_id)[0]
        session = Session.objects.get(id=session_id)
        session.title.should.be.equal(title)

    def test_responsive_layout(self):
        profile = webdriver.FirefoxProfile()
        profile.set_preference(
            "general.useragent.override",
            "Mozilla/5.0 (iPad; CPU OS 5_1 like Mac OS X) AppleWebKit/534.46 (KHTML, like Gecko ) Version/5.1 Mobile/9B176 Safari/7534.48.3"  # noqa
        )
        driver = webdriver.Firefox(profile)

        old_browser = self.browser
        self.set_browser(driver)
        try:
            self.browser.set_window_size(width=1040, height=1200)  # 1024 + 16px for scroll bar, apparently?

            self.visit_home()

            self.find('.chart-row .nav-tabs li:first-child').text.should.contain('Outcomes')
            self.find('#sunburst-chart svg').get_attribute('width').should.be.greater_than('249')

            self.browser.set_window_size(width=1023, height=1200)
            self.visit_home()

            self.find('.chart-row .nav-tabs li:first-child').text.should.contain('Map')
        finally:
            driver.close()
            self.set_browser(old_browser)
            self.browser.set_window_size(width=1200, height=1000)

    def test_hamburger_menu(self):
        self.visit_home()
        try:
            self.browser.set_window_size(800, 1000)

            self.is_element_displayed('.landing-nav .nav-tabs').should.be.true
            self.is_element_displayed('.landing-nav .tablist').should.be.false

            self.find('.landing-nav .nav-tabs .fa-bars').click()
            self.find('.landing-nav .nav-tabs-sidebar').get_attribute('class').shouldnt.contain('hidden')

            self.find('.landing-nav .nav-tabs-sidebar .fa-times').click()
            self.find('.landing-nav .nav-tabs-sidebar').get_attribute('class').should.contain('hidden')

            self.find('.landing-nav .nav-tabs .fa-bars').click()
            self.find('#landing-page > div.landing-page.fixed-nav > nav > div > div.nav-tabs.pull-right > div > ul > li:nth-child(3) > a').click()  # noqa
            self.until_ajax_complete()
            self.find('.landing-nav .nav-tabs-sidebar').get_attribute('class').should.contain('hidden')
        finally:
            self.set_default_window_size()
            self.try_to_revive_browser()

    def test_overlay_hamburger_menu(self):
        self.visit_home()
        try:
            self.browser.set_window_size(800, 1000)

            self.find('.landing-nav .nav-tabs .fa-bars').click()
            self.find('#overlay').get_attribute('class').should.contain('active')

            self.find('.landing-nav .nav-tabs-sidebar .fa-times').click()
            self.find('#overlay').get_attribute('class').shouldnt.contain('active')

            self.find('.landing-nav .nav-tabs .fa-bars').click()
            self.find('#landing-page > div.landing-page.fixed-nav > nav > div > div.nav-tabs.pull-right > div > ul > li:nth-child(3) > a').click()  # noqa
            self.until_ajax_complete()
            self.find('#overlay').get_attribute('class').shouldnt.contain('active')

            self.find('.landing-nav .nav-tabs .fa-bars').click()
            self.find('#overlay').get_attribute('class').should.contain('active')
        finally:
            self.set_default_window_size()
            self.try_to_revive_browser()
Beispiel #44
0
 def setUp(self):
     self.officer = OfficerFactory()
     OfficerAllegationFactory.create_batch(2, officer=self.officer)
 def setUp(self):
     self.allegation_category = AllegationCategoryFactory()
     self.officer_allegation = OfficerAllegationFactory(
         cat=self.allegation_category, final_finding='NS')