def test_expunger_invokes_time_analyzer_with_most_recent_charge(self):
        CrawlerFactory.create(
            self.crawler,
            cases={
                'X0001':
                CaseDetails.case_x(
                    arrest_date=self.FIFTEEN_YEARS_AGO.strftime('%m/%d/%Y'),
                    charge1_name='Aggravated theft in the first degree',
                    charge1_statute='164.057',
                    charge1_level='Felony Class B',
                    dispo_ruling_1='Convicted',
                    dispo_date=self.FIFTEEN_YEARS_AGO.strftime('%m/%d/%Y')),
                'X0002':
                CaseDetails.case_x(),
                'X0003':
                CaseDetails.case_x()
            })

        expunger = Expunger(self.crawler.result.cases)
        expunger.run()

        assert len(expunger._type_analyzer.class_b_felonies) == 1
        assert expunger._type_analyzer.class_b_felonies[
            0].name == 'Aggravated theft in the first degree'
        assert expunger._time_analyzer._class_b_felonies[
            0].name == 'Aggravated theft in the first degree'
        assert expunger._time_analyzer._most_recent_charge.name == 'Aggravated theft in the first degree'
    def test_record_with_only_an_mrd_is_time_eligible(self):
        record = Record([self.case_1])
        expunger = Expunger(record)
        expunger.run()

        assert self.recent_dismissal.expungement_result.time_eligibility.status is EligibilityStatus.ELIGIBLE
        assert self.recent_dismissal.expungement_result.time_eligibility.reason == ""
        assert self.recent_dismissal.expungement_result.time_eligibility.date_will_be_eligible is None
    def test_record_with_only_an_mrd_is_time_eligible(self):
        record = Record([self.case_1])
        expunger = Expunger(record)
        expunger.run()

        assert self.recent_dismissal.expungement_result.time_eligibility is True
        assert self.recent_dismissal.expungement_result.time_eligibility_reason == ''
        assert self.recent_dismissal.expungement_result.date_of_eligibility is None
    def test_mrd_blocks_dismissals_in_unrelated_cases(self):
        unrelated_dismissal = ChargeFactory.create_dismissed_charge(case=self.case_2, date=Time.TEN_YEARS_AGO)
        self.case_2.charges = [unrelated_dismissal]

        record = Record([self.case_1, self.case_2])
        expunger = Expunger(record)
        expunger.run()

        assert unrelated_dismissal.expungement_result.time_eligibility.status is False
        assert unrelated_dismissal.expungement_result.time_eligibility.reason == 'Recommend sequential expungement'
        assert unrelated_dismissal.expungement_result.time_eligibility.date_will_be_eligible == Time.ONE_YEARS_FROM_NOW
    def test_type_analyzer_runs_when_open_cases_exit(self):
        CrawlerFactory.create(
            self.crawler, JohnDoe.RECORD, {
                'X0001': CaseDetails.CASE_X1,
                'X0002': CaseDetails.CASE_WITHOUT_FINANCIAL_SECTION,
                'X0003': CaseDetails.CASE_WITHOUT_DISPOS
            })
        expunger = Expunger(self.crawler.result.cases)
        expunger.run()

        assert expunger.cases[0].charges[
            1].expungement_result.type_eligibility is True
def test_acquitted_felony_class_b_with_subsequent_conviction():
    b_felony_charge = create_class_b_felony_charge(
        Time.LESS_THAN_TWENTY_YEARS_AGO, "Dismissed")
    case_1 = CaseFactory.create()
    case_1.charges = [b_felony_charge]
    subsequent_charge = ChargeFactory.create(
        disposition=["Convicted", Time.TEN_YEARS_AGO])
    case_2 = CaseFactory.create()
    case_2.charges = [subsequent_charge]

    expunger = Expunger(Record([case_1, case_2]))
    expunger.run()

    assert b_felony_charge.expungement_result.type_eligibility.status is EligibilityStatus.ELIGIBLE
    assert b_felony_charge.expungement_result.time_eligibility.status is EligibilityStatus.ELIGIBLE
    def test_all_mrd_case_related_dismissals_are_expungeable(self):
        case_related_dismissal = ChargeFactory.create_dismissed_charge(case=self.case_1, date=Time.TWO_YEARS_AGO)
        self.case_1.charges.append(case_related_dismissal)

        record = Record([self.case_1])
        expunger = Expunger(record)
        expunger.run()

        assert self.recent_dismissal.expungement_result.time_eligibility.status is True
        assert self.recent_dismissal.expungement_result.time_eligibility.reason == ''
        assert self.recent_dismissal.expungement_result.time_eligibility.date_will_be_eligible is None

        assert case_related_dismissal.expungement_result.time_eligibility.status is True
        assert case_related_dismissal.expungement_result.time_eligibility.reason == ''
        assert case_related_dismissal.expungement_result.time_eligibility.date_will_be_eligible is None
