Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions docs/source/redact/generator_metadata.rst
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ Phone number synthesis

* ``use_us_phone_number_generator`` (bool, default ``False``) -- When ``True``, generated telephone numbers use a US phone number format.
* ``replace_invalid_numbers`` (bool, default ``True``) -- When ``True``, detected telephone numbers that are not valid are still replaced with synthesized values.
* ``preserve_us_area_code`` (bool, default ``False``) -- When ``True`` and ``use_us_phone_number_generator`` is also ``True``, the area code of the original phone number is preserved in the synthesized value.

.. code-block:: python

Expand All @@ -114,6 +115,7 @@ Phone number synthesis
"PHONE_NUMBER": PhoneNumberGeneratorMetadata(
use_us_phone_number_generator=True,
replace_invalid_numbers=True,
preserve_us_area_code=True,
),
}

Expand Down
8 changes: 8 additions & 0 deletions tests/tests/metadata_tests/test_payload_serialization.py
Original file line number Diff line number Diff line change
Expand Up @@ -379,13 +379,15 @@ def test_to_payload_defaults(self):
assert payload["swaps"] == {}
assert payload["useUsPhoneNumberGenerator"] is False
assert payload["replaceInvalidNumbers"] is True
assert payload["preserveUsAreaCode"] is False
assert payload["constantValue"] is None

def test_to_payload_with_values(self):
metadata = PhoneNumberGeneratorMetadata(
generator_version=GeneratorVersion.V2,
use_us_phone_number_generator=True,
replace_invalid_numbers=False,
preserve_us_area_code=True,
swaps={"555-1234": "555-5678"},
constant_value="REDACTED"
)
Expand All @@ -396,6 +398,7 @@ def test_to_payload_with_values(self):
assert payload["swaps"] == {"555-1234": "555-5678"}
assert payload["useUsPhoneNumberGenerator"] is True
assert payload["replaceInvalidNumbers"] is False
assert payload["preserveUsAreaCode"] is True
assert payload["constantValue"] == "REDACTED"

def test_from_payload_defaults(self):
Expand All @@ -407,6 +410,7 @@ def test_from_payload_defaults(self):
assert metadata.swaps == {}
assert metadata.use_us_phone_number_generator is False
assert metadata.replace_invalid_numbers is True
assert metadata.preserve_us_area_code is False
assert metadata.constant_value is None

def test_from_payload_with_values(self):
Expand All @@ -416,6 +420,7 @@ def test_from_payload_with_values(self):
"swaps": {"111": "222"},
"useUsPhoneNumberGenerator": True,
"replaceInvalidNumbers": False,
"preserveUsAreaCode": True,
"constantValue": "REDACTED"
}
metadata = PhoneNumberGeneratorMetadata.from_payload(payload)
Expand All @@ -425,6 +430,7 @@ def test_from_payload_with_values(self):
assert metadata.swaps == {"111": "222"}
assert metadata.use_us_phone_number_generator is True
assert metadata.replace_invalid_numbers is False
assert metadata.preserve_us_area_code is True
assert metadata.constant_value == "REDACTED"

def test_from_payload_invalid_generator_raises(self):
Expand All @@ -438,6 +444,7 @@ def test_roundtrip(self):
generator_version=GeneratorVersion.V2,
use_us_phone_number_generator=True,
replace_invalid_numbers=False,
preserve_us_area_code=True,
swaps={"phone1": "phone2"},
constant_value="REDACTED"
)
Expand All @@ -450,6 +457,7 @@ def test_roundtrip(self):
assert restored.swaps == original.swaps
assert restored.use_us_phone_number_generator == original.use_us_phone_number_generator
assert restored.replace_invalid_numbers == original.replace_invalid_numbers
assert restored.preserve_us_area_code == original.preserve_us_area_code
assert restored.constant_value == original.constant_value


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ def test_json_dumps_works_directly(self):
generator_version=GeneratorVersion.V2,
use_us_phone_number_generator=True,
replace_invalid_numbers=False,
preserve_us_area_code=True,
swaps={"555-1234": "555-5678"}
)
json_str = json.dumps(metadata)
Expand All @@ -22,6 +23,7 @@ def test_json_dumps_works_directly(self):
assert parsed["generatorVersion"] == "V2"
assert parsed["useUsPhoneNumberGenerator"] is True
assert parsed["replaceInvalidNumbers"] is False
assert parsed["preserveUsAreaCode"] is True
assert parsed["swaps"] == {"555-1234": "555-5678"}

