import asyncio import importlib import json import os import socket import subprocess import sys from pathlib import Path from datetime import datetime from unittest import mock from unittest.mock import AsyncMock, MagicMock, mock_open, patch import click import httpx import pytest import yaml from fastapi import FastAPI from fastapi.testclient import TestClient sys.path.insert( 0, os.path.abspath("../../..") ) # Adds the parent directory to the system-path import litellm from litellm.proxy.auth.user_api_key_auth import user_api_key_auth from litellm.proxy.proxy_server import app, initialize example_embedding_result = { "object": "list", "data": [ { "object": "embedding", "index": 0, "embedding": [ -0.006929283495992422, -0.005336422007530928, -4.547132266452536e-05, -0.024047505110502243, -0.006929283495992422, -0.005336422007530928, -4.547132266452536e-05, -0.024047505110502243, -0.006929283495992422, -0.005336422007530928, -4.547132266452536e-05, -0.024047505110502243, ], } ], "model": "text-embedding-3-small", "usage": {"prompt_tokens": 5, "total_tokens": 5}, } def mock_patch_aembedding(): return mock.patch( "litellm.proxy.proxy_server.llm_router.aembedding", return_value=example_embedding_result, ) @pytest.fixture(scope="function") def client_no_auth(): # Assuming litellm.proxy.proxy_server is an object from litellm.proxy.proxy_server import cleanup_router_config_variables cleanup_router_config_variables() filepath = os.path.dirname(os.path.abspath(__file__)) config_fp = f"{filepath}/test_configs/test_config_no_auth.yaml" # initialize can get run in parallel, it sets specific variables for the fast api app, sinc eit gets run in parallel different tests use the wrong variables asyncio.run(initialize(config=config_fp, debug=True)) return TestClient(app) def test_login_v2_returns_redirect_url_and_sets_cookie(monkeypatch): mock_login_result = {"user_id": "test-user"} mock_prisma_client = MagicMock() mock_authenticate_user = AsyncMock(return_value=mock_login_result) mock_create_ui_token_object = MagicMock(return_value={"user_id": "test-user"}) mock_jwt_encode = MagicMock(return_value="signed-token") monkeypatch.setattr( "litellm.proxy.auth.login_utils.authenticate_user", mock_authenticate_user, ) monkeypatch.setattr( "litellm.proxy.auth.login_utils.create_ui_token_object", mock_create_ui_token_object, ) monkeypatch.setattr("jwt.encode", mock_jwt_encode) monkeypatch.setattr("litellm.proxy.proxy_server.master_key", "test-master-key") monkeypatch.setattr("litellm.proxy.proxy_server.general_settings", {}) monkeypatch.setattr("litellm.proxy.proxy_server.premium_user", False) monkeypatch.setattr("litellm.proxy.proxy_server.prisma_client", mock_prisma_client) monkeypatch.setattr("litellm.proxy.utils.get_server_root_path", lambda: "") client = TestClient(app) response = client.post( "/v2/login", json={"username": "alice", "password": "secret"}, ) assert response.status_code == 200 assert ( response.json() == {"redirect_url": "http://testserver/ui/?login=success"} ) assert response.cookies.get("token") == "signed-token" mock_authenticate_user.assert_awaited_once_with( username="alice", password="secret", master_key="test-master-key", prisma_client=mock_prisma_client, ) mock_create_ui_token_object.assert_called_once_with( login_result=mock_login_result, general_settings={}, premium_user=False, ) mock_jwt_encode.assert_called_once_with( {"user_id": "test-user"}, "test-master-key", algorithm="HS256", ) def test_fallback_login_has_no_deprecation_banner(client_no_auth): response = client_no_auth.get("/fallback/login") assert response.status_code == 200 html = response.text assert '