cuenca-validations 2.0.0.dev7__tar.gz → 2.0.0.dev8__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. {cuenca_validations-2.0.0.dev7 → cuenca_validations-2.0.0.dev8}/PKG-INFO +1 -1
  2. {cuenca_validations-2.0.0.dev7 → cuenca_validations-2.0.0.dev8}/cuenca_validations/types/card.py +5 -1
  3. {cuenca_validations-2.0.0.dev7 → cuenca_validations-2.0.0.dev8}/cuenca_validations/types/files.py +2 -2
  4. {cuenca_validations-2.0.0.dev7 → cuenca_validations-2.0.0.dev8}/cuenca_validations/types/general.py +2 -24
  5. {cuenca_validations-2.0.0.dev7 → cuenca_validations-2.0.0.dev8}/cuenca_validations/types/morals.py +0 -2
  6. {cuenca_validations-2.0.0.dev7 → cuenca_validations-2.0.0.dev8}/cuenca_validations/types/queries.py +10 -31
  7. {cuenca_validations-2.0.0.dev7 → cuenca_validations-2.0.0.dev8}/cuenca_validations/types/requests.py +8 -8
  8. cuenca_validations-2.0.0.dev8/cuenca_validations/version.py +1 -0
  9. {cuenca_validations-2.0.0.dev7 → cuenca_validations-2.0.0.dev8}/cuenca_validations.egg-info/PKG-INFO +1 -1
  10. {cuenca_validations-2.0.0.dev7 → cuenca_validations-2.0.0.dev8}/tests/test_card.py +5 -1
  11. {cuenca_validations-2.0.0.dev7 → cuenca_validations-2.0.0.dev8}/tests/test_errors.py +0 -25
  12. {cuenca_validations-2.0.0.dev7 → cuenca_validations-2.0.0.dev8}/tests/test_types.py +8 -12
  13. cuenca_validations-2.0.0.dev7/cuenca_validations/version.py +0 -1
  14. {cuenca_validations-2.0.0.dev7 → cuenca_validations-2.0.0.dev8}/LICENSE +0 -0
  15. {cuenca_validations-2.0.0.dev7 → cuenca_validations-2.0.0.dev8}/README.md +0 -0
  16. {cuenca_validations-2.0.0.dev7 → cuenca_validations-2.0.0.dev8}/cuenca_validations/__init__.py +0 -0
  17. {cuenca_validations-2.0.0.dev7 → cuenca_validations-2.0.0.dev8}/cuenca_validations/card_bins.py +0 -0
  18. {cuenca_validations-2.0.0.dev7 → cuenca_validations-2.0.0.dev8}/cuenca_validations/errors.py +0 -0
  19. {cuenca_validations-2.0.0.dev7 → cuenca_validations-2.0.0.dev8}/cuenca_validations/py.typed +0 -0
  20. {cuenca_validations-2.0.0.dev7 → cuenca_validations-2.0.0.dev8}/cuenca_validations/types/__init__.py +0 -0
  21. {cuenca_validations-2.0.0.dev7 → cuenca_validations-2.0.0.dev8}/cuenca_validations/types/enums.py +0 -0
  22. {cuenca_validations-2.0.0.dev7 → cuenca_validations-2.0.0.dev8}/cuenca_validations/types/identities.py +0 -0
  23. {cuenca_validations-2.0.0.dev7 → cuenca_validations-2.0.0.dev8}/cuenca_validations/typing.py +0 -0
  24. {cuenca_validations-2.0.0.dev7 → cuenca_validations-2.0.0.dev8}/cuenca_validations/validators.py +0 -0
  25. {cuenca_validations-2.0.0.dev7 → cuenca_validations-2.0.0.dev8}/cuenca_validations.egg-info/SOURCES.txt +0 -0
  26. {cuenca_validations-2.0.0.dev7 → cuenca_validations-2.0.0.dev8}/cuenca_validations.egg-info/dependency_links.txt +0 -0
  27. {cuenca_validations-2.0.0.dev7 → cuenca_validations-2.0.0.dev8}/cuenca_validations.egg-info/requires.txt +0 -0
  28. {cuenca_validations-2.0.0.dev7 → cuenca_validations-2.0.0.dev8}/cuenca_validations.egg-info/top_level.txt +0 -0
  29. {cuenca_validations-2.0.0.dev7 → cuenca_validations-2.0.0.dev8}/setup.cfg +0 -0
  30. {cuenca_validations-2.0.0.dev7 → cuenca_validations-2.0.0.dev8}/setup.py +0 -0
  31. {cuenca_validations-2.0.0.dev7 → cuenca_validations-2.0.0.dev8}/tests/__init__.py +0 -0
  32. {cuenca_validations-2.0.0.dev7 → cuenca_validations-2.0.0.dev8}/tests/test_statement.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: cuenca_validations