示例#8
0
    def test_expunger_runs_time_analyzer(self):
        record = CrawlerFactory.create(self.crawler,
                              cases={'X0001': CaseDetails.case_x(arrest_date=self.FIFTEEN_YEARS_AGO.strftime('%m/%d/%Y'),
                                                                 dispo_date=self.FIFTEEN_YEARS_AGO.strftime('%m/%d/%Y'),
                                                                 dispo_ruling_1='Dismissed',
                                                                 dispo_ruling_2='Convicted',
                                                                 dispo_ruling_3='Acquitted'),
                                     'X0002': CaseDetails.case_x(arrest_date=self.TWO_YEARS_AGO.strftime('%m/%d/%Y'),
                                                                 dispo_ruling_1='Dismissed',
                                                                 dispo_ruling_2='Dismissed',
                                                                 dispo_ruling_3='Dismissed'),
                                     'X0003': CaseDetails.case_x(arrest_date=self.ONE_YEAR_AGO.strftime('%m/%d/%Y'),
                                                                 dispo_ruling_1='No Complaint',
                                                                 dispo_ruling_2='No Complaint',
                                                                 dispo_ruling_3='No Complaint')})
        expunger = Expunger(record)

        assert expunger.run() is True

        assert expunger.most_recent_conviction is None
        assert expunger.second_most_recent_conviction is None
        assert expunger.most_recent_dismissal.disposition.ruling == 'No Complaint'
        assert len(expunger.acquittals) == 8

        assert record.cases[0].charges[0].expungement_result.time_eligibility.status is False
        assert record.cases[0].charges[1].expungement_result.time_eligibility.status is True
        assert record.cases[0].charges[2].expungement_result.time_eligibility.status is False

        assert record.cases[1].charges[0].expungement_result.time_eligibility.status is False
        assert record.cases[1].charges[1].expungement_result.time_eligibility.status is False
        assert record.cases[1].charges[2].expungement_result.time_eligibility.status is False

        assert record.cases[2].charges[0].expungement_result.time_eligibility.status is True
        assert record.cases[2].charges[1].expungement_result.time_eligibility.status is True
        assert record.cases[2].charges[2].expungement_result.time_eligibility.status is True
示例#9
0
 def test_expunger_with_open_case(self):
     record = CrawlerFactory.create(self.crawler, JohnDoe.RECORD, {'X0001': CaseDetails.CASE_X1,
                                                          'X0002': CaseDetails.CASE_WITHOUT_FINANCIAL_SECTION,
                                                          'X0003': CaseDetails.CASE_WITHOUT_DISPOS})
     expunger = Expunger(record)
     assert expunger.run() is False
     assert expunger.errors == ['Open cases exist']
