From 1b105a288fcaa16bc659f4912edd0e82ff779b48 Mon Sep 17 00:00:00 2001 From: Kevin Schmid Date: Fri, 4 Sep 2026 15:20:27 -0400 Subject: [PATCH] Fix GoogleDriveHook.get_file_id parent query operand order (#72541) --- .../providers/google/suite/hooks/drive.py | 2 +- .../unit/google/suite/hooks/test_drive.py | 74 +++++++++++++++++++ 2 files changed, 75 insertions(+), 1 deletion(-) diff --git a/providers/google/src/airflow/providers/google/suite/hooks/drive.py b/providers/google/src/airflow/providers/google/suite/hooks/drive.py index 5f6a21b3e97ad..7888fb1d11930 100644 --- a/providers/google/src/airflow/providers/google/suite/hooks/drive.py +++ b/providers/google/src/airflow/providers/google/suite/hooks/drive.py @@ -225,7 +225,7 @@ def get_file_id( """ query = f"name = '{file_name}'" if folder_id: - query += f" and parents in '{folder_id}'" + query += f" and '{folder_id}' in parents" if not include_trashed: query += " and trashed=false" diff --git a/providers/google/tests/unit/google/suite/hooks/test_drive.py b/providers/google/tests/unit/google/suite/hooks/test_drive.py index 51da97fa1b2fc..85ed3d622c099 100644 --- a/providers/google/tests/unit/google/suite/hooks/test_drive.py +++ b/providers/google/tests/unit/google/suite/hooks/test_drive.py @@ -294,6 +294,16 @@ def test_get_file_id_when_one_file_exists(self, mock_get_conn): ] result_value = self.gdrive_hook.get_file_id(folder_id, file_name, drive_id) + mock_get_conn.return_value.files.return_value.list.assert_called_once_with( + q=f"name = '{file_name}' and '{folder_id}' in parents", + spaces="drive", + fields="files(id, mimeType)", + orderBy="modifiedTime desc", + driveId=drive_id, + includeItemsFromAllDrives=True, + supportsAllDrives=True, + corpora="drive", + ) assert result_value == {"id": "ID_1", "mime_type": "text/plain"} @mock.patch("airflow.providers.google.suite.hooks.drive.GoogleDriveHook.get_conn") @@ -328,6 +338,16 @@ def test_get_file_id_when_multiple_files_exists(self, mock_get_conn): ] result_value = self.gdrive_hook.get_file_id(folder_id, file_name, drive_id) + mock_get_conn.return_value.files.return_value.list.assert_called_once_with( + q=f"name = '{file_name}' and '{folder_id}' in parents", + spaces="drive", + fields="files(id, mimeType)", + orderBy="modifiedTime desc", + driveId=drive_id, + includeItemsFromAllDrives=True, + supportsAllDrives=True, + corpora="drive", + ) assert result_value == {"id": "ID_1", "mime_type": "text/plain"} @mock.patch("airflow.providers.google.suite.hooks.drive.GoogleDriveHook.get_conn") @@ -339,8 +359,62 @@ def test_get_file_id_when_no_file_exists(self, mock_get_conn): mock_get_conn.return_value.files.return_value.list.return_value.execute.side_effect = [{"files": []}] result_value = self.gdrive_hook.get_file_id(folder_id, file_name, drive_id) + mock_get_conn.return_value.files.return_value.list.assert_called_once_with( + q=f"name = '{file_name}' and '{folder_id}' in parents", + spaces="drive", + fields="files(id, mimeType)", + orderBy="modifiedTime desc", + driveId=drive_id, + includeItemsFromAllDrives=True, + supportsAllDrives=True, + corpora="drive", + ) assert result_value == {} + @pytest.mark.parametrize( + ("include_trashed", "expected_query"), + [ + (True, "name = 'abc123.csv' and 'abxy1z' in parents"), + (False, "name = 'abc123.csv' and 'abxy1z' in parents and trashed=false"), + ], + ) + @mock.patch("airflow.providers.google.suite.hooks.drive.GoogleDriveHook.get_conn") + def test_get_file_id_uses_collection_membership_parents_query( + self, mock_get_conn, include_trashed, expected_query + ): + folder_id = "abxy1z" + drive_id = "abc123" + file_name = "abc123.csv" + mock_get_conn.return_value.files.return_value.list.return_value.execute.return_value = {"files": []} + + self.gdrive_hook.get_file_id(folder_id, file_name, drive_id, include_trashed=include_trashed) + + mock_get_conn.return_value.files.return_value.list.assert_called_once_with( + q=expected_query, + spaces="drive", + fields="files(id, mimeType)", + orderBy="modifiedTime desc", + driveId=drive_id, + includeItemsFromAllDrives=True, + supportsAllDrives=True, + corpora="drive", + ) + + @mock.patch("airflow.providers.google.suite.hooks.drive.GoogleDriveHook.get_conn") + def test_get_file_id_query_without_drive_id(self, mock_get_conn): + folder_id = "abxy1z" + file_name = "abc123.csv" + mock_get_conn.return_value.files.return_value.list.return_value.execute.return_value = {"files": []} + + self.gdrive_hook.get_file_id(folder_id, file_name) + + mock_get_conn.return_value.files.return_value.list.assert_called_once_with( + q=f"name = '{file_name}' and '{folder_id}' in parents", + spaces="drive", + fields="files(id, mimeType)", + orderBy="modifiedTime desc", + ) + @mock.patch("airflow.providers.google.suite.hooks.drive.MediaFileUpload") @mock.patch("airflow.providers.google.suite.hooks.drive.GoogleDriveHook.get_conn") @mock.patch("airflow.providers.google.suite.hooks.drive.GoogleDriveHook._ensure_folders_exists")