def test_extractor_post_triggers_slack_notification(self, testapp):
        ''' A valid heartbeat post triggers a Slack notification
        '''
        # set up the extractor
        department = Department.create(name="Good Police Department", short_name="GPD", load_defaults=False)
        Extractor.create(username='******', email='*****@*****.**', password="******", department_id=department.id, next_month=10, next_year=2006)

        # set the correct authorization
        testapp.authorization = ('Basic', ('extractor', 'password'))

        # set a fake Slack webhook URL
        fake_webhook_url = 'http://webhook.example.com/'
        current_app.config['SLACK_WEBHOOK_URL'] = fake_webhook_url

        # create a mock to receive POST requests to that URL
        responses.add(responses.POST, fake_webhook_url, status=200)

        # post a sample json object to the heartbeat URL
        testapp.post_json("/data/heartbeat", params={"heartbeat": "heartbeat"})

        # test the captured post payload
        post_body = json.loads(responses.calls[0].request.body)
        assert 'Comport Pinged by Extractor!' in post_body['text']

        # delete the fake Slack webhook URL
        del(current_app.config['SLACK_WEBHOOK_URL'])
        # reset the mock
        responses.reset()
Ejemplo n.º 2
0
    def test_valid_login_replies_with_request(self, testapp):
        right_department = Department.create(name="good2", load_defaults=False)

        Extractor.create(username="******", email="*****@*****.**", password="******", department_id=right_department.id)
        testapp.authorization = ("Basic", ("good4", "valid"))

        res = testapp.post_json("/data/heartbeat", params={"json": "yep"}, expect_errors=True)
        assert res.status_code == 200
 def test_reject_extractor_post_with_wrong_password(self, testapp):
     ''' An extractor login with the wrong password is rejected.
     '''
     Extractor.create(username='******', email='*****@*****.**', password="******")
     testapp.authorization = ('Basic', ('extractor', 'drowssap'))
     response = testapp.post("/data/heartbeat", expect_errors=True)
     assert response.status_code == 401
     assert response.text == 'Extractor authorization failed!'
Ejemplo n.º 4
0
    def test_updated_text_on_schema_pages(self, testapp):
        ''' The notice of the last time a dataset was updated is on all schema pages
        '''
        department = Department.create(name="B Police Department",
                                       short_name="BPD",
                                       is_public=True)
        CitizenComplaintBPD.create(department_id=department.id,
                                   opaque_id="12345abcde")
        UseOfForceIncidentBPD.create(department_id=department.id,
                                     opaque_id="23456bcdef")
        OfficerInvolvedShootingBPD.create(department_id=department.id,
                                          opaque_id="34567cdefg")

        SRDepartment = Department.create(name="SR Police Department",
                                         short_name="SRPD",
                                         is_public=True)
        PursuitSRPD.create(department_id=SRDepartment.id,
                           opaque_id="45678defgh")

        extractor_password = '******'
        bpd_extractor, envs = Extractor.from_department_and_password(
            department=department, password=extractor_password)
        bpd_extractor.last_contact = datetime.datetime(2012, 9, 16)
        srpd_extractor, envs = Extractor.from_department_and_password(
            department=SRDepartment, password=extractor_password)
        srpd_extractor.last_contact = datetime.datetime(2014, 11, 2)

        response = testapp.get("/department/BPD/schema/complaints/")
        soup = BeautifulSoup(response.text)
        updated_span = soup.find("span", {"class": "updated"})
        assert updated_span is not None
        assert "Last Updated September 16, 2012" == updated_span.text

        response = testapp.get("/department/BPD/schema/useofforce/")
        soup = BeautifulSoup(response.text)
        updated_span = soup.find("span", {"class": "updated"})
        assert updated_span is not None
        assert "Last Updated September 16, 2012" == updated_span.text

        response = testapp.get(
            "/department/BPD/schema/officerinvolvedshootings/")
        soup = BeautifulSoup(response.text)
        updated_span = soup.find("span", {"class": "updated"})
        assert updated_span is not None
        assert "Last Updated September 16, 2012" == updated_span.text

        response = testapp.get("/department/SRPD/schema/pursuits/")
        soup = BeautifulSoup(response.text)
        updated_span = soup.find("span", {"class": "updated"})
        assert updated_span is not None
        assert "Last Updated November 02, 2014" == updated_span.text
Ejemplo n.º 5
0
    def test_correct_complaint_cap (self, testapp):
        ''' New complaint data from the extractor is processed as expected.
        '''
        # Set up the extractor
        department = Department.create(name="IM Police Department", short_name="IMPD", load_defaults=False)
        extractor, envs = Extractor.from_department_and_password(department=department, password="******")

        # Set the correct authorization
        testapp.authorization = ('Basic', (extractor.username, 'password'))

        # Get a generated list of complaint descriptions from the JSON test client
        test_client = JSONTestClient()
        complaint_count = 1
        complaint_data = test_client.get_prebaked_complaints(last=complaint_count)
        complaint_data[0]["allegation"] = "Rude, demeaning, or affronting language"

        # post the json to the complaint URL
        response = testapp.post_json("/data/complaints", params={'month': 0, 'year': 0, 'data': complaint_data})

        # assert that we got the expected reponse
        assert response.status_code == 200
        assert response.json_body['updated'] == 0
        assert response.json_body['added'] == complaint_count

        # check the complaint incident in the database against the data that was sent
        cleaner = Cleaners()
        sent_complaint = cleaner.capitalize_incident(complaint_data[0])
        check_complaint = CitizenComplaintIMPD.query.filter_by(opaque_id=sent_complaint['opaqueId']).first()
        assert check_complaint.allegation == "Rude, Demeaning, or Affronting Language"
        with open("scratch.txt", "w") as text_file:
            text_file.write("Complaint Data: {} ".format(check_complaint.allegation))
Ejemplo n.º 6
0
    def test_post_assaults_data(self, testapp):
        ''' New assaults data from the extractor is processed as expected.
        '''
        # Set up the extractor
        department = Department.create(name="IM Police Department", short_name="IMPD", load_defaults=False)
        extractor, envs = Extractor.from_department_and_password(department=department, password="******")

        # Set the correct authorization
        testapp.authorization = ('Basic', (extractor.username, 'password'))

        # Get a generated list of assault descriptions from the JSON test client
        test_client = JSONTestClient()
        assault_count = 1
        assault_data = test_client.get_prebaked_assaults(last=assault_count)
        # post the json to the assault URL
        response = testapp.post_json("/data/assaults", params={'month': 0, 'year': 0, 'data': assault_data})

        # assert that we got the expected reponse
        assert response.status_code == 200
        assert response.json_body['updated'] == 0
        assert response.json_body['added'] == assault_count

        # check the assault incident in the database against the data that was sent
        cleaner = Cleaners()
        sent_assault = cleaner.capitalize_incident(assault_data[0])
        check_assault = AssaultOnOfficerIMPD.query.filter_by(opaque_id=sent_assault['opaqueId']).first()
        assert check_assault.service_type == sent_assault['serviceType']
        assert check_assault.force_type == sent_assault['forceType']
        assert check_assault.assignment == sent_assault['assignment']
        assert check_assault.arrest_made == sent_assault['arrestMade']
        assert check_assault.officer_injured == sent_assault['officerInjured']
        assert check_assault.officer_killed == sent_assault['officerKilled']
        assert check_assault.report_filed == sent_assault['reportFiled']
