Beispiel #1
0
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_doubly_eligible_b_felony_gets_normal_eligibility_rule():
    # This charge is both ManufactureDelivery and also a class B felony. ManufactureDelivery classification takes precedence and the B felony time rule does not apply.
    manudel_charges = ChargeFactory.create_ambiguous_charge(
        case_number="1",
        name="Manufacture/Delivery 1",
        statute="4759922b",
        level="Felony Class B",
        date=Time.LESS_THAN_TWENTY_YEARS_AGO,
        disposition=DispositionCreator.create(ruling="Convicted", date=Time.LESS_THAN_TWENTY_YEARS_AGO),
    )
    manudel_type_eligilibility = RecordMerger.merge_type_eligibilities(manudel_charges)

    case_1a = CaseFactory.create(case_number="1", charges=tuple([manudel_charges[0]]))
    case_1b = CaseFactory.create(case_number="1", charges=tuple([manudel_charges[1]]))
    subsequent_charge = ChargeFactory.create(
        case_number="2",
        disposition=DispositionCreator.create(ruling="Convicted", date=Time.TEN_YEARS_AGO),
    )
    case_2 = CaseFactory.create(case_number="2", charges=tuple([subsequent_charge]))

    possible_record_1 = Record(tuple([case_1a, case_2]))
    possible_record_2 = Record(tuple([case_1b, case_2]))
    expunger_result_1 = Expunger.run(possible_record_1)
    expunger_result_2 = Expunger.run(possible_record_2)

    assert manudel_type_eligilibility.status is EligibilityStatus.ELIGIBLE
    assert expunger_result_1[manudel_charges[0].ambiguous_charge_id].status is EligibilityStatus.ELIGIBLE
    assert expunger_result_2[manudel_charges[1].ambiguous_charge_id].status is EligibilityStatus.ELIGIBLE
Beispiel #3
0
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"
Beispiel #4
0
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"  # 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"  # type: ignore
Beispiel #5
0
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"
Beispiel #6
0
def test_manufacture_delivery_manudel():
    charges = ChargeFactory.create_ambiguous_charge(
        name="Manu/Del Cntrld Sub-SC 1", statute="4759921B", level="Felony Class A", disposition=Dispositions.CONVICTED
    )
    type_eligibility = RecordMerger.merge_type_eligibilities(charges)

    assert type_eligibility.status is EligibilityStatus.NEEDS_MORE_ANALYSIS
    assert type_eligibility.reason == "Eligible under 137.226 ⬥ Ineligible by omission from statute"
Beispiel #7
0
def test_manufacture_delivery_dismissed():
    charges = ChargeFactory.create_ambiguous_charge(
        name="Manufacture/Delivery", statute="4759922b", level="Felony Class A", disposition=Dispositions.DISMISSED
    )
    type_eligibility = RecordMerger.merge_type_eligibilities(charges)

    assert type_eligibility.status is EligibilityStatus.ELIGIBLE
    assert type_eligibility.reason == "Dismissals are generally eligible under 137.225(1)(b)"
Beispiel #8
0
def test_ineligible():
    type_eligibility = TypeEligibility(EligibilityStatus.INELIGIBLE,
                                       "Ineligible under some statute")
    charge_eligibility = RecordMerger.compute_charge_eligibility(
        type_eligibility, [])

    assert charge_eligibility.status == ChargeEligibilityStatus.INELIGIBLE
    assert charge_eligibility.label == "Ineligible"
Beispiel #9
0
def test_type_eligible_but_time_eligibility_missing():
    type_eligibility = TypeEligibility(EligibilityStatus.ELIGIBLE,
                                       "Eligible under some statute")
    charge_eligibility = RecordMerger.compute_charge_eligibility(
        type_eligibility, [])

    assert charge_eligibility.status == ChargeEligibilityStatus.UNKNOWN
    assert charge_eligibility.label == "Possibly Eligible"
