cuenca-validations 2.1.35.dev1__py3-none-any.whl → 2.1.36.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 +8 -2
- cuenca_validations/types/enums.py +8 -0
- cuenca_validations/types/queries.py +0 -2
- cuenca_validations/types/requests.py +20 -15
- cuenca_validations/version.py +1 -1
- {cuenca_validations-2.1.35.dev1.dist-info → cuenca_validations-2.1.36.dev0.dist-info}/METADATA +1 -1
- {cuenca_validations-2.1.35.dev1.dist-info → cuenca_validations-2.1.36.dev0.dist-info}/RECORD +12 -12
- tests/test_requests.py +0 -29
- tests/test_types.py +57 -28
- {cuenca_validations-2.1.35.dev1.dist-info → cuenca_validations-2.1.36.dev0.dist-info}/WHEEL +0 -0
- {cuenca_validations-2.1.35.dev1.dist-info → cuenca_validations-2.1.36.dev0.dist-info}/licenses/LICENSE +0 -0
- {cuenca_validations-2.1.35.dev1.dist-info → cuenca_validations-2.1.36.dev0.dist-info}/top_level.txt +0 -0
|
@@ -44,6 +44,10 @@ __all__ = [
|
|
|
44
44
|
'FileBatchUploadRequest',
|
|
45
45
|
'FileRequest',
|
|
46
46
|
'FileUploadRequest',
|
|
47
|
+
'FraudFundsTransferErrorResponse',
|
|
48
|
+
'FraudFundsTransferReasonCode',
|
|
49
|
+
'FraudFundsTransferRequest',
|
|
50
|
+
'FraudFundsTransferSuccessResponse',
|
|
47
51
|
'Gender',
|
|
48
52
|
'IncomeType',
|
|
49
53
|
'IssuerNetwork',
|
|
@@ -91,7 +95,6 @@ __all__ = [
|
|
|
91
95
|
'TransferNetwork',
|
|
92
96
|
'TransferQuery',
|
|
93
97
|
'TransferRequest',
|
|
94
|
-
'UpdateTransferRequest',
|
|
95
98
|
'UserCardNotification',
|
|
96
99
|
'UserCredentialRequest',
|
|
97
100
|
'UserCredentialUpdateRequest',
|
|
@@ -144,6 +147,7 @@ from .enums import (
|
|
|
144
147
|
EventType,
|
|
145
148
|
FileExtension,
|
|
146
149
|
FileFormat,
|
|
150
|
+
FraudFundsTransferReasonCode,
|
|
147
151
|
Gender,
|
|
148
152
|
IncomeType,
|
|
149
153
|
IssuerNetwork,
|
|
@@ -231,6 +235,9 @@ from .requests import (
|
|
|
231
235
|
FileBatchUploadRequest,
|
|
232
236
|
FileRequest,
|
|
233
237
|
FileUploadRequest,
|
|
238
|
+
FraudFundsTransferErrorResponse,
|
|
239
|
+
FraudFundsTransferRequest,
|
|
240
|
+
FraudFundsTransferSuccessResponse,
|
|
234
241
|
KYCValidationRequest,
|
|
235
242
|
LimitedWalletRequest,
|
|
236
243
|
PartnerRequest,
|
|
@@ -244,7 +251,6 @@ from .requests import (
|
|
|
244
251
|
StrictTransferRequest,
|
|
245
252
|
TOSRequest,
|
|
246
253
|
TransferRequest,
|
|
247
|
-
UpdateTransferRequest,
|
|
248
254
|
UserCredentialRequest,
|
|
249
255
|
UserCredentialUpdateRequest,
|
|
250
256
|
UserListsRequest,
|
|
@@ -79,6 +79,14 @@ class TransactionStatus(str, Enum):
|
|
|
79
79
|
failed = 'failed'
|
|
80
80
|
|
|
81
81
|
|
|
82
|
+
class FraudFundsTransferReasonCode(str, Enum):
|
|
83
|
+
user_not_found = 'USER_NOT_FOUND'
|
|
84
|
+
user_not_fraud_blocked = 'USER_NOT_FRAUD_BLOCKED'
|
|
85
|
+
insufficient_funds = 'INSUFFICIENT_FUNDS'
|
|
86
|
+
clabe_invalid = 'CLABE_INVALID'
|
|
87
|
+
internal_error = 'INTERNAL_ERROR'
|
|
88
|
+
|
|
89
|
+
|
|
82
90
|
class TransferNetwork(str, Enum):
|
|
83
91
|
internal = 'internal'
|
|
84
92
|
spei = 'spei'
|
|
@@ -154,11 +154,9 @@ class WalletTransactionQuery(QueryParams):
|
|
|
154
154
|
|
|
155
155
|
|
|
156
156
|
class UserQuery(QueryParams):
|
|
157
|
-
ids: Optional[list[str]] = Field(default=None, max_length=MAX_PAGE_SIZE)
|
|
158
157
|
phone_number: Optional[str] = None
|
|
159
158
|
email_address: Optional[EmailStr] = None
|
|
160
159
|
status: Optional[UserStatus] = None
|
|
161
|
-
is_blocked: Optional[bool] = None
|
|
162
160
|
identity_uri: Optional[str] = None
|
|
163
161
|
has_curp_document: Optional[bool] = None
|
|
164
162
|
clabe: Optional[Clabe] = None
|
|
@@ -29,6 +29,7 @@ from ..types.enums import (
|
|
|
29
29
|
Country,
|
|
30
30
|
EcommerceIndicator,
|
|
31
31
|
FileExtension,
|
|
32
|
+
FraudFundsTransferReasonCode,
|
|
32
33
|
Gender,
|
|
33
34
|
IncomeType,
|
|
34
35
|
IssuerNetwork,
|
|
@@ -45,7 +46,6 @@ from ..types.enums import (
|
|
|
45
46
|
State,
|
|
46
47
|
TermsOfService,
|
|
47
48
|
TrackDataMethod,
|
|
48
|
-
TransactionStatus,
|
|
49
49
|
TransactionTokenValidationStatus,
|
|
50
50
|
UserCardNotification,
|
|
51
51
|
UserStatus,
|
|
@@ -155,20 +155,6 @@ class StrictTransferRequest(BaseTransferRequest):
|
|
|
155
155
|
)
|
|
156
156
|
|
|
157
157
|
|
|
158
|
-
class UpdateTransferRequest(BaseRequest):
|
|
159
|
-
status: TransactionStatus
|
|
160
|
-
|
|
161
|
-
@field_validator('status')
|
|
162
|
-
@classmethod
|
|
163
|
-
def validate_status(cls, status: TransactionStatus) -> TransactionStatus:
|
|
164
|
-
if status not in (
|
|
165
|
-
TransactionStatus.succeeded,
|
|
166
|
-
TransactionStatus.failed,
|
|
167
|
-
):
|
|
168
|
-
raise ValueError('status must be succeeded or failed')
|
|
169
|
-
return status
|
|
170
|
-
|
|
171
|
-
|
|
172
158
|
class CardUpdateRequest(BaseRequest):
|
|
173
159
|
status: Optional[CardStatus] = None
|
|
174
160
|
pin_block: Optional[str] = None
|
|
@@ -324,6 +310,25 @@ class WalletTransactionRequest(BaseRequest):
|
|
|
324
310
|
amount: StrictPositiveInt
|
|
325
311
|
|
|
326
312
|
|
|
313
|
+
class FraudFundsTransferRequest(BaseRequest):
|
|
314
|
+
request_id: NonEmptyStr
|
|
315
|
+
user_id: NonEmptyStr
|
|
316
|
+
clabe: Clabe
|
|
317
|
+
amount: Optional[StrictPositiveInt] = None
|
|
318
|
+
concepto: Optional[NonEmptyStr] = None
|
|
319
|
+
|
|
320
|
+
|
|
321
|
+
class FraudFundsTransferSuccessResponse(BaseRequest):
|
|
322
|
+
transaction_id: NonEmptyStr
|
|
323
|
+
amount: StrictPositiveInt
|
|
324
|
+
clave_rastreo: NonEmptyStr
|
|
325
|
+
|
|
326
|
+
|
|
327
|
+
class FraudFundsTransferErrorResponse(BaseRequest):
|
|
328
|
+
reason_code: FraudFundsTransferReasonCode
|
|
329
|
+
message: NonEmptyStr
|
|
330
|
+
|
|
331
|
+
|
|
327
332
|
class FraudValidationRequest(BaseModel):
|
|
328
333
|
amount: StrictPositiveInt
|
|
329
334
|
merchant_name: str
|
cuenca_validations/version.py
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
__version__ = '2.1.
|
|
1
|
+
__version__ = '2.1.36.dev0'
|
{cuenca_validations-2.1.35.dev1.dist-info → cuenca_validations-2.1.36.dev0.dist-info}/RECORD
RENAMED
|
@@ -4,27 +4,27 @@ 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=ZTTZbKLgrsc7eKRxJttcvmfXh67hnvcRwc_ZNNFFnTk,28
|
|
8
|
+
cuenca_validations/types/__init__.py,sha256=hvnj0A-oxSr6hBxuAELHhoHeE6VvXZ2QXIRO7Sw3EeA,5809
|
|
9
9
|
cuenca_validations/types/card.py,sha256=UGzz8NTFAverUmdUKAK1oGHnOnjSNTpIRUm93vKSSGY,1295
|
|
10
|
-
cuenca_validations/types/enums.py,sha256=
|
|
10
|
+
cuenca_validations/types/enums.py,sha256=we9to83E3QGcx29rKXVGCPkAmB7T9r1YcGu58dvkamQ,20847
|
|
11
11
|
cuenca_validations/types/files.py,sha256=2CszbwF9ytXV9suFFwyDjYG4XxY8UhCjRw3HttVXXNw,269
|
|
12
12
|
cuenca_validations/types/general.py,sha256=eYFYwyx_a4_J480GYpqW3DFbZabDFcUjvLRMQbShIUc,5622
|
|
13
13
|
cuenca_validations/types/helpers.py,sha256=4veeLZbugHHqZk0ezSim978VhH6Vq8XTrEhe1eE_r3A,1531
|
|
14
14
|
cuenca_validations/types/identities.py,sha256=j2xxh3UYHJe6IbAwr9yNXJkebTth_-g3SUmHeiPez8M,5513
|
|
15
15
|
cuenca_validations/types/morals.py,sha256=davabh5hAnFVQyM7-yCyDaT5ewXnm0cr1BtqDIwzkX8,1833
|
|
16
|
-
cuenca_validations/types/queries.py,sha256=
|
|
17
|
-
cuenca_validations/types/requests.py,sha256
|
|
18
|
-
cuenca_validations-2.1.
|
|
16
|
+
cuenca_validations/types/queries.py,sha256=iVr6Z8ahXon0rlqQLu7aqRY6WtRxkN-1C7A2zeVt2-4,5314
|
|
17
|
+
cuenca_validations/types/requests.py,sha256=-PmmTHNGHXKq4wf5qN3tUMgczlsHmS8DUyx5vlY3bCE,24544
|
|
18
|
+
cuenca_validations-2.1.36.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=lQgOPjLsogpMphl5wg--vxj9JF2DJF0A2DzQVG5dOEU,3072
|
|
24
24
|
tests/test_statement.py,sha256=IOE0rRRBgBZSJv_FLaETEyn5NzzXKMNTqgjv99GX-68,1436
|
|
25
|
-
tests/test_types.py,sha256=
|
|
25
|
+
tests/test_types.py,sha256=xPBOWsz-VFT8CxfwCAulLshkZKZkIJTjZP40GxwsLgI,23019
|
|
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.36.dev0.dist-info/METADATA,sha256=VuMgdvHupkIGPO8H-y5rCOjT9H_hSjhzQ129_VHvIOU,1600
|
|
28
|
+
cuenca_validations-2.1.36.dev0.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
|
|
29
|
+
cuenca_validations-2.1.36.dev0.dist-info/top_level.txt,sha256=4233xdOs2HtuT-GFRjcDcwK0IwdwvWdczOtk0fPB6Gw,25
|
|
30
|
+
cuenca_validations-2.1.36.dev0.dist-info/RECORD,,
|
tests/test_requests.py
CHANGED
|
@@ -5,7 +5,6 @@ from pydantic_extra_types.phone_numbers import PhoneNumber
|
|
|
5
5
|
from cuenca_validations.types.enums import VerificationType
|
|
6
6
|
from cuenca_validations.types.requests import (
|
|
7
7
|
PasswordResetRequest,
|
|
8
|
-
UpdateTransferRequest,
|
|
9
8
|
UserTOSAgreementRequest,
|
|
10
9
|
UserUpdateRequest,
|
|
11
10
|
VerificationRequest,
|
|
@@ -95,31 +94,3 @@ def test_user_update_request_normalizes_email() -> None:
|
|
|
95
94
|
def test_user_update_request_normalizes_phone() -> None:
|
|
96
95
|
req = UserUpdateRequest(phone_number=PhoneNumber('+116504401222'))
|
|
97
96
|
assert req.phone_number == '+16504401222'
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
@pytest.mark.parametrize('status', ['succeeded', 'failed'])
|
|
101
|
-
def test_update_transfer_request_valid_status(status: str) -> None:
|
|
102
|
-
req = UpdateTransferRequest.model_validate({'status': status})
|
|
103
|
-
assert req.status == status
|
|
104
|
-
assert req.model_dump() == {'status': status}
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
@pytest.mark.parametrize('status', ['created', 'submitted', 'in_review'])
|
|
108
|
-
def test_update_transfer_request_invalid_status(status: str) -> None:
|
|
109
|
-
with pytest.raises(ValidationError) as ex:
|
|
110
|
-
UpdateTransferRequest.model_validate({'status': status})
|
|
111
|
-
assert 'status' in str(ex.value)
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
def test_update_transfer_request_missing_status() -> None:
|
|
115
|
-
with pytest.raises(ValidationError) as ex:
|
|
116
|
-
UpdateTransferRequest.model_validate({})
|
|
117
|
-
assert 'status' in str(ex.value)
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
def test_update_transfer_request_forbids_extra() -> None:
|
|
121
|
-
with pytest.raises(ValidationError) as ex:
|
|
122
|
-
UpdateTransferRequest.model_validate(
|
|
123
|
-
{'status': 'succeeded', 'foo': 'bar'}
|
|
124
|
-
)
|
|
125
|
-
assert 'Extra inputs are not permitted' in str(ex.value)
|
tests/test_types.py
CHANGED
|
@@ -12,6 +12,10 @@ from pydantic.fields import FieldInfo
|
|
|
12
12
|
|
|
13
13
|
from cuenca_validations.types import (
|
|
14
14
|
CardQuery,
|
|
15
|
+
FraudFundsTransferErrorResponse,
|
|
16
|
+
FraudFundsTransferReasonCode,
|
|
17
|
+
FraudFundsTransferRequest,
|
|
18
|
+
FraudFundsTransferSuccessResponse,
|
|
15
19
|
JSONEncoder,
|
|
16
20
|
QueryParams,
|
|
17
21
|
SantizedDict,
|
|
@@ -247,34 +251,6 @@ def test_user_query_rejects_invalid(field, value):
|
|
|
247
251
|
UserQuery(**{field: value})
|
|
248
252
|
|
|
249
253
|
|
|
250
|
-
def test_user_query_accepts_ids_and_is_blocked():
|
|
251
|
-
query = UserQuery(ids=['US1', 'US2'], is_blocked=True)
|
|
252
|
-
assert query.ids == ['US1', 'US2']
|
|
253
|
-
assert query.is_blocked is True
|
|
254
|
-
dumped = query.model_dump(exclude_none=True)
|
|
255
|
-
assert dumped['ids'] == ['US1', 'US2']
|
|
256
|
-
assert dumped['is_blocked'] is True
|
|
257
|
-
assert isinstance(dumped['ids'], list)
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
def test_user_query_rejects_ids_over_limit():
|
|
261
|
-
with pytest.raises(ValidationError):
|
|
262
|
-
UserQuery(ids=[f'US{i}' for i in range(101)])
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
def test_user_query_ids_empty_list_ok():
|
|
266
|
-
query = UserQuery(ids=[])
|
|
267
|
-
assert query.ids == []
|
|
268
|
-
assert 'ids' in query.model_dump(exclude_none=True)
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
def test_user_query_ids_none_excluded_from_dump():
|
|
272
|
-
query = UserQuery()
|
|
273
|
-
dumped = query.model_dump(exclude_none=True)
|
|
274
|
-
assert 'ids' not in dumped
|
|
275
|
-
assert 'is_blocked' not in dumped
|
|
276
|
-
|
|
277
|
-
|
|
278
254
|
def test_exclude_none_in_dict():
|
|
279
255
|
request = ApiKeyUpdateRequest(user_id='US123')
|
|
280
256
|
assert request.model_dump() == dict(user_id='US123')
|
|
@@ -664,6 +640,59 @@ def test_bank_account_validation_clabe_request():
|
|
|
664
640
|
assert BankAccountValidationRequest(account_number='646180157098510917')
|
|
665
641
|
|
|
666
642
|
|
|
643
|
+
def test_fraud_funds_transfer_models():
|
|
644
|
+
request = FraudFundsTransferRequest(
|
|
645
|
+
request_id='f0a2b3-request-hash',
|
|
646
|
+
user_id='US123',
|
|
647
|
+
clabe='646180157098510917',
|
|
648
|
+
amount=10000,
|
|
649
|
+
concepto=' Devolución fraude ',
|
|
650
|
+
)
|
|
651
|
+
|
|
652
|
+
assert request.concepto == 'Devolución fraude'
|
|
653
|
+
assert request.model_dump() == {
|
|
654
|
+
'request_id': 'f0a2b3-request-hash',
|
|
655
|
+
'user_id': 'US123',
|
|
656
|
+
'clabe': '646180157098510917',
|
|
657
|
+
'amount': 10000,
|
|
658
|
+
'concepto': 'Devolución fraude',
|
|
659
|
+
}
|
|
660
|
+
|
|
661
|
+
request_full_balance = FraudFundsTransferRequest(
|
|
662
|
+
request_id='f0a2b3-request-hash',
|
|
663
|
+
user_id='US123',
|
|
664
|
+
clabe='646180157098510917',
|
|
665
|
+
)
|
|
666
|
+
|
|
667
|
+
assert request_full_balance.model_dump() == {
|
|
668
|
+
'request_id': 'f0a2b3-request-hash',
|
|
669
|
+
'user_id': 'US123',
|
|
670
|
+
'clabe': '646180157098510917',
|
|
671
|
+
}
|
|
672
|
+
|
|
673
|
+
success = FraudFundsTransferSuccessResponse(
|
|
674
|
+
transaction_id='SP123',
|
|
675
|
+
amount=10000,
|
|
676
|
+
clave_rastreo='CUENCA123',
|
|
677
|
+
)
|
|
678
|
+
|
|
679
|
+
assert success.model_dump() == {
|
|
680
|
+
'transaction_id': 'SP123',
|
|
681
|
+
'amount': 10000,
|
|
682
|
+
'clave_rastreo': 'CUENCA123',
|
|
683
|
+
}
|
|
684
|
+
|
|
685
|
+
error = FraudFundsTransferErrorResponse(
|
|
686
|
+
reason_code=FraudFundsTransferReasonCode.insufficient_funds,
|
|
687
|
+
message='Fondos insuficientes',
|
|
688
|
+
)
|
|
689
|
+
|
|
690
|
+
assert error.model_dump() == {
|
|
691
|
+
'reason_code': 'INSUFFICIENT_FUNDS',
|
|
692
|
+
'message': 'Fondos insuficientes',
|
|
693
|
+
}
|
|
694
|
+
|
|
695
|
+
|
|
667
696
|
@pytest.mark.parametrize(
|
|
668
697
|
'input_data',
|
|
669
698
|
[
|
|
File without changes
|
|
File without changes
|
{cuenca_validations-2.1.35.dev1.dist-info → cuenca_validations-2.1.36.dev0.dist-info}/top_level.txt
RENAMED
|
File without changes
|