cuenca-validations 2.1.47__tar.gz → 2.1.48__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 (36) hide show
  1. {cuenca_validations-2.1.47 → cuenca_validations-2.1.48}/PKG-INFO +1 -1
  2. {cuenca_validations-2.1.47 → cuenca_validations-2.1.48}/cuenca_validations/types/__init__.py +2 -2
  3. {cuenca_validations-2.1.47 → cuenca_validations-2.1.48}/cuenca_validations/types/enums.py +0 -7
  4. {cuenca_validations-2.1.47 → cuenca_validations-2.1.48}/cuenca_validations/types/requests.py +24 -44
  5. cuenca_validations-2.1.48/cuenca_validations/version.py +1 -0
  6. {cuenca_validations-2.1.47 → cuenca_validations-2.1.48}/cuenca_validations.egg-info/PKG-INFO +1 -1
  7. {cuenca_validations-2.1.47 → cuenca_validations-2.1.48}/tests/test_requests.py +22 -16
  8. cuenca_validations-2.1.47/cuenca_validations/version.py +0 -1
  9. {cuenca_validations-2.1.47 → cuenca_validations-2.1.48}/LICENSE +0 -0
  10. {cuenca_validations-2.1.47 → cuenca_validations-2.1.48}/README.md +0 -0
  11. {cuenca_validations-2.1.47 → cuenca_validations-2.1.48}/cuenca_validations/__init__.py +0 -0
  12. {cuenca_validations-2.1.47 → cuenca_validations-2.1.48}/cuenca_validations/card_bins.py +0 -0
  13. {cuenca_validations-2.1.47 → cuenca_validations-2.1.48}/cuenca_validations/errors.py +0 -0
  14. {cuenca_validations-2.1.47 → cuenca_validations-2.1.48}/cuenca_validations/py.typed +0 -0
  15. {cuenca_validations-2.1.47 → cuenca_validations-2.1.48}/cuenca_validations/types/card.py +0 -0
  16. {cuenca_validations-2.1.47 → cuenca_validations-2.1.48}/cuenca_validations/types/files.py +0 -0
  17. {cuenca_validations-2.1.47 → cuenca_validations-2.1.48}/cuenca_validations/types/general.py +0 -0
  18. {cuenca_validations-2.1.47 → cuenca_validations-2.1.48}/cuenca_validations/types/helpers.py +0 -0
  19. {cuenca_validations-2.1.47 → cuenca_validations-2.1.48}/cuenca_validations/types/identities.py +0 -0
  20. {cuenca_validations-2.1.47 → cuenca_validations-2.1.48}/cuenca_validations/types/morals.py +0 -0
  21. {cuenca_validations-2.1.47 → cuenca_validations-2.1.48}/cuenca_validations/types/queries.py +0 -0
  22. {cuenca_validations-2.1.47 → cuenca_validations-2.1.48}/cuenca_validations/typing.py +0 -0
  23. {cuenca_validations-2.1.47 → cuenca_validations-2.1.48}/cuenca_validations/validators.py +0 -0
  24. {cuenca_validations-2.1.47 → cuenca_validations-2.1.48}/cuenca_validations.egg-info/SOURCES.txt +0 -0
  25. {cuenca_validations-2.1.47 → cuenca_validations-2.1.48}/cuenca_validations.egg-info/dependency_links.txt +0 -0
  26. {cuenca_validations-2.1.47 → cuenca_validations-2.1.48}/cuenca_validations.egg-info/requires.txt +0 -0
  27. {cuenca_validations-2.1.47 → cuenca_validations-2.1.48}/cuenca_validations.egg-info/top_level.txt +0 -0
  28. {cuenca_validations-2.1.47 → cuenca_validations-2.1.48}/setup.cfg +0 -0
  29. {cuenca_validations-2.1.47 → cuenca_validations-2.1.48}/setup.py +0 -0
  30. {cuenca_validations-2.1.47 → cuenca_validations-2.1.48}/tests/__init__.py +0 -0
  31. {cuenca_validations-2.1.47 → cuenca_validations-2.1.48}/tests/test_card.py +0 -0
  32. {cuenca_validations-2.1.47 → cuenca_validations-2.1.48}/tests/test_errors.py +0 -0
  33. {cuenca_validations-2.1.47 → cuenca_validations-2.1.48}/tests/test_helpers.py +0 -0
  34. {cuenca_validations-2.1.47 → cuenca_validations-2.1.48}/tests/test_statement.py +0 -0
  35. {cuenca_validations-2.1.47 → cuenca_validations-2.1.48}/tests/test_types.py +0 -0
  36. {cuenca_validations-2.1.47 → cuenca_validations-2.1.48}/tests/test_validators.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cuenca_validations
3
- Version: 2.1.47
3
+ Version: 2.1.48
4
4
  Summary: Cuenca common validations
5
5
  Home-page: https://github.com/cuenca-mx/cuenca-validations
6
6
  Author: Cuenca
