test: 补充知识处理、检索与 Agent 回归用例

覆盖切块、向量检索、工具调用和历史预算;模型相关用例使用桩。
This commit is contained in:
WangShen007 committed 2026-10-04 20:55:00 +08:00
1 parent 362d79a5c2
commit f4d8019829
123 files changed
+29005

No files matched your search

+880
View File
@@ -0,0 +1,880 @@
"""
Copyright 2024-2026 ChatterMate
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
"""
import pytest
from unittest.mock import patch, MagicMock, AsyncMock
from fastapi import HTTPException, Request, Depends
from sqlalchemy.orm import Session
from uuid import uuid4
from app.core.auth import (
check_permissions,
get_current_user,
get_current_organization,
require_permissions,
require_permission,
require_subscription_management,
require_unified_permissions,
require_any_unified_permission
)
from app.models.user import User
from app.models.organization import Organization
from app.models.permission import Permission
from app.models.role import Role
@pytest.fixture
def mock_db():
"""Create a mock database session"""
db = MagicMock(spec=Session)
return db
@pytest.fixture
def mock_user():
"""Create a mock user with role and permissions"""
user_id = uuid4()
org_id = uuid4()
# Create permissions
view_chats_permission = Permission(id=1, name="view_chats")
manage_agents_permission = Permission(id=2, name="manage_agents")
# Create role with permissions
role = Role(id=1, name="Agent", permissions=[view_chats_permission, manage_agents_permission])
# Create user with role
user = User(
id=user_id,
email="test@example.com",
hashed_password="hashed_password",
is_active=True,
organization_id=org_id,
full_name="Test User",
role=role
)
return user
@pytest.fixture
def mock_super_admin():
"""Create a mock user with super_admin permission"""
user_id = uuid4()
org_id = uuid4()
# Create super_admin permission
super_admin_permission = Permission(id=3, name="super_admin")
# Create role with super_admin permission
role = Role(id=2, name="Super Admin", permissions=[super_admin_permission])
# Create user with role
user = User(
id=user_id,
email="admin@example.com",
hashed_password="hashed_password",
is_active=True,
organization_id=org_id,
full_name="Admin User",
role=role
)
return user
@pytest.fixture
def mock_organization():
"""Create a mock organization"""
org_id = uuid4()
return Organization(
id=org_id,
name="Test Organization",
domain="test.com",
is_active=True
)
def test_check_permissions_with_required_permissions(mock_user):
"""Test check_permissions when user has the required permissions"""
result = check_permissions(mock_user, ["view_chats"])
assert result is True
def test_check_permissions_without_required_permissions(mock_user):
"""Test check_permissions when user doesn't have the required permissions"""
result = check_permissions(mock_user, ["delete_organization"])
assert result is False
def test_check_permissions_with_super_admin(mock_super_admin):
"""Test check_permissions with super_admin permission"""
result = check_permissions(mock_super_admin, ["delete_organization"])
assert result is True
def test_check_permissions_without_role():
"""Test check_permissions when user has no role"""
user = User(
id=uuid4(),
email="noauth@example.com",
hashed_password="hashed_password",
is_active=True
)
result = check_permissions(user, ["view_chats"])
assert result is False
@pytest.mark.asyncio
async def test_get_current_user_with_cookie(mock_db, mock_user):
"""Test get_current_user with access token in cookie"""
# Mock request with cookie
request = MagicMock(spec=Request)
access_token = "valid_access_token"
# Mock live_payload
payload = {"sub": str(mock_user.id)}
# Mock db query
mock_db.query.return_value.filter.return_value.first.return_value = mock_user
with patch('app.core.auth.live_payload', return_value=payload):
result = await get_current_user(request, access_token, mock_db)
assert result == mock_user
@pytest.mark.asyncio
async def test_get_current_user_with_auth_header(mock_db, mock_user):
"""Test get_current_user with access token in Authorization header"""
# Mock request with Authorization header
request = MagicMock(spec=Request)
request.headers.get.return_value = "Bearer valid_access_token"
# Mock live_payload
payload = {"sub": str(mock_user.id)}
# Mock db query
mock_db.query.return_value.filter.return_value.first.return_value = mock_user
with patch('app.core.auth.live_payload', return_value=payload):
result = await get_current_user(request, None, mock_db)
assert result == mock_user
@pytest.mark.asyncio
async def test_get_current_user_no_token(mock_db):
"""Test get_current_user with no access token"""
# Mock request with no token
request = MagicMock(spec=Request)
request.headers.get.return_value = None
with pytest.raises(HTTPException) as exc_info:
await get_current_user(request, None, mock_db)
assert exc_info.value.status_code == 401
assert exc_info.value.detail == "Not authenticated"
@pytest.mark.asyncio
async def test_get_current_user_invalid_token(mock_db):
"""Test get_current_user with invalid token"""
# Mock request
request = MagicMock(spec=Request)
access_token = "invalid_token"
# Mock live_payload
with patch('app.core.auth.live_payload', return_value=None):
with pytest.raises(HTTPException) as exc_info:
await get_current_user(request, access_token, mock_db)
assert exc_info.value.status_code == 401
assert exc_info.value.detail == "Invalid authentication token"
@pytest.mark.asyncio
async def test_get_current_user_invalid_payload(mock_db):
"""Test get_current_user with invalid payload"""
# Mock request
request = MagicMock(spec=Request)
access_token = "valid_token_invalid_payload"
# Mock live_payload
payload = {"not_sub": "invalid"}
with patch('app.core.auth.live_payload', return_value=payload):
with pytest.raises(HTTPException) as exc_info:
await get_current_user(request, access_token, mock_db)
assert exc_info.value.status_code == 401
assert exc_info.value.detail == "Invalid token payload"
@pytest.mark.asyncio
async def test_get_current_user_user_not_found(mock_db):
"""Test get_current_user when user not found"""
# Mock request
request = MagicMock(spec=Request)
access_token = "valid_token"
# Mock live_payload
payload = {"sub": str(uuid4())}
# Mock db query - user not found
mock_db.query.return_value.filter.return_value.first.return_value = None
with patch('app.core.auth.live_payload', return_value=payload):
with pytest.raises(HTTPException) as exc_info:
await get_current_user(request, access_token, mock_db)
assert exc_info.value.status_code == 401
assert exc_info.value.detail == "User not found"
@pytest.mark.asyncio
async def test_get_current_user_inactive_user(mock_db, mock_user):
"""Test get_current_user with inactive user"""
# Mock request
request = MagicMock(spec=Request)
access_token = "valid_token"
# Set user as inactive
mock_user.is_active = False
# Mock live_payload
payload = {"sub": str(mock_user.id)}
# Mock db query
mock_db.query.return_value.filter.return_value.first.return_value = mock_user
with patch('app.core.auth.live_payload', return_value=payload):
with pytest.raises(HTTPException) as exc_info:
await get_current_user(request, access_token, mock_db)
assert exc_info.value.status_code == 401
assert exc_info.value.detail == "User is inactive"
@pytest.mark.asyncio
async def test_get_current_user_exception(mock_db):
"""Test get_current_user with exception"""
# Mock request
request = MagicMock(spec=Request)
access_token = "valid_token"
# Mock live_payload to raise exception
with patch('app.core.auth.live_payload', side_effect=Exception("Test exception")):
with pytest.raises(HTTPException) as exc_info:
await get_current_user(request, access_token, mock_db)
assert exc_info.value.status_code == 401
assert exc_info.value.detail == "Could not validate credentials"
@pytest.mark.asyncio
async def test_get_current_organization_success(mock_db, mock_user, mock_organization):
"""Test get_current_organization success"""
# Mock db query
mock_db.query.return_value.filter.return_value.first.return_value = mock_organization
result = await get_current_organization(mock_user, mock_db)
assert result == mock_organization
@pytest.mark.asyncio
async def test_get_current_organization_no_org_id(mock_db):
"""Test get_current_organization with no organization_id"""
# Create user with no organization_id
user = User(
id=uuid4(),
email="noorg@example.com",
hashed_password="hashed_password",
is_active=True,
organization_id=None
)
with pytest.raises(HTTPException) as exc_info:
await get_current_organization(user, mock_db)
assert exc_info.value.status_code == 403
assert exc_info.value.detail == "User is not associated with any organization"
@pytest.mark.asyncio
async def test_get_current_organization_not_found(mock_db, mock_user):
"""Test get_current_organization when organization not found"""
# Mock db query - organization not found
mock_db.query.return_value.filter.return_value.first.return_value = None
with pytest.raises(HTTPException) as exc_info:
await get_current_organization(mock_user, mock_db)
assert exc_info.value.status_code == 404
assert exc_info.value.detail == "Organization not found or inactive"
# Test the require_permissions function indirectly through check_permissions
def test_require_permissions_check_with_permissions(mock_user):
"""Test the check used in require_permissions when user has the required permissions"""
result = check_permissions(mock_user, ["view_chats"])
assert result is True
def test_require_permissions_check_without_permissions(mock_user):
"""Test the check used in require_permissions when user doesn't have the required permissions"""
result = check_permissions(mock_user, ["delete_organization"])
assert result is False
# Test the require_permission function indirectly through role.has_permission
def test_require_permission_check_with_permission(mock_user):
"""Test the check used in require_permission when user has the required permission"""
# Mock the has_permission method
mock_user.role.has_permission = MagicMock(return_value=True)
# Check if the role has the permission
result = mock_user.role.has_permission("view_chats")
assert result is True
# Verify the has_permission method was called with the correct permission
mock_user.role.has_permission.assert_called_once_with("view_chats")
def test_require_permission_check_without_permission(mock_user):
"""Test the check used in require_permission when user doesn't have the required permission"""
# Mock the has_permission method
mock_user.role.has_permission = MagicMock(return_value=False)
# Check if the role has the permission
result = mock_user.role.has_permission("delete_organization")
assert result is False
# Verify the has_permission method was called with the correct permission
mock_user.role.has_permission.assert_called_once_with("delete_organization")
# Test the require_subscription_management function indirectly through role.can_manage_subscription
def test_require_subscription_management_check_with_permission(mock_user):
"""Test the check used in require_subscription_management when user has the permission"""
# Mock the can_manage_subscription method
mock_user.role.can_manage_subscription = MagicMock(return_value=True)
# Check if the role can manage subscriptions
result = mock_user.role.can_manage_subscription()
assert result is True
# Verify the can_manage_subscription method was called
mock_user.role.can_manage_subscription.assert_called_once()
def test_require_subscription_management_check_without_permission(mock_user):
"""Test the check used in require_subscription_management when user doesn't have the permission"""
# Mock the can_manage_subscription method
mock_user.role.can_manage_subscription = MagicMock(return_value=False)
# Check if the role can manage subscriptions
result = mock_user.role.can_manage_subscription()
assert result is False
# Verify the can_manage_subscription method was called
mock_user.role.can_manage_subscription.assert_called_once()
@pytest.mark.asyncio
async def test_require_permissions_inner_function(mock_user):
"""Test the inner function of require_permissions directly"""
# Create the inner function
permission_checker = require_permissions("view_chats")
# Mock Depends to return our user
with patch('fastapi.Depends', return_value=mock_user):
# Call the inner function
result = await permission_checker(mock_user)
assert result == mock_user
@pytest.mark.asyncio
async def test_require_permissions_inner_function_forbidden(mock_user):
"""Test the inner function of require_permissions with insufficient permissions"""
# Create the inner function
permission_checker = require_permissions("delete_organization")
# Call the inner function and expect an exception
with pytest.raises(HTTPException) as exc_info:
await permission_checker(mock_user)
assert exc_info.value.status_code == 403
assert exc_info.value.detail == "Not enough permissions"
@pytest.mark.asyncio
async def test_require_permission_inner_function(mock_user):
"""Test the inner function of require_permission directly"""
# Mock the role's has_permission method
mock_user.role.has_permission = MagicMock(return_value=True)
# Create the inner function
permission_dependency = require_permission("view_chats")
# Call the inner function
result = await permission_dependency(mock_user)
assert result == mock_user
mock_user.role.has_permission.assert_called_once_with("view_chats")
@pytest.mark.asyncio
async def test_require_permission_inner_function_forbidden(mock_user):
"""Test the inner function of require_permission with insufficient permissions"""
# Mock the role's has_permission method
mock_user.role.has_permission = MagicMock(return_value=False)
# Create the inner function
permission_dependency = require_permission("delete_organization")
# Call the inner function and expect an exception
with pytest.raises(HTTPException) as exc_info:
await permission_dependency(mock_user)
assert exc_info.value.status_code == 403
assert exc_info.value.detail == "User does not have required permission: delete_organization"
mock_user.role.has_permission.assert_called_once_with("delete_organization")
@pytest.mark.asyncio
async def test_require_subscription_management_with_permission(mock_user):
"""Test require_subscription_management with sufficient permissions"""
# Mock the role's can_manage_subscription method
mock_user.role.can_manage_subscription = MagicMock(return_value=True)
# Call the function
result = require_subscription_management(mock_user)
assert result == mock_user
mock_user.role.can_manage_subscription.assert_called_once()
@pytest.mark.asyncio
async def test_require_subscription_management_without_permission(mock_user):
"""Test require_subscription_management with insufficient permissions"""
# Mock the role's can_manage_subscription method
mock_user.role.can_manage_subscription = MagicMock(return_value=False)
# Call the function and expect an exception
with pytest.raises(HTTPException) as exc_info:
require_subscription_management(mock_user)
assert exc_info.value.status_code == 403
assert exc_info.value.detail == "User does not have permission to manage subscriptions"
mock_user.role.can_manage_subscription.assert_called_once()
# ==================== Tests for get_auth_info_from_request ====================
from app.core.auth import get_auth_info_from_request
def test_get_auth_info_from_request_shopify_url():
"""Test get_auth_info_from_request with Shopify URL"""
request = MagicMock(spec=Request)
request.url = "https://example.com/api/shopify/products"
result = get_auth_info_from_request(request)
assert result["is_shopify"] is True
def test_get_auth_info_from_request_non_shopify_url():
"""Test get_auth_info_from_request with non-Shopify URL"""
request = MagicMock(spec=Request)
request.url = "https://example.com/api/users"
result = get_auth_info_from_request(request)
assert result["is_shopify"] is False
# ==================== Tests for get_unified_auth ====================
from app.core.auth import get_unified_auth
@pytest.mark.asyncio
async def test_get_unified_auth_jwt_success(mock_db, mock_user):
"""Test get_unified_auth with valid JWT token"""
request = MagicMock(spec=Request)
request.url = "https://example.com/api/agents"
request.query_params = {}
request.cookies.get.return_value = "valid_token"
request.headers.get.return_value = None
# Add manage_agents permission
manage_agents_perm = Permission(id=2, name="manage_agents")
mock_user.role.permissions = [manage_agents_perm]
payload = {"sub": str(mock_user.id)}
mock_db.query.return_value.filter.return_value.first.return_value = mock_user
with patch('app.core.auth.live_payload', return_value=payload):
result = await get_unified_auth(request, mock_db)
assert result["auth_type"] == "jwt"
assert result["organization_id"] == mock_user.organization_id
assert result["current_user"] == mock_user
@pytest.mark.asyncio
async def test_get_unified_auth_jwt_no_token(mock_db):
"""Test get_unified_auth without token"""
request = MagicMock(spec=Request)
request.url = "https://example.com/api/agents"
request.query_params = {}
request.cookies.get.return_value = None
request.headers.get.return_value = None
with pytest.raises(HTTPException) as exc_info:
await get_unified_auth(request, mock_db)
assert exc_info.value.status_code == 401
@pytest.mark.asyncio
async def test_get_unified_auth_jwt_invalid_token(mock_db):
"""Test get_unified_auth with invalid JWT token"""
request = MagicMock(spec=Request)
request.url = "https://example.com/api/agents"
request.query_params = {}
request.cookies.get.return_value = "invalid_token"
request.headers.get.return_value = None
with patch('app.core.auth.live_payload', return_value=None):
with pytest.raises(HTTPException) as exc_info:
await get_unified_auth(request, mock_db)
assert exc_info.value.status_code == 401
assert exc_info.value.detail == "Invalid authentication token"
@pytest.mark.asyncio
async def test_get_unified_auth_jwt_user_not_found(mock_db):
"""Test get_unified_auth when user not found"""
request = MagicMock(spec=Request)
request.url = "https://example.com/api/agents"
request.query_params = {}
request.cookies.get.return_value = "valid_token"
request.headers.get.return_value = None
payload = {"sub": str(uuid4())}
mock_db.query.return_value.filter.return_value.first.return_value = None
with patch('app.core.auth.live_payload', return_value=payload):
with pytest.raises(HTTPException) as exc_info:
await get_unified_auth(request, mock_db)
assert exc_info.value.status_code == 401
assert exc_info.value.detail == "User not found"
@pytest.mark.asyncio
async def test_get_unified_auth_jwt_inactive_user(mock_db, mock_user):
"""Test get_unified_auth with inactive user"""
request = MagicMock(spec=Request)
request.url = "https://example.com/api/agents"
request.query_params = {}
request.cookies.get.return_value = "valid_token"
request.headers.get.return_value = None
mock_user.is_active = False
payload = {"sub": str(mock_user.id)}
mock_db.query.return_value.filter.return_value.first.return_value = mock_user
with patch('app.core.auth.live_payload', return_value=payload):
with pytest.raises(HTTPException) as exc_info:
await get_unified_auth(request, mock_db)
assert exc_info.value.status_code == 401
assert exc_info.value.detail == "User is inactive"
@pytest.mark.asyncio
async def test_get_unified_auth_authenticates_without_permissions(mock_db, mock_user):
"""get_unified_auth authenticates; it does not authorize.
It used to hardcode a manage_agents check, so every route sharing the helper
inherited it — including reading your own org's subscription, which locked
every non-admin out of the entire app.
"""
request = MagicMock(spec=Request)
request.url = "https://example.com/api/agents"
request.query_params = {}
request.cookies.get.return_value = "valid_token"
request.headers.get.return_value = None
mock_user.role.permissions = [Permission(id=1, name="view_only")]
payload = {"sub": str(mock_user.id)}
mock_db.query.return_value.filter.return_value.first.return_value = mock_user
with patch('app.core.auth.live_payload', return_value=payload):
result = await get_unified_auth(request, mock_db)
assert result["auth_type"] == "jwt"
assert result["current_user"] is mock_user
@pytest.mark.asyncio
async def test_require_unified_permissions_rejects_missing_permission(mock_user):
"""The wrapper is what enforces the route's requirement."""
mock_user.role.permissions = [Permission(id=1, name="view_only")]
checker = require_unified_permissions("manage_agents")
with pytest.raises(HTTPException) as exc_info:
await checker(auth_info={"auth_type": "jwt", "current_user": mock_user})
assert exc_info.value.status_code == 403
assert exc_info.value.detail == "Not enough permissions"
@pytest.mark.asyncio
async def test_require_unified_permissions_allows_holder(mock_user):
"""A user holding the permission passes through unchanged."""
mock_user.role.permissions = [Permission(id=1, name="manage_agents")]
auth_info = {"auth_type": "jwt", "current_user": mock_user}
checker = require_unified_permissions("manage_agents")
assert await checker(auth_info=auth_info) is auth_info
@pytest.mark.asyncio
async def test_require_any_unified_permission_is_or_semantics(mock_user):
"""Any one of the listed permissions is enough."""
mock_user.role.permissions = [Permission(id=1, name="view_agents")]
checker = require_any_unified_permission("view_agents", "manage_agents")
result = await checker(auth_info={"auth_type": "jwt", "current_user": mock_user})
assert result["auth_type"] == "jwt"
@pytest.mark.asyncio
async def test_unified_permissions_pass_through_shop_session():
"""A Shopify shop session authenticates a store, not a person.
It carries no current_user and no role, so there is nothing to check — it
must pass through exactly as it did before authorization moved out.
"""
auth_info = {"auth_type": "shopify", "organization_id": uuid4()}
assert await require_unified_permissions("manage_agents")(auth_info=auth_info) is auth_info
assert await require_any_unified_permission("manage_agents")(auth_info=auth_info) is auth_info
@pytest.mark.asyncio
async def test_unified_permissions_tolerate_absent_current_user_key():
"""Callers that omit the key entirely must not blow up with a KeyError."""
auth_info = {"auth_type": "jwt", "organization_id": uuid4()}
assert await require_unified_permissions("manage_agents")(auth_info=auth_info) is auth_info
@pytest.mark.asyncio
async def test_get_unified_auth_shopify_context(mock_db):
"""Test get_unified_auth with Shopify context"""
request = MagicMock(spec=Request)
request.url = "https://example.com/api/shopify/agents"
request.query_params = {}
mock_auth_result = {
"auth_type": "shopify",
"organization_id": uuid4(),
"user_id": uuid4(),
"current_user": None
}
with patch('app.services.shopify_session.require_shopify_or_jwt_auth', new_callable=AsyncMock) as mock_shopify_auth:
mock_shopify_auth.return_value = mock_auth_result
result = await get_unified_auth(request, mock_db)
assert result["auth_type"] == "shopify"
@pytest.mark.asyncio
async def test_get_unified_auth_with_auth_header(mock_db, mock_user):
"""Test get_unified_auth with Authorization header"""
request = MagicMock(spec=Request)
request.url = "https://example.com/api/agents"
request.query_params = {}
request.cookies.get.return_value = None
request.headers.get.return_value = "Bearer valid_token"
manage_agents_perm = Permission(id=2, name="manage_agents")
mock_user.role.permissions = [manage_agents_perm]
payload = {"sub": str(mock_user.id)}
mock_db.query.return_value.filter.return_value.first.return_value = mock_user
with patch('app.core.auth.live_payload', return_value=payload):
result = await get_unified_auth(request, mock_db)
assert result["auth_type"] == "jwt"
assert result["current_user"] == mock_user
# ==================== Tests for get_unified_chat_auth ====================
from app.core.auth import get_unified_chat_auth
@pytest.mark.asyncio
async def test_get_unified_chat_auth_jwt_success(mock_db, mock_user):
"""Test get_unified_chat_auth with valid JWT token"""
request = MagicMock(spec=Request)
request.url = "https://example.com/api/chats"
request.cookies.get.return_value = "valid_token"
request.headers.get.return_value = None
# Add chat permissions
view_all_chats = Permission(id=10, name="view_all_chats")
mock_user.role.permissions = [view_all_chats]
payload = {"sub": str(mock_user.id)}
mock_db.query.return_value.filter.return_value.first.return_value = mock_user
with patch('app.core.auth.live_payload', return_value=payload):
result = await get_unified_chat_auth(request, mock_db)
assert result["auth_type"] == "jwt"
assert result["can_view_all"] is True
assert result["can_view_assigned"] is False
@pytest.mark.asyncio
async def test_get_unified_chat_auth_view_assigned(mock_db, mock_user):
"""Test get_unified_chat_auth with view_assigned_chats permission"""
request = MagicMock(spec=Request)
request.url = "https://example.com/api/chats"
request.cookies.get.return_value = "valid_token"
request.headers.get.return_value = None
# Add assigned chats permission only
view_assigned_chats = Permission(id=11, name="view_assigned_chats")
mock_user.role.permissions = [view_assigned_chats]
payload = {"sub": str(mock_user.id)}
mock_db.query.return_value.filter.return_value.first.return_value = mock_user
with patch('app.core.auth.live_payload', return_value=payload):
result = await get_unified_chat_auth(request, mock_db)
assert result["auth_type"] == "jwt"
assert result["can_view_all"] is False
assert result["can_view_assigned"] is True
@pytest.mark.asyncio
async def test_get_unified_chat_auth_no_permissions(mock_db, mock_user):
"""Test get_unified_chat_auth without chat permissions"""
request = MagicMock(spec=Request)
request.url = "https://example.com/api/chats"
request.cookies.get.return_value = "valid_token"
request.headers.get.return_value = None
# No chat permissions
other_perm = Permission(id=1, name="other_permission")
mock_user.role.permissions = [other_perm]
payload = {"sub": str(mock_user.id)}
mock_db.query.return_value.filter.return_value.first.return_value = mock_user
with patch('app.core.auth.live_payload', return_value=payload):
with pytest.raises(HTTPException) as exc_info:
await get_unified_chat_auth(request, mock_db)
assert exc_info.value.status_code == 403
assert exc_info.value.detail == "Not enough permissions"
@pytest.mark.asyncio
async def test_get_unified_chat_auth_shopify_context(mock_db):
"""Test get_unified_chat_auth with Shopify context"""
request = MagicMock(spec=Request)
request.url = "https://example.com/api/shopify/chats"
mock_auth_result = {
"auth_type": "shopify",
"organization_id": uuid4(),
"user_id": uuid4(),
"current_user": None
}
with patch('app.services.shopify_session.require_shopify_or_jwt_auth', new_callable=AsyncMock) as mock_shopify_auth:
mock_shopify_auth.return_value = mock_auth_result
result = await get_unified_chat_auth(request, mock_db)
assert result["auth_type"] == "shopify"
@pytest.mark.asyncio
async def test_get_unified_chat_auth_no_token(mock_db):
"""Test get_unified_chat_auth without token"""
request = MagicMock(spec=Request)
request.url = "https://example.com/api/chats"
request.cookies.get.return_value = None
request.headers.get.return_value = None
with pytest.raises(HTTPException) as exc_info:
await get_unified_chat_auth(request, mock_db)
assert exc_info.value.status_code == 401
@pytest.mark.asyncio
async def test_get_unified_chat_auth_exception(mock_db):
"""Test get_unified_chat_auth with exception"""
request = MagicMock(spec=Request)
request.url = "https://example.com/api/chats"
request.cookies.get.return_value = "valid_token"
request.headers.get.return_value = None
with patch('app.core.auth.live_payload', side_effect=Exception("Test error")):
with pytest.raises(HTTPException) as exc_info:
await get_unified_chat_auth(request, mock_db)
assert exc_info.value.status_code == 401
@pytest.mark.asyncio
async def test_get_unified_auth_exception(mock_db):
"""Test get_unified_auth with unexpected exception"""
request = MagicMock(spec=Request)
request.url = "https://example.com/api/agents"
request.query_params = {}
request.cookies.get.return_value = "valid_token"
request.headers.get.return_value = None
with patch('app.core.auth.live_payload', side_effect=Exception("Unexpected error")):
with pytest.raises(HTTPException) as exc_info:
await get_unified_auth(request, mock_db)
assert exc_info.value.status_code == 401
@pytest.mark.asyncio
async def test_get_current_user_from_cookie_directly(mock_db, mock_user):
"""Test get_current_user when token is read directly from cookies"""
request = MagicMock(spec=Request)
request.cookies = {"access_token": "valid_cookie_token"}
request.headers.get.return_value = None
payload = {"sub": str(mock_user.id)}
mock_db.query.return_value.filter.return_value.first.return_value = mock_user
with patch('app.core.auth.live_payload', return_value=payload):
result = await get_current_user(request, None, mock_db)
assert result == mock_user