def testParseCharge_MapAcrossFields(self): # Arrange overrides_builder = EnumOverrides.Builder() overrides_builder.add("FELONY", ChargeClass.FELONY, ChargeDegree) overrides_builder.add("FIRST DEGREE", ChargeDegree.FIRST, ChargeClass) metadata = FakeIngestMetadata.for_county( region="REGION", enum_overrides=overrides_builder.build() ) ingest_charge = ingest_info_pb2.Charge( charge_class="first degree", degree="felony" ) # Act charge.copy_fields_to_builder(self.subject, ingest_charge, metadata) result = self.subject.build() # Assert expected_result = entities.Charge.new_with_defaults( degree=ChargeDegree.FIRST, degree_raw_text="FELONY", charge_class=ChargeClass.FELONY, class_raw_text="FIRST DEGREE", status=ChargeStatus.PRESENT_WITHOUT_INFO, ) self.assertEqual(result, expected_result)
def testEnumMultipleFieldShareEnumType(self): enum_fields = { "admission_reason": StateIncarcerationPeriodAdmissionReason, "projected_release_reason": StateIncarcerationPeriodReleaseReason, "release_reason": StateIncarcerationPeriodReleaseReason, } proto = StateIncarcerationPeriod( admission_reason="PAROLE_REVOCATION", projected_release_reason="CONDITIONAL_RELEASE", release_reason="SERVED", ) enum_mappings = EnumMappings(proto, enum_fields, EnumOverrides.Builder().build()) self.assertEqual( StateIncarcerationPeriodReleaseReason.CONDITIONAL_RELEASE, enum_mappings.get( StateIncarcerationPeriodReleaseReason, field_name="projected_release_reason", ), ) self.assertEqual( StateIncarcerationPeriodReleaseReason.SENTENCE_SERVED, enum_mappings.get(StateIncarcerationPeriodReleaseReason, field_name="release_reason"), )
def testParseBooking_MapAcrossFields(self): # Arrange overrides_builder = EnumOverrides.Builder() overrides_builder.add("WORK RELEASE", Classification.WORK_RELEASE, AdmissionReason) overrides_builder.add("transfer", AdmissionReason.TRANSFER, CustodyStatus) metadata = IngestMetadata.new_with_defaults( ingest_time=_INGEST_TIME, enum_overrides=overrides_builder.build()) ingest_booking = ingest_info_pb2.Booking( admission_reason="work release", custody_status="transfer") # Act booking.copy_fields_to_builder(self.subject, ingest_booking, metadata) result = self.subject.build() # Assert expected_result = entities.Booking.new_with_defaults( admission_date=_INGEST_TIME.date(), admission_reason=AdmissionReason.TRANSFER, admission_reason_raw_text="WORK RELEASE", admission_date_inferred=True, custody_status=CustodyStatus.PRESENT_WITHOUT_INFO, custody_status_raw_text="TRANSFER", classification=Classification.WORK_RELEASE, last_seen_time=_INGEST_TIME, first_seen_time=_INGEST_TIME, ) self.assertEqual(result, expected_result)
def test_ignoreWithPredicate(self): overrides_builder = EnumOverrides.Builder() overrides_builder.ignore_with_predicate(lambda s: s.startswith("NO"), ChargeClass) overrides = overrides_builder.build() self.assertTrue(overrides.should_ignore("NONE", ChargeClass))
def test_ignore(self): overrides_builder = EnumOverrides.Builder() overrides_builder.ignore("A", ChargeClass) overrides = overrides_builder.build() self.assertTrue(overrides.should_ignore("A", ChargeClass)) self.assertFalse(overrides.should_ignore("A", BondType))
def setUp(self) -> None: super().setUp() overrides_builder = EnumOverrides.Builder() overrides_builder.add( "PV", StateIncarcerationPeriodAdmissionReason.PAROLE_REVOCATION) overrides_builder.add( "REC", StateIncarcerationPeriodAdmissionReason.RETURN_FROM_ESCAPE) overrides_builder.add( "ADM", StateIncarcerationPeriodAdmissionReason.NEW_ADMISSION) self.overrides = overrides_builder.build()
def test_ignore(self): overrides_builder = EnumOverrides.Builder() overrides_builder.ignore('A', ChargeClass) overrides_builder.ignore(lambda s: s.startswith('NO'), ChargeClass) overrides = overrides_builder.build() self.assertTrue(overrides.should_ignore('NONE', ChargeClass)) self.assertTrue(overrides.should_ignore('NONE', ChargeClass)) self.assertTrue(overrides.should_ignore('A', ChargeClass)) self.assertFalse(overrides.should_ignore('A', BondType))
def create_fake_nd_region(self): fake_region = create_autospec(Region) overrides_builder = EnumOverrides.Builder() overrides_builder.add( 'PV', StateIncarcerationPeriodAdmissionReason.PAROLE_REVOCATION) overrides_builder.add( 'REC', StateIncarcerationPeriodAdmissionReason.RETURN_FROM_ESCAPE) overrides_builder.add( 'ADM', StateIncarcerationPeriodAdmissionReason.NEW_ADMISSION) fake_region.get_enum_overrides.return_value = overrides_builder.build() return fake_region
def test_add(self): overrides_builder = EnumOverrides.Builder() overrides_builder.add("A", Race.ASIAN) overrides_builder.add("A", ChargeDegree.FIRST) overrides = overrides_builder.build() self.assertIsNone(overrides.parse("A", ChargeClass)) self.assertEqual(overrides.parse("A", Race), Race.ASIAN) self.assertEqual(overrides.parse("A", ChargeDegree), ChargeDegree.FIRST)
def testMapperErrorsCaughtAndThrownAsEntityMatchingError(self): def very_bad_mapper_that_asserts( _raw_text: str) -> Optional[FakeEntityEnum]: raise ValueError('Something bad happened!') overrides_builder = EnumOverrides.Builder() overrides_builder.add_mapper(very_bad_mapper_that_asserts, FakeEntityEnum) overrides = overrides_builder.build() with self.assertRaises(EnumParsingError): FakeEntityEnum.parse('A STRING TO PARSE', overrides)
def test_add_matchPredicate(self): is_pending = lambda s: s.startswith('PENDING') overrides_builder = EnumOverrides.Builder() overrides_builder.add(is_pending, BondStatus.PENDING) overrides = overrides_builder.build() self.assertIsNone(overrides.parse('PEND', BondStatus)) self.assertEqual(overrides.parse('PENDING', BondStatus), BondStatus.PENDING) self.assertEqual( overrides.parse('PENDING - WAITING TO SEE MAGISTRATE', BondStatus), BondStatus.PENDING)
def test_add_mapper(self): is_pending = lambda s: BondStatus.PENDING if s.startswith("PENDING" ) else None overrides_builder = EnumOverrides.Builder() overrides_builder.add_mapper(is_pending, BondStatus) overrides = overrides_builder.build() self.assertIsNone(overrides.parse("PEND", BondStatus)) self.assertEqual(overrides.parse("PENDING", BondStatus), BondStatus.PENDING) self.assertEqual( overrides.parse("PENDING - WAITING TO SEE MAGISTRATE", BondStatus), BondStatus.PENDING, )
def testParseBond_MapStatusToType(self): # Arrange ingest_bond = ingest_info_pb2.Bond(bond_type="bond revoked") overrides_builder = EnumOverrides.Builder() overrides_builder.add("BOND REVOKED", BondStatus.REVOKED, BondType) overrides = overrides_builder.build() # Act result = bond.convert( ingest_bond, attr.evolve(_EMPTY_METADATA, enum_overrides=overrides)) # Assert expected_result = entities.Bond.new_with_defaults( bond_type_raw_text="BOND REVOKED", status=BondStatus.REVOKED) self.assertEqual(result, expected_result)
def testEnumFromOriginalFieldIsPreferred(self): enum_fields = { "charge_class": ChargeClass, "status": ChargeStatus, } proto = Charge(charge_class="O", status="VIOLATION") overrides_builder = EnumOverrides.Builder() overrides_builder.add("O", ChargeClass.PROBATION_VIOLATION) overrides_builder.add("VIOLATION", ChargeClass.INFRACTION, ChargeStatus) enum_mappings = EnumMappings(proto, enum_fields, overrides_builder.build()) self.assertEqual(ChargeClass.PROBATION_VIOLATION, enum_mappings.get(ChargeClass))
def testMultipleMappingsFails(self): enum_fields = { 'degree': ChargeDegree, 'status': ChargeStatus, } proto = Charge(degree='O', status='VIOLATION') overrides_builder = EnumOverrides.Builder() overrides_builder.add('O', ChargeClass.PROBATION_VIOLATION, ChargeDegree) overrides_builder.add('VIOLATION', ChargeClass.INFRACTION, ChargeStatus) enum_mappings = EnumMappings(proto, enum_fields, overrides_builder.build()) with self.assertRaises(ValueError): enum_mappings.get(ChargeClass)
def testMultipleMappingsFails(self): enum_fields = { "degree": ChargeDegree, "status": ChargeStatus, } proto = Charge(degree="O", status="VIOLATION") overrides_builder = EnumOverrides.Builder() overrides_builder.add("O", ChargeClass.PROBATION_VIOLATION, ChargeDegree) overrides_builder.add("VIOLATION", ChargeClass.INFRACTION, ChargeStatus) enum_mappings = EnumMappings(proto, enum_fields, overrides_builder.build()) with self.assertRaises(ValueError): enum_mappings.get(ChargeClass)
def get_standard_enum_overrides() -> EnumOverrides: """ Returns a dict that contains all string to enum mappings that are region specific. These overrides have a higher precedence than the global mappings in ingest/constants. Note: Before overriding this method, consider directly adding each mapping directly into the respective global mappings instead. """ overrides_builder = EnumOverrides.Builder() for ethnicity_string, ethnicity in ETHNICITY_MAP.items(): # mypy is unable to correctly type the EntityEnums in constants.person. See # https://github.com/python/mypy/issues/3327 ethnicity_enum = cast(Ethnicity, ethnicity) if ethnicity_enum is Ethnicity.HISPANIC: overrides_builder.add(ethnicity_string, ethnicity_enum, Race) overrides_builder.add("OUT ON BOND", BondStatus.POSTED, BondType) overrides_builder.add_mapper(_felony_mapper, ChargeClass, ChargeStatus) return overrides_builder.build()
def testParseCharge_MapAcrossFields(self): # Arrange overrides_builder = EnumOverrides.Builder() overrides_builder.add('FELONY', ChargeClass.FELONY, ChargeDegree) overrides_builder.add('FIRST DEGREE', ChargeDegree.FIRST, ChargeClass) metadata = IngestMetadata.new_with_defaults( enum_overrides=overrides_builder.build()) ingest_charge = ingest_info_pb2.Charge(charge_class='first degree', degree='felony') # Act charge.copy_fields_to_builder(self.subject, ingest_charge, metadata) result = self.subject.build() # Assert expected_result = entities.Charge.new_with_defaults( degree=ChargeDegree.FIRST, degree_raw_text='FELONY', charge_class=ChargeClass.FELONY, class_raw_text='FIRST DEGREE', status=ChargeStatus.PRESENT_WITHOUT_INFO) self.assertEqual(result, expected_result)
def testEnumMultipleFieldShareEnumType(self): enum_fields = { 'admission_reason': StateIncarcerationPeriodAdmissionReason, 'projected_release_reason': StateIncarcerationPeriodReleaseReason, 'release_reason': StateIncarcerationPeriodReleaseReason } proto = StateIncarcerationPeriod( admission_reason='PAROLE_REVOCATION', projected_release_reason='CONDITIONAL_RELEASE', release_reason='SERVED') enum_mappings = EnumMappings(proto, enum_fields, EnumOverrides.Builder().build()) self.assertEqual( StateIncarcerationPeriodReleaseReason.CONDITIONAL_RELEASE, enum_mappings.get(StateIncarcerationPeriodReleaseReason, field_name='projected_release_reason')) self.assertEqual( StateIncarcerationPeriodReleaseReason.SENTENCE_SERVED, enum_mappings.get(StateIncarcerationPeriodReleaseReason, field_name='release_reason'))
def test_add_fromDifferentEnum(self): overrides_builder = EnumOverrides.Builder() overrides = overrides_builder.build() self.assertIsNone(overrides.parse("LATINO", Ethnicity))
def testParse_WithOverrides_UsesOverrides(self) -> None: overrides_builder = EnumOverrides.Builder() overrides_builder.add("BAN", FakeEntityEnum.BANANA) overrides = overrides_builder.build() self.assertEqual(FakeEntityEnum.parse("ban", overrides), FakeEntityEnum.BANANA)
def testCanParse_WithNoneOverride(self): overrides_builder = EnumOverrides.Builder() overrides_builder.ignore("BANANA", FakeEntityEnum) overrides = overrides_builder.build() self.assertTrue(FakeEntityEnum.can_parse("banana", overrides))
def test_overwrite_double_add_succeeds(self) -> None: overrides_builder = EnumOverrides.Builder() overrides_builder.add("A", ChargeDegree.FIRST) overrides_builder.add("A", ChargeDegree.SECOND, force_overwrite=True)
def testCanParse_WithOverrides(self): overrides_builder = EnumOverrides.Builder() overrides_builder.ignore('BAN', FakeEntityEnum) overrides = overrides_builder.build() self.assertTrue(FakeEntityEnum.can_parse('ban', overrides))
# ============================================================================= """Tests for converting StateIncarcerationIncidentOutcomes.""" import unittest from datetime import date from recidiviz.common.constants.enum_overrides import EnumOverrides from recidiviz.common.constants.state.state_incarceration_incident import ( StateIncarcerationIncidentOutcomeType, ) from recidiviz.ingest.models import ingest_info_pb2 from recidiviz.persistence.entity.state import entities from recidiviz.persistence.ingest_info_converter.state.entity_helpers import ( state_incarceration_incident_outcome, ) from recidiviz.tests.persistence.database.database_test_utils import FakeIngestMetadata _ENUM_OVERRIDES = (EnumOverrides.Builder().add( "LCP", StateIncarcerationIncidentOutcomeType.PRIVILEGE_LOSS).build()) _METADATA_WITH_OVERRIDES = FakeIngestMetadata.for_state( "us_ca", enum_overrides=_ENUM_OVERRIDES) class StateIncarcerationIncidentOutcomeConverterTest(unittest.TestCase): """Tests for converting StateIncarcerationIncidentOutcomes.""" def testParseStateIncarcerationIncident(self): # Arrange ingest_incident_outcome = ingest_info_pb2.StateIncarcerationIncidentOutcome( state_incarceration_incident_outcome_id="INCIDENT_OUTCOME_ID", outcome_type="LCP", date_effective="1/2/2019", hearing_date="12/29/2018", report_date="12/30/2019", state_code="us_ca",
def testParse_WithNoneOverride_IgnoresDefaultMap(self): overrides_builder = EnumOverrides.Builder() overrides_builder.ignore('BANANA', FakeEntityEnum) overrides = overrides_builder.build() self.assertEqual(FakeEntityEnum.parse('banana', overrides), None)
def test_double_add_fails(self) -> None: overrides_builder = EnumOverrides.Builder() overrides_builder.add("A", ChargeDegree.FIRST) with self.assertRaises(ValueError): overrides_builder.add("A", ChargeDegree.SECOND)
def testParse_WithOverrides_UsesOverrides(self): overrides_builder = EnumOverrides.Builder() overrides_builder.add('BAN', FakeEntityEnum.BANANA) overrides = overrides_builder.build() self.assertEqual(FakeEntityEnum.parse('ban', overrides), FakeEntityEnum.BANANA)