def test_expunger_runs_time_analyzer(record_with_specific_dates):
    record = record_with_specific_dates
    expunger = Expunger(record)
    charges_with_summary = expunger.charges_with_summary

    assert expunger.run()

    assert charges_with_summary.most_recent_conviction is None
    assert charges_with_summary.second_most_recent_conviction is None
    assert (charges_with_summary.most_recent_dismissal
            and charges_with_summary.most_recent_dismissal.disposition
            and charges_with_summary.most_recent_dismissal.disposition.ruling
            == "No Complaint")
    assert len(charges_with_summary.acquittals) == 8

    assert record.cases[0].charges[
        0].expungement_result.time_eligibility.status is EligibilityStatus.INELIGIBLE
    assert record.cases[0].charges[
        1].expungement_result.time_eligibility.status is EligibilityStatus.ELIGIBLE
    assert record.cases[0].charges[
        2].expungement_result.time_eligibility.status is EligibilityStatus.INELIGIBLE

    assert record.cases[1].charges[
        0].expungement_result.time_eligibility.status is EligibilityStatus.INELIGIBLE
    assert record.cases[1].charges[
        1].expungement_result.time_eligibility.status is EligibilityStatus.INELIGIBLE
    assert record.cases[1].charges[
        2].expungement_result.time_eligibility.status is EligibilityStatus.INELIGIBLE

    assert record.cases[2].charges[
        0].expungement_result.time_eligibility.status is EligibilityStatus.ELIGIBLE
    assert record.cases[2].charges[
        1].expungement_result.time_eligibility.status is EligibilityStatus.ELIGIBLE
    assert record.cases[2].charges[
        2].expungement_result.time_eligibility.status is EligibilityStatus.ELIGIBLE
    def test_expunger_calls_time_analyzer(self):
        CrawlerFactory.create(
            self.crawler,
            cases={
                'X0001':
                CaseDetails.case_x(
                    arrest_date=self.FIFTEEN_YEARS_AGO.strftime('%m/%d/%Y'),
                    dispo_ruling_1='Dismissed',
                    dispo_ruling_2='Dismissed',
                    dispo_ruling_3='Acquitted'),
                'X0002':
                CaseDetails.case_x(
                    arrest_date=self.TWO_YEARS_AGO.strftime('%m/%d/%Y'),
                    dispo_ruling_1='Dismissed',
                    dispo_ruling_2='Convicted',
                    dispo_ruling_3='Dismissed'),
                'X0003':
                CaseDetails.case_x(
                    arrest_date=self.ONE_YEAR_AGO.strftime('%m/%d/%Y'),
                    dispo_ruling_1='No Complaint',
                    dispo_ruling_2='Convicted',
                    dispo_ruling_3='No Complaint')
            })
        expunger = Expunger(self.crawler.result.cases)

        assert expunger.run() is True

        assert expunger._time_analyzer._most_recent_conviction.date == self.ONE_YEAR_AGO
        assert expunger._time_analyzer._second_most_recent_conviction.date == self.TWO_YEARS_AGO
        assert expunger._time_analyzer._most_recent_dismissal.date == self.ONE_YEAR_AGO
        assert expunger._time_analyzer._num_acquittals == 4
示例#12
0
def test_expunger_runs_time_analyzer(record_with_specific_dates):
    record = record_with_specific_dates
    expunger = Expunger(record)
    assert expunger.run()

    print(record.cases[0].charges[0])
    assert record.cases[0].charges[
        0].expungement_result.time_eligibility.status is EligibilityStatus.INELIGIBLE
    assert record.cases[0].charges[
        1].expungement_result.time_eligibility.status is EligibilityStatus.ELIGIBLE
    assert record.cases[0].charges[
        2].expungement_result.time_eligibility.status is EligibilityStatus.INELIGIBLE

    assert record.cases[1].charges[
        0].expungement_result.time_eligibility.status is EligibilityStatus.INELIGIBLE
    assert record.cases[1].charges[
        1].expungement_result.time_eligibility.status is EligibilityStatus.INELIGIBLE
    assert record.cases[1].charges[
        2].expungement_result.time_eligibility.status is EligibilityStatus.INELIGIBLE

    assert record.cases[2].charges[
        0].expungement_result.time_eligibility.status is EligibilityStatus.ELIGIBLE
    assert record.cases[2].charges[
        1].expungement_result.time_eligibility.status is EligibilityStatus.ELIGIBLE
    assert record.cases[2].charges[
        2].expungement_result.time_eligibility.status is EligibilityStatus.ELIGIBLE
    def test_expunger_with_an_empty_record(self):
        CrawlerFactory.create(self.crawler, JohnDoe.BLANK_RECORD, {})
        expunger = Expunger(self.crawler.result.cases)

        assert expunger.run() is True
        assert expunger._most_recent_dismissal is None
        assert expunger._most_recent_conviction is None