Ejemplo n.º 7
0
    def test_can_set_extractor_start_date(self, testapp):
        ''' Can set an extraction start date.
        '''
        # set up the department
        department = Department.create(name="IM Police Department", short_name="IMPD", load_defaults=False)

        # set up a user
        user = User.create(username="******", email="*****@*****.**", password="******")
        user.departments.append(department)
        user.active = True
        user.save()
        # login
        response = testapp.get("/login/")
        form = response.forms['loginForm']
        form['username'] = user.username
        form['password'] = '******'
        response = form.submit().follow()

        # create an extractor account
        extractor_password = "******"
        extractor, _ = Extractor.from_department_and_password(department=department, password=extractor_password)

        # submit the extractor start date form
        response = testapp.get("/department/{}".format(department.id))
        form = response.forms["extractionStartForm"]
        submit_month = 10
        submit_year = 2006
        form['month'] = str(submit_month)
        form['year'] = str(submit_year)
        response = form.submit('submit').follow()

        # the new date was set
        assert extractor.next_month == submit_month
        assert extractor.next_year == submit_year
Ejemplo n.º 8
0
    def test_extractors_are_users(self):
        department = DepartmentFactory()
        department.save()

        extractor = Extractor.create(username='******', email='*****@*****.**', department_id=department.id)

        assert extractor.department_id == department.id
Ejemplo n.º 9
0
    def test_can_set_extractor_start_date(self, testapp):
        ''' Can set an extraction start date.
        '''
        # set up the department
        department = Department.create(name="Good Police Department", short_name="GPD", load_defaults=False)

        # set up a user
        user = User.create(username="******", email="*****@*****.**", password="******")
        user.departments.append(department)
        user.active = True
        user.save()
        # login
        response = testapp.get("/login/")
        form = response.forms['loginForm']
        form['username'] = user.username
        form['password'] = '******'
        response = form.submit().follow()

        # create an extractor account
        extractor_password = "******"
        extractor, _ = Extractor.from_department_and_password(department=department, password=extractor_password)

        # submit the extractor start date form
        response = testapp.get("/department/{}".format(department.id))
        form = response.forms["extractionStartForm"]
        submit_month = 10
        submit_year = 2006
        form['month'] = str(submit_month)
        form['year'] = str(submit_year)
        response = form.submit('submit').follow()

        # the new date was set
        assert extractor.next_month == submit_month
        assert extractor.next_year == submit_year
    def test_successful_extractor_post(self, testapp):
        ''' Send a valid heartbeat post, get a valid response.
        '''
        # set up the extractor
        department = Department.create(name="Good Police Department", short_name="GPD", load_defaults=False)
        Extractor.create(username='******', email='*****@*****.**', password="******", department_id=department.id, next_month=10, next_year=2006)

        # set the correct authorization
        testapp.authorization = ('Basic', ('extractor', 'password'))

        # post a sample json object to the heartbeat URL
        response = testapp.post_json("/data/heartbeat", params={"heartbeat": "heartbeat"})
        # assert that we got the expected response
        assert response.status_code == 200
        assert response.json_body['nextMonth'] == 10
        assert response.json_body['nextYear'] == 2006
        assert response.json_body['received'] == {'heartbeat': 'heartbeat'}
    def test_post_mistyped_uof_data(self, testapp):
        ''' New UOF data from the extractor is processed as expected.
        '''
        # Set up the extractor
        department = Department.create(name="Good Police Department", short_name="GPD", load_defaults=False)
        extractor, envs = Extractor.from_department_and_password(department=department, password="******")

        # Set the correct authorization
        testapp.authorization = ('Basic', (extractor.username, 'password'))

        # Get a generated list of UOF descriptions from the JSON test client
        test_client = JSONTestClient()
        uof_count = 1
        uof_data = test_client.get_prebaked_uof(last=uof_count)

        # The app expects number values to be transmitted as strings. Let's change them to integers.
        uof_data[0]['residentAge'] = 28
        uof_data[0]['officerAge'] = 46
        uof_data[0]['officerYearsOfService'] = 17

        # post the json to the UOF URL
        response = testapp.post_json("/data/UOF", params={'month': 0, 'year': 0, 'data': uof_data})

        # assert that we got the expected reponse
        assert response.status_code == 200
        assert response.json_body['updated'] == 0
        assert response.json_body['added'] == uof_count

        # check the uof incident in the database against the data that was sent
        cleaner = Cleaners()
        sent_uof = uof_data[0]
        check_uof = UseOfForceIncident.query.filter_by(opaque_id=sent_uof['opaqueId']).first()
        assert check_uof.occured_date.strftime('%Y-%m-%d %-H:%-M:%S') == sent_uof['occuredDate']
        assert check_uof.division == cleaner.capitalize(sent_uof['division'])
        assert check_uof.precinct == cleaner.capitalize(sent_uof['precinct'])
        assert check_uof.shift == cleaner.capitalize(sent_uof['shift'])
        assert check_uof.beat == cleaner.capitalize(sent_uof['beat'])
        assert check_uof.disposition == sent_uof['disposition']
        assert check_uof.officer_force_type == cleaner.officer_force_type(sent_uof['officerForceType'])
        assert check_uof.use_of_force_reason == sent_uof['useOfForceReason']
        assert check_uof.service_type == sent_uof['serviceType']
        assert check_uof.arrest_made == sent_uof['arrestMade']
        assert check_uof.arrest_charges == sent_uof['arrestCharges']
        assert check_uof.resident_weapon_used == sent_uof['residentWeaponUsed']
        assert check_uof.resident_injured == sent_uof['residentInjured']
        assert check_uof.resident_hospitalized == sent_uof['residentHospitalized']
        assert check_uof.officer_injured == sent_uof['officerInjured']
        assert check_uof.officer_hospitalized == sent_uof['officerHospitalized']
        assert check_uof.resident_race == cleaner.race(sent_uof['residentRace'])
        assert check_uof.resident_sex == cleaner.sex(sent_uof['residentSex'])
        assert check_uof.resident_age == cleaner.number_to_string(sent_uof['residentAge'])
        assert check_uof.resident_condition == sent_uof['residentCondition']
        assert check_uof.officer_identifier == sent_uof['officerIdentifier']
        assert check_uof.officer_race == cleaner.race(sent_uof['officerRace'])
        assert check_uof.officer_sex == cleaner.sex(sent_uof['officerSex'])
        assert check_uof.officer_age == cleaner.number_to_string(sent_uof['officerAge'])
        assert check_uof.officer_years_of_service == cleaner.number_to_string(sent_uof['officerYearsOfService'])
        assert check_uof.officer_condition == sent_uof['officerCondition']
Ejemplo n.º 12
0
    def test_extractors_are_users(self):
        department = DepartmentFactory()
        department.save()

        extractor = Extractor.create(username='******', email='*****@*****.**')
        extractor.departments.append(department)
        extractor.save()

        assert extractor.first_department().id == department.id
Ejemplo n.º 13
0
    def test_users_are_not_extractors(self):
        department = DepartmentFactory()
        department.save()
        user = User(username='******', email='*****@*****.**')
        user.departments.append(department)
        user.save()

        assert Extractor.get_by_id(user.id) == None
        assert Extractor.query.filter_by(username=user.username).first() == None
Ejemplo n.º 14
0
    def test_users_are_not_extractors(self):
        department = DepartmentFactory()
        department.save()
        user = User(username='******', email='*****@*****.**')
        user.departments.append(department)
        user.save()

        assert Extractor.get_by_id(user.id) == None
        assert Extractor.query.filter_by(
            username=user.username).first() == None
