def test_associatePeriodsWithSentence_doNotMovePlaceholderPeriods(self): # Arrange placeholder_sp = StateSupervisionPeriod.new_with_defaults() placeholder_ip = StateIncarcerationPeriod.new_with_defaults() inc_s_2 = StateIncarcerationSentence.new_with_defaults( external_id=_EXTERNAL_ID, start_date=_DATE_1, completion_date=_DATE_8) inc_s = StateIncarcerationSentence.new_with_defaults( external_id=_EXTERNAL_ID_2, start_date=_DATE_1, completion_date=_DATE_8, incarceration_periods=[placeholder_ip], supervision_periods=[placeholder_sp]) sg = StateSentenceGroup.new_with_defaults( incarceration_sentences=[inc_s, inc_s_2]) state_person = StatePerson.new_with_defaults(sentence_groups=[sg]) # Should remain unchanged - placeholder period should not get attached to any other sentences expected_person = attr.evolve(state_person) # Act input_people = converter.convert_entity_people_to_schema_people( [state_person]) move_periods_onto_sentences_by_date(input_people) # Assert self.assert_people_match([expected_person], input_people)
def test_associateSvrsWithIps_dontAssociateTheSameSvr(self): # Arrange svr_1 = StateSupervisionViolationResponse.new_with_defaults( response_date=_DATE_1, revocation_type=StateSupervisionViolationResponseRevocationType. REINCARCERATION) placeholder_sv = StateSupervisionViolation.new_with_defaults( supervision_violation_responses=[svr_1]) placeholder_sp = StateSupervisionPeriod.new_with_defaults( supervision_violation_entries=[placeholder_sv]) placeholder_ss = StateSupervisionSentence.new_with_defaults( supervision_periods=[placeholder_sp]) ip_1 = StateIncarcerationPeriod.new_with_defaults( admission_date=_DATE_2, admission_reason=StateIncarcerationPeriodAdmissionReason. PROBATION_REVOCATION) ip_2 = StateIncarcerationPeriod.new_with_defaults( admission_date=_DATE_4, admission_reason=StateIncarcerationPeriodAdmissionReason. PROBATION_REVOCATION) placeholder_is = StateIncarcerationSentence.new_with_defaults( incarceration_periods=[ip_1, ip_2]) placeholder_sg = StateSentenceGroup.new_with_defaults( incarceration_sentences=[placeholder_is], supervision_sentences=[placeholder_ss]) placeholder_person = StatePerson.new_with_defaults( sentence_groups=[placeholder_sg]) expected_svr_1 = attr.evolve(svr_1) expected_placeholder_sv = attr.evolve( placeholder_sv, supervision_violation_responses=[expected_svr_1]) expected_placeholder_sp = attr.evolve( placeholder_sp, supervision_violation_entries=[expected_placeholder_sv]) expected_placeholder_ss = attr.evolve( placeholder_ss, supervision_periods=[expected_placeholder_sp]) expected_ip_1 = attr.evolve( ip_1, source_supervision_violation_response=expected_svr_1) expected_ip_2 = attr.evolve(ip_2) expected_placeholder_is = attr.evolve( placeholder_is, incarceration_periods=[expected_ip_1, expected_ip_2]) expected_placeholder_sg = attr.evolve( placeholder_sg, supervision_sentences=[expected_placeholder_ss], incarceration_sentences=[expected_placeholder_is]) expected_placeholder_person = attr.evolve( placeholder_person, sentence_groups=[expected_placeholder_sg]) # Act input_people = \ converter.convert_entity_people_to_schema_people( [placeholder_person]) associate_revocation_svrs_with_ips(input_people) # Assert self.assert_people_match([expected_placeholder_person], input_people)
def test_associatePeriodsWithSentence_doNotMatchSentenceWithNoStart(self): # Arrange placeholder_sp = StateSupervisionPeriod.new_with_defaults() sp = StateSupervisionPeriod.new_with_defaults( external_id=_EXTERNAL_ID_3, start_date=_DATE_2, termination_date=_DATE_3) ip = StateIncarcerationPeriod.new_with_defaults( external_id=_EXTERNAL_ID_3, admission_date=_DATE_2, release_date=_DATE_3) inc_s_no_dates = StateIncarcerationSentence.new_with_defaults( external_id=_EXTERNAL_ID, supervision_periods=[placeholder_sp]) placeholder_inc_s = StateIncarcerationSentence.new_with_defaults( incarceration_periods=[ip], supervision_periods=[sp]) sg = StateSentenceGroup.new_with_defaults( incarceration_sentences=[inc_s_no_dates, placeholder_inc_s]) state_person = StatePerson.new_with_defaults(sentence_groups=[sg]) # Should remain unchanged - the non-placeholder period should not get moved onto sentence with an id # but no start date expected_person = attr.evolve(state_person) # Act input_people = converter.convert_entity_people_to_schema_people( [state_person]) move_periods_onto_sentences_by_date(input_people) # Assert self.assert_people_match([expected_person], input_people)
def test_associatePeriodsWithSentence_periodNoLongerMatches(self): # Arrange sp_which_no_longer_overlaps = StateSupervisionPeriod.new_with_defaults( supervision_period_id=_ID, external_id=_EXTERNAL_ID, state_code=_STATE_CODE, start_date=_DATE_6) ip_which_no_longer_overlaps = StateIncarcerationPeriod.new_with_defaults( incarceration_period_id=_ID, external_id=_EXTERNAL_ID, state_code=_STATE_CODE, admission_date=_DATE_6) # This sentence, which has already been written to the DB, has presumably been updated so that the date range no # longer overlaps with the attached periods. inc_s_updated_dates = StateIncarcerationSentence.new_with_defaults( incarceration_sentence_id=_ID_2, external_id=_EXTERNAL_ID, state_code=_STATE_CODE, start_date=_DATE_3, completion_date=_DATE_5, incarceration_periods=[ip_which_no_longer_overlaps], supervision_periods=[sp_which_no_longer_overlaps]) sg = StateSentenceGroup.new_with_defaults( sentence_group_id=_ID_3, state_code=_STATE_CODE, incarceration_sentences=[inc_s_updated_dates]) state_person = StatePerson.new_with_defaults(person_id=_ID, sentence_groups=[sg]) expected_sp = attr.evolve(sp_which_no_longer_overlaps) expected_ip = attr.evolve(ip_which_no_longer_overlaps) expected_is = attr.evolve(inc_s_updated_dates, incarceration_periods=[], supervision_periods=[]) # We expect that a new placeholder supervision sentence has been created to hold on to the orphaned periods expected_placeholder_ss = StateSupervisionSentence.new_with_defaults( state_code=_STATE_CODE, status=StateSentenceStatus.PRESENT_WITHOUT_INFO, incarceration_periods=[expected_ip], supervision_periods=[expected_sp]) expected_sg = attr.evolve( sg, incarceration_sentences=[expected_is], supervision_sentences=[expected_placeholder_ss]) expected_person = attr.evolve(state_person, sentence_groups=[expected_sg]) # Act input_people = converter.convert_entity_people_to_schema_people( [state_person]) move_periods_onto_sentences_by_date(input_people) # Assert self.assert_people_match([expected_person], input_people)
def test_associatedSupervisionPeriodsWithSentences(self): # Arrange sp_no_match = StateSupervisionPeriod.new_with_defaults( external_id=_EXTERNAL_ID, start_date=_DATE, termination_date=_DATE_2) sp_1 = StateSupervisionPeriod.new_with_defaults( external_id=_EXTERNAL_ID, start_date=_DATE_4, termination_date=_DATE_6) sp_2 = StateSupervisionPeriod.new_with_defaults( external_id=_EXTERNAL_ID_2, start_date=_DATE_6, termination_date=None) placeholder_ss = StateSupervisionSentence.new_with_defaults( supervision_periods=[sp_no_match, sp_1, sp_2]) ss = StateSupervisionSentence.new_with_defaults( external_id=_EXTERNAL_ID, start_date=_DATE_4, completion_date=None) inc_s = StateIncarcerationSentence.new_with_defaults( external_id=_EXTERNAL_ID, start_date=_DATE_3, completion_date=_DATE_5) sg = StateSentenceGroup.new_with_defaults( incarceration_sentences=[inc_s], supervision_sentences=[ss, placeholder_ss]) state_person = StatePerson.new_with_defaults(sentence_groups=[sg]) expected_sp_1 = attr.evolve(sp_1) expected_sp_2 = attr.evolve(sp_2) expected_placeholder_ss = attr.evolve( placeholder_ss, supervision_periods=[sp_no_match]) expected_inc_s = attr.evolve(inc_s, supervision_periods=[expected_sp_1]) expected_ss = attr.evolve( ss, supervision_periods=[expected_sp_1, expected_sp_2]) expected_sg = attr.evolve( sg, supervision_sentences=[expected_ss, expected_placeholder_ss], incarceration_sentences=[expected_inc_s]) expected_person = attr.evolve(state_person, sentence_groups=[expected_sg]) # Act input_people = \ converter.convert_entity_people_to_schema_people( [state_person]) move_supervision_periods_onto_sentences_by_date(input_people) # Assert self.assert_people_match([expected_person], input_people)
def assert_people_match(self, expected_people: List[StatePerson], matched_people: List[schema.StatePerson]): converted_matched = \ converter.convert_schema_objects_to_entity(matched_people) db_expected_with_backedges = \ converter.convert_entity_people_to_schema_people(expected_people) expected_with_backedges = \ converter.convert_schema_objects_to_entity( db_expected_with_backedges) self.assertEqual(expected_with_backedges, converted_matched)
def test_associatedPeriodsWithSentences_doNotAssociateToClosedButUnterminatedSentences( self): # Arrange sp_1 = StateSupervisionPeriod.new_with_defaults( external_id=_EXTERNAL_ID, start_date=_DATE_6, termination_date=None) ip_1 = StateIncarcerationPeriod.new_with_defaults( external_id=_EXTERNAL_ID, admission_date=_DATE_6, release_date=None) placeholder_ss = StateSupervisionSentence.new_with_defaults( supervision_periods=[sp_1], incarceration_periods=[ip_1]) ss = StateSupervisionSentence.new_with_defaults( external_id=_EXTERNAL_ID, status=StateSentenceStatus.COMPLETED, start_date=_DATE_4, completion_date=None) inc_s = StateIncarcerationSentence.new_with_defaults( external_id=_EXTERNAL_ID, status=StateSentenceStatus.COMPLETED, start_date=_DATE_4, completion_date=None) sg = StateSentenceGroup.new_with_defaults( incarceration_sentences=[inc_s], supervision_sentences=[ss, placeholder_ss]) state_person = StatePerson.new_with_defaults(sentence_groups=[sg]) expected_sp_1 = attr.evolve(sp_1) expected_ip_1 = attr.evolve(ip_1) expected_placeholder_ss = attr.evolve( placeholder_ss, supervision_periods=[expected_sp_1], incarceration_periods=[expected_ip_1]) expected_inc_s = attr.evolve(inc_s) expected_ss = attr.evolve(ss) expected_sg = attr.evolve( sg, supervision_sentences=[expected_ss, expected_placeholder_ss], incarceration_sentences=[expected_inc_s]) expected_person = attr.evolve(state_person, sentence_groups=[expected_sg]) # Act input_people = converter.convert_entity_people_to_schema_people( [state_person]) move_periods_onto_sentences_by_date(input_people) # Assert self.assert_people_match([expected_person], input_people)
def test_associateViolationsWithSupervisionPeriodsWhereViolationNoLongerOverlaps( self): # Act sv_ss = StateSupervisionViolation.new_with_defaults( supervision_violation_id=_ID, state_code=_STATE_CODE, violation_date=_DATE_4) # This supervision period, which has already been written to the DB, has presumably been updated so that the # date range no longer overlaps with the attached violation (or the violation has been updated). sp_ss = StateSupervisionPeriod.new_with_defaults( supervision_period_id=_ID, external_id=_EXTERNAL_ID, state_code=_STATE_CODE, start_date=_DATE, termination_date=_DATE_3, supervision_violation_entries=[sv_ss]) ss = StateSupervisionSentence.new_with_defaults( supervision_sentence_id=_ID, external_id=_EXTERNAL_ID, state_code=_STATE_CODE, supervision_periods=[sp_ss]) sg = StateSentenceGroup.new_with_defaults(sentence_group_id=_ID, state_code=_STATE_CODE, supervision_sentences=[ss]) state_person = StatePerson.new_with_defaults(person_id=_ID, sentence_groups=[sg]) expected_sv_ss = attr.evolve(sv_ss) expected_sp_ss = attr.evolve(sp_ss, supervision_violation_entries=[]) expected_placeholder_sp_ss = StateSupervisionPeriod.new_with_defaults( state_code=_STATE_CODE, status=StateSupervisionPeriodStatus.PRESENT_WITHOUT_INFO, supervision_violation_entries=[expected_sv_ss]) expected_ss = attr.evolve( ss, supervision_periods=[expected_placeholder_sp_ss, expected_sp_ss]) expected_sg = attr.evolve(sg, supervision_sentences=[expected_ss]) expected_person = attr.evolve(state_person, sentence_groups=[expected_sg]) # Act input_people = \ converter.convert_entity_people_to_schema_people( [state_person]) move_violations_onto_supervision_periods_by_date(input_people) # Assert self.assert_people_match([expected_person], input_people)
def assert_people_match(self, expected_people: List[StatePerson], matched_people: List[schema.StatePerson], debug: bool = False): converted_matched = converter.convert_schema_objects_to_entity( matched_people) db_expected_with_backedges = converter.convert_entity_people_to_schema_people( expected_people) expected_with_backedges = converter.convert_schema_objects_to_entity( db_expected_with_backedges) if debug: print_visible_header_label('EXPECTED') print_entity_trees(expected_with_backedges) print_visible_header_label('FINAL') print_entity_trees(converted_matched) self.assertEqual(expected_with_backedges, converted_matched)
def infer_release_on_open_bookings(region_code: str, last_ingest_time: datetime.datetime, custody_status: CustodyStatus) -> None: """ Look up all open bookings whose last_seen_time is earlier than the provided last_ingest_time in the provided region, update those bookings to have an inferred release date equal to the provided last_ingest_time. Args: region_code: the region_code last_ingest_time: The last time complete data was ingested for this region. In the normal ingest pipeline, this is the last start time of a background scrape for the region. custody_status: The custody status to be marked on the found open bookings. Defaults to INFERRED_RELEASE """ session = SessionFactory.for_schema_base(JailsBase) try: logging.info("Reading all bookings that happened before [%s]", last_ingest_time) people = county_dao.read_people_with_open_bookings_scraped_before_time( session, region_code, last_ingest_time) logging.info( "Found [%s] people with bookings that will be inferred released", len(people), ) for person in people: persistence_utils.remove_pii_for_person(person) _infer_release_date_for_bookings(person.bookings, last_ingest_time, custody_status) db_people = converter.convert_entity_people_to_schema_people(people) database.write_people( session, db_people, IngestMetadata(region=region_code, jurisdiction_id="", ingest_time=last_ingest_time), ) session.commit() except Exception: session.rollback() raise finally: session.close()
def _assert_people_match( self, expected_people, matched_people, debug=False): converted_matched = \ converter.convert_schema_objects_to_entity(matched_people) db_expected_with_backedges = \ converter.convert_entity_people_to_schema_people(expected_people) expected_with_backedges = \ converter.convert_schema_objects_to_entity( db_expected_with_backedges) clear_db_ids(converted_matched) clear_db_ids(expected_with_backedges) if debug: print('============== EXPECTED WITH BACKEDGES ==============') print_entity_trees(expected_with_backedges) print('============== CONVERTED MATCHED ==============') print_entity_trees(converted_matched) self.assertCountEqual(expected_with_backedges, converted_matched)
def assert_people_match(self, expected_people: List[StatePerson], matched_people: List[schema.StatePerson], debug: bool = True): converted_matched = \ converter.convert_schema_objects_to_entity(matched_people) db_expected_with_backedges = \ converter.convert_entity_people_to_schema_people(expected_people) expected_with_backedges = \ converter.convert_schema_objects_to_entity( db_expected_with_backedges) if debug: print('============== EXPECTED WITH BACKEDGES ==============') print_entity_trees(expected_with_backedges) print('============== CONVERTED MATCHED ==============') print_entity_trees(converted_matched) self.assertCountEqual(expected_with_backedges, converted_matched)
def match_people_and_return_error_count( *, db_people: List[entities.Person], ingested_people: List[entities.Person]) -> MatchedEntities: """ Attempts to match all people from |ingested_people| with people from the |db_people|. Returns an MatchedEntities object that contains the results of matching. """ people = [] orphaned_entities = [] error_count = 0 matched_people_by_db_id: Dict[int, entities.Person] = {} for ingested_person in ingested_people: try: ingested_person_orphans: List[Entity] = [] match_person( ingested_person=ingested_person, db_people=db_people, orphaned_entities=ingested_person_orphans, matched_people_by_db_id=matched_people_by_db_id, ) people.append(ingested_person) orphaned_entities.extend(ingested_person_orphans) except EntityMatchingError as e: logging.exception( "Found %s while matching ingested person. \nPerson: %s", e.__class__.__name__, ingested_person, ) increment_error(e.entity_name) error_count += 1 schema_people = converter.convert_entity_people_to_schema_people(people) schema_orphaned_entities = converter.convert_entities_to_schema( orphaned_entities) return MatchedEntities( people=schema_people, orphaned_entities=schema_orphaned_entities, error_count=error_count, )
def test_associatedPeriodsWithSentences_oneDayPeriodOverlapsWithStartOfSentence( self): sp = StateSupervisionPeriod.new_with_defaults(external_id=_EXTERNAL_ID, start_date=_DATE_2, termination_date=_DATE_2) placeholder_ss = StateSupervisionSentence.new_with_defaults( supervision_periods=[sp]) ss = StateSupervisionSentence.new_with_defaults( external_id=_EXTERNAL_ID, start_date=_DATE_2, completion_date=_DATE_3, status=StateSentenceStatus.SERVING) sg = StateSentenceGroup.new_with_defaults( supervision_sentences=[ss, placeholder_ss]) state_person = StatePerson.new_with_defaults(sentence_groups=[sg]) expected_sp = attr.evolve(sp) expected_placeholder_ss = attr.evolve(placeholder_ss, supervision_periods=[], incarceration_periods=[]) expected_ss = attr.evolve(ss, supervision_periods=[expected_sp]) expected_sg = attr.evolve( sg, supervision_sentences=[expected_ss, expected_placeholder_ss]) expected_person = attr.evolve(state_person, sentence_groups=[expected_sg]) # Act input_people = converter.convert_entity_people_to_schema_people( [state_person]) move_periods_onto_sentences_by_date(input_people) # Assert self.assert_people_match([expected_person], input_people)
def test_associateSvrsWithIps(self): # Arrange ip_1 = StateIncarcerationPeriod.new_with_defaults( admission_date=_DATE_1, admission_reason= StateIncarcerationPeriodAdmissionReason.PROBATION_REVOCATION) ip_2 = StateIncarcerationPeriod.new_with_defaults( admission_date=_DATE_2, admission_reason= StateIncarcerationPeriodAdmissionReason.PROBATION_REVOCATION) placeholder_is = StateIncarcerationSentence.new_with_defaults( incarceration_periods=[ip_1, ip_2]) svr_1 = StateSupervisionViolationResponse.new_with_defaults( response_date=_DATE_1 - datetime.timedelta(days=1), revocation_type=StateSupervisionViolationResponseRevocationType. REINCARCERATION) svr_2 = StateSupervisionViolationResponse.new_with_defaults( response_date=_DATE_2 + datetime.timedelta(days=1), revocation_type=StateSupervisionViolationResponseRevocationType. REINCARCERATION) svr_3 = StateSupervisionViolationResponse.new_with_defaults( response_date=_DATE_2 + datetime.timedelta(days=30), revocation_type=StateSupervisionViolationResponseRevocationType. RETURN_TO_SUPERVISION) placeholder_sv = StateSupervisionViolation.new_with_defaults( supervision_violation_responses=[svr_1, svr_2, svr_3]) placeholder_sp = StateSupervisionPeriod.new_with_defaults( supervision_violation_entries=[placeholder_sv]) placeholder_ss = StateSupervisionSentence.new_with_defaults( supervision_periods=[placeholder_sp]) placeholder_sg = StateSentenceGroup.new_with_defaults( incarceration_sentences=[placeholder_is], supervision_sentences=[placeholder_ss]) placeholder_person = StatePerson.new_with_defaults( sentence_groups=[placeholder_sg]) external_id = StatePersonExternalId.new_with_defaults( external_id=_EXTERNAL_ID) person_without_revocation = StatePerson.new_with_defaults( external_ids=[external_id]) expected_svr_1 = attr.evolve(svr_1) expected_svr_2 = attr.evolve(svr_2) expected_svr_3 = attr.evolve(svr_3) expected_placeholder_sv = attr.evolve( placeholder_sv, supervision_violation_responses=[expected_svr_1, expected_svr_2, expected_svr_3]) expected_placeholder_sp = attr.evolve( placeholder_sp, supervision_violation_entries=[expected_placeholder_sv]) expected_placeholder_ss = attr.evolve( placeholder_ss, supervision_periods=[expected_placeholder_sp]) expected_ip_1 = attr.evolve( ip_1, source_supervision_violation_response=expected_svr_1) expected_ip_2 = attr.evolve( ip_2, source_supervision_violation_response=expected_svr_2) expected_placeholder_is = attr.evolve( placeholder_is, incarceration_periods=[expected_ip_1, expected_ip_2]) expected_placeholder_sg = attr.evolve( placeholder_sg, supervision_sentences=[expected_placeholder_ss], incarceration_sentences=[expected_placeholder_is]) expected_placeholder_person = attr.evolve( placeholder_person, sentence_groups=[expected_placeholder_sg]) expected_person_without_revocation = attr.evolve( person_without_revocation) # Act input_people = \ converter.convert_entity_people_to_schema_people( [person_without_revocation, placeholder_person]) associate_revocation_svrs_with_ips(input_people) # Assert self.assert_people_match( [expected_person_without_revocation, expected_placeholder_person], input_people)
def test_moveContactsOntoSupervisionPeriodsForPerson(self): self.maxDiff = None # Arrange sc_1 = StateSupervisionContact.new_with_defaults(contact_date=_DATE_2) sc_2 = StateSupervisionContact.new_with_defaults(contact_date=_DATE_3) sc_3 = StateSupervisionContact.new_with_defaults(contact_date=_DATE_8) placeholder_sp_ss = StateSupervisionPeriod.new_with_defaults( supervision_contacts=[sc_1, sc_3]) sp_ss = StateSupervisionPeriod.new_with_defaults( external_id=_EXTERNAL_ID, start_date=_DATE_1, termination_date=_DATE_3) sp_2_ss = StateSupervisionPeriod.new_with_defaults( external_id=_EXTERNAL_ID_2, start_date=_DATE_7) ss = StateSupervisionSentence.new_with_defaults( external_id=_EXTERNAL_ID, supervision_periods=[sp_ss, sp_2_ss, placeholder_sp_ss]) placeholder_sp_is = StateSupervisionPeriod.new_with_defaults( supervision_contacts=[sc_2, sc_3]) sp_is = StateSupervisionPeriod.new_with_defaults( external_id=_EXTERNAL_ID_3, start_date=_DATE_2, termination_date=_DATE_3) sp_2_is = StateSupervisionPeriod.new_with_defaults( external_id=_EXTERNAL_ID_4, start_date=_DATE_3, termination_date=_DATE_6) inc_s = StateIncarcerationSentence.new_with_defaults( external_id=_EXTERNAL_ID, supervision_periods=[sp_is, sp_2_is, placeholder_sp_is]) sg = StateSentenceGroup.new_with_defaults( incarceration_sentences=[inc_s]) sg_2 = StateSentenceGroup.new_with_defaults(supervision_sentences=[ss]) state_person = StatePerson.new_with_defaults( sentence_groups=[sg, sg_2]) expected_sc_1 = attr.evolve(sc_1) expected_sc_2 = attr.evolve(sc_2) expected_sc_3 = attr.evolve(sc_3) expected_placeholder_sp_ss = attr.evolve(placeholder_sp_ss, supervision_contacts=[]) expected_sp_ss = attr.evolve(sp_ss, supervision_contacts=[expected_sc_1]) expected_sp_2_ss = attr.evolve(sp_2_ss, supervision_contacts=[expected_sc_3]) expected_ss = attr.evolve(ss, supervision_periods=[ expected_placeholder_sp_ss, expected_sp_ss, expected_sp_2_ss ]) expected_placeholder_sp_is = attr.evolve(placeholder_sp_is, supervision_contacts=[]) expected_sp_is = attr.evolve(sp_is, supervision_contacts=[expected_sc_1]) expected_sp_2_is = attr.evolve(sp_2_is, supervision_contacts=[expected_sc_2]) expected_inc_s = attr.evolve(inc_s, supervision_periods=[ expected_placeholder_sp_is, expected_sp_is, expected_sp_2_is ]) expected_sg = attr.evolve(sg, incarceration_sentences=[expected_inc_s]) expected_sg_2 = attr.evolve(sg_2, supervision_sentences=[expected_ss]) expected_person = attr.evolve( state_person, sentence_groups=[expected_sg, expected_sg_2]) # Act input_people = converter.convert_entity_people_to_schema_people( [state_person]) move_contacts_onto_supervision_periods_for_person( input_people, _STATE_CODE) # Assert self.assert_people_match([expected_person], input_people)
def test_inferReleaseDateOnOpenBookings(self): # Arrange hold = county_entities.Hold.new_with_defaults(hold_id=ID, status=HoldStatus.ACTIVE, status_raw_text='ACTIVE') sentence = county_entities.Sentence.new_with_defaults( sentence_id=ID, status=SentenceStatus.SERVING, status_raw_text='SERVING', booking_id=ID) bond = county_entities.Bond.new_with_defaults( bond_id=ID, status=BondStatus.SET, status_raw_text='NOT_REQUIRED', booking_id=ID) charge = county_entities.Charge.new_with_defaults( charge_id=ID, status=ChargeStatus.PENDING, status_raw_text='PENDING', sentence=sentence, bond=bond) booking_open = county_entities.Booking.new_with_defaults( booking_id=ID, custody_status=CustodyStatus.IN_CUSTODY, custody_status_raw_text='IN CUSTODY', admission_date=DATE, last_seen_time=SCRAPER_START_DATETIME - timedelta(days=1), first_seen_time=SCRAPER_START_DATETIME - timedelta(days=1), charges=[charge], holds=[hold]) booking_resolved = attr.evolve(booking_open, booking_id=ID_2, custody_status=CustodyStatus.RELEASED, custody_status_raw_text='RELEASED', release_date=DATE_2, charges=[], holds=[]) booking_open_most_recent_scrape = attr.evolve( booking_open, booking_id=ID_3, last_seen_time=SCRAPER_START_DATETIME, charges=[], holds=[]) person = county_entities.Person.new_with_defaults( person_id=ID, region=REGION_1, jurisdiction_id=JURISDICTION_ID, bookings=[booking_open, booking_resolved]) person_unmatched = county_entities.Person.new_with_defaults( person_id=ID_2, region=REGION_1, jurisdiction_id=JURISDICTION_ID, bookings=[booking_open_most_recent_scrape]) session = SessionFactory.for_schema_base(JailsBase) database.write_people( session, converter.convert_entity_people_to_schema_people( [person, person_unmatched]), DEFAULT_METADATA) session.commit() session.close() expected_hold = attr.evolve(hold, status=HoldStatus.REMOVED_WITHOUT_INFO, status_raw_text=None) expected_sentence = attr.evolve( sentence, status=SentenceStatus.REMOVED_WITHOUT_INFO, status_raw_text=None) expected_bond = attr.evolve(bond, status=BondStatus.REMOVED_WITHOUT_INFO, status_raw_text=None) expected_charge = attr.evolve(charge, status=ChargeStatus.REMOVED_WITHOUT_INFO, status_raw_text=None, bond=expected_bond, sentence=expected_sentence) expected_resolved_booking = attr.evolve( booking_open, custody_status=CustodyStatus.INFERRED_RELEASE, custody_status_raw_text=None, release_date=SCRAPER_START_DATETIME.date(), release_date_inferred=True, charges=[expected_charge], holds=[expected_hold]) expected_person = attr.evolve( person, bookings=[expected_resolved_booking, booking_resolved]) # Act persistence.infer_release_on_open_bookings( REGION_1, SCRAPER_START_DATETIME, CustodyStatus.INFERRED_RELEASE) # Assert people = county_dao.read_people( SessionFactory.for_schema_base(JailsBase)) self.assertCountEqual(people, [expected_person, person_unmatched])
def test_associateSvrsWithIps_within90Days(self) -> None: # Arrange svr_1 = StateSupervisionViolationResponse.new_with_defaults( state_code=_STATE_CODE, response_date=_DATE_2 + datetime.timedelta(days=1), revocation_type=StateSupervisionViolationResponseRevocationType. REINCARCERATION, ) svr_2 = StateSupervisionViolationResponse.new_with_defaults( state_code=_STATE_CODE, response_date=_DATE_4 + datetime.timedelta(days=100), revocation_type=StateSupervisionViolationResponseRevocationType. RETURN_TO_SUPERVISION, ) placeholder_sv = StateSupervisionViolation.new_with_defaults( state_code=_STATE_CODE, supervision_violation_responses=[svr_1, svr_2]) placeholder_sp = StateSupervisionPeriod.new_with_defaults( state_code=_STATE_CODE, supervision_violation_entries=[placeholder_sv], status=StateSupervisionPeriodStatus.PRESENT_WITHOUT_INFO, ) placeholder_ss = StateSupervisionSentence.new_with_defaults( state_code=_STATE_CODE, supervision_periods=[placeholder_sp], status=StateSentenceStatus.PRESENT_WITHOUT_INFO, ) ip_1 = StateIncarcerationPeriod.new_with_defaults( state_code=_STATE_CODE, admission_date=_DATE_2, admission_reason=StateIncarcerationPeriodAdmissionReason. PROBATION_REVOCATION, status=StateIncarcerationPeriodStatus.PRESENT_WITHOUT_INFO, ) ip_2 = StateIncarcerationPeriod.new_with_defaults( state_code=_STATE_CODE, admission_date=_DATE_4, admission_reason=StateIncarcerationPeriodAdmissionReason. PROBATION_REVOCATION, status=StateIncarcerationPeriodStatus.PRESENT_WITHOUT_INFO, ) placeholder_is = StateIncarcerationSentence.new_with_defaults( state_code=_STATE_CODE, incarceration_periods=[ip_1, ip_2], status=StateSentenceStatus.PRESENT_WITHOUT_INFO, ) placeholder_sg = StateSentenceGroup.new_with_defaults( state_code=_STATE_CODE, status=StateSentenceStatus.PRESENT_WITHOUT_INFO, incarceration_sentences=[placeholder_is], supervision_sentences=[placeholder_ss], ) placeholder_person = StatePerson.new_with_defaults( state_code=_STATE_CODE, sentence_groups=[placeholder_sg]) expected_svr_1 = attr.evolve(svr_1) expected_svr_2 = attr.evolve(svr_2) expected_placeholder_sv = attr.evolve( placeholder_sv, supervision_violation_responses=[expected_svr_1, expected_svr_2], ) expected_placeholder_sp = attr.evolve( placeholder_sp, supervision_violation_entries=[expected_placeholder_sv]) expected_placeholder_ss = attr.evolve( placeholder_ss, supervision_periods=[expected_placeholder_sp]) expected_ip_1 = attr.evolve( ip_1, source_supervision_violation_response=expected_svr_1) expected_ip_2 = attr.evolve(ip_2) expected_placeholder_is = attr.evolve( placeholder_is, incarceration_periods=[expected_ip_1, expected_ip_2]) expected_placeholder_sg = attr.evolve( placeholder_sg, supervision_sentences=[expected_placeholder_ss], incarceration_sentences=[expected_placeholder_is], ) expected_placeholder_person = attr.evolve( placeholder_person, sentence_groups=[expected_placeholder_sg]) # Act input_people = converter.convert_entity_people_to_schema_people( [placeholder_person]) associate_revocation_svrs_with_ips(input_people) # Assert self.assert_people_match([expected_placeholder_person], input_people)
def test_moveViolationsOntoSupervisionPeriodsForSentence(self): # Arrange sv_1 = StateSupervisionViolation.new_with_defaults( violation_date=_DATE_2) svr = StateSupervisionViolationResponse.new_with_defaults( response_date=_DATE_3) sv_2 = StateSupervisionViolation.new_with_defaults( supervision_violation_responses=[svr]) sv_3 = StateSupervisionViolation.new_with_defaults( violation_date=_DATE_8) placeholder_sp_ss = StateSupervisionPeriod.new_with_defaults( supervision_violation_entries=[sv_1, sv_3]) sp_ss = StateSupervisionPeriod.new_with_defaults( external_id=_EXTERNAL_ID, start_date=_DATE_1, termination_date=_DATE_3) sp_2_ss = StateSupervisionPeriod.new_with_defaults( external_id=_EXTERNAL_ID_2, start_date=_DATE_7) ss = StateSupervisionSentence.new_with_defaults( external_id=_EXTERNAL_ID, supervision_periods=[sp_ss, sp_2_ss, placeholder_sp_ss]) placeholder_sp_is = StateSupervisionPeriod.new_with_defaults( supervision_violation_entries=[sv_2, sv_3]) sp_is = StateSupervisionPeriod.new_with_defaults( external_id=_EXTERNAL_ID_3, start_date=_DATE_2, termination_date=_DATE_3) sp_2_is = StateSupervisionPeriod.new_with_defaults( external_id=_EXTERNAL_ID_4, start_date=_DATE_3, termination_date=_DATE_6) inc_s = StateIncarcerationSentence.new_with_defaults( external_id=_EXTERNAL_ID, supervision_periods=[sp_is, sp_2_is, placeholder_sp_is]) sg = StateSentenceGroup.new_with_defaults( incarceration_sentences=[inc_s], supervision_sentences=[ss]) state_person = StatePerson.new_with_defaults(sentence_groups=[sg]) expected_sv_1 = attr.evolve(sv_1) expected_svr_2 = attr.evolve(svr) expected_sv_2 = attr.evolve( sv_2, supervision_violation_responses=[expected_svr_2]) expected_sv_3 = attr.evolve(sv_3) expected_placeholder_sp_ss = attr.evolve( placeholder_sp_ss, supervision_violation_entries=[]) expected_sp_ss = attr.evolve( sp_ss, supervision_violation_entries=[expected_sv_1]) expected_sp_2_ss = attr.evolve( sp_2_ss, supervision_violation_entries=[expected_sv_3]) expected_ss = attr.evolve(ss, supervision_periods=[ expected_placeholder_sp_ss, expected_sp_ss, expected_sp_2_ss ]) expected_placeholder_sp_is = attr.evolve( placeholder_sp_is, supervision_violation_entries=[expected_sv_3]) expected_sp_is = attr.evolve(sp_is, supervision_violation_entries=[]) expected_sp_2_is = attr.evolve( sp_2_is, supervision_violation_entries=[expected_sv_2]) expected_inc_s = attr.evolve(inc_s, supervision_periods=[ expected_placeholder_sp_is, expected_sp_is, expected_sp_2_is ]) expected_sg = attr.evolve(sg, supervision_sentences=[expected_ss], incarceration_sentences=[expected_inc_s]) expected_person = attr.evolve(state_person, sentence_groups=[expected_sg]) # Act input_people = converter.convert_entity_people_to_schema_people( [state_person]) move_violations_onto_supervision_periods_for_sentence(input_people) # Assert self.assert_people_match([expected_person], input_people)