diff --git a/cuenca/resources/sessions.py b/cuenca/resources/sessions.py index ba51be64..91bc76fa 100644 --- a/cuenca/resources/sessions.py +++ b/cuenca/resources/sessions.py @@ -20,6 +20,7 @@ class Session(Creatable, Retrievable, Queryable): success_url: Optional[SerializableAnyUrl] = None failure_url: Optional[SerializableAnyUrl] = None type: Optional[SessionType] = None + resource_id: Optional[str] = None model_config = ConfigDict( json_schema_extra={ @@ -32,6 +33,7 @@ class Session(Creatable, Retrievable, Queryable): 'success_url': 'http://example_success.com', 'failure_url': 'http://example_failure.com', 'type': 'session.registration', + 'resource_id': 'some_resource_id', } } ) @@ -43,6 +45,7 @@ def create( type: SessionType, success_url: Optional[str] = None, failure_url: Optional[str] = None, + resource_id: Optional[str] = None, *, session: http.Session = http.session, ) -> 'Session': @@ -51,5 +54,6 @@ def create( type=type, success_url=success_url, failure_url=failure_url, + resource_id=resource_id, ) return cls._create(session=session, **req.model_dump()) diff --git a/cuenca/version.py b/cuenca/version.py index 3d0c0861..4cd1c0f6 100644 --- a/cuenca/version.py +++ b/cuenca/version.py @@ -1,3 +1,3 @@ -__version__ = '2.1.10' +__version__ = '2.1.11' CLIENT_VERSION = __version__ API_VERSION = '2020-03-19' diff --git a/requirements.txt b/requirements.txt index 9243749f..27446495 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,3 @@ requests==2.32.3 -cuenca-validations==2.1.16 +cuenca-validations==2.1.17.dev4 pydantic-extra-types==2.10.2 diff --git a/tests/conftest.py b/tests/conftest.py index c22b96f3..ecdab318 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,11 +1,14 @@ import datetime as dt from io import BytesIO +from typing import Any, Generator import pytest -from cuenca_validations.types import Country, Gender, State +from cuenca_validations.types import Country, Gender, SessionType, State from cuenca_validations.types.enums import Profession import cuenca +from cuenca.http import Session as ClientSession +from cuenca.resources.sessions import Session cuenca.configure(sandbox=True) @@ -76,3 +79,23 @@ def user_lists_request() -> dict: def file() -> BytesIO: with open('tests/data/test_file.jpeg', 'rb') as image_file: return BytesIO(image_file.read()) + + +@pytest.fixture +def session_with_resource_id() -> Generator[Session, Any, Any]: + session = Session.create( + 'USPR4JxMuwSG60u2h4gBpB6Q', + SessionType.onboarding_verification, + resource_id='68b887f60c33abad1ea841d3', + ) + yield session + + +@pytest.fixture +def client_authed_with_session( + session_with_resource_id: Session, +) -> Generator[ClientSession, Any, Any]: + client = ClientSession() + client.configure(session_token=session_with_resource_id.id, sandbox=True) + client.basic_auth = ('', '') + yield client diff --git a/tests/resources/cassettes/test_session_create_with_resource_id.yaml b/tests/resources/cassettes/test_session_create_with_resource_id.yaml new file mode 100644 index 00000000..44527c65 --- /dev/null +++ b/tests/resources/cassettes/test_session_create_with_resource_id.yaml @@ -0,0 +1,47 @@ +interactions: +- request: + body: '{"user_id": "USPR4JxMuwSG60u2h4gBpB6Q", "type": "session.onboarding_verification", + "resource_id": "68b887f60c33abad1ea841d3"}' + headers: + Authorization: + - DUMMY + Content-Length: + - '125' + Content-Type: + - application/json + User-Agent: + - cuenca-python/2.1.11 + X-Cuenca-Api-Version: + - '2020-03-19' + method: POST + uri: https://sandbox.cuenca.com/sessions + response: + body: + string: '{"id":"SS-x6PU8GxSpKYL9btp4Btog","created_at":"2025-09-10T20:33:32.483427","user_id":"USPR4JxMuwSG60u2h4gBpB6Q","platform_id":"PTZbBlk__kQt-wfwzP5nwA9A","expires_at":"2025-09-10T20:43:32.483438","success_url":null,"failure_url":null,"type":"session.onboarding_verification","resource_id":"68b887f60c33abad1ea841d3"}' + headers: + Connection: + - keep-alive + Content-Length: + - '315' + Content-Type: + - application/json + Date: + - Wed, 10 Sep 2025 20:33:32 GMT + X-Request-Time: + - 'value: 0.167' + x-amz-apigw-id: + - QtAIfG7eCYcEsfQ= + x-amzn-Remapped-Connection: + - keep-alive + x-amzn-Remapped-Content-Length: + - '315' + x-amzn-Remapped-Date: + - Wed, 10 Sep 2025 20:33:32 GMT + x-amzn-Remapped-Server: + - nginx/1.28.0 + x-amzn-RequestId: + - deb095dd-c1c6-4837-b5ac-54a0c41d9fb2 + status: + code: 201 + message: Created +version: 1 diff --git a/tests/resources/cassettes/test_session_with_resource_id_authorized.yaml b/tests/resources/cassettes/test_session_with_resource_id_authorized.yaml new file mode 100644 index 00000000..9a02d01a --- /dev/null +++ b/tests/resources/cassettes/test_session_with_resource_id_authorized.yaml @@ -0,0 +1,88 @@ +interactions: + - request: + body: + '{"user_id": "USPR4JxMuwSG60u2h4gBpB6Q", "type": "session.onboarding_verification", + "resource_id": "68b887f60c33abad1ea841d3"}' + headers: + Authorization: + - DUMMY + Content-Length: + - "125" + Content-Type: + - application/json + User-Agent: + - cuenca-python/2.1.11 + X-Cuenca-Api-Version: + - "2020-03-19" + method: POST + uri: https://sandbox.cuenca.com/sessions + response: + body: + string: '{"id":"SSOXga_D_VQXCPsWQT7Z0ddQ","created_at":"2025-09-10T20:33:32.875517","user_id":"USPR4JxMuwSG60u2h4gBpB6Q","platform_id":"PTZbBlk__kQt-wfwzP5nwA9A","expires_at":"2025-09-10T20:43:32.875529","success_url":null,"failure_url":null,"type":"session.onboarding_verification","resource_id":"68b887f60c33abad1ea841d3"}' + headers: + Connection: + - keep-alive + Content-Length: + - "315" + Content-Type: + - application/json + Date: + - Wed, 10 Sep 2025 20:33:32 GMT + X-Request-Time: + - "value: 0.151" + x-amz-apigw-id: + - QtAIjGCGiYcEuZw= + x-amzn-Remapped-Connection: + - keep-alive + x-amzn-Remapped-Content-Length: + - "315" + x-amzn-Remapped-Date: + - Wed, 10 Sep 2025 20:33:32 GMT + x-amzn-Remapped-Server: + - nginx/1.28.0 + x-amzn-RequestId: + - 0d6c920d-4608-4d1c-9858-fe81fccba4b1 + status: + code: 201 + message: Created + - request: + body: null + headers: + User-Agent: + - cuenca-python/2.1.11 + X-Cuenca-Api-Version: + - "2020-03-19" + X-Cuenca-SessionId: + - SSOXga_D_VQXCPsWQT7Z0ddQ + method: GET + uri: https://sandbox.cuenca.com/onboarding_verifications/68b887f60c33abad1ea841d3 + response: + body: + string: '{"gov_id_document_number":"267202610","gov_id_front":"https://media-cdn.prod.metamap.com","proof_of_address":"https://media-cdn.prod.metamap.com","liveness_selfie":"https://media-cdn.prod.metamap.com"}' + headers: + Connection: + - keep-alive + Content-Length: + - "2359" + Content-Type: + - application/json + Date: + - Wed, 10 Sep 2025 20:33:33 GMT + X-Request-Time: + - "value: 0.388" + x-amz-apigw-id: + - QtAImGe5iYcEi4g= + x-amzn-Remapped-Connection: + - keep-alive + x-amzn-Remapped-Content-Length: + - "2359" + x-amzn-Remapped-Date: + - Wed, 10 Sep 2025 20:33:33 GMT + x-amzn-Remapped-Server: + - nginx/1.28.0 + x-amzn-RequestId: + - 848ed62c-6ec3-4150-a3fb-5a082cb313b4 + status: + code: 200 + message: OK +version: 1 diff --git a/tests/resources/cassettes/test_session_with_resource_id_unauthorized.yaml b/tests/resources/cassettes/test_session_with_resource_id_unauthorized.yaml new file mode 100644 index 00000000..4c5cf043 --- /dev/null +++ b/tests/resources/cassettes/test_session_with_resource_id_unauthorized.yaml @@ -0,0 +1,86 @@ +interactions: + - request: + body: + '{"user_id": "USPR4JxMuwSG60u2h4gBpB6Q", "type": "session.onboarding_verification", + "resource_id": "68b887f60c33abad1ea841d3"}' + headers: + Authorization: + - DUMMY + Content-Length: + - "125" + Content-Type: + - application/json + User-Agent: + - cuenca-python/2.1.11 + X-Cuenca-Api-Version: + - "2020-03-19" + method: POST + uri: https://sandbox.cuenca.com/sessions + response: + body: + string: '{"id":"SSsxQina5sTNii7gv--OXg1g","created_at":"2025-09-10T20:34:31.525777","user_id":"USPR4JxMuwSG60u2h4gBpB6Q","platform_id":"PTZbBlk__kQt-wfwzP5nwA9A","expires_at":"2025-09-10T20:44:31.525789","success_url":null,"failure_url":null,"type":"session.onboarding_verification","resource_id":"68b887f60c33abad1ea841d3"}' + headers: + Connection: + - keep-alive + Content-Length: + - "315" + Content-Type: + - application/json + Date: + - Wed, 10 Sep 2025 20:34:31 GMT + X-Request-Time: + - "value: 0.129" + x-amz-apigw-id: + - QtARtGC6iYcEJYA= + x-amzn-Remapped-Connection: + - keep-alive + x-amzn-Remapped-Content-Length: + - "315" + x-amzn-Remapped-Date: + - Wed, 10 Sep 2025 20:34:31 GMT + x-amzn-Remapped-Server: + - nginx/1.28.0 + x-amzn-RequestId: + - 965c6cc2-31d3-4024-9c21-09ae6d4da534 + status: + code: 201 + message: Created + - request: + body: null + headers: + User-Agent: + - cuenca-python/2.1.11 + X-Cuenca-Api-Version: + - "2020-03-19" + X-Cuenca-SessionId: + - SSsxQina5sTNii7gv--OXg1g + method: GET + uri: https://sandbox.cuenca.com/onboarding_verifications/68b887f60c33abad1ea841d4 + response: + body: + string: '{"error":"User has not enough permissions"}' + headers: + Connection: + - keep-alive + Content-Length: + - "43" + Content-Type: + - application/json + Date: + - Wed, 10 Sep 2025 20:34:31 GMT + x-amz-apigw-id: + - QtARxHZtCYcEoCg= + x-amzn-Remapped-Connection: + - keep-alive + x-amzn-Remapped-Content-Length: + - "43" + x-amzn-Remapped-Date: + - Wed, 10 Sep 2025 20:34:31 GMT + x-amzn-Remapped-Server: + - nginx/1.28.0 + x-amzn-RequestId: + - c9539c27-70d2-4821-8afc-4bd7146253ef + status: + code: 401 + message: Unauthorized +version: 1 diff --git a/tests/resources/test_sessions.py b/tests/resources/test_sessions.py index cd57dba0..4830cb45 100644 --- a/tests/resources/test_sessions.py +++ b/tests/resources/test_sessions.py @@ -2,7 +2,8 @@ from cuenca_validations.types import Profession, SessionType from pydantic import ValidationError -import cuenca +from cuenca.exc import CuencaResponseException +from cuenca.http import Session as ClientSession from cuenca.resources import CurpValidation, Session, User @@ -33,8 +34,40 @@ def test_session_create(curp_validation_request: dict, user_request: dict): assert user_session.user_id == user.id assert user_session.type == SessionType.registration - ephimeral_cuenca_session = cuenca.http.Session() + ephimeral_cuenca_session = ClientSession() ephimeral_cuenca_session.configure(session_token=user_session.id) user = User.update(user.id, profession=Profession.comercio) assert user.profession == Profession.comercio + + +@pytest.mark.vcr +def test_session_create_with_resource_id( + session_with_resource_id: Session, +) -> None: + assert session_with_resource_id.user_id == 'USPR4JxMuwSG60u2h4gBpB6Q' + assert session_with_resource_id.resource_id == '68b887f60c33abad1ea841d3' + + +@pytest.mark.vcr +def test_session_with_resource_id_authorized( + client_authed_with_session: ClientSession, +) -> None: + resource_id = '68b887f60c33abad1ea841d3' + response = client_authed_with_session.get( + f'onboarding_verifications/{resource_id}' + ) + + assert response['gov_id_document_number'] == '267202610' + + +@pytest.mark.vcr +def test_session_with_resource_id_unauthorized( + client_authed_with_session: ClientSession, +) -> None: + resource_id = '68b887f60c33abad1ea841d4' + with pytest.raises(CuencaResponseException) as e: + client_authed_with_session.get( + f'onboarding_verifications/{resource_id}' + ) + assert e.value.json['error'] == 'User has not enough permissions'