3
- Version: 2.0.0.dev7
3
+ Version: 2.0.0.dev8
4
4
  Summary: Cuenca common validations
5
5
  Home-page: https://github.com/cuenca-mx/cuenca-validations
6
6
  Author: Cuenca
@@ -13,7 +13,11 @@ class StrictPaymentCardNumber(BaseModel):
13
13
  def validate_bin(cls, card_number: PaymentCardNumber) -> PaymentCardNumber:
14
14
  if card_number.bin not in CARD_BINS:
15
15
  raise PydanticCustomError(
16
- 'payment_card_number.bin', 'Invalid BIN: Bank code not found.'
16
+ 'payment_card_number.bin',
17
+ 'The card number contains a BIN (first six digits) '
18
+ 'that does not have a known association with a Mexican bank.'
19
+ 'To add the association, please file an issue:'
20
+ 'https://github.com/cuenca-mx/cuenca-validations/issues',
17
21
  )
18
22
  return card_number
19
23
 
@@ -1,6 +1,6 @@
1
1
  from typing import Optional
2
2
 
3
- from pydantic import AnyHttpUrl, BaseModel
3
+ from pydantic import BaseModel, HttpUrl
4
4
 
5
5
  from .enums import KYCFileType
6
6
 
@@ -9,4 +9,4 @@ class BatchFileMetadata(BaseModel):
9
9
  id: Optional[str] = None
10
10
  is_back: bool
11
11
  type: KYCFileType
12
- url: AnyHttpUrl
12
+ url: HttpUrl
@@ -19,32 +19,10 @@ class JSONEncoder(json.JSONEncoder):
19
19
  return sanitize_item(o, default=super().default)
20
20
 
21
21
 
22
- def validate_strict_positive_int(value: int) -> int:
23
- if not isinstance(value, int):
24
- raise ValueError("Value must be an integer")
25
- if value <= 0:
26
- raise ValueError("Value must be greater than 0")
27
- if value > 21_474_836_47:
28
- raise ValueError("Value must be less than 21_474_836_47")
29
- return value
30
-
31
-
32
- StrictPositiveInt = Annotated[
33
- int, BeforeValidator(validate_strict_positive_int)
34
- ]
35
-
36
-
37
- def validate_strict_positive_float(value: float) -> float:
38
- if not isinstance(value, float):
39
- raise ValueError("Value must be a float")
40
- if value <= 0:
41
- raise ValueError("Value must be greater than 0")
42
- return value
22
+ StrictPositiveInt = Annotated[int, Field(strict=True, gt=0, le=21_474_836_47)]
43
23
 
44
24
 
45
- StrictPositiveFloat = Annotated[
46
- float, BeforeValidator(validate_strict_positive_float)
47
- ]
25
+ StrictPositiveFloat = Annotated[float, Field(strict=True, gt=0)]
48
26
 
49
27
 
50
28
  def validate_only_digits(value: str) -> str:
@@ -49,8 +49,6 @@ class VulnerableActivityDetails(BaseModel):
49
49
 
50
50
 
51
51
  class PhysicalPerson(BaseModel):
52
- model_config = dict(arbitrary_types_allowed=True)
53
-
54
52
  names: str
55
53
  first_surname: str
56
54
  second_surname: Optional[str] = None
@@ -5,10 +5,11 @@ from pydantic import (
5
5
  BaseModel,
6
6
  ConfigDict,
7
7
  EmailStr,
8
+ Field,
8
9
  PositiveInt,
9
- conint,
10
10
  field_validator,
11
11
  )
12
+ from typing_extensions import Annotated
12
13
 
13
14
  from ..typing import DictStrAny
14
15
  from ..validators import sanitize_dict
@@ -31,9 +32,9 @@ MAX_PAGE_SIZE = 100
31
32
 
32
33
  class QueryParams(BaseModel):
33
34
  count: bool = False
34
- page_size: conint( # type: ignore[valid-type]
35
- gt=0, le=MAX_PAGE_SIZE
36
- ) = MAX_PAGE_SIZE # Add default value
35
+ page_size: Annotated[
36
+ int, Field(strict=True, gt=0, le=MAX_PAGE_SIZE, default=MAX_PAGE_SIZE)
37
+ ]
37
38
  limit: Optional[PositiveInt] = None
38
39
  user_id: Optional[str] = None
39
40
  created_before: Optional[dt.datetime] = None
@@ -105,21 +106,6 @@ class ApiKeyQuery(QueryParams):
105
106
  'description': 'Set `true` value to fetch active keys or '
106
107
  '`false` to fetch deactivated keys'
107
108
  },