示例#14
0
def test_case_with_unrecognized_dispo(record_with_unrecognized_dispo):
    expunger = Expunger(record_with_unrecognized_dispo)
    assert expunger.run()
    assert record_with_unrecognized_dispo.errors[0] == (
        f"""Case {record_with_unrecognized_dispo.cases[0].case_number}: Something unrecognized has a charge with an unrecognized disposition.
This might be an error in the OECI database. Time analysis is ignoring this charge and may be inaccurate for other charges."""
    )
def test_felony_class_b_with_prior_conviction():
    b_felony_charge = create_class_b_felony_charge(Time.TWENTY_YEARS_AGO)
    case_1 = CaseFactory.create()
    case_1.charges = [b_felony_charge]
    prior_charge = ChargeFactory.create(
        disposition=["Convicted", Time.MORE_THAN_TWENTY_YEARS_AGO])
    case_2 = CaseFactory.create()
    case_2.charges = [prior_charge]

    expunger = Expunger(Record([case_1, case_2]))
    expunger.run()

    assert b_felony_charge.expungement_result.type_eligibility.status is EligibilityStatus.NEEDS_MORE_ANALYSIS
    assert b_felony_charge.expungement_result.type_eligibility.reason == "Further Analysis Needed"
    assert b_felony_charge.expungement_result.time_eligibility.status is EligibilityStatus.ELIGIBLE
    assert b_felony_charge.expungement_result.time_eligibility.reason == ""
示例#16
0
    def post(self):
        request_data = request.get_json()

        if request_data is None:
            error(400, "No json data in request body")

        check_data_fields(
            request_data,
            ["first_name", "last_name", "middle_name", "birth_date"])

        cipher = DataCipher(key=current_app.config.get("SECRET_KEY"))

        if not "oeci_token" in request.cookies.keys():
            error(401, "Missing login credentials to OECI.")

        decrypted_credentials = cipher.decrypt(request.cookies["oeci_token"])

        crawler = Crawler()

        login_result = crawler.login(decrypted_credentials["oeci_username"],
                                     decrypted_credentials["oeci_password"],
                                     close_session=False)

        if login_result is False:
            error(401, "Attempted login to OECI failed")

        record = crawler.search(request_data["first_name"],
                                request_data["last_name"],
                                request_data["middle_name"],
                                request_data["birth_date"])

        expunger = Expunger(record)
        expunger.run()

        try:
            save_result(request_data, record)
        except Exception as ex:
            logging.error("Saving search result failed with exception: %s" %
                          ex,
                          stack_info=True)

        response_data = {"data": {"record": record}}

        current_app.json_encoder = ExpungeModelEncoder

        return response_data  #Json-encoding happens automatically here
示例#17
0
def test_case_without_dispos(record_without_dispos):
    expunger = Expunger(record_without_dispos)
    assert record_without_dispos.cases[0].closed()
    assert expunger.run()
    assert record_without_dispos.errors[0] == (
        f"""Case {record_without_dispos.cases[0].case_number} has a charge with a missing disposition.
This might be an error in the OECI database. Time analysis is ignoring this charge and may be inaccurate for other charges."""
    )
示例#18
0
    def post(self):
        request_data = request.get_json()

        if request_data is None:
            error(400, "No json data in request body")

        check_data_fields(request_data, ["first_name", "last_name",
                                 "middle_name", "birth_date"])

        cipher = DataCipher(
            key=current_app.config.get("JWT_SECRET_KEY"))

        decrypted_credentials = cipher.decrypt(request.cookies["oeci_token"])

        crawler = Crawler()

        login_result = crawler.login(
            decrypted_credentials["oeci_username"],
            decrypted_credentials["oeci_password"],
            close_session=False)

        if login_result is False:
            error(401, "Attempted login to OECI failed")

        record = crawler.search(
            request_data["first_name"],
            request_data["last_name"],
            request_data["middle_name"],
            request_data["birth_date"])

        expunger = Expunger(record)
        expunger.run()

        response_data = {
            "data": {
                "record": record
            }
        }

        current_app.json_encoder = ExpungeModelEncoder

        return response_data #Json-encoding happens automatically here
