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
    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'
Exemple #3
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']
Exemple #4
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_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
Exemple #6
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_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
Exemple #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
    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
Exemple #11
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."""
    )
    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_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_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
Exemple #16
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
Exemple #17
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
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 == ""
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
Exemple #20
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
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
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()
Exemple #23
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
class TestExpungementAnalyzerUnitTests(unittest.TestCase):

    def test_expunger_sets_most_recent_dismissal_when_charge_is_less_than_3yrs(self):
        case = CaseFactory.create()
        mrd_charge = ChargeFactory.create_dismissed_charge(date=Time.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
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
Exemple #26
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
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
class TestSingleChargeAcquittals(unittest.TestCase):
    def setUp(self):
        self.expunger = ExpungerFactory.create()

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

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

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

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

        expunger.run()
        assert arrest.expungement_result.time_eligibility.status is EligibilityStatus.ELIGIBLE
        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
 def create():
     return Expunger(Record([]))
def test_round_trip_various_records(record):
    expunger = Expunger(record)
    expunger.run()
    json.loads(json.dumps(record, cls=ExpungeModelEncoder))