Ejemplo n.º 15
0
    def test_extractors_are_users(self):
        department = DepartmentFactory()
        department.save()

        extractor = Extractor.create(username='******',
                                     email='*****@*****.**')
        extractor.departments.append(department)
        extractor.save()

        assert extractor.first_department().id == department.id
    def test_extractors_from_department_and_password(self):
        department = DepartmentFactory()
        department.save()

        password = str(uuid.uuid4())

        extractor, envs = Extractor.from_department_and_password(department=department, password=password)

        assert department == extractor.departments[0]
        assert extractor.check_password(password) is True
        assert password in envs
    def test_get_extractor_from_department(self):
        department = DepartmentFactory()
        department.save()
        assert (" " in department.name) is True

        password = str(uuid.uuid4())

        extractor, envs = Extractor.from_department_and_password(department=department, password=password)
        extractor.save()

        assert department.get_extractor() == extractor
        assert (" " in extractor.username) is False
    def test_post_mistyped_ois_data(self, testapp):
        ''' New OIS data from the extractor is processed as expected.
        '''
        # Set up the extractor
        department = Department.create(name="Good Police Department", short_name="GPD", load_defaults=False)
        extractor, envs = Extractor.from_department_and_password(department=department, password="******")

        # Set the correct authorization
        testapp.authorization = ('Basic', (extractor.username, 'password'))

        # Get a generated list of OIS descriptions from the JSON test client
        test_client = JSONTestClient()
        ois_count = 1
        ois_data = test_client.get_prebaked_ois(last=ois_count)

        # The app expects number values to be transmitted as strings. Let's change them to integers.
        ois_data[0]['residentAge'] = 28
        ois_data[0]['officerAge'] = 46
        # And it expects this number value to be transmitted as a number, so let's make it a string.
        ois_data[0]['officerYearsOfService'] = "17"

        # post the json to the OIS URL
        response = testapp.post_json("/data/OIS", params={'month': 0, 'year': 0, 'data': ois_data})

        # assert that we got the expected reponse
        assert response.status_code == 200
        assert response.json_body['updated'] == 0
        assert response.json_body['added'] == ois_count

        # check the ois incident in the database against the data that was sent
        cleaner = Cleaners()
        sent_ois = ois_data[0]
        check_ois = OfficerInvolvedShooting.query.filter_by(opaque_id=sent_ois['opaqueId']).first()
        assert check_ois.occured_date.strftime('%Y-%m-%d %-H:%-M:%S') == sent_ois['occuredDate']
        assert check_ois.division == cleaner.capitalize(sent_ois['division'])
        assert check_ois.precinct == cleaner.capitalize(sent_ois['precinct'])
        assert check_ois.shift == cleaner.capitalize(sent_ois['shift'])
        assert check_ois.beat == cleaner.capitalize(sent_ois['beat'])
        assert check_ois.disposition == sent_ois['disposition']
        assert check_ois.resident_race == cleaner.race(sent_ois['residentRace'])
        assert check_ois.resident_sex == cleaner.sex(sent_ois['residentSex'])
        assert check_ois.resident_age == cleaner.number_to_string(sent_ois['residentAge'])
        assert check_ois.resident_weapon_used == cleaner.resident_weapon_used(sent_ois['residentWeaponUsed'])
        assert check_ois.resident_condition == sent_ois['residentCondition']
        assert check_ois.officer_identifier == sent_ois['officerIdentifier']
        assert check_ois.officer_weapon_used == sent_ois['officerForceType']
        assert check_ois.officer_race == cleaner.race(sent_ois['officerRace'])
        assert check_ois.officer_sex == cleaner.sex(sent_ois['officerSex'])
        assert check_ois.officer_age == cleaner.number_to_string(sent_ois['officerAge'])
        assert check_ois.officer_years_of_service == cleaner.string_to_integer(sent_ois['officerYearsOfService'])
        assert check_ois.officer_condition == sent_ois['officerCondition']
    def test_regen_extractor_envs(self):
        department = DepartmentFactory()
        department.save()

        password = str(uuid.uuid4())

        extractor, envs = Extractor.from_department_and_password(department=department, password=password)
        extractor.save()
        new_password = str(uuid.uuid4())

        extractor.set_password(new_password)

        assert extractor.check_password(new_password) is True
        assert new_password in extractor.generate_envs(new_password)
    def test_post_mistyped_complaint_data(self, testapp):
        ''' New complaint data from the extractor with wrongly typed data is processed as expected.
        '''
        # Set up the extractor
        department = Department.create(name="Good Police Department", short_name="GPD", load_defaults=False)
        extractor, envs = Extractor.from_department_and_password(department=department, password="******")

        # Set the correct authorization
        testapp.authorization = ('Basic', (extractor.username, 'password'))

        # Get a generated list of complaint descriptions from the JSON test client
        test_client = JSONTestClient()
        complaint_count = 1
        complaint_data = test_client.get_prebaked_complaints(last=complaint_count)

        # The app expects number values to be transmitted as strings. Let's change them to integers.
        complaint_data[0]['residentAge'] = 28
        complaint_data[0]['officerAge'] = 46
        complaint_data[0]['officerYearsOfService'] = 17

        # post the json to the complaint URL
        response = testapp.post_json("/data/complaints", params={'month': 0, 'year': 0, 'data': complaint_data})

        # assert that we got the expected reponse
        assert response.status_code == 200
        assert response.json_body['updated'] == 0
        assert response.json_body['added'] == complaint_count

        # check the complaint incident in the database against the data that was sent
        cleaner = Cleaners()
        sent_complaint = cleaner.capitalize_incident(complaint_data[0])
        check_complaint = CitizenComplaint.query.filter_by(opaque_id=sent_complaint['opaqueId']).first()
        assert check_complaint.occured_date.strftime('%Y-%m-%d %-H:%-M:%S') == sent_complaint['occuredDate']
        assert check_complaint.division == sent_complaint['division']
        assert check_complaint.precinct == sent_complaint['precinct']
        assert check_complaint.shift == sent_complaint['shift']
        assert check_complaint.beat == sent_complaint['beat']
        assert check_complaint.disposition == sent_complaint['disposition']
        assert check_complaint.service_type == sent_complaint['serviceType']
        assert check_complaint.source == sent_complaint['source']
        assert check_complaint.allegation_type == sent_complaint['allegationType']
        assert check_complaint.allegation == sent_complaint['allegation']
        assert check_complaint.resident_race == cleaner.race(sent_complaint['residentRace'])
        assert check_complaint.resident_sex == cleaner.sex(sent_complaint['residentSex'])
        assert check_complaint.resident_age == cleaner.number_to_string(sent_complaint['residentAge'])
        assert check_complaint.officer_identifier == sent_complaint['officerIdentifier']
        assert check_complaint.officer_race == cleaner.race(sent_complaint['officerRace'])
        assert check_complaint.officer_sex == cleaner.sex(sent_complaint['officerSex'])
        assert check_complaint.officer_age == cleaner.number_to_string(sent_complaint['officerAge'])
        assert check_complaint.officer_years_of_service == cleaner.number_to_string(sent_complaint['officerYearsOfService'])
Ejemplo n.º 21
0
def edit_extractor(extractor_id):
    extractor = Extractor.get_by_id(extractor_id)
    if not extractor:
        abort(404)

    form = EditExtractorForm(request.form, departments=[d.id for d in extractor.departments])
    form.departments.choices = [(d.id, d.name) for d in Department.query.order_by('name')]

    if request.method == 'POST':
        extractor.departments = [Department.get_by_id(int(d)) for d in form.departments.data]
        extractor.save()
        flash('Extractor updated.', 'info')
        return redirect(url_for('admin.admin_dashboard'))

    return render_template("admin/editExtractor.html", form=form, extractor=extractor)
Ejemplo n.º 22
0
    def test_current_mmyy_on_no_setdate(self, testapp):
        ''' When there is no fixed date, it should send the current month and current year '''
        # set up the extractor
        department = Department.create(name="IM Police Department", short_name="IMPD", load_defaults=False)
        extractor, _ = Extractor.from_department_and_password(department=department, password="******")

        # set the correct authorization
        testapp.authorization = ('Basic', (extractor.username, 'password'))

        # post a sample json object to the heartbeat URL
        response = testapp.post_json("/data/heartbeat", params={"heartbeat": "heartbeat"})

        # current month and year
        now = datetime.now()

        # assert that we got the expected response
        assert response.status_code == 200
        assert response.json_body['nextMonth'] == now.month
        assert response.json_body['nextYear'] == now.year
        assert response.json_body['received'] == {'heartbeat': 'heartbeat'}
