From 4ea6b47b91065ea5351e64bf3bf53d00ff751ee1 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 8 Mar 2026 11:33:27 +0000 Subject: [PATCH 1/2] Initial plan From 14c94326402aed375a8178198ccd045f91765d74 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 8 Mar 2026 11:44:30 +0000 Subject: [PATCH 2/2] test: increase app/api/google_drive.py coverage to 100% Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com> --- tests/test_api_google_drive_final.py | 202 +++++++++++++++++++++++++++ 1 file changed, 202 insertions(+) create mode 100644 tests/test_api_google_drive_final.py diff --git a/tests/test_api_google_drive_final.py b/tests/test_api_google_drive_final.py new file mode 100644 index 00000000..38ede9e1 --- /dev/null +++ b/tests/test_api_google_drive_final.py @@ -0,0 +1,202 @@ +""" +Final coverage tests for app/api/google_drive.py. + +Targets the remaining uncovered branches from the 97.03% baseline: + - 88->93 : update_google_drive_settings — refresh_token is empty/falsy + - 180->191: test_google_drive_token — OAuth credentials have no expiry + - 214 : test_google_drive_token — generic connection error (not token-related) + - 302->306: get_google_drive_token_info — credentials already valid (no refresh) + - 307->318: get_google_drive_token_info — credentials have no expiry + - 395->397: save_dropbox_settings — refresh_token falsy inside use_oauth block + - 449->451: save_dropbox_settings — refresh_token falsy in in-memory update + - 468->470: save_dropbox_settings — folder_id falsy in db-persist block +""" + +from datetime import datetime, timedelta +from unittest.mock import MagicMock, patch + +import pytest +from fastapi.testclient import TestClient + + +@pytest.mark.unit +class TestUpdateSettingsEmptyRefreshToken: + """Cover branch 88->93: refresh_token falsy in update_google_drive_settings.""" + + @pytest.mark.asyncio + async def test_update_settings_empty_refresh_token(self): + """Call update_google_drive_settings directly with empty refresh_token (branch 88->93).""" + from unittest.mock import MagicMock + + from starlette.requests import Request as StarletteRequest + + from app.api.google_drive import update_google_drive_settings + + mock_request = MagicMock(spec=StarletteRequest) + mock_request.session = {} + mock_db = MagicMock() + + with patch("app.api.google_drive.save_setting_to_db"): + with patch("app.api.google_drive.notify_settings_updated"): + result = await update_google_drive_settings( + request=mock_request, + refresh_token="", # falsy → branch 88->93 + client_id="cid", + client_secret=None, + folder_id=None, + use_oauth="true", + db=mock_db, + ) + assert result["status"] == "success" + + +@pytest.mark.unit +class TestTestTokenOAuthNoBranchExpiry: + """Cover branches 180->191 and line 214 in test_google_drive_token.""" + + @patch("app.api.google_drive.settings") + def test_test_token_oauth_no_expiry_on_credentials(self, mock_settings, client: TestClient): + """OAuth token test where credentials.expiry is None (branch 180->191).""" + type(mock_settings).google_drive_use_oauth = property(lambda self: True) + type(mock_settings).google_drive_client_id = property(lambda self: "client_id") + type(mock_settings).google_drive_client_secret = property(lambda self: "secret") + type(mock_settings).google_drive_refresh_token = property(lambda self: "refresh") + + mock_creds = MagicMock() + mock_creds.valid = True + mock_creds.expiry = None # no expiry → branch 180->191 + + mock_service = MagicMock() + mock_service.about.return_value.get.return_value.execute.return_value = { + "user": {"emailAddress": "user@example.com"} + } + + with ( + patch("app.tasks.upload_to_google_drive.get_drive_service_oauth", return_value=mock_service), + patch("google.oauth2.credentials.Credentials", return_value=mock_creds), + ): + response = client.get("/api/google-drive/test-token") + + assert response.status_code == 200 + data = response.json() + assert data["status"] == "success" + assert data["auth_type"] == "oauth" + + @patch("app.api.google_drive.settings") + def test_test_token_oauth_generic_connection_error(self, mock_settings, client: TestClient): + """OAuth token test raises a generic error without 'token' or 'invalid_grant' (line 214).""" + type(mock_settings).google_drive_use_oauth = property(lambda self: True) + type(mock_settings).google_drive_client_id = property(lambda self: "client_id") + type(mock_settings).google_drive_client_secret = property(lambda self: "secret") + type(mock_settings).google_drive_refresh_token = property(lambda self: "refresh") + + # Error message deliberately avoids "token" and "invalid_grant" + with patch( + "app.tasks.upload_to_google_drive.get_drive_service_oauth", + side_effect=Exception("Connection refused by remote host"), + ): + response = client.get("/api/google-drive/test-token") + + assert response.status_code == 200 + data = response.json() + assert data["status"] == "error" + assert "Connection error" in data["message"] + + +@pytest.mark.unit +class TestGetTokenInfoCredentialsBranches: + """Cover branches 302->306 and 307->318 in get_google_drive_token_info.""" + + @patch("app.api.google_drive.settings") + def test_get_token_info_credentials_already_valid(self, mock_settings, client: TestClient): + """credentials.valid is True — no refresh needed (branch 302->306).""" + type(mock_settings).google_drive_use_oauth = property(lambda self: True) + type(mock_settings).google_drive_client_id = property(lambda self: "client_id") + type(mock_settings).google_drive_client_secret = property(lambda self: "secret") + type(mock_settings).google_drive_refresh_token = property(lambda self: "refresh") + + mock_creds = MagicMock() + mock_creds.valid = True # already valid → skip refresh (branch 302->306) + mock_creds.expiry = datetime.now() + timedelta(hours=1) + mock_creds.token = "access_token_value" + + with patch("google.oauth2.credentials.Credentials", return_value=mock_creds): + response = client.get("/api/google-drive/get-token-info") + + assert response.status_code == 200 + data = response.json() + assert data["status"] == "success" + assert data["access_token"] == "access_token_value" + + @patch("app.api.google_drive.settings") + def test_get_token_info_credentials_no_expiry(self, mock_settings, client: TestClient): + """credentials.expiry is None — expiration_info stays empty (branch 307->318).""" + type(mock_settings).google_drive_use_oauth = property(lambda self: True) + type(mock_settings).google_drive_client_id = property(lambda self: "client_id") + type(mock_settings).google_drive_client_secret = property(lambda self: "secret") + type(mock_settings).google_drive_refresh_token = property(lambda self: "refresh") + + mock_creds = MagicMock() + mock_creds.valid = True + mock_creds.expiry = None # no expiry → branch 307->318 + mock_creds.token = "access_token_value" + + with patch("google.oauth2.credentials.Credentials", return_value=mock_creds): + response = client.get("/api/google-drive/get-token-info") + + assert response.status_code == 200 + data = response.json() + assert data["status"] == "success" + assert data["token_info"] == {} + + +@pytest.mark.unit +class TestSaveGoogleDriveSettingsFalsyFields: + """Cover branches 395->397, 449->451, 468->470 in save_dropbox_settings. + + Note: the Google Drive save endpoint is named save_dropbox_settings in the + source (app/api/google_drive.py) due to an existing naming inconsistency. + """ + + @patch("app.api.google_drive.settings") + @patch("os.path.exists", return_value=False) + @pytest.mark.asyncio + async def test_save_settings_empty_refresh_token_with_oauth(self, _mock_exists, mock_settings): + """use_oauth=true, refresh_token="" — skips token blocks (branches 395->397 and 449->451).""" + from unittest.mock import MagicMock + + from starlette.requests import Request as StarletteRequest + + from app.api.google_drive import save_dropbox_settings + + mock_request = MagicMock(spec=StarletteRequest) + mock_request.session = {} + mock_db = MagicMock() + + with patch("app.api.google_drive.save_setting_to_db"): + with patch("app.api.google_drive.notify_settings_updated"): + result = await save_dropbox_settings( + request=mock_request, + refresh_token="", # falsy → branches 395->397 and 449->451 + client_id="cid", + client_secret=None, + folder_id=None, + use_oauth="true", + db=mock_db, + ) + assert result["status"] == "success" + + @patch("app.api.google_drive.settings") + @patch("os.path.exists", return_value=False) + def test_save_settings_no_folder_id(self, _mock_exists, mock_settings, client: TestClient): + """folder_id not supplied — skips folder_id db-persist block (branch 468->470).""" + response = client.post( + "/api/google-drive/save-settings", + data={ + "refresh_token": "some_refresh_token", + # no folder_id → branch 468->470 + }, + ) + assert response.status_code == 200 + data = response.json() + assert data["status"] == "success"