Exemplo n.º 1
0
    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"),
        )
Exemplo n.º 2
0
    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)
Exemplo n.º 3
0
    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 update_overrides_from_maps(
    base_enum_overrides: EnumOverrides, overrides: Dict[EntityEnum, List[str]],
    ignores: Dict[EntityEnumMeta,
                  List[str]], override_mappers: Dict[EntityEnumMeta,
                                                     EnumMapper],
    ignore_predicates: Dict[EntityEnumMeta,
                            EnumIgnorePredicate]) -> EnumOverrides:
    overrides_builder = base_enum_overrides.to_builder()

    for mapped_enum, text_tokens in overrides.items():
        for text_token in text_tokens:
            overrides_builder.add(text_token, mapped_enum)

    for ignored_enum, text_tokens in ignores.items():
        for text_token in text_tokens:
            overrides_builder.ignore(text_token, ignored_enum)

    for mapped_enum_cls, mapper in override_mappers.items():
        overrides_builder.add_mapper(mapper, mapped_enum_cls)

    for ignored_enum_cls, ignore_predicate in ignore_predicates.items():
        overrides_builder.ignore_with_predicate(ignore_predicate,
                                                ignored_enum_cls)

    return overrides_builder.build()
Exemplo n.º 5
0
    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))
Exemplo n.º 6
0
 def get_scraper_enum_overrides(self) -> EnumOverrides:
     """Retrieves the overrides object of a scraper region."""
     if self.is_direct_ingest:
         raise ValueError("Method not supported for direct ingest region.")
     obj = self.get_scraper()
     if obj:
         return obj.get_enum_overrides()
     return EnumOverrides.empty()
Exemplo n.º 7
0
    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()
Exemplo n.º 9
0
    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)
Exemplo n.º 10
0
    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))
Exemplo n.º 11
0
 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
Exemplo n.º 12
0
    def test_entity_deserialize_use_normal_constructor(self) -> None:
        with self.assertRaises(TypeError):
            _ = MyEntity(int_with_default="3")  # type: ignore[arg-type]
        with self.assertRaises(TypeError):
            _ = MyEntity(opt_int="3")  # type: ignore[arg-type]

        with self.assertRaises(TypeError):
            _ = MyEntity(bool_with_default="True")  # type: ignore[arg-type]
        with self.assertRaises(TypeError):
            _ = MyEntity(opt_bool="True")  # type: ignore[arg-type]

        with self.assertRaises(TypeError):
            _ = MyEntity(
                enum_with_default=EnumParser(  # type: ignore[arg-type]
                    raw_text="BLACK",
                    enum_cls=Race,
                    enum_overrides=EnumOverrides.empty(),
                )
            )
        with self.assertRaises(TypeError):
            _ = MyEntity(
                opt_enum=EnumParser(  # type: ignore[arg-type]
                    raw_text="BLACK",
                    enum_cls=Race,
                    enum_overrides=EnumOverrides.empty(),
                )
            )

        default_entity = MyEntity()
        expected_default_entity = MyEntity(
            int_with_default=1,
            bool_with_default=True,
            str_with_default="default",
            enum_with_default=Race.EXTERNAL_UNKNOWN,
            opt_int=None,
            opt_bool=None,
            opt_str=None,
            opt_enum=None,
        )

        self.assertEqual(default_entity, expected_default_entity)
Exemplo n.º 13
0
    def test_entity_deserialize(self) -> None:
        expected_default_entity = MyEntity(
            int_with_default=1,
            bool_with_default=True,
            str_with_default="default",
            enum_with_default=Race.EXTERNAL_UNKNOWN,
            opt_int=None,
            opt_bool=None,
            opt_str=None,
            opt_enum=None,
        )

        self.assertEqual(expected_default_entity, MyEntityFactory.deserialize())

        self.assertEqual(
            attr.evolve(expected_default_entity, str_with_default="HELLO"),
            MyEntityFactory.deserialize(str_with_default="hello"),
        )
        self.assertEqual(
            attr.evolve(expected_default_entity, opt_str="HELLO"),
            MyEntityFactory.deserialize(opt_str="hello"),
        )

        self.assertEqual(
            attr.evolve(expected_default_entity, int_with_default=3),
            MyEntityFactory.deserialize(int_with_default="3"),
        )
        self.assertEqual(
            attr.evolve(expected_default_entity, opt_int=3),
            MyEntityFactory.deserialize(opt_int="3"),
        )

        self.assertEqual(
            attr.evolve(expected_default_entity, bool_with_default=False),
            MyEntityFactory.deserialize(bool_with_default="False"),
        )
        self.assertEqual(
            attr.evolve(expected_default_entity, opt_bool=False),
            MyEntityFactory.deserialize(opt_bool="False"),
        )

        enum_parser = EnumParser(
            raw_text="BLACK", enum_cls=Race, enum_overrides=EnumOverrides.empty()
        )
        self.assertEqual(
            attr.evolve(expected_default_entity, enum_with_default=Race.BLACK),
            MyEntityFactory.deserialize(enum_with_default=enum_parser),
        )
        self.assertEqual(
            attr.evolve(expected_default_entity, opt_enum=Race.BLACK),
            MyEntityFactory.deserialize(opt_enum=enum_parser),
        )
Exemplo n.º 14
0
 def for_state(
     cls,
     region: str,
     enum_overrides: Optional[EnumOverrides] = None,
 ) -> IngestMetadata:
     return IngestMetadata(
         region=region,
         jurisdiction_id="",
         ingest_time=datetime.datetime(2020, 4, 14, 12, 31, 00),
         enum_overrides=enum_overrides or EnumOverrides.empty(),
         system_level=SystemLevel.STATE,
         database_key=SQLAlchemyDatabaseKey.canonical_for_schema(SchemaType.STATE),
     )
Exemplo n.º 15
0
    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)
Exemplo n.º 16
0
    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)
Exemplo n.º 17
0
    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,
        )
Exemplo n.º 18
0
    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))
Exemplo n.º 19
0
    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)
Exemplo n.º 20
0
    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)
Exemplo n.º 22
0
 def for_county(
     cls,
     region: str,
     jurisdiction_id: Optional[str] = None,
     ingest_time: Optional[datetime.datetime] = None,
     enum_overrides: Optional[EnumOverrides] = None,
     facility_id: Optional[str] = None,
 ) -> IngestMetadata:
     return IngestMetadata(
         region=region,
         jurisdiction_id=jurisdiction_id or "jurisdiction_id",
         ingest_time=ingest_time or datetime.datetime(2020, 4, 14, 12, 31, 00),
         enum_overrides=enum_overrides or EnumOverrides.empty(),
         facility_id=facility_id,
         system_level=SystemLevel.COUNTY,
         database_key=SQLAlchemyDatabaseKey.for_schema(SchemaType.JAILS),
     )
Exemplo n.º 23
0
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()
Exemplo n.º 24
0
    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)
Exemplo n.º 25
0
    def test_deserialize_StatePerson(self) -> None:
        result = deserialize_entity_factories.StatePersonFactory.deserialize(
            state_code="us_xx",
            gender=EnumParser("MALE", Gender, EnumOverrides.empty()),
            gender_raw_text="MALE",
            full_name='{"full_name": "full NAME"}',
            birthdate="12-31-1999",
            current_address="NNN\n  STREET \t ZIP",
            residency_status="NNN\n  STREET \t ZIP",
        )

        # Assert
        expected_result = entities.StatePerson.new_with_defaults(
            gender=Gender.MALE,
            gender_raw_text="MALE",
            full_name='{"full_name": "FULL NAME"}',
            birthdate=date(year=1999, month=12, day=31),
            birthdate_inferred_from_age=None,
            current_address="NNN STREET ZIP",
            residency_status=ResidencyStatus.PERMANENT,
            state_code="US_XX",
        )

        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'))
# =============================================================================
"""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",
Exemplo n.º 28
0
 def get_enum_overrides(self) -> EnumOverrides:
     """Retrieves the overrides object of a region"""
     obj = self.get_ingestor()
     if obj:
         return obj.get_enum_overrides()
     return EnumOverrides.empty()
 def test_parseGenderEnum(self):
     assert Gender.parse("Male", EnumOverrides.empty()) == Gender.MALE
 def test_parseBadGenderEnum(self):
     with pytest.raises(EnumParsingError):
         Gender.parse("ABD", EnumOverrides.empty())