Beispiel #10
0
def test_possibly_type_eligible_but_time_eligibility_missing():
    type_eligibility = TypeEligibility(EligibilityStatus.NEEDS_MORE_ANALYSIS,
                                       "Unrecognized charge")
    charge_eligibility = RecordMerger.compute_charge_eligibility(
        type_eligibility, [])

    assert charge_eligibility.status == ChargeEligibilityStatus.UNKNOWN
    assert charge_eligibility.label == "Possibly Eligible"
Beispiel #11
0
def test_will_be_eligible():
    today = date.today()
    type_eligibility = TypeEligibility(EligibilityStatus.ELIGIBLE, "Eligible under some statute")
    time_eligibility = TimeEligibility(EligibilityStatus.INELIGIBLE, "Ineligible under some statute", today)
    charge_eligibility = RecordMerger.compute_charge_eligibility(type_eligibility, [time_eligibility])

    assert charge_eligibility.status == ChargeEligibilityStatus.WILL_BE_ELIGIBLE
    assert charge_eligibility.label == f"Eligible {today.strftime('%b %-d, %Y')}"
def test_duii_dismissed():
    charges = build_charges(statute="813.010", disposition_ruling="Acquitted")
    duii_type_eligibility = RecordMerger.merge_type_eligibilities(charges)

    assert duii_type_eligibility.status is EligibilityStatus.NEEDS_MORE_ANALYSIS
    assert (
        duii_type_eligibility.reason
        == "Diverted DUII – Ineligible under 137.225(8) OR Dismissed Criminal Charge – Dismissals are generally eligible under 137.225(1)(d)"
    )
Beispiel #13
0
def test_duii_diverted():
    charges = build_charges(statute="813.011", disposition_ruling="Diverted")
    duii_type_eligibility = RecordMerger.merge_type_eligibilities(charges)

    assert duii_type_eligibility.status is EligibilityStatus.NEEDS_MORE_ANALYSIS
    assert (
        duii_type_eligibility.reason ==
        "137.225(8)(b) - Diverted DUIIs are ineligible ⬥ Dismissals are generally eligible under 137.225(1)(b)"
    )
Beispiel #14
0
def test_will_be_eligible():
    type_eligibility = TypeEligibility(EligibilityStatus.ELIGIBLE, "Eligible under some statute")
    time_eligibility = TimeEligibility(
        EligibilityStatus.INELIGIBLE, "Ineligible under some statute", Time.ONE_YEARS_FROM_NOW
    )
    charge_eligibility = RecordMerger.compute_charge_eligibility(type_eligibility, [time_eligibility])

    assert charge_eligibility.status == ChargeEligibilityStatus.WILL_BE_ELIGIBLE
    assert charge_eligibility.label == f"Eligible {Time.ONE_YEARS_FROM_NOW.strftime('%b %-d, %Y')}"
Beispiel #15
0
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_manufacture_delivery_manudel_felony_c():
    charges = ChargeFactory.create_ambiguous_charge(
        name="Manu/Del Cntrld Sub-SC 1",
        statute="4759921B",
        level="Felony Class C",
        disposition=Dispositions.CONVICTED)
    type_eligibility = RecordMerger.merge_type_eligibilities(charges)

    assert type_eligibility.status is EligibilityStatus.ELIGIBLE
    assert type_eligibility.reason == "Felony Class C – Eligible under 137.225(1)(b)"
def test_pcs_class_c():
    charges = ChargeFactory.create_ambiguous_charge(
        name="PCS",
        statute="4759924A",
        level="Felony Class C",
        disposition=Dispositions.CONVICTED,
    )
    type_eligibility = RecordMerger.merge_type_eligibilities(charges)

    assert type_eligibility.status is EligibilityStatus.ELIGIBLE
    assert type_eligibility.reason == "Felony Class C – Eligible under 137.225(1)(b)"
def test_sex_crimes_with_romeo_and_juliet_exception(sex_crimes_statute):
    charges = ChargeFactory.create_ambiguous_charge(
        name="Generic",
        statute=sex_crimes_statute,
        level="Misdemeanor Class A",
        disposition=Dispositions.CONVICTED)
    type_eligibility = RecordMerger.merge_type_eligibilities(charges)
    assert isinstance(charges[0], Misdemeanor)
    assert isinstance(charges[1], RomeoAndJulietIneligibleSexCrime)
    assert type_eligibility.status is EligibilityStatus.NEEDS_MORE_ANALYSIS
    assert type_eligibility.reason == "Eligible under 137.225(5)(b) тме Failure to meet requirements under 163A.140(1)"