def test_felony_class_b_with_subsequent_conviction():
    b_felony_charge = create_class_b_felony_charge(Time.TWENTY_YEARS_AGO)
    case_1 = CaseFactory.create()
    case_1.charges = [b_felony_charge]
    subsequent_charge = ChargeFactory.create(
        disposition=["Convicted", Time.TEN_YEARS_AGO])
    case_2 = CaseFactory.create()
    case_2.charges = [subsequent_charge]

    expunger = Expunger(Record([case_1, case_2]))
    expunger.run()

    assert b_felony_charge.expungement_result.time_eligibility.status is EligibilityStatus.INELIGIBLE
    assert (
        b_felony_charge.expungement_result.time_eligibility.reason ==
        "Never. Class B felony can have no subsequent arrests or convictions (137.225(5)(a)(A)(ii))"
    )
    assert b_felony_charge.expungement_result.time_eligibility.date_will_be_eligible == None

    # The Class B felony does not affect eligibility of another charge that is otherwise eligible
    assert subsequent_charge.expungement_result.time_eligibility.status is EligibilityStatus.ELIGIBLE
    assert subsequent_charge.expungement_result.type_eligibility.status is EligibilityStatus.ELIGIBLE
def test_doubly_eligible_b_felony_gets_normal_eligibility_rule():
    # This charge is both List B and also a class B felony. List B classification takes precedence.
    list_b_charge = ChargeFactory.create(
        name="Assault in the second degree",
        statute="163.175",
        level="Felony Class B",
        date=Time.LESS_THAN_TWENTY_YEARS_AGO,
        disposition=["Convicted", Time.LESS_THAN_TWENTY_YEARS_AGO],
    )

    case_1 = CaseFactory.create()
    case_1.charges = [list_b_charge]
    subsequent_charge = ChargeFactory.create(
        disposition=["Convicted", Time.TEN_YEARS_AGO])
    case_2 = CaseFactory.create()
    case_2.charges = [subsequent_charge]

    expunger = Expunger(Record([case_1, case_2]))
    expunger.run()

    assert list_b_charge.expungement_result.time_eligibility.status is EligibilityStatus.ELIGIBLE
    assert list_b_charge.expungement_result.type_eligibility.status is EligibilityStatus.NEEDS_MORE_ANALYSIS
示例#21
0
def test_case_with_mulitple_disposition_errors(
        record_with_multiple_disposition_errors):
    expunger = Expunger(record_with_multiple_disposition_errors)
    assert expunger.run()
    unrecognized_error_message = f"""The following cases have charges with an unrecognized disposition.
This might be an error in the OECI database. Time analysis is ignoring these charges and may be inaccurate for other charges.
Case numbers: """
    cases_order_1 = "X0001: Something unrecognized, X0002: Something unrecognized"
    cases_order_2 = "X0002: Something unrecognized, X0001: Something unrecognized"
    assert (unrecognized_error_message + cases_order_1
            in record_with_multiple_disposition_errors.errors
            or unrecognized_error_message + cases_order_2
            in record_with_multiple_disposition_errors.errors)
    missing_error_message = f"""Case X0003 has a charge with a missing disposition.
This might be an error in the OECI database. Time analysis is ignoring this charge and may be inaccurate for other charges."""
    assert missing_error_message in record_with_multiple_disposition_errors.errors
示例#22
0
    def test_expunger_categorizes_charges(self):
        record = CrawlerFactory.create(self.crawler,
                              cases={'X0001': CaseDetails.case_x(dispo_ruling_1='Convicted - Failure to show',
                                                                 dispo_ruling_2='Dismissed',
                                                                 dispo_ruling_3='Acquitted'),
                                     'X0002': CaseDetails.case_x(dispo_ruling_1='Dismissed',
                                                                 dispo_ruling_2='Convicted',
                                                                 dispo_ruling_3='Convicted'),
                                     'X0003': CaseDetails.case_x(dispo_ruling_1='No Complaint',
                                                                 dispo_ruling_2='Dismissed',
                                                                 dispo_ruling_3='Convicted')})
        expunger = Expunger(record)

        assert expunger.run() is True
        assert len(expunger.acquittals) == 5
        assert len(expunger.convictions) == 4