Ejemplo n.º 23
0
def edit_extractor(extractor_id):
    extractor = Extractor.get_by_id(extractor_id)
    if not extractor:
        abort(404)

    form = EditExtractorForm(request.form,
                             departments=[d.id for d in extractor.departments])
    form.departments.choices = [(d.id, d.name)
                                for d in Department.query.order_by('name')]

    if request.method == 'POST':
        extractor.departments = [
            Department.get_by_id(int(d)) for d in form.departments.data
        ]
        extractor.save()
        flash('Extractor updated.', 'info')
        return redirect(url_for('admin.admin_dashboard'))

    return render_template("admin/editExtractor.html",
                           form=form,
                           extractor=extractor)
    def test_skip_multiple_complaint_data(self, testapp):
        ''' Multiple complaint data from the extractor is skipped.
        '''
        # Set up the extractor
        department = Department.create(name="Good Police Department", short_name="GPD", load_defaults=False)
        extractor, envs = Extractor.from_department_and_password(department=department, password="******")

        # Set the correct authorization
        testapp.authorization = ('Basic', (extractor.username, 'password'))

        # Get a generated list of complaint descriptions from the JSON test client
        test_client = JSONTestClient()
        complaint_data = test_client.get_prebaked_complaints(last=1)
        # post the json to the complaint URL
        response = testapp.post_json("/data/complaints", params={'month': 0, 'year': 0, 'data': complaint_data})

        # assert that we got the expected reponse
        assert response.status_code == 200
        assert response.json_body['updated'] == 0
        assert response.json_body['added'] == 1

        # Get the second pre-baked complaint
        multiple_complaint_data = test_client.get_prebaked_complaints(first=1, last=2)
        # Swap in the opaque ID from the first complaint
        multiple_complaint_data[0]["opaqueId"] = complaint_data[0]["opaqueId"]
        # The complaint will be skipped as a 'multiple' if these fields are the same
        multiple_complaint_data[0]["allegationType"] = complaint_data[0]["allegationType"]
        multiple_complaint_data[0]["allegation"] = complaint_data[0]["allegation"]
        multiple_complaint_data[0]["officerIdentifier"] = complaint_data[0]["officerIdentifier"]
        # post the json to the complaint URL
        response = testapp.post_json("/data/complaints", params={'month': 0, 'year': 0, 'data': multiple_complaint_data})

        # assert that we got the expected reponse
        assert response.status_code == 200
        assert response.json_body['updated'] == 0
        assert response.json_body['added'] == 0

        # There is one complaint in the database.
        all_complaints = CitizenComplaint.query.all()
        assert len(all_complaints) == 1
    def test_post_ois_data_near_match_does_not_update(self, testapp):
        ''' OIS data with the same ID but different details creates a new record.
        '''
        # Set up the extractor
        department = Department.create(name="Good Police Department", short_name="GPD", load_defaults=False)
        extractor, envs = Extractor.from_department_and_password(department=department, password="******")

        # Set the correct authorization
        testapp.authorization = ('Basic', (extractor.username, 'password'))

        # Get a generated list of OIS descriptions from the JSON test client
        test_client = JSONTestClient()
        ois_data = test_client.get_prebaked_ois(last=1)
        # post the json to the OIS URL
        response = testapp.post_json("/data/OIS", params={'month': 0, 'year': 0, 'data': ois_data})

        # assert that we got the expected reponse
        assert response.status_code == 200
        assert response.json_body['updated'] == 0
        assert response.json_body['added'] == 1

        # Get the second pre-baked ois incident
        updated_ois_data = test_client.get_prebaked_ois(first=1, last=2)
        # Swap in the opaque ID from the first ois incident
        updated_ois_data[0]["opaqueId"] = ois_data[0]["opaqueId"]
        # post the json to the ois URL
        response = testapp.post_json("/data/OIS", params={'month': 0, 'year': 0, 'data': updated_ois_data})

        # assert that we got the expected reponse
        assert response.status_code == 200
        assert response.json_body['updated'] == 0
        assert response.json_body['added'] == 1

        # There's only one complaint in the database.
        all_ois = OfficerInvolvedShooting.query.all()
        assert len(all_ois) == 2