def test_json_includes_type_field(self):
Expand All @@ -43,6 +45,7 @@ def test_json_roundtrip_with_defaults(self):
assert restored.generator_version == original.generator_version
assert restored.use_us_phone_number_generator == original.use_us_phone_number_generator
assert restored.replace_invalid_numbers == original.replace_invalid_numbers
assert restored.preserve_us_area_code == original.preserve_us_area_code
assert restored.swaps == original.swaps

def test_json_roundtrip_with_custom_values(self):
Expand All @@ -51,6 +54,7 @@ def test_json_roundtrip_with_custom_values(self):
generator_version=GeneratorVersion.V2,
use_us_phone_number_generator=True,
replace_invalid_numbers=False,
preserve_us_area_code=True,
swaps={"phone1": "phone2"}
)
json_str = json.dumps(original)
Expand All @@ -61,29 +65,35 @@ def test_json_roundtrip_with_custom_values(self):
assert restored.generator_version == GeneratorVersion.V2
assert restored.use_us_phone_number_generator is True
assert restored.replace_invalid_numbers is False
assert restored.preserve_us_area_code is True
assert restored.swaps == {"phone1": "phone2"}

def test_attribute_access_works(self):
"""Property-based attribute access should work."""
metadata = PhoneNumberGeneratorMetadata(
use_us_phone_number_generator=True,
replace_invalid_numbers=False
replace_invalid_numbers=False,
preserve_us_area_code=True
)

assert metadata.use_us_phone_number_generator is True
assert metadata.replace_invalid_numbers is False
assert metadata.preserve_us_area_code is True
assert metadata.custom_generator == GeneratorType.PhoneNumber

def test_attribute_setter_works(self):
"""Property setter should update the underlying dict."""
metadata = PhoneNumberGeneratorMetadata()
metadata.use_us_phone_number_generator = True
metadata.replace_invalid_numbers = False
metadata.preserve_us_area_code = True

assert metadata.use_us_phone_number_generator is True
assert metadata["useUsPhoneNumberGenerator"] is True
assert metadata.replace_invalid_numbers is False
assert metadata["replaceInvalidNumbers"] is False
assert metadata.preserve_us_area_code is True
assert metadata["preserveUsAreaCode"] is True

def test_dict_access_works(self):
"""Direct dict access should work."""
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,18 @@ class PhoneNumberGeneratorMetadata(BaseMetadata):
When ``True``, phone numbers that are detected but are not valid
phone numbers are replaced with synthesized values. Default
is ``True``.
preserve_us_area_code : bool
When ``True`` and ``use_us_phone_number_generator`` is also ``True``,
the area code of the original phone number is preserved in the
synthesized value. Default is ``False``.
"""

def __init__(
self,
generator_version: GeneratorVersion = GeneratorVersion.V1,
use_us_phone_number_generator: bool = False,
replace_invalid_numbers: bool = True,
preserve_us_area_code: bool = False,
swaps: Optional[Dict[str,str]] = {},
constant_value: Optional[str] = None,
):
Expand All @@ -38,6 +43,7 @@ def __init__(
)
self["useUsPhoneNumberGenerator"] = use_us_phone_number_generator
self["replaceInvalidNumbers"] = replace_invalid_numbers
self["preserveUsAreaCode"] = preserve_us_area_code

@property
def use_us_phone_number_generator(self) -> bool:
Expand All @@ -55,6 +61,14 @@ def replace_invalid_numbers(self) -> bool:
def replace_invalid_numbers(self, value: bool):
self["replaceInvalidNumbers"] = value

@property
def preserve_us_area_code(self) -> bool:
return self["preserveUsAreaCode"]

@preserve_us_area_code.setter
def preserve_us_area_code(self, value: bool):
self["preserveUsAreaCode"] = value

def to_payload(self) -> Dict:
return dict(self)

Expand All @@ -72,6 +86,7 @@ def from_payload(payload: Dict) -> "PhoneNumberGeneratorMetadata":
generator_version=base_metadata.generator_version,
use_us_phone_number_generator=payload.get("useUsPhoneNumberGenerator", False),
replace_invalid_numbers=payload.get("replaceInvalidNumbers", True),
preserve_us_area_code=payload.get("preserveUsAreaCode", False),
swaps=base_metadata.swaps,
constant_value=base_metadata.constant_value
)
Expand Down
Loading