108
- 'count': {
109
- 'description': 'Set `true` value to get only a counter'
110
- },
111
- 'page_size': {'description': 'Number of items per page'},
112
- 'limit': {'description': 'Limit of items to query'},
113
- 'created_before': {
114
- 'description': 'Filtered items have a `created_at` '
115
- 'date equal or lower than this value, this field '
116
- 'represents the max creation date.'
117
- },
118
- 'created_after': {
119
- 'description': 'Filtered items have a `created_at` '
120
- 'date equal or greater than this value, this field '
121
- 'represents the min creation date.'
122
- },
123
109
  }
124
110
  },
125
111
  )
@@ -139,14 +125,9 @@ class CardQuery(QueryParams):
139
125
  type: Optional[CardType] = None
140
126
 
141
127
  @field_validator('exp_month', 'exp_year', 'cvv2', 'cvv')
142
- def query_by_exp_cvv_if_number_set(cls, v, info):
143
- if not info.data.get('number'):
144
- raise ValueError(
145
- '''
146
- exp_month, exp_year, cvv and cvv2 can
147
- only be set when number is provided
148
- '''
149
- )
128
+ def query_by_exp_cvv_if_number_set(cls, v, values):
129
+ if not values.data.get('number'):
130
+ raise ValueError('Number must be set to query by exp or cvv')
150
131
  return v
151
132
 
152
133
 
@@ -155,8 +136,8 @@ class StatementQuery(QueryParams):
155
136
  month: int
156
137
 
157
138
  @field_validator('month')
158
- def validate_year_month(cls, month, info):
159
- year = info.data['year']
139
+ def validate_year_month(cls, month, values):
140
+ year = values.data['year']
160
141
  month_now = dt.date.today().replace(day=1)
161
142
  month_set = dt.date(year, month, 1)
162
143
  if month_set >= month_now:
@@ -190,8 +171,6 @@ class UserQuery(QueryParams):
190
171
 
191
172
 
192
173
  class IdentityQuery(QueryParams):
193
- model_config = dict(arbitrary_types_allowed=True)
194
-
195
174
  curp: Optional[CurpField] = None
196
175
  rfc: Optional[str] = None
197
176
  status: Optional[UserStatus] = None
@@ -112,8 +112,8 @@ class TransferRequest(BaseRequest):
112
112
  )
113
113
 
114
114
 
115
- class StrictTransferRequest(BaseRequest):
116
- account_number: Union[Clabe, StrictPaymentCardNumber]
115
+ class StrictTransferRequest(TransferRequest):
116
+ account_number: Union[Clabe, StrictPaymentCardNumber] # type: ignore
117
117
 
118
118
 
119
119
  class CardUpdateRequest(BaseRequest):
@@ -140,8 +140,8 @@ class CardActivationRequest(BaseModel):
140
140
  pattern=r'\d{16}',
141
141
  ),
142
142
  ]
