"""Test KYC notification router.""" from http import HTTPStatus import json from unittest import mock from aws_lambda_powertools.utilities.typing.lambda_context import LambdaContext import pytest from src.main import handler from src.models.ows_payee import PayeeItem from src.models.payee import Payee, PayeeEntityType from tests.utils.base import generate_event @pytest.mark.parametrize( 'program_id,payoneer_client_reference_id,payoneer_payee_id,status,body,is_payee', ( (100500, '14', 1014, HTTPStatus.OK, None, False), ( 'abc', '14', 1014, HTTPStatus.UNPROCESSABLE_ENTITY, [{'loc': ['path', 'program_id'], 'type': 'int_parsing'}], False, ), ( 100500, 'aaa', None, HTTPStatus.UNPROCESSABLE_ENTITY, [ { 'loc': ['body', 'Payee Id', 'int'], 'type': 'int_parsing', }, { 'loc': ['body', 'Payee Id', 'uuid'], 'type': 'uuid_parsing', }, {'loc': ['body', 'Payoneer Id'], 'type': 'int_type'}, ], False, ), ( 100500, '25401ddb-483e-11f0-9627-0e1655f1d811', 1014, HTTPStatus.OK, None, True, ), ), ) @mock.patch('src.models.kyc_notification.get_payee') @mock.patch('src.routers.kyc_notification.handle_kyc_approved') def test_process_kyc_approved( mocked_handle_kyc_approved: mock.Mock, mocked_get_payee: mock.Mock, program_id: str | int | None, payoneer_client_reference_id: str, payoneer_payee_id: str | int | None, status: HTTPStatus, body: list[dict[str, list[str] | str]] | None, is_payee: bool, lambda_context: LambdaContext, ) -> None: """Test process_kyc_approved.""" payee_id = 40 mocked_get_payee.return_value = PayeeItem(payee_id=payee_id) payee = Payee( payee_type=PayeeEntityType.payee if is_payee else PayeeEntityType.account_payee, payee_id=str(payee_id) if is_payee else payoneer_client_reference_id, ) response = handler( generate_event( method='POST', path=f'/program/{program_id}/payees/kyc/approved', body={ 'Payee Id': payoneer_client_reference_id, 'Payoneer Id': payoneer_payee_id, }, ), lambda_context, ) assert response['statusCode'] == status result = json.loads(response['body']) if body: result = result['detail'] assert result == body if status == HTTPStatus.OK: mocked_handle_kyc_approved.assert_called_once_with(payee=payee) else: mocked_handle_kyc_approved.assert_not_called() if status == HTTPStatus.OK and is_payee: mocked_get_payee.assert_called_once_with(payoneer_client_reference_id) else: mocked_get_payee.assert_not_called() @pytest.mark.parametrize( 'program_id,payoneer_client_reference_id,payoneer_payee_id,reason,status,body', ( (100500, '14', 1014, 'tst_reason', HTTPStatus.OK, None), ( 'abc', 'aaa', None, None, HTTPStatus.UNPROCESSABLE_ENTITY, [ {'loc': ['path', 'program_id'], 'type': 'int_parsing'}, { 'loc': ['body', 'Payee Id', 'int'], 'type': 'int_parsing', }, { 'loc': ['body', 'Payee Id', 'uuid'], 'type': 'uuid_parsing', }, {'loc': ['body', 'Payoneer Id'], 'type': 'int_type'}, ], ), ), ) @mock.patch('src.routers.kyc_notification.handle_kyc_declined') def test_process_kyc_declined( mocked_handle_kyc_declined: mock.Mock, program_id: str | int | None, payoneer_client_reference_id: str, payoneer_payee_id: str | int | None, reason: str | None, status: HTTPStatus, body: list[dict[str, list[str] | str]] | None, lambda_context: LambdaContext, ) -> None: """Test process_kyc_declined.""" payee = Payee( payee_type=PayeeEntityType.account_payee, payee_id=payoneer_client_reference_id ) response = handler( generate_event( method='POST', path=f'/program/{program_id}/payees/kyc/declined', body={ 'Payee Id': payoneer_client_reference_id, 'Payoneer Id': payoneer_payee_id, 'Reason Description': reason, }, ), lambda_context, ) assert response['statusCode'] == status result = json.loads(response['body']) if body: result = result['detail'] assert result == body if status == HTTPStatus.OK: mocked_handle_kyc_declined.assert_called_once_with(payee=payee, reason=reason) else: mocked_handle_kyc_declined.assert_not_called() @pytest.mark.parametrize( ( 'program_id,payoneer_client_reference_id,payoneer_payee_id,session_id,file_upload_link' ',requirement_id,sub_requirement_id,status,body' ), ( (1005, '3', 10, 'session1', 'lnk1', 'req1', 'subr', HTTPStatus.OK, None), ( 'abc', 'aaa', None, 123, None, None, 11, HTTPStatus.UNPROCESSABLE_ENTITY, [ {'loc': ['path', 'program_id'], 'type': 'int_parsing'}, { 'loc': ['body', 'Payee Id', 'int'], 'type': 'int_parsing', }, { 'loc': ['body', 'Payee Id', 'uuid'], 'type': 'uuid_parsing', }, {'loc': ['body', 'Payoneer Id'], 'type': 'int_type'}, {'loc': ['body', 'Session Id'], 'type': 'string_type'}, {'loc': ['body', 'File Upload Link'], 'type': 'string_type'}, {'loc': ['body', 'Sub Requirement Id'], 'type': 'string_type'}, ], ), ), ) @mock.patch('src.routers.kyc_notification.handle_kyc_notification') def test_process_kyc_notification( mocked_handle_kyc_notification: mock.Mock, program_id: str | int | None, payoneer_client_reference_id: str, payoneer_payee_id: str | int | None, session_id: str | int | None, file_upload_link: str | int | None, requirement_id: str | int | None, sub_requirement_id: str | int | None, status: HTTPStatus, body: list[dict[str, list[str] | str]] | None, lambda_context: LambdaContext, ) -> None: """Test process_kyc_notification.""" payee = Payee( payee_type=PayeeEntityType.account_payee, payee_id=payoneer_client_reference_id ) response = handler( generate_event( method='POST', path=f'/program/{program_id}/payees/kyc/notification', body={ 'Payee Id': payoneer_client_reference_id, 'Payoneer Id': payoneer_payee_id, 'Session Id': session_id, 'File Upload Link': file_upload_link, 'Requirement Id': requirement_id, 'Sub Requirement Id': sub_requirement_id, }, ), lambda_context, ) assert response['statusCode'] == status result = json.loads(response['body']) if body: result = result['detail'] assert result == body if status == HTTPStatus.OK: mocked_handle_kyc_notification.assert_called_once_with( payee=payee, file_upload_link=file_upload_link, requirement_id=requirement_id, sub_requirement_id=sub_requirement_id, ) else: mocked_handle_kyc_notification.assert_not_called() @pytest.mark.parametrize( ( 'program_id,payoneer_client_reference_id,payoneer_payee_id,session_id,file_upload_link,requirement_type_id' ',sub_requirement_status_id,possible_sub_requirement_types,entity_reference_type_id' ',entity_reference_id,status,body' ), ( ( 105, '31', 101, 'session2', 'lnk2', 123, 12321, 'subt', 10, 'ref1', HTTPStatus.OK, None, ), ( 'abc', 'aaa', None, 123, None, None, 'bb', 11, 'yy', 9, HTTPStatus.UNPROCESSABLE_ENTITY, [ {'loc': ['path', 'program_id'], 'type': 'int_parsing'}, { 'loc': ['body', 'Payee Id', 'int'], 'type': 'int_parsing', }, { 'loc': ['body', 'Payee Id', 'uuid'], 'type': 'uuid_parsing', }, {'loc': ['body', 'Payoneer Id'], 'type': 'int_type'}, {'loc': ['body', 'Session Id'], 'type': 'string_type'}, {'loc': ['body', 'File Upload Link'], 'type': 'string_type'}, {'loc': ['body', 'Sub Requirement Status Id'], 'type': 'int_parsing'}, { 'loc': ['body', 'Possible Sub Requirement Types'], 'type': 'string_type', }, {'loc': ['body', 'Entity Reference Id'], 'type': 'string_type'}, {'loc': ['body', 'Entity Reference Type Id'], 'type': 'int_parsing'}, ], ), ), ) @mock.patch('src.routers.kyc_notification.handle_kyc_requirement_reopen') def test_process_kyc_requirement_reopen( mocked_handle_kyc_requirement_reopen: mock.Mock, program_id: str | int | None, payoneer_client_reference_id: str, payoneer_payee_id: str | int | None, session_id: str | int | None, file_upload_link: str | int | None, requirement_type_id: int | str | None, sub_requirement_status_id: int | str | None, possible_sub_requirement_types: str | int | None, entity_reference_type_id: int | str | None, entity_reference_id: str | int | None, status: HTTPStatus, body: list[dict[str, list[str] | str]] | None, lambda_context: LambdaContext, ) -> None: """Test process_kyc_requirement_reopen.""" payee = Payee( payee_type=PayeeEntityType.account_payee, payee_id=payoneer_client_reference_id ) response = handler( generate_event( method='POST', path=f'/program/{program_id}/payees/kyc/re-open', body={ 'Payee Id': payoneer_client_reference_id, 'Payoneer Id': payoneer_payee_id, 'Session Id': session_id, 'File Upload Link': file_upload_link, 'Requirement Type Id': requirement_type_id, 'Sub Requirement Status Id': sub_requirement_status_id, 'Possible Sub Requirement Types': possible_sub_requirement_types, 'Entity Reference Id': entity_reference_id, 'Entity Reference Type Id': entity_reference_type_id, }, ), lambda_context, ) assert response['statusCode'] == status result = json.loads(response['body']) if body: result = result['detail'] assert result == body if status == HTTPStatus.OK: mocked_handle_kyc_requirement_reopen.assert_called_once_with( payee=payee, file_upload_link=file_upload_link, requirement_type_id=requirement_type_id, sub_requirement_status_id=sub_requirement_status_id, possible_sub_requirement_types=possible_sub_requirement_types, entity_reference_id=entity_reference_id, entity_reference_type_id=entity_reference_type_id, ) else: mocked_handle_kyc_requirement_reopen.assert_not_called()