示例#23
0
def test_expunger_runs_time_analyzer(record_with_specific_dates):
    record = record_with_specific_dates
    expunger = Expunger(record)

    assert expunger.run()

    assert expunger.most_recent_conviction is None
    assert expunger.second_most_recent_conviction is None
    assert expunger.most_recent_dismissal.disposition.ruling == 'No Complaint'
    assert len(expunger.acquittals) == 8

    assert record.cases[0].charges[0].expungement_result.time_eligibility.status is False
    assert record.cases[0].charges[1].expungement_result.time_eligibility.status is True
    assert record.cases[0].charges[2].expungement_result.time_eligibility.status is False

    assert record.cases[1].charges[0].expungement_result.time_eligibility.status is False
    assert record.cases[1].charges[1].expungement_result.time_eligibility.status is False
    assert record.cases[1].charges[2].expungement_result.time_eligibility.status is False

    assert record.cases[2].charges[0].expungement_result.time_eligibility.status is True
    assert record.cases[2].charges[1].expungement_result.time_eligibility.status is True
    assert record.cases[2].charges[2].expungement_result.time_eligibility.status is True
示例#24
0
def test_expunger_with_open_case(record_with_open_case):
    expunger = Expunger(record_with_open_case)

    assert not expunger.run()
    assert "All charges are ineligible because there is one or more open case" in record_with_open_case.errors[
        0]
