def test_arrest_is_unaffected_if_conviction_is_older(): # A single violation doesn't block other records, but it is still subject to the 3 year rule. violation_charge = ChargeFactory.create( level="Class A Violation", date=Time.TEN_YEARS_AGO, disposition=["Convicted", Time.LESS_THAN_THREE_YEARS_AGO]) arrest = ChargeFactory.create(disposition=["Dismissed", Time.ONE_YEAR_AGO]) case = CaseFactory.create() case.charges = [violation_charge, arrest] expunger = Expunger(Record([case])) expunger.run() assert arrest.expungement_result.time_eligibility.status is EligibilityStatus.ELIGIBLE assert arrest.expungement_result.time_eligibility.date_will_be_eligible == None assert arrest.expungement_result.time_eligibility.reason == ""
def test_single_violation_is_time_restricted(): # A single violation doesn't block other records, but it is still subject to the 3 year rule. violation_charge = ChargeFactory.create( level="Class A Violation", date=Time.TEN_YEARS_AGO, disposition=["Convicted", Time.LESS_THAN_THREE_YEARS_AGO]) case = CaseFactory.create() case.charges = [violation_charge] expunger = Expunger(Record([case])) expunger.run() assert violation_charge.expungement_result.time_eligibility.status is EligibilityStatus.INELIGIBLE assert violation_charge.expungement_result.time_eligibility.reason == "Time-ineligible under 137.225(1)(a)" assert violation_charge.expungement_result.time_eligibility.date_will_be_eligible == date.today( ) + relativedelta(days=+1)
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
class TestExpungementAnalyzerUnitTests(unittest.TestCase): TEN_YEARS = (date.today() + relativedelta(years=-10)).strftime('%m/%d/%Y') LESS_THAN_TEN_YEARS_AGO = ( date.today() + relativedelta(years=-10, days=+1)).strftime('%m/%d/%Y') LESS_THAN_THREE_YEARS_AGO = ( date.today() + relativedelta(years=-3, days=+1)).strftime('%m/%d/%Y') THREE_YEARS_AGO = (date.today() + relativedelta(years=-3)).strftime('%m/%d/%Y') TWO_YEARS_AGO = (date.today() + relativedelta(years=-2)).strftime('%m/%d/%Y') ONE_YEAR_AGO = (date.today() + relativedelta(years=-1)).strftime('%m/%d/%Y') TWO_YEAR_AGO_DATE = (date.today() + relativedelta(years=-2)).strftime('%m/%d/%Y') ONE_YEAR_AGO_DATE = (date.today() + relativedelta(years=-1)).strftime('%m/%d/%Y') THREE_YEAR_AGO_DATE = (date.today() + relativedelta(years=-3)).strftime('%m/%d/%Y') FOUR_YEAR_AGO_DATE = (date.today() + relativedelta(years=-4)).strftime('%m/%d/%Y') def test_expunger_sets_most_recent_dismissal_when_charge_is_less_than_3yrs( self): case = CaseFactory.create() mrd_charge = ChargeFactory.create_dismissed_charge( date=self.LESS_THAN_THREE_YEARS_AGO) case.charges = [mrd_charge] record = Record([case]) expunger = Expunger(record) expunger.run() assert expunger.most_recent_dismissal is mrd_charge
class TestChargeClass(unittest.TestCase): TEN_YEARS_AGO = (date.today() + relativedelta(years=-10)).strftime('%m/%d/%Y') LESS_THAN_TEN_YEARS_AGO = (date.today() + relativedelta(years=-10, days=+1)).strftime('%m/%d/%Y') LESS_THAN_THREE_YEARS_AGO = (date.today() + relativedelta(years=-3, days=+1)).strftime('%m/%d/%Y') THREE_YEARS_AGO = (date.today() + relativedelta(years=-3)).strftime('%m/%d/%Y') def setUp(self): self.charge = ChargeFactory.build() def test_it_initializes_simple_statute(self): self.charge['statute'] = '1231235B' charge = ChargeFactory.save(self.charge) assert charge.statute == '1231235B' def test_it_normalizes_statute(self): self.charge['statute'] = '-123.123(5)()B' charge = ChargeFactory.save(self.charge) assert charge.statute == '1231235B' def test_it_converts_statute_to_uppercase(self): self.charge['statute'] = '-123.123(5)()b' charge = ChargeFactory.save(self.charge) assert charge.statute == '1231235B' def test_it_retrieves_its_parent_instance(self): case = CaseFactory.create() charge = ChargeFactory.create(case=case) assert charge.case()() is case
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
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 setUp(self): self.charge = ChargeFactory.default_dict() def test_it_initializes_simple_statute(self): self.charge["statute"] = "1231235B" charge = ChargeFactory.create(**self.charge) assert charge.statute == "1231235B" def test_it_normalizes_statute(self): self.charge["statute"] = "-123.123(5)()B" charge = ChargeFactory.create(**self.charge) assert charge.statute == "1231235B" def test_it_converts_statute_to_uppercase(self): self.charge["statute"] = "-123.123(5)()b" charge = ChargeFactory.create(**self.charge) assert charge.statute == "1231235B" def test_it_retrieves_its_parent_instance(self): case = CaseFactory.create() charge = ChargeFactory.create(case=case) assert charge.case()() is case
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 == ""
def test_violation_is_2mrc(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.charges_with_summary.second_most_recent_conviction is self.viol2_charge
def test_felony_class_b_with_prior_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])) prior_charge = ChargeFactory.create( disposition=DispositionCreator.create(ruling="Convicted", date=Time.MORE_THAN_TWENTY_YEARS_AGO) ) case_2 = CaseFactory.create(case_number="2", charges=tuple([prior_charge])) expunger_result = Expunger.run(Record(tuple([case_1, case_2]))) assert b_felony_charge.type_eligibility.status is EligibilityStatus.ELIGIBLE assert ( b_felony_charge.type_eligibility.reason == "Convictions that fulfill the conditions of 137.225(1)(b) are eligible" ) assert expunger_result[b_felony_charge.ambiguous_charge_id].status is EligibilityStatus.ELIGIBLE assert expunger_result[b_felony_charge.ambiguous_charge_id].reason == "Eligible now"
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_misdemeanor_is_second_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.second_most_recent_conviction is self.mrc_charge
def build(): return { 'case': CaseFactory.create(), 'name': 'Theft of services', 'statute': '164.125', 'level': 'Misdemeanor Class A', 'date': '1/1/0001' }
def test_mrc_is_eligible_in_two_years(self): nine_year_old_conviction = ChargeFactory.create( disposition=DispositionCreator.create(ruling="Convicted", date=Time.NINE_YEARS_AGO)) one_year_old_conviction = ChargeFactory.create( disposition=DispositionCreator.create(ruling="Convicted", date=Time.ONE_YEAR_AGO)) eligibility_date = one_year_old_conviction.disposition.date + Time.THREE_YEARS case = CaseFactory.create( charges=tuple([one_year_old_conviction, nine_year_old_conviction])) record = Record(tuple([case])) expunger_result = Expunger.run(record) assert expunger_result[ one_year_old_conviction. ambiguous_charge_id].date_will_be_eligible == eligibility_date
def test_sort_by_case_date(): case1 = CaseFactory.create(case_number="1", date_location=["1/1/2018", "Multnomah"]) case2 = CaseFactory.create(case_number="2", date_location=["1/1/2019", "Multnomah"]) case3 = CaseFactory.create(case_number="3", date_location=["1/1/2020", "Multnomah"]) record = Record(tuple([case1, case2, case3])) assert record.cases[0].summary.case_number == "1" assert record.cases[1].summary.case_number == "2" assert record.cases[2].summary.case_number == "3" sorted_record = RecordCreator.sort_record_by_case_date(record) assert sorted_record.cases[0].summary.case_number == "3" assert sorted_record.cases[1].summary.case_number == "2" assert sorted_record.cases[2].summary.case_number == "1"
class TestDismissalBlock(unittest.TestCase): def setUp(self): self.case_1 = CaseFactory.create() self.case_2 = CaseFactory.create() self.recent_dismissal = ChargeFactory.create_dismissed_charge(case=self.case_1, date=Time.TWO_YEARS_AGO) self.case_1.charges = [self.recent_dismissal] 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 True 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_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 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_mrd_does_not_block_convictions(self): case = CaseFactory.create() convicted_charge = ChargeFactory.create(case=case, date=Time.TWENTY_YEARS_AGO, disposition=['Convicted', Time.TWENTY_YEARS_AGO]) case.charges = [convicted_charge] record = Record([self.case_1, case]) expunger = Expunger(record) expunger.run() assert convicted_charge.expungement_result.time_eligibility.status is True assert convicted_charge.expungement_result.time_eligibility.reason == '' assert convicted_charge.expungement_result.time_eligibility.date_will_be_eligible is None
def build(disposition=None): return { "case": CaseFactory.create(), "name": "Theft of services", "statute": "164.125", "level": "Misdemeanor Class A", "date": "1/1/0001", "disposition": disposition, }
def test_arrest_is_unaffected_if_conviction_eligibility_is_older(): violation_charge = ChargeFactory.create( level="Class A Violation", date=Time.TEN_YEARS_AGO, disposition=DispositionCreator.create( ruling="Convicted", date=Time.LESS_THAN_THREE_YEARS_AGO), ) arrest = ChargeFactory.create(disposition=DispositionCreator.create( ruling="Dismissed", date=Time.ONE_YEAR_AGO)) case = CaseFactory.create(charges=tuple([violation_charge, arrest])) expunger_result = Expunger.run(Record(tuple([case]))) assert expunger_result[ arrest.ambiguous_charge_id].status is EligibilityStatus.ELIGIBLE assert expunger_result[ arrest.ambiguous_charge_id].date_will_be_eligible == arrest.date assert expunger_result[arrest.ambiguous_charge_id].reason == "Eligible now"
def test_arrest_is_unaffected_if_conviction_eligibility_is_older(): violation_charge = ChargeFactory.create( level="Class A Violation", date=Time.TEN_YEARS_AGO, disposition=Disposition(ruling="Convicted", date=Time.LESS_THAN_THREE_YEARS_AGO), ) arrest = ChargeFactory.create( disposition=Disposition(ruling="Dismissed", date=Time.ONE_YEAR_AGO)) case = CaseFactory.create() case.charges = [violation_charge, arrest] expunger = Expunger(Record([case])) expunger.run() assert arrest.expungement_result.time_eligibility.status is EligibilityStatus.ELIGIBLE assert arrest.expungement_result.time_eligibility.date_will_be_eligible == arrest.date assert arrest.expungement_result.time_eligibility.reason == ""
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=DispositionCreator.create(ruling="Convicted", date=Time.ONE_YEAR_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 == "Never. Type ineligible charges are always time ineligible." ) assert expunger_result[charge.ambiguous_charge_id].date_will_be_eligible == date.max()
def default_dict(disposition=None): return { "case": CaseFactory.create(), "name": "Theft of services", "statute": "164.125", "level": "Misdemeanor Class A", "date": date_class(1901, 1, 1), "disposition": disposition, }
class TestJuvenileCharge(unittest.TestCase): def test_juvenile_charge(self): case = CaseFactory.create(type_status=["Juvenile Delinquency: Misdemeanor", "Closed"]) juvenile_charge = ChargeFactory.create(case=case, disposition=("Acquitted", date(2001, 1, 1))) assert juvenile_charge.__class__.__name__ == "JuvenileCharge" assert juvenile_charge.type_name == "Juvenile" assert juvenile_charge.expungement_result.type_eligibility.status is EligibilityStatus.NEEDS_MORE_ANALYSIS assert juvenile_charge.expungement_result.type_eligibility.reason == "Potentially eligible under 419A.262"
class TestJuvenileCharge(unittest.TestCase): def test_juvenile_charge(self): case = CaseFactory.create( type_status=['Juvenile Delinquency: Misdemeanor', 'Closed']) juvenile_charge = ChargeFactory.create(case=case) assert juvenile_charge.__class__.__name__ == 'JuvenileCharge' assert juvenile_charge.expungement_result.type_eligibility is None assert juvenile_charge.expungement_result.type_eligibility_reason == 'Juvenile Charge : Needs further analysis'
def test_3_violations_are_time_restricted(): violation_charge_1 = ChargeFactory.create( level="Class A Violation", date=Time.LESS_THAN_THREE_YEARS_AGO, disposition=DispositionCreator.create( ruling="Convicted", date=Time.LESS_THAN_THREE_YEARS_AGO), ) violation_charge_2 = ChargeFactory.create( level="Class A Violation", date=Time.TWO_YEARS_AGO, disposition=DispositionCreator.create(ruling="Convicted", date=Time.TWO_YEARS_AGO), ) violation_charge_3 = ChargeFactory.create( level="Class A Violation", date=Time.ONE_YEAR_AGO, disposition=DispositionCreator.create(ruling="Convicted", date=Time.ONE_YEAR_AGO), ) arrest = ChargeFactory.create(disposition=DispositionCreator.create( ruling="Dismissed", date=Time.ONE_YEAR_AGO)) case = CaseFactory.create(charges=tuple( [violation_charge_3, violation_charge_2, violation_charge_1, arrest])) expunger_result = Expunger.run(Record(tuple([case]))) earliest_date_eligible = min( expunger_result[ violation_charge_1.ambiguous_charge_id].date_will_be_eligible, expunger_result[ violation_charge_2.ambiguous_charge_id].date_will_be_eligible, expunger_result[ violation_charge_3.ambiguous_charge_id].date_will_be_eligible, ) assert expunger_result[ arrest.ambiguous_charge_id].status is EligibilityStatus.INELIGIBLE 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 == earliest_date_eligible
class TestSecondMRCLogic(unittest.TestCase): def setUp(self): self.expunger = ExpungerFactory.create() def run_expunger(self, mrc, second_mrc): case = CaseFactory.create() case.charges = [mrc, second_mrc] record = Record([case]) expunger = Expunger(record) expunger.run()
def test_record_summarizer_multiple_cases(): case_all_eligible = CaseFactory.create( case_number="0000", balance="100.00", date_location=["1/1/1995", "Multnomah"]) case_all_eligible.charges = [ ChargeFactory.create(case=case_all_eligible, name="Theft of dignity", disposition=["Convicted", Time.TEN_YEARS_AGO]) ]
def test_three_violations_with_oldest_violation_is_2mrc(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.second_most_recent_conviction is first_violation
def test_single_violation_is_time_restricted(): # A single violation doesn't block other records, but it is still subject to the 3 year rule. violation_charge = ChargeFactory.create( level="Class A Violation", date=Time.TEN_YEARS_AGO, disposition=DispositionCreator.create(ruling="Convicted", date=Time.LESS_THAN_ONE_YEAR_AGO), ) case = CaseFactory.create(charges=tuple([violation_charge])) expunger_result = Expunger.run(Record(tuple([case]))) assert expunger_result[violation_charge.ambiguous_charge_id].status is EligibilityStatus.INELIGIBLE assert ( expunger_result[violation_charge.ambiguous_charge_id].reason == "One year from date of conviction (137.225(1)(b))" ) assert expunger_result[violation_charge.ambiguous_charge_id].date_will_be_eligible == date.today() + relativedelta( days=+1 )