@@ -67,6 +67,7 @@ __all__ = [
67
67
  'LegalPersonRequest',
68
68
  'LegalPersonUpdateRequest',
69
69
  'OperatorLoginRequest',
70
+ 'OperatorLoginUpdateRequest',
70
71
  'OperatorQuery',
71
72
  'OperatorRequest',
72
73
  'OperatorRole',
@@ -108,7 +109,6 @@ __all__ = [
108
109
  'TransactionStatus',
109
110
  'TransferNetwork',
110
111
  'TransferOrderLineRequest',
111
- 'TransferOrderLineStatus',
112
112
  'TransferOrderQuery',
113
113
  'TransferOrderRequest',
114
114
  'TransferOrderStatus',
@@ -190,7 +190,6 @@ from .enums import (
190
190
  TrackDataMethod,
191
191
  TransactionStatus,
192
192
  TransferNetwork,
193
- TransferOrderLineStatus,
194
193
  TransferOrderStatus,
195
194
  UserCardNotification,
196
195
  UserStatus,
@@ -272,6 +271,7 @@ from .requests import (
272
271
  LegalPersonUpdateRequest,
273
272
  LimitedWalletRequest,
274
273
  OperatorLoginRequest,
274
+ OperatorLoginUpdateRequest,
275
275
  OperatorRequest,
276
276
  OperatorUpdateRequest,
277
277
  PartnerRequest,
@@ -765,13 +765,6 @@ class OperatorStatus(str, Enum):
765
765
 
766
766
  class TransferOrderStatus(str, Enum):
767
767
  created = 'created'
768
- authorizing = 'authorizing'
769
768
  authorized = 'authorized'
770
769
  rejected = 'rejected'
771
770
  expired = 'expired'
772
-
773
-
774
- class TransferOrderLineStatus(str, Enum):
775
- pending = 'pending'
776
- invalid = 'invalid'
777
- submitted = 'submitted'
@@ -993,6 +993,16 @@ class OperatorLoginRequest(BaseRequest):
993
993
  return normalize_email(email)
994
994
 
995
995
 
996
+ class OperatorLoginUpdateRequest(BaseRequest):
997
+ """Complete operator login by verifying the emailed OTP code."""
998
+
999
+ code: StrictStr
1000
+
1001
+ model_config = ConfigDict(
1002
+ json_schema_extra={'example': {'code': '123456'}},
1003
+ )
1004
+
1005
+
996
1006
  class ReferencedClabeRequest(BaseRequest):
997
1007
  legal_person_id: str
998
1008
  allowed_curp_rfc: Union[Curp, Rfc]
@@ -1011,10 +1021,6 @@ class PhoneVerificationAssociationRequest(BaseRequest):
1011
1021
  verification_id: str
1012
1022
 
1013
1023
 
1014
- MAX_TRANSFER_ORDER_BATCH_LINES = 5000
1015
- MAX_TRANSFER_ORDER_EXPIRATION_HOURS = 24 * 7
1016
-
1017
-
1018
1024
  class TransferOrderLineRequest(BaseRequest):
1019
1025
  account_number: str
1020
1026
  recipient_name: str
@@ -1034,57 +1040,31 @@ class TransferOrderLineRequest(BaseRequest):
1034
1040
 
1035
1041
 
1036
1042
  class TransferOrderRequest(BaseRequest):
1037
- account_number: Optional[str] = None
1038
- recipient_name: Optional[str] = None
1039
- amount: Optional[int] = None
1040
- descriptor: Optional[str] = None
1041
1043
  idempotency_key: str
1042
- user_id: Optional[str] = None
1043
- items: Optional[list[TransferOrderLineRequest]] = None
1044
- expires_in_hours: Optional[int] = Field(
1045
- default=None,
1046
- gt=0,
1047
- le=MAX_TRANSFER_ORDER_EXPIRATION_HOURS,
1048
- )
1044
+ legal_person_id: Optional[str] = None
1045
+ items: list[TransferOrderLineRequest]
1049
1046
 
1050
1047
  model_config = ConfigDict(
1051
1048
  json_schema_extra={
1052
1049
  'example': {
1053
- 'account_number': '646180157034181180',
1054
- 'recipient_name': 'Doroteo Arango',
1055
- 'amount': 100_00,
1056
- 'descriptor': 'Mezcal, pulque y tequila',
1057
1050
  'idempotency_key': 'UNIQUE-KEY-003',
1058
- 'user_id': 'USWqY5cvkISJOxHyEKjAKf8w',
1051
+ 'legal_person_id': 'USWqY5cvkISJOxHyEKjAKf8w',
1052
+ 'items': [
1053
+ {
1054
+ 'account_number': '646180157034181180',
1055
+ 'recipient_name': 'Doroteo Arango',
1056
+ 'amount': 100_00,
1057
+ 'descriptor': 'Mezcal, pulque y tequila',
1058
+ }
1059
+ ],
1059
1060
  }
1060
1061
  },
1061
1062
  )
1062
1063
 
1063
1064
  @model_validator(mode='after')
1064
- def require_unitario_or_batch(self) -> 'TransferOrderRequest':
1065
- has_items = bool(self.items)
1066
- has_flat = all(
1067
- (
1068
- self.account_number is not None,
1069
- self.recipient_name is not None,
1070
- self.amount is not None,
1071
- self.descriptor is not None,
1072
- )
1073
- )
1074
- if has_items == has_flat:
1075
- raise ValueError(
1076
- 'Provide either a single transfer (account_number, '
1077
- 'recipient_name, amount, descriptor) or items[] for a batch, '
1078
- 'not both'
1079
- )
1080
- if self.items is not None:
1081
- if len(self.items) > MAX_TRANSFER_ORDER_BATCH_LINES:
1082
- raise ValueError(
1083
- 'Batch exceeds maximum of '
1084
- f'{MAX_TRANSFER_ORDER_BATCH_LINES} lines'
1085
- )
1086
- if len(self.items) == 0:
1087
- raise ValueError('items must not be empty')
1065
+ def validate_items(self) -> 'TransferOrderRequest':
1066
+ if len(self.items) == 0:
1067
+ raise ValueError('items must not be empty')
1088
1068
  return self
1089
1069
 
1090
1070
 
@@ -0,0 +1 @@
1
+ __version__ = '2.1.48'
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cuenca_validations
3
- Version: 2.1.47
3
+ Version: 2.1.48
4
4
  Summary: Cuenca common validations
5
5
  Home-page: https://github.com/cuenca-mx/cuenca-validations
6
6
  Author: Cuenca
@@ -9,8 +9,8 @@ from cuenca_validations.types.enums import (
9
9
  )
10
10
  from cuenca_validations.types.queries import OperatorQuery
11
11
  from cuenca_validations.types.requests import (
12
- MAX_TRANSFER_ORDER_BATCH_LINES,
13
12
  OperatorLoginRequest,
13
+ OperatorLoginUpdateRequest,
14
14
  OperatorRequest,
15
15
  OperatorUpdateRequest,
16
16
  PasswordResetRequest,
@@ -92,6 +92,19 @@ def test_operator_login_request_forbids_extra() -> None:
92
92
  assert 'Extra inputs are not permitted' in str(ex.value)
93
93
 
94
94
 
95
+ def test_operator_login_update_request_valid() -> None:
96
+ req = OperatorLoginUpdateRequest.model_validate({'code': '123456'})
97
+ assert req.code == '123456'
98
+
99
+
100
+ def test_operator_login_update_request_forbids_extra() -> None:
101
+ with pytest.raises(ValidationError) as ex:
102
+ OperatorLoginUpdateRequest.model_validate(
103
+ {'code': '123456', 'foo': 'bar'}
104
+ )
105
+ assert 'Extra inputs are not permitted' in str(ex.value)
106
+
107
+
95
108
  def test_operator_query_valid() -> None:
96
109
  query = OperatorQuery.model_validate({'email': 'maria.lopez@aceros.com'})
97
110
  assert str(query.email) == 'maria.lopez@aceros.com'
@@ -230,26 +243,19 @@ def test_transfer_order_request_shape() -> None:
230
243
  'descriptor': 'Mezcal',
231
244
  }
232
245
  single = TransferOrderRequest.model_validate(
233
- {**line, 'idempotency_key': 'single'}
246
+ {'idempotency_key': 'single', 'items': [line]}
234
247
  )
235
- assert single.items is None
248
+ assert single.items is not None
249
+ assert len(single.items) == 1
236
250
  batch = TransferOrderRequest.model_validate(
237
- {'idempotency_key': 'batch', 'items': [line]}
251
+ {'idempotency_key': 'batch', 'items': [line, line]}
238
252
  )
239
253
  assert batch.items is not None
254
+ assert len(batch.items) == 2
240
255
 
241
- with pytest.raises(ValidationError, match='not both'):
242
- TransferOrderRequest.model_validate(
243
- {**line, 'idempotency_key': 'both', 'items': [line]}
244
- )
245
256
  with pytest.raises(ValidationError, match='items must not be empty'):
246
257
  TransferOrderRequest.model_validate(
247
- {**line, 'idempotency_key': 'empty', 'items': []}
248
- )
249
- with pytest.raises(ValidationError, match='Batch exceeds maximum'):
250
- TransferOrderRequest.model_validate(
251
- {
252
- 'idempotency_key': 'too-many',
253
- 'items': [line] * (MAX_TRANSFER_ORDER_BATCH_LINES + 1),
254
- }
258
+ {'idempotency_key': 'empty', 'items': []}
255
259
  )
260
+ with pytest.raises(ValidationError):
261
+ TransferOrderRequest.model_validate({'idempotency_key': 'missing'})
@@ -1 +0,0 @@
1
- __version__ = '2.1.47'