cuenca-validations 2.1.48.dev1__py3-none-any.whl → 2.1.49.dev0__py3-none-any.whl
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.
- cuenca_validations/types/__init__.py +2 -2
- cuenca_validations/types/requests.py +40 -46
- cuenca_validations/version.py +1 -1
- {cuenca_validations-2.1.48.dev1.dist-info → cuenca_validations-2.1.49.dev0.dist-info}/METADATA +1 -1
- {cuenca_validations-2.1.48.dev1.dist-info → cuenca_validations-2.1.49.dev0.dist-info}/RECORD +9 -9
- tests/test_requests.py +63 -15
- {cuenca_validations-2.1.48.dev1.dist-info → cuenca_validations-2.1.49.dev0.dist-info}/WHEEL +0 -0
- {cuenca_validations-2.1.48.dev1.dist-info → cuenca_validations-2.1.49.dev0.dist-info}/licenses/LICENSE +0 -0
- {cuenca_validations-2.1.48.dev1.dist-info → cuenca_validations-2.1.49.dev0.dist-info}/top_level.txt +0 -0
|
@@ -83,7 +83,6 @@ __all__ = [
|
|
|
83
83
|
'Profession',
|
|
84
84
|
'QueryParams',
|
|
85
85
|
'ReferencedClabeRequest',
|
|
86
|
-
'RejectTransferOrderRequest',
|
|
87
86
|
'LegalRfc',
|
|
88
87
|
'Rfc',
|
|
89
88
|
'QuestionnairesRequest',
|
|
@@ -114,6 +113,7 @@ __all__ = [
|
|
|
114
113
|
'TransferOrderStatus',
|
|
115
114
|
'TransferQuery',
|
|
116
115
|
'TransferRequest',
|
|
116
|
+
'UpdateTransferOrderRequest',
|
|
117
117
|
'UpdateTransferRequest',
|
|
118
118
|
'UserCardNotification',
|
|
119
119
|
'UserCredentialRequest',
|
|
@@ -280,7 +280,6 @@ from .requests import (
|
|
|
280
280
|
PlatformRequest,
|
|
281
281
|
QuestionnairesRequest,
|
|
282
282
|
ReferencedClabeRequest,
|
|
283
|
-
RejectTransferOrderRequest,
|
|
284
283
|
SavingRequest,
|
|
285
284
|
SavingUpdateRequest,
|
|
286
285
|
SessionRequest,
|
|
@@ -289,6 +288,7 @@ from .requests import (
|
|
|
289
288
|
TransferOrderLineRequest,
|
|
290
289
|
TransferOrderRequest,
|
|
291
290
|
TransferRequest,
|
|
291
|
+
UpdateTransferOrderRequest,
|
|
292
292
|
UpdateTransferRequest,
|
|
293
293
|
UserCredentialRequest,
|
|
294
294
|
UserCredentialUpdateRequest,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import datetime as dt
|
|
2
|
-
from typing import Annotated, Any, Optional, Union
|
|
2
|
+
from typing import Annotated, Any, Literal, Optional, Union
|
|
3
3
|
|
|
4
4
|
from clabe import BANK_NAMES, Clabe
|
|
5
5
|
from pydantic import (
|
|
@@ -50,6 +50,7 @@ from ..types.enums import (
|
|
|
50
50
|
TrackDataMethod,
|
|
51
51
|
TransactionStatus,
|
|
52
52
|
TransactionTokenValidationStatus,
|
|
53
|
+
TransferOrderStatus,
|
|
53
54
|
UserCardNotification,
|
|
54
55
|
UserStatus,
|
|
55
56
|
VerificationStatus,
|
|
@@ -1021,10 +1022,6 @@ class PhoneVerificationAssociationRequest(BaseRequest):
|
|
|
1021
1022
|
verification_id: str
|
|
1022
1023
|
|
|
1023
1024
|
|
|
1024
|
-
MAX_TRANSFER_ORDER_BATCH_LINES = 5000
|
|
1025
|
-
MAX_TRANSFER_ORDER_EXPIRATION_HOURS = 24 * 7
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
1025
|
class TransferOrderLineRequest(BaseRequest):
|
|
1029
1026
|
account_number: str
|
|
1030
1027
|
recipient_name: str
|
|
@@ -1044,65 +1041,62 @@ class TransferOrderLineRequest(BaseRequest):
|
|
|
1044
1041
|
|
|
1045
1042
|
|
|
1046
1043
|
class TransferOrderRequest(BaseRequest):
|
|
1047
|
-
account_number: Optional[str] = None
|
|
1048
|
-
recipient_name: Optional[str] = None
|
|
1049
|
-
amount: Optional[int] = None
|
|
1050
|
-
descriptor: Optional[str] = None
|
|
1051
1044
|
idempotency_key: str
|
|
1052
1045
|
legal_person_id: Optional[str] = None
|
|
1053
|
-
items:
|
|
1054
|
-
expires_in_hours: Optional[int] = Field(
|
|
1055
|
-
default=None,
|
|
1056
|
-
gt=0,
|
|
1057
|
-
le=MAX_TRANSFER_ORDER_EXPIRATION_HOURS,
|
|
1058
|
-
)
|
|
1046
|
+
items: list[TransferOrderLineRequest]
|
|
1059
1047
|
|
|
1060
1048
|
model_config = ConfigDict(
|
|
1061
1049
|
json_schema_extra={
|
|
1062
1050
|
'example': {
|
|
1063
|
-
'account_number': '646180157034181180',
|
|
1064
|
-
'recipient_name': 'Doroteo Arango',
|
|
1065
|
-
'amount': 100_00,
|
|
1066
|
-
'descriptor': 'Mezcal, pulque y tequila',
|
|
1067
1051
|
'idempotency_key': 'UNIQUE-KEY-003',
|
|
1068
1052
|
'legal_person_id': 'USWqY5cvkISJOxHyEKjAKf8w',
|
|
1053
|
+
'items': [
|
|
1054
|
+
{
|
|
1055
|
+
'account_number': '646180157034181180',
|
|
1056
|
+
'recipient_name': 'Doroteo Arango',
|
|
1057
|
+
'amount': 100_00,
|
|
1058
|
+
'descriptor': 'Mezcal, pulque y tequila',
|
|
1059
|
+
}
|
|
1060
|
+
],
|
|
1069
1061
|
}
|
|
1070
1062
|
},
|
|
1071
1063
|
)
|
|
1072
1064
|
|
|
1073
1065
|
@model_validator(mode='after')
|
|
1074
|
-
def
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
(
|
|
1078
|
-
self.account_number is not None,
|
|
1079
|
-
self.recipient_name is not None,
|
|
1080
|
-
self.amount is not None,
|
|
1081
|
-
self.descriptor is not None,
|
|
1082
|
-
)
|
|
1083
|
-
)
|
|
1084
|
-
if has_items == has_flat:
|
|
1085
|
-
raise ValueError(
|
|
1086
|
-
'Provide either a single transfer (account_number, '
|
|
1087
|
-
'recipient_name, amount, descriptor) or items[] for a batch, '
|
|
1088
|
-
'not both'
|
|
1089
|
-
)
|
|
1090
|
-
if self.items is not None:
|
|
1091
|
-
if len(self.items) > MAX_TRANSFER_ORDER_BATCH_LINES:
|
|
1092
|
-
raise ValueError(
|
|
1093
|
-
'Batch exceeds maximum of '
|
|
1094
|
-
f'{MAX_TRANSFER_ORDER_BATCH_LINES} lines'
|
|
1095
|
-
)
|
|
1096
|
-
if len(self.items) == 0:
|
|
1097
|
-
raise ValueError('items must not be empty')
|
|
1066
|
+
def validate_items(self) -> 'TransferOrderRequest':
|
|
1067
|
+
if len(self.items) == 0:
|
|
1068
|
+
raise ValueError('items must not be empty')
|
|
1098
1069
|
return self
|
|
1099
1070
|
|
|
1100
1071
|
|
|
1101
|
-
class
|
|
1102
|
-
|
|
1072
|
+
class UpdateTransferOrderRequest(BaseRequest):
|
|
1073
|
+
status: Literal[
|
|
1074
|
+
TransferOrderStatus.authorized, TransferOrderStatus.rejected
|
|
1075
|
+
]
|
|
1076
|
+
rejection_reason: Optional[str] = None
|
|
1103
1077
|
|
|
1104
1078
|
model_config = ConfigDict(
|
|
1105
1079
|
json_schema_extra={
|
|
1106
|
-
'
|
|
1080
|
+
'examples': [
|
|
1081
|
+
{'status': 'authorized'},
|
|
1082
|
+
{
|
|
1083
|
+
'status': 'rejected',
|
|
1084
|
+
'rejection_reason': 'Monto incorrecto',
|
|
1085
|
+
},
|
|
1086
|
+
]
|
|
1107
1087
|
},
|
|
1108
1088
|
)
|
|
1089
|
+
|
|
1090
|
+
@model_validator(mode='after')
|
|
1091
|
+
def validate_rejection_reason(self) -> 'UpdateTransferOrderRequest':
|
|
1092
|
+
if self.status is TransferOrderStatus.rejected:
|
|
1093
|
+
if (
|
|
1094
|
+
self.rejection_reason is None
|
|
1095
|
+
or not self.rejection_reason.strip()
|
|
1096
|
+
):
|
|
1097
|
+
raise ValueError('rejection_reason is required')
|
|
1098
|
+
elif self.rejection_reason is not None:
|
|
1099
|
+
raise ValueError(
|
|
1100
|
+
'rejection_reason is only allowed when status is rejected'
|
|
1101
|
+
)
|
|
1102
|
+
return self
|
cuenca_validations/version.py
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
__version__ = '2.1.
|
|
1
|
+
__version__ = '2.1.49.dev0'
|
{cuenca_validations-2.1.48.dev1.dist-info → cuenca_validations-2.1.49.dev0.dist-info}/RECORD
RENAMED
|
@@ -4,8 +4,8 @@ cuenca_validations/errors.py,sha256=OtM8EgiKqYdz9Hn66AbBO96orL1or7efkyt0vh0Zxbs,
|
|
|
4
4
|
cuenca_validations/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
5
5
|
cuenca_validations/typing.py,sha256=1QCu81IbVZZpyInjyeAuO-nF36gpT5Gi4o6V9PozuOU,204
|
|
6
6
|
cuenca_validations/validators.py,sha256=zXSnU5-EMbQZBD-PfFXgP4Z6G7cm7KFDWXB7Nie6WUk,2682
|
|
7
|
-
cuenca_validations/version.py,sha256=
|
|
8
|
-
cuenca_validations/types/__init__.py,sha256=
|
|
7
|
+
cuenca_validations/version.py,sha256=E1OKARtICq_n0Q4ukZ9yaw-H6GS0VhkKcaXf2C4kIGg,28
|
|
8
|
+
cuenca_validations/types/__init__.py,sha256=M657giDGa3sejskWMPIAfCXJHDgbh4p9J9BnheKJR-A,6711
|
|
9
9
|
cuenca_validations/types/card.py,sha256=UGzz8NTFAverUmdUKAK1oGHnOnjSNTpIRUm93vKSSGY,1295
|
|
10
10
|
cuenca_validations/types/enums.py,sha256=If8N4-AbM9daHmnH6txmBb9AqN0Ey7gi3jmkOZOIDAU,21104
|
|
11
11
|
cuenca_validations/types/files.py,sha256=2CszbwF9ytXV9suFFwyDjYG4XxY8UhCjRw3HttVXXNw,269
|
|
@@ -14,17 +14,17 @@ cuenca_validations/types/helpers.py,sha256=4veeLZbugHHqZk0ezSim978VhH6Vq8XTrEhe1
|
|
|
14
14
|
cuenca_validations/types/identities.py,sha256=j2xxh3UYHJe6IbAwr9yNXJkebTth_-g3SUmHeiPez8M,5513
|
|
15
15
|
cuenca_validations/types/morals.py,sha256=davabh5hAnFVQyM7-yCyDaT5ewXnm0cr1BtqDIwzkX8,1833
|
|
16
16
|
cuenca_validations/types/queries.py,sha256=yJZGW3p6uWGaBm6mjDp7KBgg7oLh0CUlAJeeVLRzowk,6134
|
|
17
|
-
cuenca_validations/types/requests.py,sha256=
|
|
18
|
-
cuenca_validations-2.1.
|
|
17
|
+
cuenca_validations/types/requests.py,sha256=26YyfGHh1egdjAHUWTDjTtelXARWKNPB6npPHkW1Tcg,32336
|
|
18
|
+
cuenca_validations-2.1.49.dev0.dist-info/licenses/LICENSE,sha256=wR76FmxBbfnQpwELkkE5iMF8sFIafEMgXLTE4N4WPTc,1063
|
|
19
19
|
tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
20
20
|
tests/test_card.py,sha256=QAfRz7e11gWICPnFJZ2tiYgUsFV3C9TwzJXrDnDNXFw,1202
|
|
21
21
|
tests/test_errors.py,sha256=ixiIgEuBuzfsL5p4uCFdF32XqFRtTPF6EVhGJ0keOrI,930
|
|
22
22
|
tests/test_helpers.py,sha256=fx2R7y6oQO8XeQzevJe826NuHkBgvtznZicomchB3Gg,899
|
|
23
|
-
tests/test_requests.py,sha256=
|
|
23
|
+
tests/test_requests.py,sha256=NlXAvKDLyVy0tYDUHy3oNkxeX1KcA-dfyqwftddHWBo,10627
|
|
24
24
|
tests/test_statement.py,sha256=IOE0rRRBgBZSJv_FLaETEyn5NzzXKMNTqgjv99GX-68,1436
|
|
25
25
|
tests/test_types.py,sha256=rPjqPGfPU73MSdbeJpoW_ai5TAO25hWSnQAt_H7ZIeI,23055
|
|
26
26
|
tests/test_validators.py,sha256=Jjr9gWTT4cRntGiKvQK4fncqx3JkEuTWkKm1VqpRHTs,1829
|
|
27
|
-
cuenca_validations-2.1.
|
|
28
|
-
cuenca_validations-2.1.
|
|
29
|
-
cuenca_validations-2.1.
|
|
30
|
-
cuenca_validations-2.1.
|
|
27
|
+
cuenca_validations-2.1.49.dev0.dist-info/METADATA,sha256=7CzNDGl4cHPMNcq-p0u36AMzFYj2tFFmM34sc-pfn_E,1600
|
|
28
|
+
cuenca_validations-2.1.49.dev0.dist-info/WHEEL,sha256=YVMoNqKzERt-wjUZwJ33xBGAwnFl-4cqbYkTtWa4itE,91
|
|
29
|
+
cuenca_validations-2.1.49.dev0.dist-info/top_level.txt,sha256=4233xdOs2HtuT-GFRjcDcwK0IwdwvWdczOtk0fPB6Gw,25
|
|
30
|
+
cuenca_validations-2.1.49.dev0.dist-info/RECORD,,
|
tests/test_requests.py
CHANGED
|
@@ -5,17 +5,18 @@ from pydantic_extra_types.phone_numbers import PhoneNumber
|
|
|
5
5
|
from cuenca_validations.types.enums import (
|
|
6
6
|
Country,
|
|
7
7
|
OperatorRole,
|
|
8
|
+
TransferOrderStatus,
|
|
8
9
|
VerificationType,
|
|
9
10
|
)
|
|
10
11
|
from cuenca_validations.types.queries import OperatorQuery
|
|
11
12
|
from cuenca_validations.types.requests import (
|
|
12
|
-
MAX_TRANSFER_ORDER_BATCH_LINES,
|
|
13
13
|
OperatorLoginRequest,
|
|
14
14
|
OperatorLoginUpdateRequest,
|
|
15
15
|
OperatorRequest,
|
|
16
16
|
OperatorUpdateRequest,
|
|
17
17
|
PasswordResetRequest,
|
|
18
18
|
TransferOrderRequest,
|
|
19
|
+
UpdateTransferOrderRequest,
|
|
19
20
|
UpdateTransferRequest,
|
|
20
21
|
UserTOSAgreementRequest,
|
|
21
22
|
UserUpdateRequest,
|
|
@@ -244,26 +245,73 @@ def test_transfer_order_request_shape() -> None:
|
|
|
244
245
|
'descriptor': 'Mezcal',
|
|
245
246
|
}
|
|
246
247
|
single = TransferOrderRequest.model_validate(
|
|
247
|
-
{
|
|
248
|
+
{'idempotency_key': 'single', 'items': [line]}
|
|
248
249
|
)
|
|
249
|
-
assert single.items is None
|
|
250
|
+
assert single.items is not None
|
|
251
|
+
assert len(single.items) == 1
|
|
250
252
|
batch = TransferOrderRequest.model_validate(
|
|
251
|
-
{'idempotency_key': 'batch', 'items': [line]}
|
|
253
|
+
{'idempotency_key': 'batch', 'items': [line, line]}
|
|
252
254
|
)
|
|
253
255
|
assert batch.items is not None
|
|
256
|
+
assert len(batch.items) == 2
|
|
254
257
|
|
|
255
|
-
with pytest.raises(ValidationError, match='not both'):
|
|
256
|
-
TransferOrderRequest.model_validate(
|
|
257
|
-
{**line, 'idempotency_key': 'both', 'items': [line]}
|
|
258
|
-
)
|
|
259
258
|
with pytest.raises(ValidationError, match='items must not be empty'):
|
|
260
259
|
TransferOrderRequest.model_validate(
|
|
261
|
-
{
|
|
260
|
+
{'idempotency_key': 'empty', 'items': []}
|
|
262
261
|
)
|
|
263
|
-
with pytest.raises(ValidationError
|
|
264
|
-
TransferOrderRequest.model_validate(
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
262
|
+
with pytest.raises(ValidationError):
|
|
263
|
+
TransferOrderRequest.model_validate({'idempotency_key': 'missing'})
|
|
264
|
+
|
|
265
|
+
|
|
266
|
+
def test_update_transfer_order_request_authorized() -> None:
|
|
267
|
+
req = UpdateTransferOrderRequest.model_validate({'status': 'authorized'})
|
|
268
|
+
assert req.status is TransferOrderStatus.authorized
|
|
269
|
+
assert req.rejection_reason is None
|
|
270
|
+
|
|
271
|
+
|
|
272
|
+
def test_update_transfer_order_request_rejected() -> None:
|
|
273
|
+
req = UpdateTransferOrderRequest.model_validate(
|
|
274
|
+
{'status': 'rejected', 'rejection_reason': 'Monto incorrecto'}
|
|
275
|
+
)
|
|
276
|
+
assert req.status is TransferOrderStatus.rejected
|
|
277
|
+
assert req.rejection_reason == 'Monto incorrecto'
|
|
278
|
+
|
|
279
|
+
|
|
280
|
+
def test_update_transfer_order_request_rejected_requires_reason() -> None:
|
|
281
|
+
with pytest.raises(ValidationError, match='rejection_reason is required'):
|
|
282
|
+
UpdateTransferOrderRequest.model_validate({'status': 'rejected'})
|
|
283
|
+
with pytest.raises(ValidationError, match='rejection_reason is required'):
|
|
284
|
+
UpdateTransferOrderRequest.model_validate(
|
|
285
|
+
{'status': 'rejected', 'rejection_reason': ''}
|
|
286
|
+
)
|
|
287
|
+
with pytest.raises(ValidationError, match='rejection_reason is required'):
|
|
288
|
+
UpdateTransferOrderRequest.model_validate(
|
|
289
|
+
{'status': 'rejected', 'rejection_reason': ' '}
|
|
269
290
|
)
|
|
291
|
+
|
|
292
|
+
|
|
293
|
+
def test_update_transfer_order_request_authorized_forbids_reason() -> None:
|
|
294
|
+
with pytest.raises(
|
|
295
|
+
ValidationError,
|
|
296
|
+
match='rejection_reason is only allowed when status is rejected',
|
|
297
|
+
):
|
|
298
|
+
UpdateTransferOrderRequest.model_validate(
|
|
299
|
+
{'status': 'authorized', 'rejection_reason': 'no'}
|
|
300
|
+
)
|
|
301
|
+
|
|
302
|
+
|
|
303
|
+
def test_update_transfer_order_request_rejects_invalid_status() -> None:
|
|
304
|
+
with pytest.raises(ValidationError):
|
|
305
|
+
UpdateTransferOrderRequest.model_validate({'status': 'created'})
|
|
306
|
+
with pytest.raises(ValidationError):
|
|
307
|
+
UpdateTransferOrderRequest.model_validate({'status': 'expired'})
|
|
308
|
+
with pytest.raises(ValidationError):
|
|
309
|
+
UpdateTransferOrderRequest.model_validate({})
|
|
310
|
+
|
|
311
|
+
|
|
312
|
+
def test_update_transfer_order_request_forbids_extra() -> None:
|
|
313
|
+
with pytest.raises(ValidationError) as ex:
|
|
314
|
+
UpdateTransferOrderRequest.model_validate(
|
|
315
|
+
{'status': 'authorized', 'operator_id': 'OP123'}
|
|
316
|
+
)
|
|
317
|
+
assert 'Extra inputs are not permitted' in str(ex.value)
|
|
File without changes
|
|
File without changes
|
{cuenca_validations-2.1.48.dev1.dist-info → cuenca_validations-2.1.49.dev0.dist-info}/top_level.txt
RENAMED
|
File without changes
|