class TestMostRecentConviction(unittest.TestCase):

    def setUp(self):
        self.case = CaseFactory.create()
        self.mrc_charge = ChargeFactory.create()
        self.viol_charge = ChargeFactory.create(level='Violation')
        self.viol2_charge = ChargeFactory.create(level='Violation')

    def run_expunger(self, cases):
        record = Record(cases)
        self.expunger = Expunger(record)
        self.expunger.run()

    def test_it_sets_most_recent_conviction_from_the_last_10yrs(self):
        self.mrc_charge.disposition = Disposition(Time.LESS_THAN_TEN_YEARS_AGO, 'Convicted')
        self.case.charges = [self.mrc_charge]
        self.run_expunger([self.case])

        assert self.expunger.most_recent_conviction is self.mrc_charge

    def test_it_does_not_set_mrc_when_greater_than_10yrs(self):
        self.mrc_charge.disposition = Disposition(Time.TEN_YEARS_AGO, 'Convicted')
        self.case.charges = [self.mrc_charge]
        self.run_expunger([self.case])

        assert self.expunger.most_recent_conviction is None

    def test_mrc_grouped_within_other_charges(self):
        self.mrc_charge.disposition = Disposition(Time.TWO_YEARS_AGO, 'Convicted')
        charge = ChargeFactory.create()
        charge.disposition = Disposition(Time.TEN_YEARS_AGO, 'Convicted')
        self.case.charges = [charge, charge, self.mrc_charge, charge, charge]
        self.run_expunger([self.case])

        assert self.expunger.most_recent_conviction is self.mrc_charge

    def test_most_recent_charge(self):
        one_year_traffic_charge = ChargeFactory.create(name='Traffic Violation',
                                                       statute='825.999',
                                                       level='Class C traffic violation',
                                                       disposition=['Convicted', Time.ONE_YEAR_AGO])

        self.case.charges = [one_year_traffic_charge]
        self.run_expunger([self.case])

        assert self.expunger.most_recent_charge is None

    def test_most_recent_charge_with_non_traffic_violations(self):
        one_year_traffic_charge = ChargeFactory.create(name='Traffic Violation',
                                                       statute='825.999',
                                                       level='Class C traffic violation',
                                                       disposition=['Convicted', Time.ONE_YEAR_AGO])
        two_year_ago_dismissal = ChargeFactory.create(disposition=['Dismissed', Time.TWO_YEARS_AGO])
        three_year_ago_dismissal = ChargeFactory.create(disposition=['Dismissed', Time.THREE_YEARS_AGO])
        four_year_traffic_charge = ChargeFactory.create(name='Traffic Violation',
                                                        statute='825.999',
                                                        level='Class C traffic violation',
                                                        disposition=['Convicted', Time.FOUR_YEARS_AGO])

        self.case.charges = [one_year_traffic_charge, two_year_ago_dismissal, three_year_ago_dismissal, four_year_traffic_charge]
        self.run_expunger([self.case])

        assert self.expunger.most_recent_charge == two_year_ago_dismissal

    def test_parking_ticket_is_not_recent_charge(self):
        parking_ticket = ChargeFactory.create(statute='40',
                                              disposition=['Convicted', Time.ONE_YEAR_AGO])

        self.case.charges = [parking_ticket]
        self.run_expunger([self.case])

        assert self.expunger.most_recent_charge is None

    def test_violation_is_not_most_recent(self):
        mrc_charge = ChargeFactory.create(level='Violation')
        self.mrc_charge.disposition = Disposition(Time.LESS_THAN_TEN_YEARS_AGO, 'Convicted')
        self.case.charges = [mrc_charge]
        self.run_expunger([self.case])

        assert self.expunger.most_recent_conviction is None

    def test_violation_and_misdemeanor_most_recent(self):
        viol_case = CaseFactory.create()

        self.viol_charge.disposition = Disposition(Time.ONE_YEAR_AGO, 'Convicted')
        self.mrc_charge.disposition = Disposition(Time.TWO_YEARS_AGO, 'Convicted')

        viol_case.charges = [self.viol_charge]
        self.case.charges = [self.mrc_charge]

        self.run_expunger([viol_case, self.case])

        assert self.expunger.most_recent_conviction is self.mrc_charge

    def test_recent_violation_and_nonrecent_misdemeanor(self):
        viol_case = CaseFactory.create()
        misd_case = CaseFactory.create()

        misd_charge = ChargeFactory.create()

        self.viol_charge.disposition = Disposition(Time.ONE_YEAR_AGO, 'Convicted')
        misd_charge.disposition = Disposition(Time.TEN_YEARS_AGO, 'Convicted')

        viol_case.charges = [self.viol_charge]
        misd_case.charges = [misd_charge]

        self.run_expunger([viol_case, misd_case])

        assert self.expunger.most_recent_conviction is None

    def test_two_most_recent_are_violations(self):
        self.viol_charge.disposition = Disposition(Time.ONE_YEAR_AGO, 'Convicted')
        self.viol2_charge.disposition = Disposition(Time.TWO_YEARS_AGO, 'Convicted')

        self.case.charges = [self.viol_charge, self.viol2_charge]

        self.run_expunger([self.case])

        assert self.expunger.most_recent_conviction is self.viol2_charge

    def test_mrc_with_two_violations(self):
        self.viol_charge.disposition = Disposition(Time.YESTERDAY, 'Convicted')
        self.viol2_charge.disposition = Disposition(Time.TWO_YEARS_AGO, 'Convicted')
        self.mrc_charge.disposition = Disposition(Time.ONE_YEAR_AGO, 'Convicted')

        case_two = CaseFactory.create()
        case_three = CaseFactory.create()

        self.case.charges = [self.viol_charge]
        case_two.charges = [self.mrc_charge]
        case_three.charges = [self.viol2_charge]

        self.run_expunger([self.case, case_two, case_three])

        assert self.expunger.most_recent_conviction is self.mrc_charge

    def test_second_violation_is_mrc(self):
        self.viol_charge.disposition = Disposition(Time.YESTERDAY, 'Convicted')
        self.viol2_charge.disposition = Disposition(Time.ONE_YEAR_AGO, 'Convicted')
        self.mrc_charge.disposition = Disposition(Time.TWO_YEARS_AGO, 'Convicted')

        case_two = CaseFactory.create()
        case_three = CaseFactory.create()

        self.case.charges = [self.viol_charge]
        case_two.charges = [self.mrc_charge]
        case_three.charges = [self.viol2_charge]

        self.run_expunger([self.case, case_two, case_three])

        assert self.expunger.most_recent_conviction is self.viol2_charge

    def test_misdemeanor_is_mrc_with_two_violations_dispod_after(self):
        self.mrc_charge.disposition = Disposition(Time.YESTERDAY, 'Convicted')
        self.viol_charge.disposition = Disposition(Time.ONE_YEAR_AGO, 'Convicted')
        self.viol2_charge.disposition = Disposition(Time.TWO_YEARS_AGO, 'Convicted')

        case_two = CaseFactory.create()
        case_three = CaseFactory.create()

        self.case.charges = [self.viol_charge]
        case_two.charges = [self.mrc_charge]
        case_three.charges = [self.viol2_charge]

        self.run_expunger([self.case, case_two, case_three])

        assert self.expunger.most_recent_conviction is self.mrc_charge

    def test_three_violations_second_violation_is_mrc(self):
        first_violation = ChargeFactory.create(level='Violation')
        self.viol2_charge.disposition = Disposition(Time.YESTERDAY, 'Convicted')
        self.viol_charge.disposition = Disposition(Time.ONE_YEAR_AGO, 'Convicted')
        first_violation.disposition = Disposition(Time.TWO_YEARS_AGO, 'Convicted')

        case_two = CaseFactory.create()
        case_three = CaseFactory.create()

        self.case.charges = [self.viol_charge]
        case_two.charges = [first_violation]
        case_three.charges = [self.viol2_charge]

        self.run_expunger([self.case, case_two, case_three])

        assert self.expunger.most_recent_conviction is self.viol_charge