Ejemplo n.º 26
0
    def test_update_uof_data(self, testapp):
        ''' Updated UOF data from the extractor is processed as expected.
        '''
        # Set up the extractor
        department = Department.create(name="IM Police Department", short_name="IMPD", load_defaults=False)
        extractor, envs = Extractor.from_department_and_password(department=department, password="******")

        # Set the correct authorization
        testapp.authorization = ('Basic', (extractor.username, 'password'))

        # Get a generated list of UOF descriptions from the JSON test client
        test_client = JSONTestClient()
        uof_data = test_client.get_prebaked_uof(last=1)
        # post the json to the UOF URL
        response = testapp.post_json("/data/UOF", params={'month': 0, 'year': 0, 'data': uof_data})

        # assert that we got the expected reponse
        assert response.status_code == 200
        assert response.json_body['updated'] == 0
        assert response.json_body['added'] == 1

        # Get the second pre-baked uof incident
        updated_uof_data = test_client.get_prebaked_uof(first=1, last=2)
        # Swap in the opaque ID from the first uof incident
        updated_uof_data[0]["opaqueId"] = uof_data[0]["opaqueId"]
        # The uof incident won't be a match unless these fields are the same
        updated_uof_data[0]["officerIdentifier"] = uof_data[0]["officerIdentifier"]
        updated_uof_data[0]["officerForceType"] = uof_data[0]["officerForceType"]
        # post the json to the uof URL
        response = testapp.post_json("/data/UOF", params={'month': 0, 'year': 0, 'data': updated_uof_data})

        # assert that we got the expected reponse
        assert response.status_code == 200
        assert response.json_body['updated'] == 1
        assert response.json_body['added'] == 0

        # There's only one complaint in the database.
        all_uof = UseOfForceIncidentIMPD.query.all()
        assert len(all_uof) == 1

        # check the uof incident in the database against the updated data that was sent
        cleaner = Cleaners()
        sent_uof = updated_uof_data[0]
        check_uof = UseOfForceIncidentIMPD.query.filter_by(opaque_id=sent_uof['opaqueId']).first()
        assert check_uof.occured_date.strftime('%Y-%m-%d %-H:%-M:%S') == sent_uof['occuredDate']
        assert check_uof.division == cleaner.capitalize(sent_uof['division'])
        assert check_uof.precinct == cleaner.capitalize(sent_uof['precinct'])
        assert check_uof.shift == cleaner.capitalize(sent_uof['shift'])
        assert check_uof.beat == cleaner.capitalize(sent_uof['beat'])
        assert check_uof.disposition == sent_uof['disposition']
        assert check_uof.officer_force_type == cleaner.officer_force_type(sent_uof['officerForceType'])
        assert check_uof.use_of_force_reason == sent_uof['useOfForceReason']
        assert check_uof.service_type == sent_uof['serviceType']
        assert check_uof.arrest_made == sent_uof['arrestMade']
        assert check_uof.arrest_charges == sent_uof['arrestCharges']
        assert check_uof.resident_weapon_used == sent_uof['residentWeaponUsed']
        assert check_uof.resident_injured == sent_uof['residentInjured']
        assert check_uof.resident_hospitalized == sent_uof['residentHospitalized']
        assert check_uof.officer_injured == sent_uof['officerInjured']
        assert check_uof.officer_hospitalized == sent_uof['officerHospitalized']
        assert check_uof.resident_race == cleaner.race(sent_uof['residentRace'])
        assert check_uof.resident_sex == cleaner.sex(sent_uof['residentSex'])
        assert check_uof.resident_age == cleaner.number_to_string(sent_uof['residentAge'])
        assert check_uof.resident_condition == sent_uof['residentCondition']
        assert check_uof.officer_identifier == sent_uof['officerIdentifier']
        assert check_uof.officer_race == cleaner.race(sent_uof['officerRace'])
        assert check_uof.officer_sex == cleaner.sex(sent_uof['officerSex'])
        assert check_uof.officer_age == cleaner.number_to_string(sent_uof['officerAge'])
        assert check_uof.officer_years_of_service == cleaner.number_to_string(sent_uof['officerYearsOfService'])
        assert check_uof.officer_condition == sent_uof['officerCondition']
    def test_all_ois_records_destroyed_when_new_record_posted(self, testapp):
        ''' Posting a new record with an id that matches a set of past records destroys all of them.
        '''
        # Set up the extractor
        department = Department.create(name="B Police Department", short_name="BPD", load_defaults=False)
        extractor, _ = Extractor.from_department_and_password(department=department, password="******")

        # Set the correct authorization
        testapp.authorization = ('Basic', (extractor.username, 'password'))

        # post to the heartbeat URL to start the update
        response = testapp.post_json("/data/heartbeat", params={"heartbeat": "heartbeat"})

        # Post 5 fake incidents with an identical opaqueId to the OIS endpoint
        ois_count = 5
        test_client = JSONTestClient()
        ois_data = test_client.make_ois(count=ois_count, short_name=department.short_name)
        use_id = ois_data[0]['opaqueId']
        for idx, _ in enumerate(ois_data):
            ois_data[idx]['opaqueId'] = use_id
        response = testapp.post_json("/data/OIS", params={'month': 0, 'year': 0, 'data': ois_data})

        # assert that we got the expected reponse
        assert response.status_code == 200

        # there are 5 incident rows in the database
        check_ois = OfficerInvolvedShootingBPD.query.all()
        assert len(check_ois) == ois_count

        # all the records in the database have the same id
        ois_records = OfficerInvolvedShootingBPD.query.filter_by(opaque_id=use_id).all()
        assert len(ois_records) == ois_count
        # verify that the opaqueId is recorded in an IncidentsUpdated table
        record_updated = IncidentsUpdated.query.filter_by(opaque_id=use_id).first()
        assert record_updated is not None
        assert record_updated.incident_type == "ois"
        assert record_updated.department_id == department.id

        # post to the heartbeat URL to start the update
        response = testapp.post_json("/data/heartbeat", params={"heartbeat": "heartbeat"})

        # Create 1 new fake incident
        new_data = test_client.make_ois(count=1, short_name=department.short_name)
        # give it the same opaqueId as the first batch
        new_data[0]['opaqueId'] = use_id

        # post the new incident
        response = testapp.post_json("/data/OIS", params={'month': 0, 'year': 0, 'data': new_data})

        # assert that we got the expected reponse
        assert response.status_code == 200

        # there is now only 1 incident row in the database
        check_ois = OfficerInvolvedShootingBPD.query.all()
        assert len(check_ois) == 1

        # verify that the opaqueID posted matches that in the database
        assert check_ois[0].opaque_id == use_id

        # verify that the opaqueId is recorded in an IncidentsUpdated table
        record_updated = IncidentsUpdated.query.filter_by(opaque_id=use_id).first()
        assert record_updated is not None
        assert record_updated.incident_type == "ois"
        assert record_updated.department_id == department.id
    def test_post_ois_data(self, testapp):
        ''' New and updated OIS data from the extractor is processed as expected.
        '''
        # Set up the extractor
        department = Department.create(name="B Police Department", short_name="BPD", load_defaults=False)
        extractor, _ = Extractor.from_department_and_password(department=department, password="******")

        # Set the correct authorization
        testapp.authorization = ('Basic', (extractor.username, 'password'))

        # post to the heartbeat URL to start the update
        response = testapp.post_json("/data/heartbeat", params={"heartbeat": "heartbeat"})

        # Post 5 fake incidents to the OIS endpoint
        ois_count = 5
        test_client = JSONTestClient()
        ois_data = test_client.make_ois(count=ois_count, short_name=department.short_name)
        response = testapp.post_json("/data/OIS", params={'month': 0, 'year': 0, 'data': ois_data})

        # assert that we got the expected reponse
        assert response.status_code == 200

        # there are 5 incident rows in the database
        check_ois = OfficerInvolvedShootingBPD.query.all()
        assert len(check_ois) == ois_count

        for incident in ois_data:
            # verify that the opaqueIDs posted match those in the database
            assert OfficerInvolvedShootingBPD.query.filter_by(opaque_id=incident['opaqueId']).first() is not None
            # verify that the opaqueIds are recorded in IncidentsUpdated tables
            record_updated = IncidentsUpdated.query.filter_by(opaque_id=incident['opaqueId']).first()
            assert record_updated is not None
            assert record_updated.incident_type == "ois"
            assert record_updated.department_id == department.id

        # post to the heartbeat URL to start a new update
        response = testapp.post_json("/data/heartbeat", params={"heartbeat": "heartbeat"})

        # Create 5 more fake incidents
        new_data = test_client.make_ois(count=ois_count, short_name=department.short_name)
        # give them the same opaqueIds as the first batch
        for idx, _ in enumerate(new_data):
            new_data[idx]['opaqueId'] = ois_data[idx]['opaqueId']

        # post the new incident rows
        response = testapp.post_json("/data/OIS", params={'month': 0, 'year': 0, 'data': new_data})

        # assert that we got the expected reponse
        assert response.status_code == 200

        # there are 5 incident rows in the database
        check_ois = OfficerInvolvedShootingBPD.query.all()
        assert len(check_ois) == ois_count

        # verify that the opaqueIDs posted match those in the database
        for incident in ois_data:
            assert OfficerInvolvedShootingBPD.query.filter_by(opaque_id=incident['opaqueId']).first() is not None

        # Create 5 more fake incidents
        new_data = test_client.make_ois(count=ois_count, short_name=department.short_name)
        # give them the same opaqueIds as the first batch
        for idx, _ in enumerate(new_data):
            new_data[idx]['opaqueId'] = ois_data[idx]['opaqueId']

        # post the new incident rows without starting a new update
        response = testapp.post_json("/data/OIS", params={'month': 0, 'year': 0, 'data': new_data})

        # assert that we got the expected reponse
        assert response.status_code == 200

        # there are 10 incident rows in the database
        check_ois = OfficerInvolvedShootingBPD.query.all()
        assert len(check_ois) == ois_count * 2
