def test_unrecognized_violation_is_not_type_eligible(): charge = ChargeFactory.create( statute="801.000", level="Class C Traffic Violation", disposition=Dispositions.UNRECOGNIZED_DISPOSITION) assert isinstance(charge.charge_type, TrafficViolation) assert charge.type_eligibility.status is EligibilityStatus.INELIGIBLE assert ( charge.type_eligibility.reason == "Always ineligible under 137.225(7)(a) (for convictions) or by omission from statute (for dismissals)" ) assert not charge.charge_type.blocks_other_charges
def test_nonblocking_charge_is_not_skipped_and_does_not_block(): civil_offense = ChargeFactory.create( level="N/A", statute="1.000", disposition=["Convicted", Time.ONE_YEAR_AGO]) violation_charge = ChargeFactory.create( level="Class A Violation", date=Time.TEN_YEARS_AGO, disposition=["Convicted", Time.TEN_YEARS_AGO]) case = CaseFactory.create() case.charges = [civil_offense, violation_charge] expunger = Expunger(Record([case])) expunger.run() assert civil_offense.expungement_result.time_eligibility.status is EligibilityStatus.INELIGIBLE assert (civil_offense.expungement_result.time_eligibility.reason == "Never. Type ineligible charges are always time ineligible.") assert civil_offense.expungement_result.time_eligibility.date_will_be_eligible == date.max assert violation_charge.expungement_result.time_eligibility.status is EligibilityStatus.ELIGIBLE
def test_pcs_dismissed_violation(): charge_dict = ChargeFactory.default_dict() charge_dict["name"] = "Poss Controlled Sub 2" charge_dict["statute"] = "4759924B" charge_dict["disposition"] = Dispositions.DISMISSED for level in ("Class C Violation", "Class c violation", "Class B Violation", "Class B violation", "Class D Violation", "Class D violation"): charge_dict["level"] = level pcs_charge = ChargeFactory.create(**charge_dict) assert isinstance(pcs_charge, Schedule1PCS) assert pcs_charge.expungement_result.type_eligibility.status is EligibilityStatus.INELIGIBLE assert pcs_charge.expungement_result.type_eligibility.reason == "Dismissed violations are ineligible by omission from statute"
def test_7_yr_old_conviction_5_yr_old_mrc(self): seven_year_ago_charge = ChargeFactory.create( disposition=["Convicted", Time.SEVEN_YEARS_AGO]) five_year_ago_charge = ChargeFactory.create( disposition=["Convicted", Time.FIVE_YEARS_AGO]) self.run_expunger(five_year_ago_charge, seven_year_ago_charge) assert seven_year_ago_charge.expungement_result.time_eligibility.status is EligibilityStatus.INELIGIBLE assert seven_year_ago_charge.expungement_result.time_eligibility.reason == "Time-ineligible under 137.225(7)(b)" assert ( seven_year_ago_charge.expungement_result.time_eligibility. date_will_be_eligible == five_year_ago_charge.disposition.date + Time.TEN_YEARS) assert five_year_ago_charge.expungement_result.time_eligibility.status is EligibilityStatus.INELIGIBLE assert (five_year_ago_charge.expungement_result.time_eligibility.reason == "Multiple convictions within last ten years") assert ( five_year_ago_charge.expungement_result.time_eligibility. date_will_be_eligible == seven_year_ago_charge.disposition.date + Time.TEN_YEARS)
def test_felony_not_b_person_felony(person_felony_statute_not_b_felony): """ Only test the first 5 statutes just to not spam another ~75 tests. """ charge_dict = ChargeFactory.default_dict( disposition=Dispositions.CONVICTED) charge_dict["name"] = "Generic" charge_dict["statute"] = person_felony_statute_not_b_felony charge_dict["level"] = "Felony Class C" charge_dict["disposition"] = Dispositions.CONVICTED person_felony_not_class_b_convicted = ChargeFactory.create(**charge_dict) assert not isinstance(person_felony_not_class_b_convicted, PersonFelonyClassB)
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_misdemeanor_missing_disposition(): misdemeanor_charge = ChargeFactory.create( name="Criminal Trespass in the Second Degree", statute="164.245", level="Misdemeanor Class C", disposition=None) assert isinstance(misdemeanor_charge, Misdemeanor) assert misdemeanor_charge.type_eligibility.status is EligibilityStatus.ELIGIBLE assert ( misdemeanor_charge.type_eligibility.reason == "Misdemeanors are always eligible under 137.225(5)(b) for convictions, or 137.225(1)(b) for dismissals" )
def test_subsection_12_dismissed(): charge_dict = ChargeFactory.default_dict() charge_dict["name"] = "Abandonment of a child" charge_dict["statute"] = "163.535" charge_dict["level"] = "Felony Class C" charge_dict["disposition"] = Dispositions.DISMISSED subsection_12_charge = ChargeFactory.create(**charge_dict) assert isinstance(subsection_12_charge, Subsection12) assert subsection_12_charge.expungement_result.type_eligibility.status is EligibilityStatus.ELIGIBLE assert ( subsection_12_charge.expungement_result.type_eligibility.reason == "Dismissals are eligible under 137.225(1)(b)" )
def test_less_than_three_year_rule_conviction(self): charge = ChargeFactory.create( disposition=["Convicted", Time.LESS_THAN_THREE_YEARS_AGO]) charges_with_summary = ChargesWithSummary( charges=[charge], most_recent_conviction=charge) TimeAnalyzer.evaluate(charges_with_summary) assert charge.expungement_result.time_eligibility.status is EligibilityStatus.INELIGIBLE assert (charge.expungement_result.time_eligibility.reason == "Most recent conviction is less than three years old") assert charge.expungement_result.time_eligibility.date_will_be_eligible == date.today( ) + relativedelta(days=+1)
def test_marijuana_ineligible_statute_475b3592a(): marijuana_felony_class_a = ChargeFactory.create( name= "Arson incident to manufacture of cannabinoid extract in first degree", statute="475b.359(2)(a)", level="Felony Class A", disposition=Dispositions.CONVICTED, ) assert isinstance(marijuana_felony_class_a, MarijuanaIneligible) assert marijuana_felony_class_a.type_name == "Marijuana Ineligible" assert marijuana_felony_class_a.type_eligibility.status is EligibilityStatus.INELIGIBLE assert marijuana_felony_class_a.type_eligibility.reason == "Ineligible under 137.226"
def test_felony_class_a_no_complaint(): felony_class_a_no_complaint = ChargeFactory.create( name="Assault in the first degree", statute="163.185", level="Felony Class A", disposition=Dispositions.NO_COMPLAINT, ) assert isinstance(felony_class_a_no_complaint.charge_type, DismissedCharge) assert felony_class_a_no_complaint.type_eligibility.status is EligibilityStatus.ELIGIBLE assert ( felony_class_a_no_complaint.type_eligibility.reason == "Dismissals are generally eligible under 137.225(1)(b)" )
def test_3_yr_old_conviction_2_yr_old_mrc(self): three_years_ago_charge = ChargeFactory.create( disposition=["Convicted", Time.THREE_YEARS_AGO]) two_years_ago_charge = ChargeFactory.create( disposition=["Convicted", Time.TWO_YEARS_AGO]) self.run_expunger(two_years_ago_charge, three_years_ago_charge) assert three_years_ago_charge.expungement_result.time_eligibility.status is EligibilityStatus.INELIGIBLE assert (three_years_ago_charge.expungement_result.time_eligibility. reason == "Time-ineligible under 137.225(7)(b)") assert ( three_years_ago_charge.expungement_result.time_eligibility. date_will_be_eligible == two_years_ago_charge.disposition.date + Time.TEN_YEARS) assert two_years_ago_charge.expungement_result.time_eligibility.status is EligibilityStatus.INELIGIBLE assert two_years_ago_charge.expungement_result.time_eligibility.reason == "Time-ineligible under 137.225(7)(b)" assert ( two_years_ago_charge.expungement_result.time_eligibility. date_will_be_eligible == three_years_ago_charge.disposition.date + Time.TEN_YEARS)
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
def test_old_traffic_statute(): charge = ChargeFactory.create(statute="483050", name="Defective Equipment", level="Infraction Class B", disposition=Dispositions.DISMISSED) assert isinstance(charge.charge_type, TrafficViolation) assert charge.type_eligibility.status is EligibilityStatus.NEEDS_MORE_ANALYSIS assert ( charge.type_eligibility.reason == "Dismissed violations are eligible under 137.225(1)(b) but administrative reasons may make this difficult to expunge." ) assert not charge.charge_type.blocks_other_charges
def test_subsection_6_dismissed(): charge_dict = ChargeFactory.default_dict() charge_dict["name"] = "Criminal mistreatment in the second degree" charge_dict["statute"] = "163.200" charge_dict["level"] = "Misdemeanor Class A" charge_dict["disposition"] = Dispositions.DISMISSED subsection_6_charge = ChargeFactory.create(**charge_dict) assert isinstance(subsection_6_charge, Subsection6) assert subsection_6_charge.expungement_result.type_eligibility.status is EligibilityStatus.ELIGIBLE assert (subsection_6_charge.expungement_result.type_eligibility.reason == "Dismissals are eligible under 137.225(1)(b)")
def test_3_violations_are_time_restricted(): violation_charge_1 = ChargeFactory.create( level="Class A Violation", date=Time.LESS_THAN_THREE_YEARS_AGO, disposition=["Convicted", Time.LESS_THAN_THREE_YEARS_AGO], ) violation_charge_2 = ChargeFactory.create( level="Class A Violation", date=Time.TWO_YEARS_AGO, disposition=["Convicted", Time.TWO_YEARS_AGO]) violation_charge_3 = ChargeFactory.create( level="Class A Violation", date=Time.ONE_YEAR_AGO, disposition=["Convicted", Time.ONE_YEAR_AGO]) arrest = ChargeFactory.create(disposition=["Dismissed", Time.ONE_YEAR_AGO]) case = CaseFactory.create() case.charges = [ violation_charge_3, violation_charge_2, violation_charge_1, arrest ] expunger = Expunger(Record([case])) expunger.run() earliest_date_eligible = min( violation_charge_1.expungement_result.time_eligibility. date_will_be_eligible, violation_charge_2.expungement_result.time_eligibility. date_will_be_eligible, violation_charge_3.expungement_result.time_eligibility. date_will_be_eligible, ) assert arrest.expungement_result.time_eligibility.status is EligibilityStatus.INELIGIBLE assert ( arrest.expungement_result.time_eligibility.reason == "The friendly rule: time eligibility of the arrest matches time eligibility of the conviction." ) assert arrest.expungement_result.time_eligibility.date_will_be_eligible == earliest_date_eligible
def test_time_eligibility_date_is_none_when_type_ineligible(self): charge = ChargeFactory.create(name='Assault in the first degree', statute='163.185', level='Felony Class A', date=Time.ONE_YEAR_AGO, disposition=['Convicted', Time.ONE_YEAR_AGO]) self.expunger.most_recent_conviction = charge self.expunger.charges = [charge] TimeAnalyzer.evaluate(self.expunger) assert charge.expungement_result.time_eligibility.status is False assert charge.expungement_result.time_eligibility.reason == 'Most recent conviction is less than three years old' assert charge.expungement_result.time_eligibility.date_will_be_eligible is None
def test_felony_c_no_disposition(): charge = ChargeFactory.create( name="Theft in the first degree", statute="164.055", level="Felony Class C", disposition=DispositionCreator.empty(), ) assert isinstance(charge.charge_type, FelonyClassC) assert charge.type_eligibility.status is EligibilityStatus.ELIGIBLE assert ( charge.type_eligibility.reason == "Eligible under 137.225(1)(b) for convictions or under 137.225(1)(d) for dismissals" )
def test_subsection_12_163535(): charge_dict = ChargeFactory.default_dict() charge_dict["name"] = "Abandonment of a child" charge_dict["statute"] = "163.535" charge_dict["level"] = "Felony Class C" charge_dict["disposition"] = Dispositions.CONVICTED subsection_12_charge = ChargeFactory.create(**charge_dict) assert isinstance(subsection_12_charge, Subsection12) assert subsection_12_charge.expungement_result.type_eligibility.status is EligibilityStatus.ELIGIBLE assert ( subsection_12_charge.expungement_result.type_eligibility.reason == "Eligible under 137.225(12). This subsection is interpreted to override any conflicting subsections." )
def test_doubly_eligible_b_felony_gets_normal_eligibility_rule(): # This charge is both Schedule1PCS and also a class B felony. Schedule1PCS classification takes precedence and the B felony time rule does not apply. pcs_charge = ChargeFactory.create( name="Unlawful possession of methamphetamine", statute="475894", level="Felony Class B", date=Time.LESS_THAN_TWENTY_YEARS_AGO, disposition=Disposition(ruling="Convicted", date=Time.LESS_THAN_TWENTY_YEARS_AGO), ) case_1 = CaseFactory.create() case_1.charges = [pcs_charge] subsequent_charge = ChargeFactory.create( disposition=Disposition(ruling="Convicted", date=Time.TEN_YEARS_AGO)) case_2 = CaseFactory.create() case_2.charges = [subsequent_charge] expunger = Expunger(Record([case_1, case_2])) expunger.run() assert pcs_charge.expungement_result.time_eligibility.status is EligibilityStatus.ELIGIBLE assert pcs_charge.expungement_result.type_eligibility.status is EligibilityStatus.ELIGIBLE
def test_subsection_12_163525(): charge_dict = ChargeFactory.default_dict() charge_dict["name"] = "Incest" charge_dict["statute"] = "163.525" charge_dict["level"] = "Felony Class C" charge_dict["disposition"] = Dispositions.CONVICTED subsection_12_charge = ChargeFactory.create(**charge_dict) assert isinstance(subsection_12_charge, Subsection12) assert subsection_12_charge.expungement_result.type_eligibility.status is EligibilityStatus.NEEDS_MORE_ANALYSIS assert ( subsection_12_charge.expungement_result.type_eligibility.reason == "Incest is possibly eligible under 137.225(12), if the victim was at least 18 years of age." )
def test_reduced_to_violation_unrecognized_disposition(): charge = ChargeFactory.create( name="Theft in the Second Degree (Reduced - DA Elected)", statute="164045", level="Violation Class A", disposition=Dispositions.UNRECOGNIZED_DISPOSITION, ) assert isinstance(charge.charge_type, ReducedToViolation) assert charge.type_eligibility.status is EligibilityStatus.ELIGIBLE assert ( charge.type_eligibility.reason == "Reduced Violations are always eligible under 137.225(5)(d) for convictions, or 137.225(1)(b) for dismissals" )
def test_less_than_three_year_rule_conviction(self): charge = ChargeFactory.create(disposition=DispositionCreator.create( ruling="Convicted", date=Time.LESS_THAN_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.INELIGIBLE assert (expunger_result[charge.ambiguous_charge_id].reason == "Three years from date of conviction (137.225(1)(a))") assert expunger_result[ charge.ambiguous_charge_id].date_will_be_eligible == date.today( ) + relativedelta(days=+1)
def test_felony_c_unrecognized_disposition(): charge = ChargeFactory.create( name="Theft in the first degree", statute="164.055", level="Felony Class C", disposition=Dispositions.UNRECOGNIZED_DISPOSITION, ) assert isinstance(charge.charge_type, FelonyClassC) assert charge.type_eligibility.status is EligibilityStatus.ELIGIBLE assert ( charge.type_eligibility.reason == "Eligible under 137.225(5)(b) for convictions or under 137.225(1)(b) for dismissals" )
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_felony_c_no_disposition(): charge_dict = ChargeFactory.default_dict() charge_dict["name"] = "Theft in the first degree" charge_dict["statute"] = "164.055" charge_dict["level"] = "Felony Class C" charge_dict["disposition"] = None charge = ChargeFactory.create(**charge_dict) assert isinstance(charge, FelonyClassC) assert charge.expungement_result.type_eligibility.status is EligibilityStatus.ELIGIBLE assert ( charge.expungement_result.type_eligibility.reason == "Eligible under 137.225(5)(b) for convictions or under 137.225(1)(b) for dismissals" )
def test_marijuana_eligible_unrecognized_dispo(): marijuana_eligible_charge = ChargeFactory.create( name="Delivery of Marijuana to Minor", statute="4758604A", level="Felony Class A", disposition=Dispositions.UNRECOGNIZED_DISPOSITION, ) assert isinstance(marijuana_eligible_charge.charge_type, MarijuanaEligible) assert marijuana_eligible_charge.type_eligibility.status is EligibilityStatus.ELIGIBLE assert ( marijuana_eligible_charge.type_eligibility.reason == "Always eligible under 137.226 (for convictions) or 137.225(1)(b) (for dismissals)" )
def test_3_violations_are_time_restricted(): violation_charge_1 = ChargeFactory.create( level="Class A Violation", date=Time.LESS_THAN_THREE_YEARS_AGO, disposition=["Convicted", Time.LESS_THAN_THREE_YEARS_AGO], ) violation_charge_2 = ChargeFactory.create( level="Class A Violation", date=Time.TWO_YEARS_AGO, disposition=["Convicted", Time.TWO_YEARS_AGO]) violation_charge_3 = ChargeFactory.create( level="Class A Violation", date=Time.ONE_YEAR_AGO, disposition=["Convicted", Time.ONE_YEAR_AGO]) case = CaseFactory.create() case.charges = [violation_charge_3, violation_charge_2, violation_charge_1] expunger = Expunger(Record([case])) expunger.run() assert violation_charge_1.expungement_result.time_eligibility.status is EligibilityStatus.INELIGIBLE assert violation_charge_1.expungement_result.time_eligibility.reason == "Time-ineligible under 137.225(7)(b)" assert (violation_charge_1.expungement_result.time_eligibility. date_will_be_eligible == violation_charge_2.disposition.date + Time.TEN_YEARS) assert violation_charge_2.expungement_result.time_eligibility.status is EligibilityStatus.INELIGIBLE assert violation_charge_2.expungement_result.time_eligibility.reason == "Time-ineligible under 137.225(7)(b)" assert (violation_charge_2.expungement_result.time_eligibility. date_will_be_eligible == violation_charge_1.disposition.date + Time.TEN_YEARS) assert violation_charge_3.expungement_result.time_eligibility.status is EligibilityStatus.INELIGIBLE assert violation_charge_3.expungement_result.time_eligibility.reason == "Time-ineligible under 137.225(7)(b)" assert (violation_charge_3.expungement_result.time_eligibility. date_will_be_eligible == violation_charge_1.disposition.date + Time.TEN_YEARS)
def test_7_yr_old_conviction_5_yr_old_mrc(self): seven_year_ago_charge = ChargeFactory.create( disposition=DispositionCreator.create(ruling="Convicted", date=Time.SEVEN_YEARS_AGO)) five_year_ago_charge = ChargeFactory.create( disposition=DispositionCreator.create(ruling="Convicted", date=Time.FIVE_YEARS_AGO)) case = CaseFactory.create( charges=tuple([five_year_ago_charge, seven_year_ago_charge])) record = Record(tuple([case])) expunger_result = Expunger.run(record) assert expunger_result[ seven_year_ago_charge. ambiguous_charge_id].status is EligibilityStatus.INELIGIBLE assert ( expunger_result[ seven_year_ago_charge.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[seven_year_ago_charge.ambiguous_charge_id]. date_will_be_eligible == five_year_ago_charge.disposition.date + Time.TEN_YEARS) assert expunger_result[ five_year_ago_charge. ambiguous_charge_id].status is EligibilityStatus.INELIGIBLE assert ( expunger_result[five_year_ago_charge.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[five_year_ago_charge.ambiguous_charge_id]. date_will_be_eligible == seven_year_ago_charge.disposition.date + Time.TEN_YEARS)
def test_dismissed_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=Disposition(ruling="Convicted", date=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