def test_round_trip_various_records(record):
    expunger = Expunger(record)
    expunger.run()
    json.loads(json.dumps(record, cls=ExpungeModelEncoder))
示例#27
0
            date=Time.TWO_YEARS_AGO)
        charge = ChargeFactory.create_dismissed_charge(
            date=Time.LESS_THAN_THREE_YEARS_AGO)
        case.charges = [charge, charge, mrd_charge]
        record = Record([case])

        charges = ChargesSummarizer.summarize(record.charges)
        assert charges.most_recent_dismissal is mrd_charge

    def test_it_skips_closed_cases_without_dispositions(self):
        case = CaseFactory.create()
        charge_without_dispo = ChargeFactory.create()
        case.charges = [charge_without_dispo]
        record = Record([case])
        expunger = Expunger(record)
        assert expunger.run()

    def test_it_skips_juvenile_charges(self):
        case = CaseFactory.create(type_status=["a juvenile case", "Closed"])
        juvenile_charge = ChargeFactory.create(case=case)
        case.charges = [juvenile_charge]

        record = Record([case])
        expunger = Expunger(record)

        assert expunger.run()
        assert expunger.charges_with_summary.charges == []


class TestDispositionlessCharge(unittest.TestCase):
    def test_charge_is_marked_as_missing_disposition(self):
示例#28
0
def test_partial_dispos(partial_dispos_record):
    expunger = Expunger(partial_dispos_record)
    assert expunger.run()
示例#29
0
def test_expunger_with_an_empty_record(empty_record):
    expunger = Expunger(empty_record)
    assert expunger.run()
        three_yr_mrc = ChargeFactory.create(
            case=case, disposition=['Convicted', Time.THREE_YEARS_AGO])

        arrest = ChargeFactory.create(
            case=case, disposition=['Dismissed', Time.THREE_YEARS_AGO])

        violation = ChargeFactory.create(
            level='Violation',
            case=case,
            disposition=['Convicted', Time.THREE_YEARS_AGO])

        case.charges = [three_yr_mrc, arrest, violation]
        record = Record([case])
        expunger = Expunger(record)

        expunger.run()
        assert three_yr_mrc.expungement_result.time_eligibility.status is EligibilityStatus.ELIGIBLE
        assert three_yr_mrc.expungement_result.time_eligibility.reason == ''
        assert three_yr_mrc.expungement_result.time_eligibility.date_will_be_eligible is None
        assert arrest.expungement_result.time_eligibility.status is EligibilityStatus.ELIGIBLE
        assert violation.expungement_result.time_eligibility.status is EligibilityStatus.INELIGIBLE
        assert violation.expungement_result.time_eligibility.date_will_be_eligible == date.today(
        ) + relativedelta(years=7)
        assert violation.expungement_result.time_eligibility.reason == 'Time-ineligible under 137.225(7)(b)'

    def test_eligible_arrests_eligibility_based_on_second_mrc(self):
        case = CaseFactory.create()

        three_yr_conviction = ChargeFactory.create(
            case=case, disposition=['Convicted', Time.THREE_YEARS_AGO])