class TestChargeClass(unittest.TestCase): TEN_YEARS_AGO = date.today() + relativedelta(years=-10) LESS_THAN_TEN_YEARS_AGO = date.today() + relativedelta(years=-10, days=+1) LESS_THAN_THREE_YEARS_AGO = date.today() + relativedelta(years=-3, days=+1) THREE_YEARS_AGO = date.today() + relativedelta(years=-3) def test_it_initializes_simple_statute(self): charge = ChargeFactory.create(statute="1231235B") assert charge.statute == "1231235B" def test_it_normalizes_statute(self): charge = ChargeFactory.create(statute="-123.123(5)()B") assert charge.statute == "1231235B" def test_it_converts_statute_to_uppercase(self): charge = ChargeFactory.create(statute="-123.123(5)()b") assert charge.statute == "1231235B" def test_it_retrieves_its_parent_instance(self): case = CaseFactory.create() charge = ChargeFactory.create(case_number=case.summary.case_number) assert charge.case([case]) is case
def test_marijuana_violation_eligible_with_prior_conviction(): marijuana_violation = ChargeFactory.create( case_number="1", name="Possession of Marijuana < 1 Ounce", statute="4758643", level="Violation Unclassified", date=date.today(), disposition=DispositionCreator.create(ruling="Convicted", date=date.today() + relativedelta(days=-1)), ) case_1 = CaseFactory.create(case_number="1", charges=tuple([marijuana_violation])) prior_conviction = ChargeFactory.create( case_number="2", name="Identity Theft", statute="165.800", level="Felony Class C", date=Time.FIVE_YEARS_AGO, disposition=DispositionCreator.create(ruling="Convicted", date=Time.ONE_YEAR_AGO), ) case_2 = CaseFactory.create(case_number="2", charges=tuple([prior_conviction])) expunger_result = Expunger.run(Record(tuple([case_1, case_2]))) assert isinstance(marijuana_violation.charge_type, MarijuanaViolation) assert expunger_result[marijuana_violation.ambiguous_charge_id].status is EligibilityStatus.ELIGIBLE assert expunger_result[prior_conviction.ambiguous_charge_id].status is EligibilityStatus.INELIGIBLE
def test_date_with_future_compares_like_date(x: date, y: date): x2 = DateWithFuture(x.year, x.month, x.day) y2 = DateWithFuture(y.year, y.month, y.day) assert (x == y) == (x2 == y2) assert (x >= y) == (x2 >= y2) # type: ignore assert (x > y) == (x2 > y2) assert (x <= y) == (x2 <= y2) # type: ignore assert (x < y) == (x2 < y2)
def _build_disposition(case_parser_data, charge_id): disposition_data = case_parser_data.hashed_dispo_data.get(charge_id) if disposition_data: date = date_class.fromdatetime( datetime.strptime(disposition_data.get("date"), "%m/%d/%Y") ) # TODO: Log error if format is not correct ruling = disposition_data.get("ruling") disposition = DispositionCreator.create(date, ruling, "amended" in disposition_data["event"].lower()) else: disposition = DispositionCreator.create(date_class.today(), "missing") return disposition
def test_eligible_mrc_with_violation(): three_yr_mrc = ChargeFactory.create( case_number="1", disposition=DispositionCreator.create(ruling="Convicted", date=Time.THREE_YEARS_AGO), ) arrest = ChargeFactory.create( case_number="1", disposition=DispositionCreator.create(ruling="Dismissed", date=Time.THREE_YEARS_AGO), ) violation = ChargeFactory.create( level="Violation", case_number="1", disposition=DispositionCreator.create(ruling="Convicted", date=Time.THREE_YEARS_AGO), ) case = CaseFactory.create(case_number="1", charges=tuple([three_yr_mrc, arrest, violation])) record = Record(tuple([case])) expunger_result = Expunger.run(record) assert expunger_result[ three_yr_mrc.ambiguous_charge_id].status is EligibilityStatus.ELIGIBLE assert expunger_result[ three_yr_mrc.ambiguous_charge_id].reason == "Eligible now" assert expunger_result[ three_yr_mrc.ambiguous_charge_id].date_will_be_eligible == date.today( ) assert expunger_result[ arrest.ambiguous_charge_id].status is EligibilityStatus.ELIGIBLE assert ( expunger_result[arrest.ambiguous_charge_id].reason == 'Time eligibility of the arrest matches conviction on the same case (the "friendly" rule)' ) assert expunger_result[ arrest.ambiguous_charge_id].date_will_be_eligible == date.today() assert expunger_result[ violation.ambiguous_charge_id].status is EligibilityStatus.INELIGIBLE assert expunger_result[ violation.ambiguous_charge_id].date_will_be_eligible == date.today( ) + relativedelta(years=7) assert ( expunger_result[violation.ambiguous_charge_id].reason == f"137.225(7)(b) – Ten years from most recent other conviction from case [{case.summary.case_number}]." )
def test_future_date_is_less_than_max_date(): assert DateWithFuture.future() < DateWithFuture.max() assert DateWithFuture.max() > DateWithFuture.future() assert DateWithFuture.future() + relativedelta( days=1) < DateWithFuture.max() assert DateWithFuture.future() - relativedelta( days=1) < DateWithFuture.max()
def test_possibly_eligible(): type_eligibility = TypeEligibility(EligibilityStatus.NEEDS_MORE_ANALYSIS, "Unrecognized charge") time_eligibility = TimeEligibility(EligibilityStatus.ELIGIBLE, "Eligible under for some reason", date.today()) time_eligibility_2 = TimeEligibility(EligibilityStatus.INELIGIBLE, "Ineligible under some statute", date.max()) charge_eligibility = RecordMerger.compute_charge_eligibility( type_eligibility, [time_eligibility, time_eligibility_2]) assert charge_eligibility.status == ChargeEligibilityStatus.POSSIBLY_ELIGIBILE assert charge_eligibility.label == "Possibly Eligible Now"
def test_eligible_arrests_eligibility_based_on_second_mrc(self): three_yr_conviction = ChargeFactory.create( case_number="1", disposition=DispositionCreator.create(ruling="Convicted", date=Time.THREE_YEARS_AGO), ) arrest = ChargeFactory.create( case_number="1", disposition=DispositionCreator.create(ruling="Dismissed", date=Time.THREE_YEARS_AGO), ) violation = ChargeFactory.create( level="Violation", case_number="1", disposition=DispositionCreator.create( ruling="Convicted", date=Time.LESS_THAN_THREE_YEARS_AGO), ) violation_2 = ChargeFactory.create( level="Violation", case_number="1", disposition=DispositionCreator.create( ruling="Convicted", date=Time.LESS_THAN_THREE_YEARS_AGO), ) case = CaseFactory.create(charges=tuple( [three_yr_conviction, arrest, violation, violation_2])) record = Record(tuple([case])) expunger_result = Expunger.run(record) assert expunger_result[ three_yr_conviction. ambiguous_charge_id].status is EligibilityStatus.INELIGIBLE assert ( expunger_result[three_yr_conviction.ambiguous_charge_id].reason == f"137.225(7)(b) – Ten years from most recent other conviction from case [{case.summary.case_number}]." ) assert expunger_result[ three_yr_conviction. ambiguous_charge_id].date_will_be_eligible == date.today( ) + relativedelta(years=7, days=1) assert expunger_result[ arrest.ambiguous_charge_id].status is EligibilityStatus.INELIGIBLE assert expunger_result[ arrest.ambiguous_charge_id].date_will_be_eligible == date.today( ) + relativedelta(years=7)
def test_add_new_charge(): record, questions = RecordCreator.build_record( search("single_case_two_charges"), "username", "password", (), { "X0001": { "summary": { "edit_status": "UPDATE" }, "charges": { "X0001-3": { "edit_status": "ADD", "charge_type": "MisdemeanorClassA", "level": "Misdemeanor Class A", "date": "1/1/2001", "disposition": { "date": "2/1/2020", "ruling": "Convicted" }, } }, } }, date.today(), LRUCache(4), ) assert isinstance(record.cases[0].charges[2].charge_type, MisdemeanorClassA) assert record.cases[0].charges[2].date == date(2001, 1, 1) assert record.cases[0].charges[2].edit_status == EditStatus.ADD
def create_ambiguous_record_with_questions( record=JohnDoe.RECORD_WITH_CLOSED_CASES, cases={ "X0001": CaseDetails.case_x(), "X0002": CaseDetails.case_x(), "X0003": CaseDetails.case_x() }, ) -> Tuple[Record, Dict[str, QuestionSummary]]: base_url = "https://publicaccess.courts.oregon.gov/PublicAccessLogin/" with requests_mock.Mocker() as m: m.post(URL.login_url(), text=PostLoginPage.POST_LOGIN_PAGE) m.post("{}{}".format(base_url, "Search.aspx?ID=100"), [{ "text": SearchPageResponse.RESPONSE }, { "text": record }]) for key, value in cases.items(): m.get("{}{}{}".format(base_url, "CaseDetail.aspx?CaseID=", key), text=value) aliases = (Alias(first_name="John", last_name="Doe", middle_name="", birth_date=""), ) return RecordCreator.build_record( RecordCreator.build_search_results, "username", "password", aliases, {}, date_class.today(), LRUCache(4))
def test_add_disposition(): record, questions = RecordCreator.build_record( search("single_case_two_charges"), "username", "password", (), { "X0001": { "summary": { "edit_status": "UPDATE" }, "charges": { "X0001-2": { "disposition": { "date": "1/1/2001", "ruling": "Convicted" }, "level": "Misdemeanor Class A", } }, } }, date.today(), LRUCache(4), ) assert record.cases[0].charges[ 1].disposition.status == DispositionStatus.CONVICTED assert record.cases[0].charges[1].edit_status == EditStatus.UNCHANGED
def test_edit_some_fields_on_case(): record, questions = RecordCreator.build_record( search("two_cases_two_charges_each"), "username", "password", (), { "X0002": { "summary": { "edit_status": "UPDATE", "location": "ocean", "balance_due": "100", "date": "1/1/1981", } } }, date.today(), LRUCache(4), ) assert len(record.cases) == 2 assert record.cases[0].summary.location == "earth" assert record.cases[0].summary.edit_status == EditStatus.UNCHANGED assert record.cases[1].summary.location == "ocean" assert record.cases[1].summary.balance_due_in_cents == 10000 assert record.cases[1].summary.date == date(1981, 1, 1) assert record.cases[1].summary.edit_status == EditStatus.UPDATE
def test_needs_more_analysis_mrc_with_single_arrest(): eligible_charge, ineligible_charge = ChargeFactory.create_ambiguous_charge( name="Assault in the third degree", statute="163.165", level="Felony Class C", disposition=DispositionCreator.create(ruling="Convicted", date=Time.THREE_YEARS_AGO), ) arrest = ChargeFactory.create(disposition=DispositionCreator.create(ruling="Dismissed", date=Time.THREE_YEARS_AGO)) case_a = CaseFactory.create(charges=tuple([eligible_charge, arrest])) case_b = CaseFactory.create(charges=tuple([ineligible_charge, arrest])) record_a = Record(tuple([case_a])) record_b = Record(tuple([case_b])) expunger_result_a = Expunger.run(record_a) expunger_result_b = Expunger.run(record_b) ten_years_from_mrc = eligible_charge.disposition.date + Time.TEN_YEARS assert expunger_result_a[arrest.ambiguous_charge_id].status is EligibilityStatus.ELIGIBLE assert ( expunger_result_a[arrest.ambiguous_charge_id].reason == 'Time eligibility of the arrest matches conviction on the same case (the "friendly" rule)' ) assert expunger_result_a[arrest.ambiguous_charge_id].date_will_be_eligible == date.today() assert expunger_result_b[arrest.ambiguous_charge_id].status is EligibilityStatus.INELIGIBLE assert ( expunger_result_b[arrest.ambiguous_charge_id].reason == "Ten years from most recent conviction (137.225(7)(b))" ) assert expunger_result_b[arrest.ambiguous_charge_id].date_will_be_eligible == ten_years_from_mrc
def test_nonblocking_charge_is_not_skipped_and_does_not_block(): civil_offense = ChargeFactory.create(level="N/A", statute="1.000", disposition=DispositionCreator.create( ruling="Convicted", date=Time.ONE_YEAR_AGO)) violation_charge = ChargeFactory.create( level="Class A Violation", date=Time.TEN_YEARS_AGO, disposition=DispositionCreator.create(ruling="Convicted", date=Time.TEN_YEARS_AGO), ) case = CaseFactory.create(charges=tuple([civil_offense, violation_charge])) expunger_result = Expunger.run(Record(tuple([case]))) assert expunger_result[ civil_offense. ambiguous_charge_id].status is EligibilityStatus.INELIGIBLE assert (expunger_result[civil_offense.ambiguous_charge_id].reason == "Never. Type ineligible charges are always time ineligible.") assert expunger_result[ civil_offense.ambiguous_charge_id].date_will_be_eligible == date.max() assert expunger_result[ violation_charge. ambiguous_charge_id].status is EligibilityStatus.ELIGIBLE
def test_felony_class_b_with_subsequent_conviction(): b_felony_charge = create_class_b_felony_charge("1", Time.TWENTY_YEARS_AGO) case_1 = CaseFactory.create(case_number="1", charges=tuple([b_felony_charge])) subsequent_charge = ChargeFactory.create( disposition=DispositionCreator.create(ruling="Convicted", date=Time.TEN_YEARS_AGO)) case_2 = CaseFactory.create(case_number="2", charges=tuple([subsequent_charge])) expunger_result = Expunger.run(Record(tuple([case_1, case_2]))) assert expunger_result[ b_felony_charge. ambiguous_charge_id].status is EligibilityStatus.INELIGIBLE assert ( expunger_result[b_felony_charge.ambiguous_charge_id].reason == "Never. Class B felony can have no subsequent arrests or convictions (137.225(5)(a)(A)(ii))" ) assert expunger_result[ b_felony_charge.ambiguous_charge_id].date_will_be_eligible == date.max( ) # The Class B felony does not affect eligibility of another charge that is otherwise eligible assert expunger_result[ subsequent_charge. ambiguous_charge_id].status is EligibilityStatus.ELIGIBLE assert subsequent_charge.type_eligibility.status is EligibilityStatus.ELIGIBLE
def test_eligible_mrc_with_single_arrest(): three_yr_mrc = ChargeFactory.create( disposition=DispositionCreator.create(ruling="Convicted", date=Time.THREE_YEARS_AGO) ) arrest = ChargeFactory.create(disposition=DispositionCreator.create(ruling="Dismissed", date=Time.THREE_YEARS_AGO)) case = CaseFactory.create(charges=tuple([three_yr_mrc, arrest])) record = Record(tuple([case])) expunger_result = Expunger.run(record) assert expunger_result[arrest.ambiguous_charge_id].status is EligibilityStatus.ELIGIBLE assert ( expunger_result[arrest.ambiguous_charge_id].reason == 'Time eligibility of the arrest matches conviction on the same case (the "friendly" rule)' ) assert expunger_result[arrest.ambiguous_charge_id].date_will_be_eligible == date.today() assert expunger_result[three_yr_mrc.ambiguous_charge_id].status is EligibilityStatus.ELIGIBLE assert expunger_result[three_yr_mrc.ambiguous_charge_id].reason == "Eligible now" assert expunger_result[three_yr_mrc.ambiguous_charge_id].date_will_be_eligible == date.today() merged_record = RecordMerger.merge([record], [expunger_result], []) assert ( merged_record.cases[0].charges[0].expungement_result.charge_eligibility.status # type: ignore == ChargeEligibilityStatus.ELIGIBLE_NOW ) assert merged_record.cases[0].charges[0].expungement_result.charge_eligibility.label == "Eligible Now" # type: ignore assert ( merged_record.cases[0].charges[1].expungement_result.charge_eligibility.status # type: ignore == ChargeEligibilityStatus.ELIGIBLE_NOW ) assert merged_record.cases[0].charges[1].expungement_result.charge_eligibility.label == "Eligible Now" # type: ignore
def create_dismissed_charge( cls, case_number=1, name="Theft of services", statute="164.125", level="Misdemeanor Class A", date=date_class(1901, 1, 1), violation_type="Offense Misdemeanor", ) -> Charge: cls.charge_count += 1 disposition = DispositionCreator.create(date=date_class.today(), ruling="Dismissed") kwargs = { "case_number": case_number, "name": name, "statute": statute, "level": level, "date": date, "disposition": disposition, "violation_type": violation_type, "balance_due_in_cents": 0, "edit_status": EditStatus.UNCHANGED, } charges = ChargeCreator.create(str(cls.charge_count), **kwargs)[0] assert len(charges) == 1 return charges[0]
def create(info, case_number, citation_number, date_location, type_status, case_detail_link, balance="0") -> CaseSummary: name = info[0] birth_year = CaseSummary._parse_birth_year(info) citation_number = citation_number[0] if citation_number else "" date, location = date_location date = date_class.fromdatetime(datetime.strptime(date, "%m/%d/%Y")) violation_type, current_status = type_status balance_due_in_cents = CaseCreator.compute_balance_due_in_cents( balance) return CaseSummary( name, birth_year, case_number, citation_number, location, date, violation_type, current_status, case_detail_link, balance_due_in_cents, )
def test_edit_charge_type_of_charge(): record, questions = RecordCreator.build_record( search("single_case_two_charges"), "username", "password", (), { "X0001": { "summary": { "edit_status": "UPDATE" }, "charges": { "X0001-2": { "edit_status": "UPDATE", "charge_type": "MisdemeanorClassA", "level": "Misdemeanor Class A", } }, } }, date.today(), LRUCache(4), ) assert isinstance(record.cases[0].charges[1].charge_type, MisdemeanorClassA)
def test_ineligible_mrc_with_arrest_on_single_case(self): # In this case, the friendly rule doesn't apply because the conviction doesn't become eligible mrc = ChargeFactory.create( case_number="1", disposition=DispositionCreator.create(ruling="Convicted", date=Time.LESS_THAN_THREE_YEARS_AGO), statute="666.666", level="Felony Class A", ) arrest = ChargeFactory.create( case_number="1", disposition=DispositionCreator.create(ruling="Dismissed", date=Time.LESS_THAN_THREE_YEARS_AGO), ) case = CaseFactory.create(charges=tuple([mrc, arrest])) record = Record(tuple([case])) expunger_result = Expunger.run(record) assert expunger_result[arrest.ambiguous_charge_id].status is EligibilityStatus.ELIGIBLE assert expunger_result[arrest.ambiguous_charge_id].reason == "Eligible now" assert expunger_result[mrc.ambiguous_charge_id].status is EligibilityStatus.INELIGIBLE assert ( expunger_result[mrc.ambiguous_charge_id].reason == "Never. Type ineligible charges are always time ineligible." ) assert expunger_result[mrc.ambiguous_charge_id].date_will_be_eligible == date.max()
def test_10_yr_old_conviction_with_less_than_3_yr_old_mrc(self): ten_yr_charge = ChargeFactory.create( disposition=DispositionCreator.create(ruling="Convicted", date=Time.TEN_YEARS_AGO) ) less_than_three_yr_mrc = ChargeFactory.create( disposition=DispositionCreator.create(ruling="Convicted", date=Time.LESS_THAN_THREE_YEARS_AGO) ) case = CaseFactory.create(charges=tuple([ten_yr_charge, less_than_three_yr_mrc])) record = Record(tuple([case])) expunger_result = Expunger.run(record) assert expunger_result[ten_yr_charge.ambiguous_charge_id].status is EligibilityStatus.INELIGIBLE assert ( expunger_result[ten_yr_charge.ambiguous_charge_id].reason == f"137.225(7)(b) – Three years from most recent other conviction from case [{case.summary.case_number}]." ) assert ( expunger_result[ten_yr_charge.ambiguous_charge_id].date_will_be_eligible == less_than_three_yr_mrc.disposition.date + Time.THREE_YEARS ) assert expunger_result[less_than_three_yr_mrc.ambiguous_charge_id].status is EligibilityStatus.INELIGIBLE assert ( expunger_result[less_than_three_yr_mrc.ambiguous_charge_id].reason == "Three years from date of conviction (137.225(1)(b))" ) assert expunger_result[ less_than_three_yr_mrc.ambiguous_charge_id ].date_will_be_eligible == date.today() + relativedelta(days=+1)
def test_3_violations_are_time_restricted(): violation_charge_1 = ChargeFactory.create( level="Class A Violation", date=Time.TWO_YEARS_AGO, disposition=DispositionCreator.create(ruling="Convicted", date=Time.LESS_THAN_TWO_YEARS_AGO), ) violation_charge_2 = ChargeFactory.create( level="Class A Violation", date=Time.ONE_YEAR_AGO, disposition=DispositionCreator.create(ruling="Convicted", date=Time.LESS_THAN_ONE_YEAR_AGO), ) violation_charge_3 = ChargeFactory.create( level="Class A Violation", date=Time.YESTERDAY, disposition=DispositionCreator.create(ruling="Convicted", date=Time.YESTERDAY), ) case = CaseFactory.create(charges=tuple([violation_charge_3, violation_charge_2, violation_charge_1])) expunger_result = Expunger.run(Record(tuple([case]))) # the 3-year-old-one is blocked by the middle one assert expunger_result[violation_charge_1.ambiguous_charge_id].status is EligibilityStatus.INELIGIBLE assert ( expunger_result[violation_charge_1.ambiguous_charge_id].reason == f"137.225(7)(b) – One year from most recent other conviction from case [{case.summary.case_number}]." ) assert expunger_result[ violation_charge_1.ambiguous_charge_id ].date_will_be_eligible == date.today() + relativedelta(days=+1) assert expunger_result[violation_charge_2.ambiguous_charge_id].status is EligibilityStatus.INELIGIBLE assert ( expunger_result[violation_charge_2.ambiguous_charge_id].reason == "One year from date of conviction (137.225(1)(b))" ) assert expunger_result[ violation_charge_2.ambiguous_charge_id ].date_will_be_eligible == date.today() + relativedelta(days=+1) assert expunger_result[violation_charge_3.ambiguous_charge_id].status is EligibilityStatus.INELIGIBLE assert ( expunger_result[violation_charge_3.ambiguous_charge_id].reason == "One year from date of conviction (137.225(1)(b))" ) assert expunger_result[ violation_charge_3.ambiguous_charge_id ].date_will_be_eligible == date.today() + relativedelta(years=+1, days=-1)
def test_felony_class_b_seven_years(): charge = create_class_b_felony_charge("1", Time.SEVEN_YEARS_AGO) case = CaseFactory.create(charges=tuple([charge])) expunger_result = Expunger.run(Record(tuple([case]))) assert expunger_result[charge.ambiguous_charge_id].status is EligibilityStatus.ELIGIBLE assert expunger_result[charge.ambiguous_charge_id].reason == "Eligible now" assert expunger_result[charge.ambiguous_charge_id].date_will_be_eligible == date.today()
def test_expunger_for_record_with_odd_event_table_contents( record_with_odd_event_table_contents): expunger_result = Expunger.run(record_with_odd_event_table_contents) assert expunger_result == { "CASEJD1-1": TimeEligibility( status=EligibilityStatus.INELIGIBLE, reason="Never. Type ineligible charges are always time ineligible.", date_will_be_eligible=date.max(), ), "CASEJD1-2": TimeEligibility( status=EligibilityStatus.INELIGIBLE, reason="Never. Type ineligible charges are always time ineligible.", date_will_be_eligible=date.max(), ), }
def _single_conviction_years_by_level(oeci_charge_level, charge_date, charge_type): if charge_type.severity_level: charge_level = charge_type.severity_level else: charge_level = oeci_charge_level if "Felony Class A" in charge_level: return ( date.max(), "Never. Felony Class A convictions are omitted from 137.225.") elif "Felony Class B" in charge_level: return ( charge_date + relativedelta(years=7), "Seven years from date of conviction (137.225(1)(b))", ) elif "Felony Class C" in charge_level: return ( charge_date + relativedelta(years=5), "Five years from date of conviction (137.225(1)(b))", ) elif "Misdemeanor Class A" in charge_level: return ( charge_date + relativedelta(years=3), "Three years from date of conviction (137.225(1)(b))", ) elif any([ level in charge_level for level in [ "Misdemeanor Class B", "Misdemeanor Class C", "Violation", "Infraction" ] ]): return ( charge_date + relativedelta(years=1), "One year from date of conviction (137.225(1)(b))", ) elif "Misdemeanor" in charge_level: return ( charge_date + relativedelta(years=3), "Three years from date of conviction (137.225(1)(b))", ) else: return ( date.max(), f'Error: unrecognized severity level in "{charge_level}". Edit this charge to have a valid level.', )
def test_update_case_with_add_and_update_and_delete_charges(): record, questions = RecordCreator.build_record( search("single_case_two_charges"), "username", "password", (), { "X0001": { "summary": { "case_number": "X0001", "edit_status": "UPDATE", "location": "ocean", "balance_due": "100", "date": "1/1/1981", }, "charges": { "X0001-1": { "edit_status": "UPDATE", "charge_type": "FelonyClassB", "level": "Felony Class B", "date": "1/1/2001", "disposition": { "date": "2/1/2020", "ruling": "Convicted" }, }, "X0001-2": { "edit_status": "DELETE" }, "X0001-3": { "edit_status": "ADD", "charge_type": "FelonyClassC", "date": "1/1/1900", "level": "Felony Class A", "disposition": { "date": "2/1/1910", "ruling": "Convicted" }, }, }, } }, date.today(), LRUCache(4), ) assert len(record.cases) == 1 assert record.cases[0].summary.location == "ocean" assert record.cases[0].summary.edit_status == EditStatus.UPDATE assert record.cases[0].charges[0].ambiguous_charge_id == "X0001-1" assert record.cases[0].charges[0].edit_status == EditStatus.UPDATE assert isinstance(record.cases[0].charges[0].charge_type, FelonyClassB) assert record.cases[0].charges[1].ambiguous_charge_id == "X0001-2" assert record.cases[0].charges[1].edit_status == EditStatus.DELETE assert record.cases[0].charges[2].ambiguous_charge_id == "X0001-3" assert record.cases[0].charges[2].edit_status == EditStatus.ADD
def test_more_than_three_year_rule_conviction(self): charge = ChargeFactory.create( disposition=DispositionCreator.create(ruling="Convicted", date=Time.THREE_YEARS_AGO) ) case = CaseFactory.create(charges=tuple([charge])) record = Record(tuple([case])) expunger_result = Expunger.run(record) assert expunger_result[charge.ambiguous_charge_id].status is EligibilityStatus.ELIGIBLE assert expunger_result[charge.ambiguous_charge_id].reason == "Eligible now" assert expunger_result[charge.ambiguous_charge_id].date_will_be_eligible == date.today()
def test_type_eligible_never_becomes_eligible(): type_eligibility = TypeEligibility(EligibilityStatus.ELIGIBLE, "Eligible under some statute") time_eligibility = TimeEligibility(EligibilityStatus.INELIGIBLE, "Never eligible under some statute", date.max()) charge_eligibility = RecordMerger.compute_charge_eligibility( type_eligibility, [time_eligibility]) assert charge_eligibility.status == ChargeEligibilityStatus.INELIGIBLE assert charge_eligibility.label == "Ineligible"
def test_eligible(): type_eligibility = TypeEligibility(EligibilityStatus.ELIGIBLE, "Eligible under some statute") time_eligibility = TimeEligibility(EligibilityStatus.ELIGIBLE, "Eligible under some statute", date.today()) charge_eligibility = RecordMerger.compute_charge_eligibility( type_eligibility, [time_eligibility]) assert charge_eligibility.status == ChargeEligibilityStatus.ELIGIBLE_NOW assert charge_eligibility.label == "Eligible Now"
def test_type_possibly_eligible_never_becomes_eligible(): type_eligibility = TypeEligibility(EligibilityStatus.NEEDS_MORE_ANALYSIS, "Unrecognized charge") time_eligibility = TimeEligibility(EligibilityStatus.INELIGIBLE, "Never eligible under some statute", date.max()) charge_eligibility = RecordMerger.compute_charge_eligibility( type_eligibility, [time_eligibility]) assert charge_eligibility.status == ChargeEligibilityStatus.INELIGIBLE assert charge_eligibility.label == "Ineligible"