Ejemplo n.º 29
0
    def run(self, department, mutators=[]):
        baseurl = "http://localhost:5000/"
        password = "******"
        extractor, envs = Extractor.from_department_and_password(
            department=department, password=password)
        comport_username = extractor.username
        comport_password = password
        end_date = datetime.datetime.now()
        start_date = end_date - relativedelta(months=18)

        data = []

        complaints = self.make_complaints(count=(900 + random.randint(0, 200)), start_date=start_date, end_date=end_date)

        for mutator in mutators:
            complaints = mutator.mutate(complaints)

        data.extend(complaints)

        print("* Adding {} fake complaints...".format(len(complaints)))

        for i in range(0, len(data), 100):
            chunk = data[i:i + 100]
            payload = {'data': chunk}

            url = baseurl + "data/complaints"

            print("- complaints {}-{}".format(i, i + len(chunk)))

            p = requests.post(url, auth=(comport_username,
                                         comport_password), json=payload)
            if p.status_code != 200:
                print("error: %s" % p.text.encode("utf-8", "ignore"))

        data = []

        use_of_force_incidents = self.make_uof(count=(900 + random.randint(0, 200)), start_date=start_date, end_date=end_date)

        for mutator in mutators:
            use_of_force_incidents = mutator.mutate(use_of_force_incidents)

        data.extend(use_of_force_incidents)

        print("* Adding {} fake uof...".format(len(use_of_force_incidents)))

        for i in range(0, len(data), 100):
            chunk = data[i:i + 100]
            payload = {'data': chunk}

            url = baseurl + "data/UOF"

            print("- uof {}-{}".format(i, i + len(chunk)))

            p = requests.post(url, auth=(comport_username,
                                         comport_password), json=payload)
            if p.status_code != 200:
                print("error: %s" % p.text.encode("utf-8", "ignore"))

        data = []

        ois_incidents = self.make_ois(count=(900 + random.randint(0, 200)), start_date=start_date, end_date=end_date)

        for mutator in mutators:
            ois_incidents = mutator.mutate(ois_incidents)

        data.extend(ois_incidents)

        print("* Adding {} fake ois...".format(len(ois_incidents)))

        for i in range(0, len(data), 100):
            chunk = data[i:i + 100]
            payload = {'data': chunk}

            url = baseurl + "data/OIS"

            print("- ois {}-{}".format(i, i + len(chunk)))

            p = requests.post(url, auth=(comport_username,
                                         comport_password), json=payload)
            if p.status_code != 200:
                print("error: %s" % p.text.encode("utf-8", "ignore"))
Ejemplo n.º 30
0
    def test_all_ois_records_destroyed_when_new_record_posted(self, testapp):
        ''' Posting a new record with an id that matches a set of past records destroys all of them.
        '''
        # Set up the extractor
        department = Department.create(name="B Police Department",
                                       short_name="BPD",
                                       load_defaults=False)
        extractor, _ = Extractor.from_department_and_password(
            department=department, password="******")

        # Set the correct authorization
        testapp.authorization = ('Basic', (extractor.username, 'password'))

        # post to the heartbeat URL to start the update
        response = testapp.post_json("/data/heartbeat",
                                     params={"heartbeat": "heartbeat"})

        # Post 5 fake incidents with an identical opaqueId to the OIS endpoint
        ois_count = 5
        test_client = JSONTestClient()
        ois_data = test_client.make_ois(count=ois_count,
                                        short_name=department.short_name)
        use_id = ois_data[0]['opaqueId']
        for idx, _ in enumerate(ois_data):
            ois_data[idx]['opaqueId'] = use_id
        response = testapp.post_json("/data/OIS",
                                     params={
                                         'month': 0,
                                         'year': 0,
                                         'data': ois_data
                                     })

        # assert that we got the expected reponse
        assert response.status_code == 200

        # there are 5 incident rows in the database
        check_ois = OfficerInvolvedShootingBPD.query.all()
        assert len(check_ois) == ois_count

        # all the records in the database have the same id
        ois_records = OfficerInvolvedShootingBPD.query.filter_by(
            opaque_id=use_id).all()
        assert len(ois_records) == ois_count
        # verify that the opaqueId is recorded in an IncidentsUpdated table
        record_updated = IncidentsUpdated.query.filter_by(
            opaque_id=use_id).first()
        assert record_updated is not None
        assert record_updated.incident_type == "ois"
        assert record_updated.department_id == department.id

        # post to the heartbeat URL to start the update
        response = testapp.post_json("/data/heartbeat",
                                     params={"heartbeat": "heartbeat"})

        # Create 1 new fake incident
        new_data = test_client.make_ois(count=1,
                                        short_name=department.short_name)
        # give it the same opaqueId as the first batch
        new_data[0]['opaqueId'] = use_id

        # post the new incident
        response = testapp.post_json("/data/OIS",
                                     params={
                                         'month': 0,
                                         'year': 0,
                                         'data': new_data
                                     })

        # assert that we got the expected reponse
        assert response.status_code == 200

        # there is now only 1 incident row in the database
        check_ois = OfficerInvolvedShootingBPD.query.all()
        assert len(check_ois) == 1

        # verify that the opaqueID posted matches that in the database
        assert check_ois[0].opaque_id == use_id

        # verify that the opaqueId is recorded in an IncidentsUpdated table
        record_updated = IncidentsUpdated.query.filter_by(
            opaque_id=use_id).first()
        assert record_updated is not None
        assert record_updated.incident_type == "ois"
        assert record_updated.department_id == department.id
Ejemplo n.º 31
0
    def test_post_uof_data(self, testapp):
        ''' New and updated UOF data from the extractor is processed as expected.
        '''
        # Set up the extractor
        department = Department.create(name="B Police Department",
                                       short_name="BPD",
                                       load_defaults=False)
        extractor, _ = Extractor.from_department_and_password(
            department=department, password="******")

        # Set the correct authorization
        testapp.authorization = ('Basic', (extractor.username, 'password'))

        # post to the heartbeat URL to start the update
        response = testapp.post_json("/data/heartbeat",
                                     params={"heartbeat": "heartbeat"})

        # Post 5 fake incidents to the UOF endpoint
        uof_count = 5
        test_client = JSONTestClient()
        uof_data = test_client.make_uof(count=uof_count,
                                        short_name=department.short_name)
        response = testapp.post_json("/data/UOF",
                                     params={
                                         'month': 0,
                                         'year': 0,
                                         'data': uof_data
                                     })

        # assert that we got the expected reponse
        assert response.status_code == 200

        # there are 5 incident rows in the database
        check_uofs = UseOfForceIncidentBPD.query.all()
        assert len(check_uofs) == uof_count

        for incident in uof_data:
            # verify that the opaqueIDs posted match those in the database
            assert UseOfForceIncidentBPD.query.filter_by(
                opaque_id=incident['opaqueId']).first() is not None
            # verify that the opaqueIds are recorded in IncidentsUpdated tables
            record_updated = IncidentsUpdated.query.filter_by(
                opaque_id=incident['opaqueId']).first()
            assert record_updated is not None
            assert record_updated.department_id == department.id
            assert record_updated.incident_type == "uof"

        # post to the heartbeat URL to start the new update
        response = testapp.post_json("/data/heartbeat",
                                     params={"heartbeat": "heartbeat"})

        # Create 5 more fake incidents
        new_data = test_client.make_uof(count=uof_count,
                                        short_name=department.short_name)
        # give them the same opaqueIds as the first batch
        for idx, _ in enumerate(new_data):
            new_data[idx]['opaqueId'] = uof_data[idx]['opaqueId']

        # post the new incident rows
        response = testapp.post_json("/data/UOF",
                                     params={
                                         'month': 0,
                                         'year': 0,
                                         'data': new_data
                                     })

        # assert that we got the expected reponse
        assert response.status_code == 200

        # there are 5 incident rows in the database
        check_uofs = UseOfForceIncidentBPD.query.all()
        assert len(check_uofs) == uof_count

        # verify that the opaqueIDs posted match those in the database
        for incident in uof_data:
            assert UseOfForceIncidentBPD.query.filter_by(
                opaque_id=incident['opaqueId']).first() is not None

        # Create 5 more fake incidents
        new_data = test_client.make_uof(count=uof_count,
                                        short_name=department.short_name)
        # give them the same opaqueIds as the first batch
        for idx, _ in enumerate(new_data):
            new_data[idx]['opaqueId'] = uof_data[idx]['opaqueId']

        # post the new incident rows without starting a new update
        response = testapp.post_json("/data/UOF",
                                     params={
                                         'month': 0,
                                         'year': 0,
                                         'data': new_data
                                     })

        # assert that we got the expected reponse
        assert response.status_code == 200

        # there are 10 incident rows in the database
        check_uofs = UseOfForceIncidentBPD.query.all()
        assert len(check_uofs) == uof_count * 2
