refactor: update test imports and patching for conditional authentication tests
This commit is contained in:
parent
057c84fdc5
commit
6fe2771421
2 changed files with 55 additions and 89 deletions
|
|
@ -3,6 +3,7 @@ from unittest.mock import patch, AsyncMock, MagicMock
|
|||
from uuid import uuid4
|
||||
from fastapi.testclient import TestClient
|
||||
from types import SimpleNamespace
|
||||
import importlib
|
||||
|
||||
from cognee.api.client import app
|
||||
|
||||
|
|
@ -30,6 +31,10 @@ def mock_authenticated_user():
|
|||
tenant_id=uuid4(),
|
||||
)
|
||||
|
||||
gau_mod = importlib.import_module(
|
||||
"cognee.modules.users.methods.get_authenticated_user"
|
||||
)
|
||||
|
||||
|
||||
class TestConditionalAuthenticationEndpoints:
|
||||
"""Test that API endpoints work correctly with conditional authentication."""
|
||||
|
|
@ -51,7 +56,7 @@ class TestConditionalAuthenticationEndpoints:
|
|||
assert response.json() == {"message": "Hello, World, I am alive!"}
|
||||
|
||||
@patch(
|
||||
"cognee.modules.users.methods.get_authenticated_user.REQUIRE_AUTHENTICATION",
|
||||
"cognee.api.client.REQUIRE_AUTHENTICATION",
|
||||
False,
|
||||
)
|
||||
def test_openapi_schema_no_global_security(self, client):
|
||||
|
|
@ -71,9 +76,9 @@ class TestConditionalAuthenticationEndpoints:
|
|||
assert "CookieAuth" in security_schemes
|
||||
|
||||
@patch("cognee.api.v1.add.add")
|
||||
@patch("cognee.modules.users.methods.get_default_user.get_default_user", new_callable=AsyncMock)
|
||||
@patch.object(gau_mod, 'get_default_user', new_callable=AsyncMock)
|
||||
@patch(
|
||||
"cognee.modules.users.methods.get_authenticated_user.REQUIRE_AUTHENTICATION",
|
||||
"cognee.api.client.REQUIRE_AUTHENTICATION",
|
||||
False,
|
||||
)
|
||||
def test_add_endpoint_with_conditional_auth(
|
||||
|
|
@ -91,12 +96,14 @@ class TestConditionalAuthenticationEndpoints:
|
|||
|
||||
response = client.post("/api/v1/add", files=files, data=form_data)
|
||||
|
||||
assert mock_get_default_user.call_count == 1
|
||||
|
||||
# Core test: authentication is not required (should not get 401)
|
||||
assert response.status_code != 401
|
||||
|
||||
@patch("cognee.modules.users.methods.get_default_user.get_default_user", new_callable=AsyncMock)
|
||||
@patch.object(gau_mod, 'get_default_user', new_callable=AsyncMock)
|
||||
@patch(
|
||||
"cognee.modules.users.methods.get_authenticated_user.REQUIRE_AUTHENTICATION",
|
||||
"cognee.api.client.REQUIRE_AUTHENTICATION",
|
||||
False,
|
||||
)
|
||||
def test_conditional_authentication_works_with_current_environment(
|
||||
|
|
@ -115,6 +122,8 @@ class TestConditionalAuthenticationEndpoints:
|
|||
|
||||
response = client.post("/api/v1/add", files=files, data=form_data)
|
||||
|
||||
assert mock_get_default_user.call_count == 1
|
||||
|
||||
# Core test: authentication is not required (should not get 401)
|
||||
assert response.status_code != 401
|
||||
# Note: This test verifies conditional authentication works in the current environment
|
||||
|
|
@ -134,7 +143,7 @@ class TestConditionalAuthenticationBehavior:
|
|||
("/api/v1/datasets", "GET"),
|
||||
],
|
||||
)
|
||||
@patch("cognee.modules.users.methods.get_default_user.get_default_user", new_callable=AsyncMock)
|
||||
@patch.object(gau_mod, 'get_default_user', new_callable=AsyncMock)
|
||||
def test_get_endpoints_work_without_auth(
|
||||
self, mock_get_default, client, endpoint, method, mock_default_user
|
||||
):
|
||||
|
|
@ -146,6 +155,8 @@ class TestConditionalAuthenticationBehavior:
|
|||
elif method == "POST":
|
||||
response = client.post(endpoint, json={})
|
||||
|
||||
assert mock_get_default.call_count == 1
|
||||
|
||||
# Should not return 401 Unauthorized (authentication is optional by default)
|
||||
assert response.status_code != 401
|
||||
|
||||
|
|
@ -159,9 +170,14 @@ class TestConditionalAuthenticationBehavior:
|
|||
except Exception:
|
||||
pass # If response is not JSON, that's fine
|
||||
|
||||
@patch("cognee.modules.settings.get_settings.get_vectordb_config")
|
||||
@patch("cognee.modules.settings.get_settings.get_llm_config")
|
||||
@patch("cognee.modules.users.methods.get_default_user.get_default_user", new_callable=AsyncMock)
|
||||
|
||||
gsm_mod = importlib.import_module(
|
||||
"cognee.modules.settings.get_settings"
|
||||
)
|
||||
|
||||
@patch.object(gsm_mod, 'get_vectordb_config')
|
||||
@patch.object(gsm_mod, 'get_llm_config')
|
||||
@patch.object(gau_mod, 'get_default_user', new_callable=AsyncMock)
|
||||
def test_settings_endpoint_integration(
|
||||
self, mock_get_default, mock_llm_config, mock_vector_config, client, mock_default_user
|
||||
):
|
||||
|
|
@ -185,6 +201,8 @@ class TestConditionalAuthenticationBehavior:
|
|||
|
||||
response = client.get("/api/v1/settings")
|
||||
|
||||
assert mock_get_default.call_count == 1
|
||||
|
||||
# Core test: authentication is not required (should not get 401)
|
||||
assert response.status_code != 401
|
||||
# Note: This test verifies conditional authentication works for settings endpoint
|
||||
|
|
@ -197,7 +215,7 @@ class TestConditionalAuthenticationErrorHandling:
|
|||
def client(self):
|
||||
return TestClient(app)
|
||||
|
||||
@patch("cognee.modules.users.methods.get_default_user.get_default_user", new_callable=AsyncMock)
|
||||
@patch.object(gau_mod, 'get_default_user', new_callable=AsyncMock)
|
||||
def test_get_default_user_fails(self, mock_get_default, client):
|
||||
"""Test behavior when get_default_user fails (with current environment)."""
|
||||
mock_get_default.side_effect = Exception("Database connection failed")
|
||||
|
|
|
|||
|
|
@ -4,22 +4,22 @@ import pytest
|
|||
from unittest.mock import AsyncMock, patch
|
||||
from uuid import uuid4
|
||||
from types import SimpleNamespace
|
||||
import importlib
|
||||
|
||||
|
||||
from cognee.modules.users.models import User
|
||||
|
||||
|
||||
gau_mod = importlib.import_module(
|
||||
"cognee.modules.users.methods.get_authenticated_user"
|
||||
)
|
||||
|
||||
|
||||
class TestConditionalAuthentication:
|
||||
"""Test cases for conditional authentication functionality."""
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@patch(
|
||||
"cognee.modules.users.methods.get_authenticated_user.get_default_user",
|
||||
new_callable=AsyncMock,
|
||||
)
|
||||
@patch(
|
||||
"cognee.modules.users.methods.get_authenticated_user.REQUIRE_AUTHENTICATION",
|
||||
False,
|
||||
)
|
||||
@patch.object(gau_mod, 'get_default_user', new_callable=AsyncMock)
|
||||
async def test_require_authentication_false_no_token_returns_default_user(
|
||||
self, mock_get_default
|
||||
):
|
||||
|
|
@ -28,25 +28,16 @@ class TestConditionalAuthentication:
|
|||
mock_default_user = SimpleNamespace(id=uuid4(), email="default@example.com", is_active=True)
|
||||
mock_get_default.return_value = mock_default_user
|
||||
|
||||
from cognee.modules.users.methods.get_authenticated_user import (
|
||||
get_authenticated_user,
|
||||
)
|
||||
# Use gau_mod.get_authenticated_user instead
|
||||
|
||||
# Test with None user (no authentication)
|
||||
result = await get_authenticated_user(user=None)
|
||||
result = await gau_mod.get_authenticated_user(user=None)
|
||||
|
||||
assert result == mock_default_user
|
||||
mock_get_default.assert_called_once()
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@patch(
|
||||
"cognee.modules.users.methods.get_authenticated_user.get_default_user",
|
||||
new_callable=AsyncMock,
|
||||
)
|
||||
@patch(
|
||||
"cognee.modules.users.methods.get_authenticated_user.REQUIRE_AUTHENTICATION",
|
||||
False,
|
||||
)
|
||||
@patch.object(gau_mod, 'get_default_user', new_callable=AsyncMock)
|
||||
async def test_require_authentication_false_with_valid_user_returns_user(
|
||||
self, mock_get_default
|
||||
):
|
||||
|
|
@ -59,22 +50,17 @@ class TestConditionalAuthentication:
|
|||
is_verified=True,
|
||||
)
|
||||
|
||||
from cognee.modules.users.methods.get_authenticated_user import (
|
||||
get_authenticated_user,
|
||||
)
|
||||
# Use gau_mod.get_authenticated_user instead
|
||||
|
||||
# Test with authenticated user
|
||||
result = await get_authenticated_user(user=mock_authenticated_user)
|
||||
result = await gau_mod.get_authenticated_user(user=mock_authenticated_user)
|
||||
|
||||
assert result == mock_authenticated_user
|
||||
mock_get_default.assert_not_called()
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@patch(
|
||||
"cognee.modules.users.methods.get_authenticated_user.REQUIRE_AUTHENTICATION",
|
||||
True,
|
||||
)
|
||||
async def test_require_authentication_true_with_user_returns_user(self):
|
||||
@patch.object(gau_mod, 'get_default_user', new_callable=AsyncMock)
|
||||
async def test_require_authentication_true_with_user_returns_user(self, mock_get_default):
|
||||
"""Test that when REQUIRE_AUTHENTICATION=true and user present, returns user."""
|
||||
mock_authenticated_user = User(
|
||||
id=uuid4(),
|
||||
|
|
@ -84,11 +70,9 @@ class TestConditionalAuthentication:
|
|||
is_verified=True,
|
||||
)
|
||||
|
||||
from cognee.modules.users.methods.get_authenticated_user import (
|
||||
get_authenticated_user,
|
||||
)
|
||||
# Use gau_mod.get_authenticated_user instead
|
||||
|
||||
result = await get_authenticated_user(user=mock_authenticated_user)
|
||||
result = await gau_mod.get_authenticated_user(user=mock_authenticated_user)
|
||||
|
||||
assert result == mock_authenticated_user
|
||||
|
||||
|
|
@ -144,7 +128,7 @@ class TestConditionalAuthenticationEnvironmentVariables:
|
|||
from cognee.modules.users.methods.get_authenticated_user import (
|
||||
REQUIRE_AUTHENTICATION,
|
||||
)
|
||||
|
||||
importlib.invalidate_caches()
|
||||
assert not REQUIRE_AUTHENTICATION
|
||||
|
||||
def test_require_authentication_true(self):
|
||||
|
|
@ -211,38 +195,19 @@ class TestConditionalAuthenticationEdgeCases:
|
|||
"""Test edge cases and error scenarios."""
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@patch(
|
||||
"cognee.modules.users.methods.get_authenticated_user.get_default_user",
|
||||
new_callable=AsyncMock,
|
||||
)
|
||||
@patch.dict(os.environ, {"REQUIRE_AUTHENTICATION": "false"})
|
||||
@patch.object(gau_mod, 'get_default_user', new_callable=AsyncMock)
|
||||
async def test_get_default_user_raises_exception(self, mock_get_default):
|
||||
"""Test behavior when get_default_user raises an exception."""
|
||||
from cognee.modules.users.methods.get_authenticated_user import (
|
||||
get_authenticated_user,
|
||||
)
|
||||
|
||||
mock_get_default.side_effect = Exception("Database error")
|
||||
|
||||
# This should propagate the exception
|
||||
with pytest.raises(Exception, match="Database error"):
|
||||
await get_authenticated_user(user=None)
|
||||
await gau_mod.get_authenticated_user(user=None)
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@patch(
|
||||
"cognee.modules.users.methods.get_authenticated_user.get_default_user",
|
||||
new_callable=AsyncMock,
|
||||
)
|
||||
@patch(
|
||||
"cognee.modules.users.methods.get_authenticated_user.REQUIRE_AUTHENTICATION",
|
||||
False,
|
||||
)
|
||||
@patch.object(gau_mod, 'get_default_user', new_callable=AsyncMock)
|
||||
async def test_user_type_consistency(self, mock_get_default):
|
||||
"""Test that the function always returns the same type."""
|
||||
from cognee.modules.users.methods.get_authenticated_user import (
|
||||
get_authenticated_user,
|
||||
)
|
||||
|
||||
mock_user = User(
|
||||
id=uuid4(),
|
||||
email="test@example.com",
|
||||
|
|
@ -255,11 +220,11 @@ class TestConditionalAuthenticationEdgeCases:
|
|||
mock_get_default.return_value = mock_default_user
|
||||
|
||||
# Test with user
|
||||
result1 = await get_authenticated_user(user=mock_user)
|
||||
result1 = await gau_mod.get_authenticated_user(user=mock_user)
|
||||
assert result1 == mock_user
|
||||
|
||||
# Test with None
|
||||
result2 = await get_authenticated_user(user=None)
|
||||
result2 = await gau_mod.get_authenticated_user(user=None)
|
||||
assert result2 == mock_default_user
|
||||
|
||||
# Both should have user-like interface
|
||||
|
|
@ -277,14 +242,7 @@ class TestConditionalAuthenticationEdgeCases:
|
|||
class TestAuthenticationScenarios:
|
||||
"""Test specific authentication scenarios that could occur in FastAPI Users."""
|
||||
|
||||
@patch(
|
||||
"cognee.modules.users.methods.get_authenticated_user.get_default_user",
|
||||
new_callable=AsyncMock,
|
||||
)
|
||||
@patch(
|
||||
"cognee.modules.users.methods.get_authenticated_user.REQUIRE_AUTHENTICATION",
|
||||
False,
|
||||
)
|
||||
@patch.object(gau_mod, 'get_default_user', new_callable=AsyncMock)
|
||||
async def test_fallback_to_default_user_scenarios(self, mock_get_default):
|
||||
"""
|
||||
Test fallback to default user for all scenarios where FastAPI Users returns None:
|
||||
|
|
@ -299,19 +257,11 @@ class TestAuthenticationScenarios:
|
|||
mock_default_user = SimpleNamespace(id=uuid4(), email="default@example.com")
|
||||
mock_get_default.return_value = mock_default_user
|
||||
|
||||
from cognee.modules.users.methods.get_authenticated_user import (
|
||||
get_authenticated_user,
|
||||
)
|
||||
|
||||
# All the above scenarios result in user=None being passed to our function
|
||||
result = await get_authenticated_user(user=None)
|
||||
result = await gau_mod.get_authenticated_user(user=None)
|
||||
assert result == mock_default_user
|
||||
mock_get_default.assert_called_once()
|
||||
|
||||
@patch(
|
||||
"cognee.modules.users.methods.get_authenticated_user.REQUIRE_AUTHENTICATION",
|
||||
False,
|
||||
)
|
||||
async def test_scenario_valid_active_user(self):
|
||||
"""Scenario: Valid JWT and user exists and is active → returns the user."""
|
||||
mock_user = User(
|
||||
|
|
@ -322,9 +272,7 @@ class TestAuthenticationScenarios:
|
|||
is_verified=True,
|
||||
)
|
||||
|
||||
from cognee.modules.users.methods.get_authenticated_user import (
|
||||
get_authenticated_user,
|
||||
)
|
||||
# Use gau_mod.get_authenticated_user instead
|
||||
|
||||
result = await get_authenticated_user(user=mock_user)
|
||||
result = await gau_mod.get_authenticated_user(user=mock_user)
|
||||
assert result == mock_user
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue