def test_nonnullFieldsEntityMatch_flatFieldsCompare(self) -> None:
        charge = schema.StateCharge(
            state_code=_STATE_CODE,
            ncic_code="1234",
            county_code=_COUNTY_CODE,
            status=ChargeStatus.PRESENT_WITHOUT_INFO,
        )
        charge_another = schema.StateCharge(
            state_code=_STATE_CODE,
            ncic_code="1234",
            status=ChargeStatus.PRESENT_WITHOUT_INFO,
        )

        # If one of the entities is merely missing a field, we still consider it a match
        self.assertTrue(
            nonnull_fields_entity_match(
                ingested_entity=EntityTree(entity=charge, ancestor_chain=[]),
                db_entity=EntityTree(entity=charge_another, ancestor_chain=[]),
            ))
        charge_another.county_code = _COUNTY_CODE_ANOTHER

        # If one of the entities has a different value, then it is not a match
        self.assertFalse(
            nonnull_fields_entity_match(
                ingested_entity=EntityTree(entity=charge, ancestor_chain=[]),
                db_entity=EntityTree(entity=charge_another, ancestor_chain=[]),
            ))
        charge_another.county_code = _COUNTY_CODE

        # All fields the same - this is a match
        self.assertTrue(
            nonnull_fields_entity_match(
                ingested_entity=EntityTree(entity=charge, ancestor_chain=[]),
                db_entity=EntityTree(entity=charge_another, ancestor_chain=[]),
            ))
    def test_nonnullFieldsEntityMatch_flatFieldsCompare(self):
        charge = StateCharge.new_with_defaults(state_code=_STATE_CODE,
                                               ncic_code='1234',
                                               county_code=_COUNTY_CODE)
        charge_another = StateCharge.new_with_defaults(state_code=_STATE_CODE,
                                                       ncic_code='1234')

        # If one of the entities is merely missing a field, we still consider it a match
        self.assertTrue(
            nonnull_fields_entity_match(
                ingested_entity=EntityTree(entity=charge, ancestor_chain=[]),
                db_entity=EntityTree(entity=charge_another,
                                     ancestor_chain=[])))
        charge_another.county_code = _COUNTY_CODE_ANOTHER

        # If one of the entities has a different value, then it is not a match
        self.assertFalse(
            nonnull_fields_entity_match(
                ingested_entity=EntityTree(entity=charge, ancestor_chain=[]),
                db_entity=EntityTree(entity=charge_another,
                                     ancestor_chain=[])))
        charge_another.county_code = _COUNTY_CODE

        # All fields the same - this is a match
        self.assertTrue(
            nonnull_fields_entity_match(
                ingested_entity=EntityTree(entity=charge, ancestor_chain=[]),
                db_entity=EntityTree(entity=charge_another,
                                     ancestor_chain=[])))
 def test_nonnullFieldsEntityMatch_externalIdCompare(self):
     charge = StateCharge.new_with_defaults(external_id=_EXTERNAL_ID)
     charge_another = StateCharge.new_with_defaults()
     self.assertFalse(
         nonnull_fields_entity_match(
             ingested_entity=EntityTree(entity=charge, ancestor_chain=[]),
             db_entity=EntityTree(entity=charge_another,
                                  ancestor_chain=[])))
     charge_another.external_id = _EXTERNAL_ID
     self.assertTrue(
         nonnull_fields_entity_match(
             ingested_entity=EntityTree(entity=charge, ancestor_chain=[]),
             db_entity=EntityTree(entity=charge_another,
                                  ancestor_chain=[])))
 def test_nonnullFieldsEntityMatch_placeholder(self):
     charge = StateCharge.new_with_defaults()
     charge_another = StateCharge.new_with_defaults()
     self.assertFalse(
         nonnull_fields_entity_match(
             ingested_entity=EntityTree(entity=charge, ancestor_chain=[]),
             db_entity=EntityTree(entity=charge_another,
                                  ancestor_chain=[])))
 def test_nonnullFieldsEntityMatch_externalIdCompare(self) -> None:
     charge = schema.StateCharge(
         state_code=_STATE_CODE,
         status=ChargeStatus.PRESENT_WITHOUT_INFO,
         external_id=_EXTERNAL_ID,
     )
     charge_another = schema.StateCharge(
         state_code=_STATE_CODE, status=ChargeStatus.PRESENT_WITHOUT_INFO)
     self.assertFalse(
         nonnull_fields_entity_match(
             ingested_entity=EntityTree(entity=charge, ancestor_chain=[]),
             db_entity=EntityTree(entity=charge_another, ancestor_chain=[]),
         ))
     charge_another.external_id = _EXTERNAL_ID
     self.assertTrue(
         nonnull_fields_entity_match(
             ingested_entity=EntityTree(entity=charge, ancestor_chain=[]),
             db_entity=EntityTree(entity=charge_another, ancestor_chain=[]),
         ))
 def test_nonnullFieldsEntityMatch_placeholder(self) -> None:
     charge = schema.StateCharge(state_code=_STATE_CODE,
                                 status=ChargeStatus.PRESENT_WITHOUT_INFO)
     charge_another = schema.StateCharge(
         state_code=_STATE_CODE, status=ChargeStatus.PRESENT_WITHOUT_INFO)
     self.assertFalse(
         nonnull_fields_entity_match(
             ingested_entity=EntityTree(entity=charge, ancestor_chain=[]),
             db_entity=EntityTree(entity=charge_another, ancestor_chain=[]),
         ))
    def _nonnull_fields_ssvr_entity_match(ingested_entity: EntityTree,
                                          db_entity: EntityTree) -> bool:
        """Custom matcher for StateSupervisionViolationResponses where we allow for flat field matching to allow for
        changes to the revocation type - we've seen this changes occasionally in the SSVRs we ingest as
        source_supervision_violation_response in our incarceration period files."""

        if not isinstance(ingested_entity.entity, schema.StateSupervisionViolationResponse):
            raise ValueError(f'Unexpected entity type [{type(ingested_entity.entity)}]')

        return nonnull_fields_entity_match(
            ingested_entity, db_entity,
            skip_fields={schema.StateSupervisionViolationResponse.revocation_type.name,
                         schema.StateSupervisionViolationResponse.revocation_type_raw_text.name})