Ejemplo n.º 32
0
    def run(self, department, mutators=[]):
        baseurl = "http://localhost:5000/"
        password = "******"
        extractor, envs = Extractor.from_department_and_password(
            department=department, password=password)
        comport_username = extractor.username
        comport_password = password

        data = []

        complaints = self.make_complaints()

        for mutator in mutators:
            complaints = mutator.mutate(complaints)

        data.extend(complaints)

        for i in range(0, len(data), 100):
            chunk = data[i:i + 100]
            payload = {'data': chunk}

            url = baseurl + "data/complaints"

            print(payload)

            p = requests.post(url, auth=(comport_username,
                                         comport_password), json=payload)
            if p.status_code != 200:
                print("error: %s" % p.text.encode("utf-8", "ignore"))

        data = []

        use_of_force_incidents = self.make_uof()

        for mutator in mutators:
            use_of_force_incidents = mutator.mutate(use_of_force_incidents)

        data.extend(use_of_force_incidents)

        for i in range(0, len(data), 100):
            chunk = data[i:i + 100]
            payload = {'data': chunk}

            url = baseurl + "data/UOF"

            print(payload)

            p = requests.post(url, auth=(comport_username,
                                         comport_password), json=payload)
            if p.status_code != 200:
                print("error: %s" % p.text.encode("utf-8", "ignore"))

        data = []

        ois_incidents = self.make_ois()

        for mutator in mutators:
            ois_incidents = mutator.mutate(ois_incidents)

        data.extend(ois_incidents)

        for i in range(0, len(data), 100):
            chunk = data[i:i + 100]
            payload = {'data': chunk}

            url = baseurl + "data/OIS"

            print(payload)

            p = requests.post(url, auth=(comport_username,
                                         comport_password), json=payload)
            if p.status_code != 200:
                print("error: %s" % p.text.encode("utf-8", "ignore"))
Ejemplo n.º 33
0
    def test_update_complaint_data(self, testapp):
        ''' Updated complaint data from the extractor is processed as expected.
        '''
        # Set up the extractor
        department = Department.create(name="IM Police Department", short_name="IMPD", load_defaults=False)
        extractor, envs = Extractor.from_department_and_password(department=department, password="******")

        # Set the correct authorization
        testapp.authorization = ('Basic', (extractor.username, 'password'))

        # Get a generated list of complaint descriptions from the JSON test client
        test_client = JSONTestClient()
        complaint_data = test_client.get_prebaked_complaints(last=1)
        # post the json to the complaint URL
        response = testapp.post_json("/data/complaints", params={'month': 0, 'year': 0, 'data': complaint_data})

        # assert that we got the expected reponse
        assert response.status_code == 200
        assert response.json_body['updated'] == 0
        assert response.json_body['added'] == 1

        # Get the second pre-baked complaint
        updated_complaint_data = test_client.get_prebaked_complaints(first=1, last=2)
        # Swap in the opaque ID from the first complaint
        updated_complaint_data[0]["opaqueId"] = complaint_data[0]["opaqueId"]
        # The complaint won't be a match unless these fields are the same
        updated_complaint_data[0]["allegationType"] = complaint_data[0]["allegationType"]
        updated_complaint_data[0]["allegation"] = complaint_data[0]["allegation"]
        updated_complaint_data[0]["officerIdentifier"] = complaint_data[0]["officerIdentifier"]
        updated_complaint_data[0]["residentRace"] = complaint_data[0]["residentRace"]
        updated_complaint_data[0]["residentSex"] = complaint_data[0]["residentSex"]
        updated_complaint_data[0]["residentAge"] = complaint_data[0]["residentAge"]
        # post the json to the complaint URL
        response = testapp.post_json("/data/complaints", params={'month': 0, 'year': 0, 'data': updated_complaint_data})

        # assert that we got the expected reponse
        assert response.status_code == 200
        assert response.json_body['updated'] == 1
        assert response.json_body['added'] == 0

        # There's only one complaint in the database.
        all_complaints = CitizenComplaintIMPD.query.all()
        assert len(all_complaints) == 1

        # check the complaint incident in the database against the updated data that was sent
        cleaner = Cleaners()
        sent_complaint = cleaner.capitalize_incident(updated_complaint_data[0])
        check_complaint = CitizenComplaintIMPD.query.filter_by(opaque_id=sent_complaint['opaqueId']).first()
        assert check_complaint.occured_date.strftime('%Y-%m-%d %-H:%-M:%S') == sent_complaint['occuredDate']
        assert check_complaint.division == sent_complaint['division']
        assert check_complaint.precinct == sent_complaint['precinct']
        assert check_complaint.shift == sent_complaint['shift']
        assert check_complaint.beat == sent_complaint['beat']
        assert check_complaint.disposition == sent_complaint['disposition']
        assert check_complaint.service_type == sent_complaint['serviceType']
        assert check_complaint.source == sent_complaint['source']
        assert check_complaint.allegation_type == sent_complaint['allegationType']
        assert check_complaint.allegation == sent_complaint['allegation']
        assert check_complaint.resident_race == cleaner.race(sent_complaint['residentRace'])
        assert check_complaint.resident_sex == cleaner.sex(sent_complaint['residentSex'])
        assert check_complaint.resident_age == cleaner.number_to_string(sent_complaint['residentAge'])
        assert check_complaint.officer_identifier == sent_complaint['officerIdentifier']
        assert check_complaint.officer_race == cleaner.race(sent_complaint['officerRace'])
        assert check_complaint.officer_sex == cleaner.sex(sent_complaint['officerSex'])
        assert check_complaint.officer_age == cleaner.number_to_string(sent_complaint['officerAge'])
        assert check_complaint.officer_years_of_service == cleaner.number_to_string(sent_complaint['officerYearsOfService'])
    def test_all_uof_records_destroyed_when_new_record_posted(self, testapp):
        """ Posting a new record with an id that matches a set of past records destroys all of them.
        """
        # Set up the extractor
        department = Department.create(name="B Police Department", short_name="LMPD", load_defaults=False)
        extractor, _ = Extractor.from_department_and_password(department=department, password="******")

        # Set the correct authorization
        testapp.authorization = ("Basic", (extractor.username, "password"))

        # post to the heartbeat URL to start the update
        response = testapp.post_json("/data/heartbeat", params={"heartbeat": "heartbeat"})

        # Post 5 fake incidents with an identical opaqueId to the UOF endpoint
        uof_count = 5
        test_client = JSONTestClient()
        uof_data = test_client.make_uof(count=uof_count, short_name=department.short_name)
        use_id = uof_data[0]["opaqueId"]
        for idx, _ in enumerate(uof_data):
            uof_data[idx]["opaqueId"] = use_id
        response = testapp.post_json("/data/UOF", params={"month": 0, "year": 0, "data": uof_data})

        # assert that we got the expected reponse
        assert response.status_code == 200

        # there are 5 incident rows in the database
        check_uofs = UseOfForceIncidentLMPD.query.all()
        assert len(check_uofs) == uof_count

        # all the records in the database have the same opaqueId
        uof_records = UseOfForceIncidentLMPD.query.filter_by(opaque_id=use_id).all()
        assert len(uof_records) == uof_count
        # verify that the opaqueId is recorded in an IncidentsUpdated table
        record_updated = IncidentsUpdated.query.filter_by(opaque_id=use_id).first()
        assert record_updated is not None
        assert record_updated.incident_type == "uof"
        assert record_updated.department_id == department.id

        # post to the heartbeat URL to start a new update
        response = testapp.post_json("/data/heartbeat", params={"heartbeat": "heartbeat"})

        # Create 1 new fake incident
        new_data = test_client.make_uof(count=1, short_name=department.short_name)
        # give it the same opaqueId as the first batch
        new_data[0]["opaqueId"] = use_id

        # post the new incident row
        response = testapp.post_json("/data/UOF", params={"month": 0, "year": 0, "data": new_data})

        # assert that we got the expected reponse
        assert response.status_code == 200

        # there is now only 1 incident row in the database
        check_uofs = UseOfForceIncidentLMPD.query.all()
        assert len(check_uofs) == 1

        # verify that the opaqueID posted matches that in the database
        assert check_uofs[0].opaque_id == use_id

        # verify that the opaqueId is recorded in an IncidentsUpdated table
        record_updated = IncidentsUpdated.query.filter_by(opaque_id=use_id).first()
        assert record_updated is not None
        assert record_updated.incident_type == "uof"
        assert record_updated.department_id == department.id
    def test_update_ois_data(self, testapp):
        ''' Updated OIS data from the extractor is processed as expected.
        '''
        # Set up the extractor
        department = Department.create(name="Good Police Department", short_name="GPD", load_defaults=False)
        extractor, envs = Extractor.from_department_and_password(department=department, password="******")

        # Set the correct authorization
        testapp.authorization = ('Basic', (extractor.username, 'password'))

        # Get a generated list of OIS descriptions from the JSON test client
        test_client = JSONTestClient()
        ois_data = test_client.get_prebaked_ois(last=1)
        # post the json to the OIS URL
        response = testapp.post_json("/data/OIS", params={'month': 0, 'year': 0, 'data': ois_data})

        # assert that we got the expected reponse
        assert response.status_code == 200
        assert response.json_body['updated'] == 0
        assert response.json_body['added'] == 1

        # Get the second pre-baked ois incident
        updated_ois_data = test_client.get_prebaked_ois(first=1, last=2)
        # Swap in the opaque ID from the first ois incident
        updated_ois_data[0]["opaqueId"] = ois_data[0]["opaqueId"]
        # The ois incident won't be a match unless this field is the same
        updated_ois_data[0]["officerIdentifier"] = ois_data[0]["officerIdentifier"]
        # post the json to the ois URL
        response = testapp.post_json("/data/OIS", params={'month': 0, 'year': 0, 'data': updated_ois_data})

        # assert that we got the expected reponse
        assert response.status_code == 200
        assert response.json_body['updated'] == 1
        assert response.json_body['added'] == 0

        # There's only one complaint in the database.
        all_ois = OfficerInvolvedShooting.query.all()
        assert len(all_ois) == 1

        # check the ois incident in the database against the updated data that was sent
        cleaner = Cleaners()
        sent_ois = updated_ois_data[0]
        check_ois = OfficerInvolvedShooting.query.filter_by(opaque_id=sent_ois['opaqueId']).first()
        assert check_ois.occured_date.strftime('%Y-%m-%d %-H:%-M:%S') == sent_ois['occuredDate']
        assert check_ois.division == cleaner.capitalize(sent_ois['division'])
        assert check_ois.precinct == cleaner.capitalize(sent_ois['precinct'])
        assert check_ois.shift == cleaner.capitalize(sent_ois['shift'])
        assert check_ois.beat == cleaner.capitalize(sent_ois['beat'])
        assert check_ois.disposition == sent_ois['disposition']
        assert check_ois.resident_race == cleaner.race(sent_ois['residentRace'])
        assert check_ois.resident_sex == cleaner.sex(sent_ois['residentSex'])
        assert check_ois.resident_age == cleaner.number_to_string(sent_ois['residentAge'])
        assert check_ois.resident_weapon_used == cleaner.resident_weapon_used(sent_ois['residentWeaponUsed'])
        assert check_ois.resident_condition == sent_ois['residentCondition']
        assert check_ois.officer_identifier == sent_ois['officerIdentifier']
        assert check_ois.officer_weapon_used == sent_ois['officerForceType']
        assert check_ois.officer_race == cleaner.race(sent_ois['officerRace'])
        assert check_ois.officer_sex == cleaner.sex(sent_ois['officerSex'])
        assert check_ois.officer_age == cleaner.number_to_string(sent_ois['officerAge'])
        assert check_ois.officer_years_of_service == cleaner.string_to_integer(sent_ois['officerYearsOfService'])
        assert check_ois.officer_condition == sent_ois['officerCondition']
    def test_post_uof_data(self, testapp):
        """ New and updated UOF data from the extractor is processed as expected.
        """
        # Set up the extractor
        department = Department.create(name="B Police Department", short_name="LMPD", load_defaults=False)
        extractor, _ = Extractor.from_department_and_password(department=department, password="******")

        # Set the correct authorization
        testapp.authorization = ("Basic", (extractor.username, "password"))

        # post to the heartbeat URL to start the update
        response = testapp.post_json("/data/heartbeat", params={"heartbeat": "heartbeat"})

        # Post 5 fake incidents to the UOF endpoint
        uof_count = 5
        test_client = JSONTestClient()
        uof_data = test_client.make_uof(count=uof_count, short_name=department.short_name)
        response = testapp.post_json("/data/UOF", params={"month": 0, "year": 0, "data": uof_data})

        # assert that we got the expected reponse
        assert response.status_code == 200

        # there are 5 incident rows in the database
        check_uofs = UseOfForceIncidentLMPD.query.all()
        assert len(check_uofs) == uof_count

        for incident in uof_data:
            # verify that the opaqueIDs posted match those in the database
            assert UseOfForceIncidentLMPD.query.filter_by(opaque_id=incident["opaqueId"]).first() is not None
            # verify that the opaqueIds are recorded in IncidentsUpdated tables
            record_updated = IncidentsUpdated.query.filter_by(opaque_id=incident["opaqueId"]).first()
            assert record_updated is not None
            assert record_updated.department_id == department.id
            assert record_updated.incident_type == "uof"

        # post to the heartbeat URL to start the new update
        response = testapp.post_json("/data/heartbeat", params={"heartbeat": "heartbeat"})

        # Create 5 more fake incidents
        new_data = test_client.make_uof(count=uof_count, short_name=department.short_name)
        # give them the same opaqueIds as the first batch
        for idx, _ in enumerate(new_data):
            new_data[idx]["opaqueId"] = uof_data[idx]["opaqueId"]

        # post the new incident rows
        response = testapp.post_json("/data/UOF", params={"month": 0, "year": 0, "data": new_data})

        # assert that we got the expected reponse
        assert response.status_code == 200

        # there are 5 incident rows in the database
        check_uofs = UseOfForceIncidentLMPD.query.all()
        assert len(check_uofs) == uof_count

        # verify that the opaqueIDs posted match those in the database
        for incident in uof_data:
            assert UseOfForceIncidentLMPD.query.filter_by(opaque_id=incident["opaqueId"]).first() is not None

        # Create 5 more fake incidents
        new_data = test_client.make_uof(count=uof_count, short_name=department.short_name)
        # give them the same opaqueIds as the first batch
        for idx, _ in enumerate(new_data):
            new_data[idx]["opaqueId"] = uof_data[idx]["opaqueId"]

        # post the new incident rows without starting a new update
        response = testapp.post_json("/data/UOF", params={"month": 0, "year": 0, "data": new_data})

        # assert that we got the expected reponse
        assert response.status_code == 200

        # there are 10 incident rows in the database
        check_uofs = UseOfForceIncidentLMPD.query.all()
        assert len(check_uofs) == uof_count * 2
Ejemplo n.º 37
0
 def test_bad_extractor_password_is_a_401(self, testapp):
     Extractor.create(username="******", email="*****@*****.**", password="******")
     testapp.authorization = ("Basic", ("good", "fake"))
     res = testapp.post("/data/heartbeat", expect_errors=True)
     assert res.status_code == 401