"""Lambda test module.""" import json from unittest.mock import MagicMock from unittest.mock import patch import httpx import pytest from owsclient.test import OwsClientMock from src import config from src.constants import general as constants from src.constants import oa_users from src.constants.features import DEFAULT_RESTRICTED_FEATURES from src import app as index from src.app import BadRequest from src.app import RetryException @patch('src.app.boto3') @patch('src.app.set_restricted_features') def test_call_set_restricted_features( mock_set_restricted_features, mock_boto3_dynamo, ows_client_mock: OwsClientMock ) -> None: """Test set_restricted_features is called successfully.""" request = { 'brand': constants.AWAL_BRAND, 'vendor_name': 'foo', 'email': 'foo@xyz.com', 'source': 'event.gdaApproval', 'service_tier_uuid': '1ed7aac0-ceb6-4c09-9166-afda8f349316'} ows_result = { 'owner': constants.AWAL_CORE_ACCOUNTS, 'contact_email': 'foo@xyz.com', 'vendor_id': 123, 'name': 'foo', 'company': constants.AWAL_BRAND, 'country_id': None, 'status': 'signed', 'label_identifier': None, 'assigned_to': oa_users.GDA_ASSIGNED_TO, 'is_distributor': 'N', 'country': None, 'source': 'event.gdaApproval'} ows_client_mock.patch( config.OWS_SERVICE_NAME, config.OWS_SERVICE_ENDPOINT ).mock(return_value=httpx.Response(200, json=ows_result)) mock_set_restricted_features.return_value = None result = index.handler(request, {}) assert result assert result == ows_result mock_set_restricted_features.assert_called_once_with( 'add', ows_result['vendor_id'], list(DEFAULT_RESTRICTED_FEATURES) ) @pytest.mark.parametrize( ('input_data', 'result', 'create_vendor_result'), [ ( { 'brand': 'awal', 'vendor_name': 'foo', 'country': 'USA', 'email': 'foo@xyz.com', 'contract_template': 'A', 'contract_approver': 'BAT', 'service_tier_uuid': '1ed7aac0-ceb6-4c09-9166-afda8f349316', 'owner': constants.AWAL_CORE_ACCOUNTS, 'extra': 'field to trim', 'source': constants.GDA_SOURCE }, { 'migrated_to_abacus': True, 'email': 'foo@xyz.com', 'service_tier_uuid': constants.GDA_SERVICE_TIER_UUID, 'owner': constants.AWAL_CORE_ACCOUNTS, 'company_brand': constants.AWAL_BRAND, 'source': 'event.gdaApproval', 'vendor_name': 'foo', 'country': 'USA', 'assigned_to': oa_users.GDA_ASSIGNED_TO, 'assigned_reviewer': oa_users.GDA_QB_LABEL, 'quarterback_label_manager': oa_users.GDA_QB_LABEL, 'closer_id': oa_users.DEFAULT_CLOSER_ID }, { 'vendor_id': 70959, 'is_distributor': 'N', 'owner': constants.AWAL_CORE_ACCOUNTS, 'name': 'foo', 'company': constants.AWAL_BRAND, 'country_id': None, 'status': None, 'label_identifier': None, 'service_tier_uuid': constants.GDA_SERVICE_TIER_UUID, 'contact_email': 'foo@xyz.com', 'migrated_to_abacus': True, 'assigned_to': oa_users.GDA_ASSIGNED_TO, 'assigned_reviewer': oa_users.GDA_QB_LABEL, 'country': 'USA', 'quarterback_label_manager': oa_users.GDA_QB_LABEL } ), # test default service_tier for gda source ( { 'brand': constants.ORCHARD_BRAND, 'vendor_name': 'foo', 'email': 'foo@xyz.com', 'contract_template': 'A', 'contract_approver': 'BAT', 'source': constants.GDA_SOURCE, 'service_tier_uuid': '2304f272-7a12-40fc-ba48-959fff435223' }, { 'migrated_to_abacus': True, 'email': 'foo@xyz.com', 'service_tier_uuid': constants.GDA_SERVICE_TIER_UUID, 'owner': constants.ORCHARD_BRAND, 'vendor_name': 'foo', 'country': None, 'company_brand': constants.ORCHARD_BRAND, 'source': 'event.gdaApproval', 'assigned_to': oa_users.GDA_ASSIGNED_TO, 'assigned_reviewer': oa_users.GDA_QB_LABEL, 'quarterback_label_manager': oa_users.GDA_QB_LABEL, 'closer_id': oa_users.DEFAULT_CLOSER_ID }, { 'vendor_id': 70959, 'is_distributor': 'N', 'owner': constants.ORCHARD_BRAND, 'name': 'foo', 'company': constants.ORCHARD_BRAND, 'country_id': None, 'status': None, 'label_identifier': None, 'contact_email': 'foo@xyz.com', 'migrated_to_abacus': True, 'service_tier_uuid': constants.GDA_SERVICE_TIER_UUID, 'country': 'USA', 'assigned_to': oa_users.GDA_ASSIGNED_TO, 'assigned_reviewer': oa_users.GDA_QB_LABEL, 'quarterback_label_manager': oa_users.GDA_QB_LABEL } ) ] ) @patch('src.app.boto3') @patch('src.app.set_restricted_features', return_value=None) def test_handler_extra_fields_service_tiers( mock_set_restricted_features, mock_boto3_dynamo, input_data, result, create_vendor_result, ows_client_mock: OwsClientMock ) -> None: """Test handler data manipulation with extra inputs and null values.""" ows_client_mock.patch( config.OWS_SERVICE_NAME, config.OWS_SERVICE_ENDPOINT ).mock(return_value=httpx.Response(200, json=create_vendor_result)) actual = index.handler(input_data, {}) assert actual assert actual == create_vendor_result # assert correct params are passed to ows_account payload = ows_client_mock.mock.calls[0].request._content assert json.loads(payload) == result headers = ows_client_mock.mock.calls[0].request.headers assert headers['Orchard-Identity-Id'] == 'ea705328-e6eb-4932-8dc2-efbe373473ae' assert headers['Orchard-Identity-UUID'] == 'ea705328-e6eb-4932-8dc2-efbe373473ae' assert headers['Orchard-Profile-Id'] == '82699' assert headers['Orchard-Profile-Type'] == 'SettingsProfile' assert headers['host'] == 'qa-ows-account.theorchard.io' mock_set_restricted_features.assert_called_once_with( 'add', create_vendor_result['vendor_id'], list(DEFAULT_RESTRICTED_FEATURES) ) @patch('src.app.boto3') def test_handler_passes_optional_attributes( mock_boto3_dynamo, ows_client_mock: OwsClientMock ) -> None: """Tests if QBLabel and AssignedTo are passed to create_vendor when set.""" input_data = { 'brand': 'orchard', 'vendor_name': 'foo', 'vendor_id': None, 'email': 'foo@xyz.com', 'source': constants.GDA_SOURCE, 'service_tier_uuid': '1ed7aac0-ceb6-4c09-9166-afda8f349316', 'assigned_to': oa_users.GDA_ASSIGNED_TO, 'quarterback_label_manager': oa_users.GDA_QB_LABEL } # mock vendor patch ows_client_mock.patch( config.OWS_SERVICE_NAME, config.OWS_SERVICE_ENDPOINT ).mock(return_value=httpx.Response(200, json={'vendor_id': 123})) # mock the set restricted features ows_client_mock.post( config.OWS_SERVICE_NAME, '/vendor/123/restricted_features/add' ).mock(return_value=httpx.Response(200, json={})) actual = index.handler(input_data, {}) assert actual # assert correct params are passed to ows_account payload = ows_client_mock.mock.calls[0].request._content assert json.loads(payload) == { 'assigned_reviewer': '2903', 'assigned_to': '3325', 'closer_id': 2912, 'company_brand': 'orchard', 'country': None, 'email': 'foo@xyz.com', 'migrated_to_abacus': True, 'owner': 'orchard', 'quarterback_label_manager': '2903', 'service_tier_uuid': '2304f272-7a12-40fc-ba48-959fff435223', 'source': 'event.gdaApproval', 'vendor_name': 'foo' } @pytest.mark.parametrize( ('test_input', 'create_vendor_result'), [ ( { 'brand': 'orchard', 'vendor_name': 'foo', 'vendor_id': None, 'email': 'foo@xyz.com', 'source': constants.AWAL_PLUS_SOURCE, 'service_tier_uuid': '1ed7aac0-ceb6-4c09-9166-afda8f349316' }, { 'name': 'foo', 'vendor_id': 70959, 'is_distributor': 'N', 'owner': constants.AWAL_CORE_ACCOUNTS, 'country_id': None, 'company': constants.AWAL_BRAND, 'migrated_to_abacus': True, 'status': None, 'label_identifier': None, 'country': 'USA', 'contact_email': 'foo@xyz.com', 'service_tier_uuid': constants.GDA_SERVICE_TIER_UUID, 'assigned_to': oa_users.GDA_ASSIGNED_TO } ), ( { 'brand': 'orchard', 'vendor_name': 'foo', 'vendor_id': None, 'email': 'foo@xyz.com', 'source': constants.GDA_SOURCE, 'service_tier_uuid': '1ed7aac0-ceb6-4c09-9166-afda8f349316' }, { 'vendor_id': 70959, 'is_distributor': 'N', 'owner': constants.ORCHARD_BRAND, 'name': 'foo', 'company': constants.ORCHARD_BRAND, 'country_id': None, 'status': None, 'label_identifier': None, 'country': 'USA', 'contact_email': 'foo@xyz.com', 'migrated_to_abacus': True, 'assigned_to': oa_users.GDA_ASSIGNED_TO, 'service_tier_uuid': constants.GDA_SERVICE_TIER_UUID, 'quarterback_label_manager': oa_users.GDA_QB_LABEL } ) ] ) @patch('src.app.boto3') def test_handler_sets_assigned_to_and_qblabel( mock_boto3_dynamo, test_input, create_vendor_result, ows_client_mock: OwsClientMock ) -> None: """Tests handler sets assigned_to and qblabel when source is gda/awal.""" # mock vendor patch ows_client_mock.patch( config.OWS_SERVICE_NAME, config.OWS_SERVICE_ENDPOINT ).mock(return_value=httpx.Response(200, json=create_vendor_result)) # mock the set restricted features vendor_id = create_vendor_result['vendor_id'] ows_client_mock.post( config.OWS_SERVICE_NAME, f'/vendor/{vendor_id}/restricted_features/add' ).mock(return_value=httpx.Response(200, json=None)) actual = index.handler(test_input, {}) assert actual assert actual == create_vendor_result assert len(ows_client_mock.mock.calls) == 2 payload = json.loads(ows_client_mock.mock.calls[0].request._content) if test_input['source'] == constants.GDA_SOURCE: assert payload['assigned_to'] == oa_users.GDA_ASSIGNED_TO assert payload['quarterback_label_manager'] == oa_users.GDA_QB_LABEL elif test_input['source'] == constants.AWAL_PLUS_SOURCE: assert payload['assigned_to'] == oa_users.GDA_ASSIGNED_TO assert payload['assigned_reviewer'] == oa_users.GDA_QB_LABEL assert 'quarterback_label_manager' not in payload else: pytest.fail('should not reach here') @pytest.mark.parametrize( ('test_input', 'create_vendor_result', 'mock_owner'), [ ( { # Test when input_data contains 'owner' 'brand': 'orchard', 'vendor_name': 'foo', 'vendor_id': None, 'email': 'foo@xyz.com', 'source': constants.AWAL_PLUS_SOURCE, 'service_tier_uuid': '1ed7aac0-ceb6-4c09-9166-afda8f349316', 'owner': 'test_owner' }, { 'name': 'foo', 'vendor_id': 70959, 'is_distributor': 'N', 'owner': 'test_owner', 'country_id': None, 'company': constants.AWAL_BRAND, 'migrated_to_abacus': True, 'status': None, 'label_identifier': None, 'country': 'USA', 'contact_email': 'foo@xyz.com', 'assigned_to': oa_users.GDA_ASSIGNED_TO, 'service_tier_uuid': constants.GDA_SERVICE_TIER_UUID }, 'test_owner' ), ( { # Test when input_data has no 'owner', 'brand'==AWAL 'brand': constants.AWAL_BRAND, 'vendor_name': 'foo', 'vendor_id': None, 'email': 'foo@xyz.com', 'source': constants.GDA_SOURCE, 'service_tier_uuid': '1ed7aac0-ceb6-4c09-9166-afda8f349316' }, { 'name': 'foo', 'vendor_id': 70959, 'is_distributor': 'N', 'owner': constants.AWAL_CORE_ACCOUNTS, 'country_id': None, 'company': constants.AWAL_BRAND, 'migrated_to_abacus': True, 'status': None, 'label_identifier': None, 'country': 'USA', 'contact_email': 'foo@xyz.com', 'assigned_to': oa_users.GDA_ASSIGNED_TO, 'service_tier_uuid': constants.GDA_SERVICE_TIER_UUID }, constants.AWAL_CORE_ACCOUNTS ), ( { # Test when input_data has no 'owner', 'brand'!=AWAL 'brand': 'orchard', 'vendor_name': 'foo', 'vendor_id': None, 'email': 'foo@xyz.com', 'source': constants.GDA_SOURCE, 'service_tier_uuid': '1ed7aac0-ceb6-4c09-9166-afda8f349316' }, { 'name': 'foo', 'vendor_id': 70959, 'is_distributor': 'N', 'owner': 'orchard', 'country_id': None, 'company': constants.AWAL_BRAND, 'migrated_to_abacus': True, 'status': None, 'label_identifier': None, 'country': 'USA', 'contact_email': 'foo@xyz.com', 'service_tier_uuid': constants.GDA_SERVICE_TIER_UUID, 'assigned_to': oa_users.GDA_ASSIGNED_TO }, 'orchard' ) ] ) @patch('src.app.boto3') def test_handler_sets_owner_from_input( mock_boto3_dynamo, test_input, create_vendor_result, mock_owner, ows_client_mock: OwsClientMock ) -> None: """Tests handler sets result.owner from input.owner when present.""" # mock vendor patch ows_client_mock.patch( config.OWS_SERVICE_NAME, config.OWS_SERVICE_ENDPOINT ).mock(return_value=httpx.Response(200, json=create_vendor_result)) # mock the set restricted features vendor_id = create_vendor_result['vendor_id'] ows_client_mock.post( config.OWS_SERVICE_NAME, f'/vendor/{vendor_id}/restricted_features/add' ).mock(return_value=httpx.Response(200, json=None)) actual = index.handler(test_input, {}) assert actual assert actual == create_vendor_result assert actual['owner'] == mock_owner @pytest.mark.parametrize( ('test_input', 'create_vendor_result'), [ ( { # Check that not calling put_item when correlation_id presents. 'brand': 'orchard', 'vendor_name': 'foo', 'vendor_id': None, 'email': 'foo@xyz.com', 'source': constants.AWAL_PLUS_SOURCE, 'service_tier_uuid': '1ed7aac0-ceb6-4c09-9166-afda8f349316', 'owner': 'test_owner', 'correlation_id': 'test-correlation-1' }, { 'name': 'foo', 'vendor_id': 70959, 'is_distributor': 'N', 'owner': 'test_owner', 'country_id': None, 'company': constants.AWAL_BRAND, 'migrated_to_abacus': True, 'status': None, 'label_identifier': None, 'country': 'USA', 'contact_email': 'foo@xyz.com', 'assigned_to': oa_users.GDA_ASSIGNED_TO, 'service_tier_uuid': constants.GDA_SERVICE_TIER_UUID, 'correlation_id': 'test-correlation-1' } ) ] ) @patch('src.app.boto3') def test_create_existing_vendor( mock_boto3_dynamo, test_input, create_vendor_result, ows_client_mock: OwsClientMock ) -> None: """Check that not calling put_item when correlation_id presents.""" # mock get vendor ows_client_mock.get( config.OWS_SERVICE_NAME, '/vendor/123' ).mock(return_value=httpx.Response(200, json=create_vendor_result)) mock_boto3_dynamo.client().get_item.return_value = { 'Item': { 'vendor_id': {'N': '123'} } } actual = index.handler(test_input, {}) assert actual assert mock_boto3_dynamo.client().put_item.call_count == 0 @patch('src.app.boto3') def test_handler_sets_attributes_for_awal_plus_source( mock_boto3_dynamo, ows_client_mock: OwsClientMock ) -> None: """Tests attributes are set if the event comes from source AWAL Plus.""" input_data = { 'brand': 'orchard', 'vendor_name': 'foo', 'vendor_id': None, 'email': 'foo@xyz.com', 'source': constants.AWAL_PLUS_SOURCE, 'service_tier_uuid': '9363881e-1120-4495-ae09-657e13609e11' } create_vendor_result = { 'name': 'foo', 'country_id': None, 'owner': constants.AWAL_BRAND, 'vendor_id': 70959, 'is_distributor': 'N', 'label_identifier': None, 'contact_email': 'foo@xyz.com', 'migrated_to_abacus': True, 'company': constants.AWAL_BRAND, 'status': None, 'country': 'USA', 'assigned_to': oa_users.GDA_ASSIGNED_TO, 'service_tier_uuid': '9363881e-1120-4495-ae09-657e13609e11', 'quarterback_label_manager': oa_users.GDA_QB_LABEL } # mock vendor patch ows_client_mock.patch( config.OWS_SERVICE_NAME, config.OWS_SERVICE_ENDPOINT ).mock(return_value=httpx.Response(200, json=create_vendor_result)) # mock the set restricted features ows_client_mock.post( config.OWS_SERVICE_NAME, '/vendor/70959/restricted_features/add' ).mock(return_value=httpx.Response(200, json=None)) actual = index.handler(input_data, {}) assert actual assert actual == create_vendor_result # assert params are set in return object assert actual.get('assigned_to') == oa_users.GDA_ASSIGNED_TO assert actual.get('quarterback_label_manager') == oa_users.GDA_QB_LABEL @patch('src.app.boto3') def test_set_restricted_features_create_vendor_bad_request( mock_boto3_dynamo, test_input, ows_client_mock: OwsClientMock ) -> None: """Test set_restricted_features when 404 error (BadRequest) occurs.""" # mock vendor patch ows_client_mock.patch( config.OWS_SERVICE_NAME, config.OWS_SERVICE_ENDPOINT ).mock(return_value=httpx.Response(200, json={'vendor_id': 70959})) # mock the set restricted features with a 404 ows_client_mock.post( config.OWS_SERVICE_NAME, '/vendor/70959/restricted_features/add' ).mock(return_value=httpx.Response(404, json=None)) with pytest.raises(BadRequest): index.handler(test_input, {}) @patch('src.app.boto3') def test_set_restricted_features_create_vendor_retry_exception( mock_boto3_dynamo, test_input, ows_client_mock: OwsClientMock ) -> None: """Test set_restricted_features when 505 error (RetryException) occurs.""" # mock vendor patch ows_client_mock.patch( config.OWS_SERVICE_NAME, config.OWS_SERVICE_ENDPOINT ).mock(return_value=httpx.Response(200, json={'vendor_id': 70959})) # mock the set restricted features with a 404 ows_client_mock.post( config.OWS_SERVICE_NAME, '/vendor/70959/restricted_features/add' ).mock(return_value=httpx.Response(500, json=None)) with pytest.raises(RetryException): index.handler(test_input, {}) @patch('src.app.boto3') def test_set_restricted_features_create_vendor_success( mock_boto3_dynamo, test_input, ows_client_mock: OwsClientMock ) -> None: """Test set_restricted_features when successful.""" ows_result = { 'migrated_to_abacus': True, 'email': 'foo@xyz.com', 'service_tier_uuid': constants.GDA_SERVICE_TIER_UUID, 'owner': constants.ORCHARD_BRAND, 'vendor_name': 'foo', 'country': None, 'company_brand': constants.ORCHARD_BRAND, 'source': 'event.gdaApproval', 'assigned_to': oa_users.GDA_ASSIGNED_TO, 'vendor_id': 70959 } # mock vendor patch ows_client_mock.patch( config.OWS_SERVICE_NAME, config.OWS_SERVICE_ENDPOINT ).mock(return_value=httpx.Response(200, json=ows_result)) # mock the set restricted features with a 404 ows_client_mock.post( config.OWS_SERVICE_NAME, '/vendor/70959/restricted_features/add' ).mock(return_value=httpx.Response(200, json=None)) actual = index.handler(test_input, {}) assert actual assert actual == ows_result @patch('src.app.boto3') def test_create_vendor_bad_request( mock_boto3_dynamo, test_input, ows_client_mock: OwsClientMock ) -> None: """Test handler behavior when 404 error (BadRequest) is thrown.""" # mock vendor patch ows_client_mock.patch( config.OWS_SERVICE_NAME, config.OWS_SERVICE_ENDPOINT ).mock(return_value=httpx.Response(400, json=None)) with pytest.raises(BadRequest): index.handler(test_input, {}) @patch('src.app.set_restricted_features') def test_handler_vendor_id_detected(mock_set_restricted_features, caplog): """Test handler function returns vendor_id when it's present in request.""" request = {'source': constants.AWAL_PLUS_SOURCE, 'vendor_id': 123, 'vendor_name': None} ows_result = {'vendor_id': int(123)} result = index.handler(request, {}) assert 'vendor_id detected, skipping vendor creation.' in caplog.text assert result assert result == ows_result mock_set_restricted_features.assert_not_called() def test_handler_validation_error(): """Test handler returns BadRequest when ValidationError is caught.""" request = { 'source': constants.AWAL_PLUS_SOURCE, 'vendor_id': None, 'vendor_name': 'foo', 'correlation_id': 'test-correlation-id' } with pytest.raises(BadRequest): index.handler(request, {}) @pytest.mark.skip(reason='Not clear what is being tested here') @pytest.mark.parametrize( ('test_input', 'create_vendor_result'), [ ( { 'brand': 'orchard', 'vendor_name': 'foo', 'vendor_id': None, 'email': 'foo@xyz.com', 'source': constants.AWAL_PLUS_SOURCE, 'service_tier_uuid': '1ed7aac0-ceb6-4c09-9166-afda8f349316', 'owner': 'test_owner', 'correlation_id': 'test-id-1' }, { 'name': 'foo', 'vendor_id': 70959, 'is_distributor': 'N', 'owner': 'test_owner', 'country_id': None, 'company': constants.AWAL_BRAND, 'migrated_to_abacus': True, 'status': None, 'label_identifier': None, 'country': 'USA', 'contact_email': 'foo@xyz.com', 'assigned_to': oa_users.GDA_ASSIGNED_TO, 'service_tier_uuid': constants.GDA_SERVICE_TIER_UUID, 'correlation_id': 'test-id-1' } ) ] ) @patch('src.app.boto3') def test_create_vendor_with_putting_item_to_dynamodb( mock_boto3_dynamo, test_input, create_vendor_result, ows_client_mock: OwsClientMock ) -> None: """Check putting item to dynamodb table during create vendor.""" # mock vendor get ows_client_mock.get( config.OWS_SERVICE_NAME, '/vendor/70959' ).mock(return_value=httpx.Response(200, json=create_vendor_result)) dynamodb = mock_boto3_dynamo.client('dynamodb', region_name='us-west-2') table_name = 'test-table' dynamodb.create_table( TableName=table_name, KeySchema=[ {'AttributeName': 'correlation_id', 'KeyType': 'HASH'}, {'AttributeName': 'vendor_id', 'KeyType': 'RANGE'} ], AttributeDefinitions=[ {'AttributeName': 'correlation_id', 'AttributeType': 'S'}, {'AttributeName': 'vendor_id', 'AttributeType': 'S'} ], ProvisionedThroughput={ 'ReadCapacityUnits': 1, 'WriteCapacityUnits': 1 } ) actual = index.handler(test_input, {}) table = dynamodb.Table(table_name) item = {'correlation_id': 'test-id-1', 'vendor_id': '12356789065'} table.put_item(Item=item) expected_response = {'Item': item} table.get_item = MagicMock(return_value=expected_response) response = table.get_item(Key={'correlation_id': 'test-id-1'}) assert actual assert response == expected_response @pytest.mark.parametrize( ('input_data', 'expected_closer_id'), [ pytest.param( { 'brand': 'orchard', 'vendor_name': 'foo', 'email': 'foo@xyz.com', 'source': constants.GDA_SOURCE, 'service_tier_uuid': '1ed7aac0-ceb6-4c09-9166-afda8f349316' }, oa_users.DEFAULT_CLOSER_ID, id='No voucher_code provided - use DEFAULT_CLOSER_ID' ), pytest.param( { 'brand': 'orchard', 'vendor_name': 'foo', 'email': 'foo@xyz.com', 'source': constants.GDA_SOURCE, 'service_tier_uuid': '1ed7aac0-ceb6-4c09-9166-afda8f349316', 'voucher_code': '1YCiL3av' }, 3493, id='Valid voucher_code - use mapped user ID' ), pytest.param( { 'brand': 'orchard', 'vendor_name': 'foo', 'email': 'foo@xyz.com', 'source': constants.GDA_SOURCE, 'service_tier_uuid': '1ed7aac0-ceb6-4c09-9166-afda8f349316', 'voucher_code': 'KaTD0ggY' }, oa_users.DEFAULT_CLOSER_ID, id='Unmapped voucher_code - should fall back to DEFAULT_CLOSER_ID' ) ] ) @patch('src.app.boto3') def test_handler_voucher_code_sets_closer_id( _mock_boto3_dynamo: MagicMock, input_data: dict, expected_closer_id: int, ows_client_mock: OwsClientMock ) -> None: """Test voucher_code logic sets correct closer_id.""" create_vendor_result = { 'vendor_id': 70959, 'name': 'foo', 'contact_email': 'foo@xyz.com' } ows_client_mock.patch( config.OWS_SERVICE_NAME, config.OWS_SERVICE_ENDPOINT ).mock(return_value=httpx.Response(200, json=create_vendor_result)) ows_client_mock.post( config.OWS_SERVICE_NAME, '/vendor/70959/restricted_features/add' ).mock(return_value=httpx.Response(200, json=None)) result = index.handler(input_data, {}) assert result payload = json.loads(ows_client_mock.mock.calls[0].request._content) assert payload['closer_id'] == expected_closer_id