143
- exp_month: Annotated[int, Field(strict=True, ge=1, le=12)] # type: ignore
144
- exp_year: Annotated[int, Field(strict=True, ge=18, le=99)] # type: ignore
143
+ exp_month: Annotated[int, Field(strict=True, ge=1, le=12)]
144
+ exp_year: Annotated[int, Field(strict=True, ge=18, le=99)]
145
145
  cvv2: Annotated[
146
146
  str,
147
147
  StringConstraints(
@@ -207,7 +207,7 @@ class CardValidationRequest(BaseModel):
207
207
  ]
208
208
  exp_month: Optional[Annotated[int, Field(strict=True, ge=1, le=12)]] = None
209
209
  exp_year: Optional[Annotated[int, Field(strict=True, ge=18, le=99)]] = None
210
- cvv: Optional[ # type: ignore
210
+ cvv: Optional[
211
211
  Annotated[
212
212
  str,
213
213
  StringConstraints(
@@ -215,7 +215,7 @@ class CardValidationRequest(BaseModel):
215
215
  ),
216
216
  ]
217
217
  ] = None
218
- cvv2: Optional[ # type: ignore
218
+ cvv2: Optional[
219
219
  Annotated[
220
220
  str,
221
221
  StringConstraints(
@@ -223,7 +223,7 @@ class CardValidationRequest(BaseModel):
223
223
  ),
224
224
  ]
225
225
  ] = None
226
- icvv: Optional[ # type: ignore
226
+ icvv: Optional[
227
227
  Annotated[
228
228
  str,
229
229
  StringConstraints(
@@ -272,7 +272,7 @@ class CardTransactionRequest(BaseModel):
272
272
  card_id: str
273
273
  user_id: str
274
274
  # In some card_validations amount is equal to 0
275
- amount: Annotated[int, Field(strict=True, ge=0)] # type: ignore
275
+ amount: Annotated[int, Field(strict=True, ge=0)]
276
276
  merchant_name: str
277
277
  merchant_type: str
278
278
  merchant_data: str
@@ -0,0 +1 @@
1
+ __version__ = '2.0.0.dev8'
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: cuenca_validations
3
- Version: 2.0.0.dev7
3
+ Version: 2.0.0.dev8
4
4
  Summary: Cuenca common validations
5
5
  Home-page: https://github.com/cuenca-mx/cuenca-validations
6
6
  Author: Cuenca
@@ -11,7 +11,11 @@ INVALID_BIN = '4050000000000001'
11
11
  def test_invalid_bin_strict_payment():
12
12
  with pytest.raises(ValidationError) as exc_info:
13
13
  StrictPaymentCardNumber(card_number=INVALID_BIN)
14
- assert 'Invalid BIN: Bank code not found.' in str(exc_info.value)
14
+ print(exc_info.value)
15
+ assert 'payment_card_number.bin' in str(exc_info.value)
16
+ assert 'The card number contains a BIN (first six digits) ' in str(
17
+ exc_info.value
18
+ )
15
19
 
16
20
 
17
21
  def test_valid_bin_strict_payment():
@@ -1,7 +1,4 @@
1
- import pytest
2
-
3
1
  from cuenca_validations.errors import (
4
- ERROR_CODES,
5
2
  ApiError,
6
3
  AuthMethodNotAllowedError,
7
4
  CuencaError,
@@ -35,25 +32,3 @@ def test_error_codes_and_status():
35
32
  for error_class, expected_code, expected_status in test_cases:
36
33
  assert error_class.code == expected_code
37
34
  assert error_class.status_code == expected_status
38
-
39
-
40
- def test_error_messages():
41
- test_message = "Mensaje de prueba"
42
-
43
- for error_class in ERROR_CODES.values():
44
- with pytest.raises(error_class) as exc_info:
45
- raise error_class(test_message)
46
- assert str(exc_info.value) == test_message
47
-
48
-
49
- def test_error_codes_mapping():
50
- for error_class in ERROR_CODES.values():
51
- assert ERROR_CODES[error_class.code] == error_class
52
-
53
-
54
- def test_api_error():
55
- with pytest.raises(ApiError) as exc_info:
56
- raise ApiError("Error interno")
57
- assert str(exc_info.value) == "Error interno"
58
- assert exc_info.value.code == 500
59
- assert exc_info.value.status_code == 500
@@ -551,7 +551,7 @@ def test_verification_attempt_request():
551
551
 
552
552
  def test_limited_wallet_request():
553
553
  curp = 'TAXM840916HNEMXT02'
554
- rfc = Rfc('TAXM840916123')
554
+ rfc = 'TAXM840916123'
555
555
  # Not valid format
556
556
  with pytest.raises(ValidationError):
557
557
  LimitedWalletRequest(allowed_curp='123', allowed_rfc='123')
@@ -594,14 +594,10 @@ def test_strict_positive_float_valid():
594
594
 
595
595
 
596
596
  def test_strict_positive_float_invalid():
597
- with pytest.raises(ValueError, match="Value must be greater than 0"):
597
+ with pytest.raises(ValueError, match="Input should be greater than 0"):
598
598
  TestFloatModel(value=0.0)
599
- with pytest.raises(ValueError, match="Value must be greater than 0"):
599
+ with pytest.raises(ValueError, match="Input should be greater than 0"):
600
600
  TestFloatModel(value=-1.5)
601
- with pytest.raises(ValueError, match="Value must be a float"):
602
- TestFloatModel(value=5)
603
- with pytest.raises(ValueError, match="Value must be a float"):
604
- TestFloatModel(value="10.5")
605
601
 
606
602
 
607
603
  class TestIntModel(BaseModel):
@@ -620,19 +616,19 @@ def test_strict_positive_int_valid():
620
616
 
621
617
 
622
618
  def test_strict_positive_int_invalid():
623
- with pytest.raises(ValueError, match="Value must be greater than 0"):
619
+ with pytest.raises(ValueError, match="Input should be greater than 0"):
624
620
  TestIntModel(value=0)
625
621
 
626
- with pytest.raises(ValueError, match="Value must be greater than 0"):
622
+ with pytest.raises(ValueError, match="Input should be greater than 0"):
627
623
  TestIntModel(value=-5)
628
624
 
629
625
  with pytest.raises(
630
- ValueError, match="Value must be less than 21_474_836_47"
626
+ ValueError, match="Input should be less than or equal to 2147483647"
631
627
  ):
632
628
  TestIntModel(value=21_474_836_48)
633
629
 
634
- with pytest.raises(ValueError, match="Value must be an integer"):
630
+ with pytest.raises(ValueError, match="Input should be a valid integer"):
635
631
  TestIntModel(value=5.5)
636
632
 
637
- with pytest.raises(ValueError, match="Value must be an integer"):
633
+ with pytest.raises(ValueError, match="Input should be a valid integer"):
638
634
  TestIntModel(value="10")
@@ -1 +0,0 @@
1
- __version__ = '2.0.0.dev7'