Beispiel #19
0
def test_manufacture_delivery_missing_disposition():
    charges = ChargeFactory.create_ambiguous_charge(
        name="Manufacture/Delivery", statute="4759922b", level="Felony Class A", disposition=None
    )
    type_eligibility = RecordMerger.merge_type_eligibilities(charges)

    assert type_eligibility.status is EligibilityStatus.NEEDS_MORE_ANALYSIS
    assert (
        type_eligibility.reason
        == "Always eligible under 137.226 (for convictions) or 137.225(1)(b) (for dismissals) ⬥ Disposition not found. Needs further analysis"
    )
 def analyze_ambiguous_record(ambiguous_record: AmbiguousRecord):
     charge_id_to_time_eligibilities = []
     for record in ambiguous_record:
         record.errors += ErrorChecker.check(record)  # TODO: Fix mutation
         expunger = Expunger(record)
         charge_id_to_time_eligibility = expunger.run()
         charge_id_to_time_eligibilities.append(
             charge_id_to_time_eligibility)
     record = RecordMerger.merge(ambiguous_record,
                                 charge_id_to_time_eligibilities)
     return record
Beispiel #21
0
def test_subsection_6_dismissed():
    charges = ChargeFactory.create_ambiguous_charge(
        name="Criminal mistreatment in the second degree",
        statute="163.200",
        level="Misdemeanor Class A",
        disposition=Dispositions.DISMISSED,
    )
    type_eligibility = RecordMerger.merge_type_eligibilities(charges)

    assert isinstance(charges[0], DismissedCharge)
    assert type_eligibility.status is EligibilityStatus.ELIGIBLE
    assert type_eligibility.reason == "Dismissals are generally eligible under 137.225(1)(b)"
def test_person_felony_class_b(person_felony_statute):
    charges = ChargeFactory.create_ambiguous_charge(
        name="Generic",
        statute=person_felony_statute,
        level="Felony Class B",
        disposition=Dispositions.CONVICTED)
    type_eligibility = RecordMerger.merge_type_eligibilities(charges)
    assert any([isinstance(charge, PersonFelonyClassB) for charge in charges])
    assert type_eligibility.status in [
        EligibilityStatus.NEEDS_MORE_ANALYSIS, EligibilityStatus.INELIGIBLE
    ]
    assert "Ineligible under 137.225(5)(a)" in type_eligibility.reason
Beispiel #23
0
def test_possibly_will_be_eligible():
    type_eligibility = TypeEligibility(EligibilityStatus.NEEDS_MORE_ANALYSIS, "Unrecognized charge")
    time_eligibility = TimeEligibility(
        EligibilityStatus.INELIGIBLE, "Ineligible for some reason", Time.ONE_YEARS_FROM_NOW
    )
    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_WILL_BE_ELIGIBLE
    assert charge_eligibility.label == f"Possibly Eligible {Time.ONE_YEARS_FROM_NOW.strftime('%b %-d, %Y')}"
Beispiel #24
0
def test_sex_crimes_with_romeo_and_juliet_exception(sex_crimes_statute):
    charges = ChargeFactory.create_ambiguous_charge(
        name="Generic", statute=sex_crimes_statute, level="Misdemeanor Class A", disposition=Dispositions.CONVICTED
    )
    type_eligibility = RecordMerger.merge_type_eligibilities(charges)
    assert isinstance(charges[0], RomeoAndJulietNMASexCrime)
    assert isinstance(charges[1], RomeoAndJulietIneligibleSexCrime)
    assert type_eligibility.status is EligibilityStatus.INELIGIBLE
    assert (
        type_eligibility.reason
        == "Possibly meets requirements under 137.225(6)(f) - Email [email protected] with subject line '6F' for free and confidential further analysis тме Fails to meet requirements under 137.225(6)(f)"
    )
