"""Test handler.""" import io from unittest.mock import MagicMock, call, patch from src import app @patch("src.app.OwsLoggingAdapter") @patch("src.app.write_csv_errors_to_s3") @patch("src.app.get_errors_from_s3") @patch("src.app.s3_client") def test_handler( mock_s3_client: MagicMock, mock_get_errors_from_s3: MagicMock, mock_write_csv_errors_to_s3: MagicMock, ows_logging_adapter_mock: MagicMock, mock_csv: str, mock_json_errors_call_args_list: list[list[dict[str, str]]], mock_flattened_json_errors: list[dict[str, str]], mock_export_id: str, mock_execution_name: str, ) -> None: """Test handler.""" mock_paginator = MagicMock() logger_mock = ows_logging_adapter_mock mock_s3_client.get_paginator.return_value = mock_paginator mock_paginator.paginate.return_value = [ { "Contents": [ { "Key": f"{mock_export_id}/{mock_execution_name}/asset_copy_errors_1.json" }, {"Key": "products.json"}, {"Key": "asset_locations_1.json"}, { "Key": f"{mock_export_id}/{mock_execution_name}/asset_copy_errors_2.json" }, { "Key": f"{mock_export_id}/{mock_execution_name}/asset_copy_errors_3.json" }, {"Key": "asset_locations_2.json"}, {"Key": "asset_locations_3.json"}, { "Key": f"{mock_export_id}/{mock_execution_name}/asset_copy_errors_4.json" }, {"Key": "asset_locations_4.json"}, ] }, { "Contents": [ { "Key": f"{mock_export_id}/{mock_execution_name}/asset_copy_errors_5.json" }, {"Key": "asset_locations_5.json"}, {"Key": "asset_locations_6.json"}, { "Key": f"{mock_export_id}/{mock_execution_name}/asset_copy_errors_6.json" }, ] }, ] ows_logging_adapter_mock.return_value = logger_mock mock_get_errors_from_s3.side_effect = mock_json_errors_call_args_list result = app.handler( { "export_id": mock_export_id, "execution_name": mock_execution_name, }, None, ) assert result == { "export_id": mock_export_id, "execution_name": mock_execution_name, } assert mock_get_errors_from_s3.call_args_list == [ call(f"{mock_export_id}/{mock_execution_name}/asset_copy_errors_1.json"), call(f"{mock_export_id}/{mock_execution_name}/asset_copy_errors_2.json"), call(f"{mock_export_id}/{mock_execution_name}/asset_copy_errors_3.json"), call(f"{mock_export_id}/{mock_execution_name}/asset_copy_errors_4.json"), call(f"{mock_export_id}/{mock_execution_name}/asset_copy_errors_5.json"), call(f"{mock_export_id}/{mock_execution_name}/asset_copy_errors_6.json"), ] mock_write_csv_errors_to_s3.assert_called_once_with( mock_flattened_json_errors, mock_export_id, logger_mock ) @patch("src.app.write_csv_errors_to_s3") @patch("src.app.get_errors_from_s3") @patch("src.app.s3_client") def test_handler_no_errors_to_report( mock_s3_client: MagicMock, mock_get_errors_from_s3: MagicMock, mock_write_csv_errors_to_s3: MagicMock, mock_export_id: str, mock_execution_name: str, ) -> None: """Test handler.""" mock_paginator = MagicMock() mock_s3_client.get_paginator.return_value = mock_paginator mock_paginator.paginate.return_value = [ { "Contents": [ {"Key": "products.json"}, {"Key": "asset_locations_1.json"}, {"Key": "asset_locations_2.json"}, {"Key": "asset_locations_3.json"}, {"Key": "asset_locations_4.json"}, ] }, { "Contents": [ {"Key": "asset_locations_5.json"}, {"Key": "asset_locations_6.json"}, ] }, ] result = app.handler( { "export_id": mock_export_id, "execution_name": mock_execution_name, }, None, ) assert result == { "export_id": mock_export_id, "execution_name": mock_execution_name, } mock_get_errors_from_s3.assert_not_called() mock_write_csv_errors_to_s3.assert_not_called() @patch("src.app.s3_client") def test_get_errors_from_s3( mock_s3_client: MagicMock, mock_json: str, mock_json_with_source_filtered_out: list[dict[str, str]], mock_export_id: str, mock_execution_name: str, ) -> None: mock_body = io.BytesIO(mock_json.encode("utf-8")) mock_object = { "Body": mock_body, "ContentType": "application/json", } mock_s3_client.get_object.return_value = mock_object mock_key = f"{mock_export_id}/{mock_execution_name}/asset_copy_errors_1.json" result = app.get_errors_from_s3(mock_key) assert result == mock_json_with_source_filtered_out @patch("src.app.pd.read_json") @patch("src.app.s3_client") def test_write_csv_errors_to_s3( mock_s3_client: MagicMock, mock_pd_read_json: MagicMock, mock_flattened_json_errors: list[dict[str, str]], mock_flattened_json_errors_serialized: str, mock_csv: str, mock_export_id: str, ) -> None: mock_json_dataframe = MagicMock() logger_mock = MagicMock() mock_json_dataframe.to_csv.return_value = mock_csv mock_pd_read_json.return_value = mock_json_dataframe mock_s3_client.put_object.return_value = { "ETag": "test-etag", "VersionId": "test-version-id", } app.write_csv_errors_to_s3(mock_flattened_json_errors, mock_export_id, logger_mock) mock_json_dataframe.to_csv.assert_called_once_with( encoding="utf-8", sep=",", index=False, header=["asset", "error_reason"] ) mock_s3_client.put_object.assert_called_once_with( Bucket="test-output-bucket", Key=f"{mock_export_id}/error_report.csv", Body=mock_csv, ContentType="text/csv", )