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
9 changes: 2 additions & 7 deletions src/cl_sii/extras/pydantic_types.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

from __future__ import annotations

import re
import sys
from typing import Any, ClassVar, Pattern

Expand Down Expand Up @@ -79,12 +78,8 @@ class _RutPydanticAnnotation:
>>> example_json_schema = example_type_adapter.json_schema()
"""

RUT_CANONICAL_STRICT_REGEX: ClassVar[Pattern] = re.compile(
re.sub(
pattern=r'\?P<\w+>',
repl='',
string=cl_sii.rut.constants.RUT_CANONICAL_STRICT_REGEX.pattern,
)
RUT_CANONICAL_STRICT_REGEX: ClassVar[Pattern] = (
cl_sii.rut.constants.RUT_CANONICAL_STRICT_JSON_SCHEMA_REGEX
)
"""
RUT (strict) regex for canonical format, without named groups.
Expand Down
12 changes: 12 additions & 0 deletions src/cl_sii/rut/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
"""

import re
from typing import Pattern

import cryptography.x509

Expand All @@ -22,6 +23,17 @@
RUT_DIGITS_MIN_VALUE = 1
"""RUT digits min value."""

RUT_CANONICAL_STRICT_JSON_SCHEMA_REGEX: Pattern[str] = re.compile("^(\\d{1,8})-([\\dK])$")
"""
RUT (strict) JSON Schema regex for canonical format.

This regex is compatible with JSON Schema and OpenAPI, which use the regular expression syntax from
JavaScript (ECMA 262), which does not support Python’s named groups.

.. tip:: If you need the regex as a string, for example to use it in a JSON Schema or
OpenAPI schema, use ``RUT_CANONICAL_STRICT_JSON_SCHEMA_REGEX.pattern``.
"""

SII_CERT_TITULAR_RUT_OID = cryptography.x509.oid.ObjectIdentifier("1.3.6.1.4.1.8321.1")
"""OID of the RUT of the certificate holder"""
# - Organismo: MINISTERIO DE ECONOMÍA / SUBSECRETARIA DE ECONOMIA
Expand Down
81 changes: 80 additions & 1 deletion src/tests/test_rut_constants.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
from __future__ import annotations

import re
import unittest
from typing import ClassVar
from typing import ClassVar, Pattern

import jsonschema

from cl_sii.rut import constants

Expand Down Expand Up @@ -34,3 +37,79 @@ def test_persona_juridica_min_value(self) -> None:

self.assertGreaterEqual(min_rut_digits, self.RUT_DIGITS_MIN_VALUE)
self.assertLessEqual(min_rut_digits, self.RUT_DIGITS_MAX_VALUE)


class RutRegexConstantsTestCase(unittest.TestCase):
RUT_CANONICAL_STRICT_REGEX: ClassVar[Pattern[str]]
RUT_CANONICAL_STRICT_JSON_SCHEMA_REGEX: ClassVar[Pattern[str]]

@classmethod
def setUpClass(cls) -> None:
super().setUpClass()

cls.RUT_CANONICAL_STRICT_REGEX = constants.RUT_CANONICAL_STRICT_REGEX
cls.RUT_CANONICAL_STRICT_JSON_SCHEMA_REGEX = (
constants.RUT_CANONICAL_STRICT_JSON_SCHEMA_REGEX
)

def test_json_schema_regex_is_python_regex_without_named_groups(self) -> None:
# %% -----Arrange-----

python_regex = self.RUT_CANONICAL_STRICT_REGEX
python_regex_without_named_groups = re.compile(
re.sub(
pattern=r'\?P<\w+>',
repl='',
string=python_regex.pattern,
)
)
expected = python_regex_without_named_groups

# %% -----Act-----

actual = self.RUT_CANONICAL_STRICT_JSON_SCHEMA_REGEX

# %% -----Assert-----

self.assertEqual(expected, actual)

# %% -----

def test_json_schema_regex_is_valid_schema(self) -> None:
# %% -----Arrange-----

schema = {
"type": "string",
"pattern": self.RUT_CANONICAL_STRICT_JSON_SCHEMA_REGEX.pattern,
}
valid_test_values = [
'0-0',
'1-9',
'6-K',
'78773510-K',
]
invalid_test_values = [
'6K',
'6-k',
'78773510-k',
'78.773.510-K',
78773510,
1.9,
None,
]

# %% -----Act & Assert-----

for test_value in valid_test_values:
with self.subTest(test_value=test_value):
try:
jsonschema.validate(instance=test_value, schema=schema)
except jsonschema.exceptions.ValidationError as exc:
self.fail(f'{exc.__class__.__name__} raised')

for invalid_test_value in invalid_test_values:
with self.subTest(test_value=invalid_test_value):
with self.assertRaises(jsonschema.exceptions.ValidationError):
jsonschema.validate(instance=invalid_test_value, schema=schema)

# %% -----
Loading