Beispiel #25
0
 def disambiguate_record(ambiguous_record, questions_data):
     questions_as_list = [
         from_dict(data_class=Question, data=question)
         for id, question in questions_data.items()
     ]
     questions = dict(
         list(map(lambda q: (q.ambiguous_charge_id, q), questions_as_list)))
     updated_ambiguous_record = RecordMerger.filter_ambiguous_record(
         ambiguous_record, questions_as_list)
     record = RecordCreator.analyze_ambiguous_record(
         updated_ambiguous_record)
     return questions, record
Beispiel #26
0
def test_subsection_6_163165():
    charges = ChargeFactory.create_ambiguous_charge(
        name="Assault in the third degree",
        statute="163.165",
        level="Felony Class C",
        disposition=Dispositions.CONVICTED,
    )
    type_eligibility = RecordMerger.merge_type_eligibilities(charges)

    assert isinstance(charges[0], FelonyClassC)
    assert isinstance(charges[1], Subsection6)
    assert type_eligibility.status is EligibilityStatus.NEEDS_MORE_ANALYSIS
    assert type_eligibility.reason == "Eligible under 137.225(5)(b) ⬥ Ineligible under 137.225(6)"
Beispiel #27
0
def test_subsection_6_163200():
    charges = ChargeFactory.create_ambiguous_charge(
        name="Criminal mistreatment in the second degree",
        statute="163.200",
        level="Misdemeanor Class A",
        disposition=Dispositions.CONVICTED,
    )
    type_eligibility = RecordMerger.merge_type_eligibilities(charges)

    assert isinstance(charges[0], Subsection6)
    assert isinstance(charges[1], Misdemeanor)
    assert type_eligibility.status is EligibilityStatus.NEEDS_MORE_ANALYSIS
    assert type_eligibility.reason == "Ineligible under 137.225(6) ⬥ Eligible under 137.225(5)(b)"
def test_manufacture_delivery_manufacturing_name():
    charges = ChargeFactory.create_ambiguous_charge(
        name="MANUFACTURING CONTROLLED SUB",
        statute="4759921A",
        level="Felony Unclassified",
        disposition=Dispositions.CONVICTED,
    )
    type_eligibility = RecordMerger.merge_type_eligibilities(charges)

    assert type_eligibility.status is EligibilityStatus.NEEDS_MORE_ANALYSIS
    assert (
        type_eligibility.reason ==
        "Marijuana Manufacture Delivery – Eligible under 137.226 OR Felony Class A – Ineligible by omission from statute OR Felony Class B – Convictions that fulfill the conditions of 137.225(1)(b) are eligible OR Felony Class C – Eligible under 137.225(1)(b)"
    )
def test_manufacture_delivery_unrecognized_disposition():
    charges = ChargeFactory.create_ambiguous_charge(
        name="Manufacture/Delivery",
        statute="4759922b",
        level="Felony Class B",
        disposition=Dispositions.UNRECOGNIZED_DISPOSITION,
    )
    type_eligibility = RecordMerger.merge_type_eligibilities(charges)

    assert type_eligibility.status is EligibilityStatus.NEEDS_MORE_ANALYSIS
    assert (
        type_eligibility.reason ==
        "Marijuana Manufacture Delivery – Always eligible under 137.226 (for convictions) or 137.225(1)(d) (for dismissals) OR Felony Class B – Disposition not recognized. Needs further analysis"
    )
def test_pcs_heroin():
    charges = ChargeFactory.create_ambiguous_charge(
        name="POSS CONTROLLED SUB HEROIN",
        statute="4757521A",
        level="Felony Unclassified",
        disposition=Dispositions.CONVICTED,
    )
    type_eligibility = RecordMerger.merge_type_eligibilities(charges)

    assert type_eligibility.status is EligibilityStatus.ELIGIBLE
    assert (
        type_eligibility.reason ==
        "Felony Class B – Convictions that fulfill the conditions of 137.225(1)(b) are eligible OR Felony Class C – Eligible under 137.225(1)(b)"
    )