"""Test graphql-gateway utils.""" import pytest from gql.transport.exceptions import TransportServerError from gql.transport.exceptions import TransportQueryError from requests.exceptions import HTTPError from unittest import mock from src.utils import graphql @mock.patch('src.common.connectors.graphql_gateway.make_request') def test_execute_query(mock_request): """Test executing gql query.""" expected_headers = { 'apollographql-client-name': 'lambda-sr-delivery-tiktok', 'apollographql-client-version': '1', 'Orchard-Identity-Id': '8955b4aa-2ad0-4b0b-a2ea-6f070554d6d0', 'Orchard-Profile-Id': '179', 'Orchard-Profile-Type': 'OrchAdminProfile', 'Cache-Control': 'no-cache' } expected_query = graphql.TRACKS_QUERY expected_params = {'isrc': 'QM6MZ2016828'} graphql._execute_tracks_query('QM6MZ2016828') assert mock_request.called assert mock_request.call_args_list == [ mock.call( expected_headers, expected_query, expected_params ) ] @mock.patch('src.utils.graphql._execute_tracks_query') def test_get_track(mock_execute_query): """Test batching execute query.""" mock_execute_query.return_value = { 'isrc': { 'tracks': { 'tracks': [ { 'trackName': 'Fire', 'labelSoundRecording': { 'label': { 'name': 'La Reserve Records' } }, 'product': { 'subgenre': { 'genre': { 'name': 'Rock' } } }, 'participations': [ { 'participant': { 'name': 'Artist A', 'uuid': '1234' }, 'participated_as': 'performer' }, { 'participant': { 'name': 'Artist B', 'uuid': '5678' }, 'participated_as': 'track_writer' } ], }, { 'trackName': 'Fire', 'labelSoundRecording': { 'label': { 'name': 'La Reserve Records' } }, 'product': { 'subgenre': { 'genre': { 'name': 'Rock' } } }, 'participations': [ { 'participant': { 'name': 'Artist A', 'uuid': '1234' }, 'participated_as': 'performer' }, { 'participant': { 'name': 'Artist B', 'uuid': '5678' }, 'participated_as': 'track_writer' } ], } ] } } } result = graphql.get_track('QM6MZ2016828') expected_result = { 'trackName': 'Fire', 'labelSoundRecording': { 'label': { 'name': 'La Reserve Records' } }, 'product': { 'subgenre': { 'genre': { 'name': 'Rock' } } }, 'participations': [ { 'participant': { 'name': 'Artist A', 'uuid': '1234' }, 'participated_as': 'performer' }, { 'participant': { 'name': 'Artist B', 'uuid': '5678' }, 'participated_as': 'track_writer' } ], } assert mock_execute_query.called assert result == expected_result @mock.patch('src.utils.graphql._execute_tracks_query') def test_get_track_exception(mock_execute_query): """Test exception tracks query.""" mock_execute_query.side_effect = HTTPError('error') with pytest.raises(HTTPError): graphql.get_track('QM6MZ2016828') @mock.patch('src.utils.graphql._execute_history_query') def test_get_last_delivered_xml_location(mock_execute_query): """Test getting last delivered xml location.""" mock_execute_query.return_value = { 'orchardSoundRecording': { 'deliveryHistory': [{ 'creationDate': '2024-01-01T00:00:00Z', 'stepFunctionName': '123-sfn', 'message': { 'details': { 'filenames': [ 'file1.xml', 'file2.xml' ] } } }] } } expected_result = '123-sfn/file1.xml' result = graphql.get_last_delivered_xml_location('1234') assert mock_execute_query.called assert expected_result == result @mock.patch('src.utils.graphql._execute_history_query') def test_get_last_delivered_xml_location_no_history(mock_execute_query): """Test getting last delivered xml location with no history.""" mock_execute_query.return_value = { 'orchardSoundRecording': { 'deliveryHistory': [] } } result = graphql.get_last_delivered_xml_location('1234') assert result is None @mock.patch('src.utils.graphql._execute_history_query') def test_get_last_delivered_xml_location_no_filenames(mock_execute_query): """Test getting last delivered xml location with no filenames.""" mock_execute_query.return_value = { 'orchardSoundRecording': { 'deliveryHistory': [{ 'creationDate': '2024-01-01T00:00:00Z', 'stepFunctionName': '123-sfn', 'message': { 'details': { 'filenames': [] } } }] } } result = graphql.get_last_delivered_xml_location('1234') assert result is None @mock.patch('src.utils.graphql._execute_history_query') def test_get_last_delivered_xml_transport_server_exception(mock_execute_query): """Test exception history query.""" mock_execute_query.side_effect = TransportServerError('error', code=503) with pytest.raises(graphql.exceptions.RetryableException): graphql.get_last_delivered_xml_location('1234') @mock.patch('src.utils.graphql._execute_history_query') def test_get_last_delivered_xml_transport_server_non_retryable_exception(mock_execute_query): """Test exception history query.""" mock_execute_query.side_effect = TransportServerError('error', code=505) with pytest.raises(TransportServerError): graphql.get_last_delivered_xml_location('1234') @mock.patch('src.utils.graphql._execute_history_query') def test_get_last_delivered_xml_transport_query_exception(mock_execute_query): """Test exception history query.""" mock_execute_query.side_effect = TransportQueryError('error') with pytest.raises(graphql.exceptions.RetryableException): graphql.get_last_delivered_xml_location('1234') @mock.patch('src.utils.graphql._execute_query') def test_get_delivery_histories_single_record(mock_execute_query): """Test get_delivery_histories returns status from the most recent record.""" mock_execute_query.return_value = { 'deliveryHistoryByOsrIds': [{ 'orchardSoundRecording': {'id': 'sr-123'}, 'orchardSoundRecordingVersion': {'versionId': 'v-1'}, 'status': 'SUCCESS', 'creationDate': '2024-01-01T00:00:00Z', 'type': 'FULL_DELIVERY', 'stepFunctionName': 'sfn-1', }] } result = graphql.get_delivery_histories(['sr-123'], 'TikTok') assert result == { 'sr-123': { 'type': 'FULL_DELIVERY', 'status': 'SUCCESS', 'has_full_delivery': True, 'last_delivered_version_id': 'v-1', } } @mock.patch('src.utils.graphql._execute_query') def test_get_delivery_histories_empty_response(mock_execute_query): """Test get_delivery_histories returns empty dict when no history exists.""" mock_execute_query.return_value = {'deliveryHistoryByOsrIds': []} result = graphql.get_delivery_histories(['sr-123'], 'TikTok') assert result == {} @mock.patch('src.utils.graphql._execute_query') def test_get_delivery_histories_none_response(mock_execute_query): """Test get_delivery_histories returns empty dict when response is None.""" mock_execute_query.return_value = {'deliveryHistoryByOsrIds': None} result = graphql.get_delivery_histories(['sr-123'], 'TikTok') assert result == {} @mock.patch('src.utils.graphql._execute_query') def test_get_delivery_histories_multiple_records_returns_most_recent(mock_execute_query): """Test get_delivery_histories picks the most recent record as the representative entry.""" mock_execute_query.return_value = { 'deliveryHistoryByOsrIds': [ { 'orchardSoundRecording': {'id': 'sr-123'}, 'orchardSoundRecordingVersion': None, 'status': 'SUCCESS', 'creationDate': '2024-01-01T00:00:00Z', 'type': 'FULL_DELIVERY', 'stepFunctionName': 'sfn-old', }, { 'orchardSoundRecording': {'id': 'sr-123'}, 'orchardSoundRecordingVersion': {'versionId': 'v-2'}, 'status': 'SUCCESS', 'creationDate': '2024-06-01T00:00:00Z', 'type': 'METADATA_UPDATE', 'stepFunctionName': 'sfn-new', }, ] } result = graphql.get_delivery_histories(['sr-123'], 'TikTok') assert result['sr-123']['type'] == 'METADATA_UPDATE' assert result['sr-123']['status'] == 'SUCCESS' assert result['sr-123']['has_full_delivery'] is True assert result['sr-123']['last_delivered_version_id'] == 'v-2' @mock.patch('src.utils.graphql._execute_query') def test_get_delivery_histories_graphql_error_raises(mock_execute_query): """Test get_delivery_histories raises on a GraphQL error in the response.""" mock_execute_query.return_value = {'errors': [{'message': 'something went wrong'}]} with pytest.raises(Exception, match='GraphQL query failed: something went wrong'): graphql.get_delivery_histories(['sr-123'], 'TikTok')