From 8165bafdb5e47d3f086eb25417d00f3d4ea1bbbf Mon Sep 17 00:00:00 2001 From: Adrian Galvan Date: Wed, 1 May 2024 20:52:51 -0700 Subject: [PATCH] Allow 204 No Content response (#4834) Co-authored-by: Kelsey Thomas <101993653+Kelsey-Ethyca@users.noreply.github.com> --- .../api/service/connectors/saas_connector.py | 4 ++ .../service/connectors/test_saas_connector.py | 54 ++++++++++++++++++- 2 files changed, 57 insertions(+), 1 deletion(-) diff --git a/src/fides/api/service/connectors/saas_connector.py b/src/fides/api/service/connectors/saas_connector.py index b3b0597935d..141d78003c1 100644 --- a/src/fides/api/service/connectors/saas_connector.py +++ b/src/fides/api/service/connectors/saas_connector.py @@ -5,6 +5,7 @@ from loguru import logger from requests import Response from sqlalchemy.orm import Session +from starlette.status import HTTP_204_NO_CONTENT from fides.api.common_exceptions import ( FidesopsException, @@ -604,6 +605,9 @@ def _unwrap_response_data(saas_request: SaaSRequest, response: Response) -> Any: """ Unwrap given Response using data_path in the given SaasRequest """ + if response.status_code == HTTP_204_NO_CONTENT: + return {} + try: return ( pydash.get(response.json(), saas_request.data_path) diff --git a/tests/ops/service/connectors/test_saas_connector.py b/tests/ops/service/connectors/test_saas_connector.py index 713ab5214e0..94148faa55e 100644 --- a/tests/ops/service/connectors/test_saas_connector.py +++ b/tests/ops/service/connectors/test_saas_connector.py @@ -7,7 +7,7 @@ import pytest from requests import Response from sqlalchemy.orm import Session -from starlette.status import HTTP_200_OK, HTTP_404_NOT_FOUND +from starlette.status import HTTP_200_OK, HTTP_204_NO_CONTENT, HTTP_404_NOT_FOUND from fides.api.common_exceptions import SkippingConsentPropagation from fides.api.graph.execution import ExecutionNode @@ -129,6 +129,15 @@ def test_unwrap_response_data_no_data_path(self): unwrapped = SaaSConnector._unwrap_response_data(fake_request, fake_response) assert response_body == unwrapped + def test_unwrap_response_no_content(self): + fake_request: SaaSRequest = SaaSRequest( + path="test/path", method=HTTPMethod.GET, data_path="user" + ) + fake_response: Response = Response() + fake_response.status_code = HTTP_204_NO_CONTENT + + assert SaaSConnector._unwrap_response_data(fake_request, fake_response) == {} + def test_delete_only_endpoint( self, saas_example_config, saas_example_connection_config ): @@ -196,6 +205,49 @@ def test_input_values( {"fidesops_grouped_inputs": [], "conversation_id": ["456"]}, ) == [{"id": "123", "from_email": "test@example.com"}] + @mock.patch("fides.api.service.connectors.saas_connector.AuthenticatedClient.send") + def test_no_content_response( + self, mock_send: Mock, saas_example_config, saas_example_connection_config + ): + """ + Verifies that no rows are returned if the status code is 204 No Content + """ + + # mock the 204 No Content response + mock_response = Response() + mock_response.status_code = HTTP_204_NO_CONTENT + mock_send.return_value = mock_response + + saas_config = SaaSConfig(**saas_example_config) + graph = saas_config.get_graph(saas_example_connection_config.secrets) + node = Node( + graph, + next( + collection + for collection in graph.collections + if collection.name == "messages" + ), + ) + traversal_node = TraversalNode(node) + request_task = traversal_node.to_mock_request_task() + execution_node = ExecutionNode(request_task) + + connector: SaaSConnector = get_connector(saas_example_connection_config) + + privacy_request = PrivacyRequest(id="123") + privacy_request.cache_identity(Identity(email="test@example.com")) + + assert ( + connector.retrieve_data( + execution_node, + Policy(), + privacy_request, + request_task, + {"fidesops_grouped_inputs": [], "conversation_id": ["456"]}, + ) + == [] + ) + def test_missing_input_values( self, saas_example_config, saas_example_connection_config ):