Files
gh-christianlouis-docuelevate/tests/test_api_google_drive_final.py
copilot-swe-agent[bot] 204000aabc fix: merge main branch and renumber migration 027→037
Resolve 3 merge conflicts and renumber the automation_hooks migration
to follow main's migration chain (036_add_document_translation_fields).

Conflicts resolved:
- app/api/__init__.py: add automation_router alongside main's new routers
- app/utils/settings_service.py: add automation_hooks_enabled alongside compliance_enabled
- tests/conftest.py: add AutomationHook alongside AuditLog/ComplianceTemplate imports

Migration renumbered:
- 027_add_automation_hooks → 037_add_automation_hooks
- down_revision: 026_add_scheduled_jobs → 036_add_document_translation_fields

Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
2026-03-16 22:40:15 +00:00

203 lines
8.9 KiB
Python

"""
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_google_drive_settings — refresh_token falsy inside use_oauth block
- 449->451: save_google_drive_settings — refresh_token falsy in in-memory update
- 468->470: save_google_drive_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_google_drive_settings.
Note: the Google Drive save endpoint is named save_google_drive_settings in the
source (app/api/google_drive.py).
"""
@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_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 save_google_drive_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"