Skip to main content
Glama
conftest.py11.6 kB
# mcp-server/tests/conftest.py import pytest import shutil import os import json from fastapi.testclient import TestClient import dotenv # Carregar .env.test explicitamente para garantir variáveis corretas nos testes dotenv.load_dotenv(dotenv_path=os.path.join(os.path.dirname(os.path.dirname(__file__)), '.env.test'), override=True) # Attempt to import the FastAPI app instance and other necessary components try: from app.main import app # The FastAPI application instance from app.utils.password import hash_password as app_hash_password FASTAPI_APP_IMPORTED = True except ImportError as e: print(f"Warning: Could not import FastAPI app or app_hash_password: {e}") print("Tests requiring the app instance or real hashing for setup might be affected or use dummies.") FASTAPI_APP_IMPORTED = False app = None # Placeholder if app import fails # Define a dummy hash_password if the real one couldn't be imported def app_hash_password(password: str) -> str: print(f"Warning: Using DUMMY app_hash_password for '{password}'") return f"dummy_hashed:{password}" # Define the paths to the master test data files and the working copies BASE_DIR = os.path.dirname(os.path.abspath(__file__)) # This will be /tests directory MASTER_RBAC_FILE = os.path.join(BASE_DIR, "data", "test_rbac_fixed.json") # Our fixed master file with all test users MASTER_REQUESTS_FILE = os.path.join(BASE_DIR, "data", "test_requests_master.json") # These are the paths for the working copies used by the app during tests. # .env.test should point RBAC_FILE and REQUESTS_FILE to these locations. WORKING_RBAC_FILE = os.path.join(BASE_DIR, "data", "test_rbac.json") WORKING_REQUESTS_FILE = os.path.join(BASE_DIR, "data", "test_requests.json") @pytest.fixture(scope="session", autouse=True) def create_master_test_data_files_if_not_exist(): data_dir = os.path.join(BASE_DIR, "data") if not os.path.exists(data_dir): os.makedirs(data_dir) # Primeiro verificamos se o arquivo master de RBAC está disponível if not os.path.exists(MASTER_RBAC_FILE): print(f"AVISO: Arquivo master RBAC {MASTER_RBAC_FILE} não encontrado!") # Ao invés de apenas criar um vazio, vamos usar o que temos no test_rbac_master.json master_data_path = os.path.join(BASE_DIR, "data", "test_rbac_master.json") if os.path.exists(master_data_path): print(f"Usando dados de teste de {master_data_path}") shutil.copyfile(master_data_path, WORKING_RBAC_FILE) else: print("Criando dados RBAC padrão para testes") # Criar dados padrão que incluem o usuário globaladmin default_rbac = { "grupos": { "group1": { "descricao": "Test Group 1", "admins": ["admin_group1"], "users": ["testuser1", "admin_group1"], "ferramentas": ["tool_x"] } }, "usuarios": { "testuser1": { "senha": "$2b$12$vNigeVwdz9D/8x9YQm2RzeK42z9k5aGIDtutY1766N5eZx/ub3azO", "grupos": ["group1"], "papel": "user" }, "admin_group1": { "senha": "$2b$12$Ezb.NwWPT3mBrp9wUwU1FuCgDCDQ.qQ/aXCGu49S2dqn4VihIIiJy", "grupos": ["group1"], "papel": "admin" }, "globaladmin": { "senha": "$2b$12$qL7NEHc85jf/.JK0CJpcI.5FO11s3GEQnmCz1xV/FrKNzezBZXmam", "grupos": [], "papel": "global_admin" } } } with open(WORKING_RBAC_FILE, 'w') as f: json.dump(default_rbac, f, indent=2) # Handling for MASTER_REQUESTS_FILE remains the same for now if not os.path.exists(MASTER_REQUESTS_FILE): initial_requests_data = {"requests": []} with open(MASTER_REQUESTS_FILE, 'w') as f: json.dump(initial_requests_data, f, indent=2) @pytest.fixture(scope="function", autouse=True) def manage_test_data_files(): """ Fixture para gerenciar os arquivos de dados de teste. Roda antes de cada teste para garantir um ambiente limpo com dados consistentes. """ data_dir = os.path.join(BASE_DIR, "data") if not os.path.exists(data_dir): os.makedirs(data_dir) # Definir os dados mínimos necessários para os testes funcionarem needed_users = [ "globaladmin", "testuser1", "plainuser", "admin_group1", "requesteruser", "admin_group_for_request" ] # Sempre recria o arquivo de teste a partir do master para cada teste print(f"Reiniciando dados de teste para um novo teste...") # Garante que o RBAC esteja em um estado consistente para cada teste # Definir uma senha hash para o globaladmin (password_global) globaladmin_password_hash = "$2b$12$PClOP0mZrASxU6NGlXL4Z.lAAsmOjRmuS/slyaepN2HAV/dIzA25W" # password_global fallback_rbac = { "grupos": { "group1": { "descricao": "Test Group 1", "admins": ["admin_group1"], "users": ["testuser1", "admin_group1"], "ferramentas": ["tool_x"] }, "group_for_request": { "descricao": "Group for access requests", "admins": ["admin_group_for_request"], "users": ["admin_group_for_request"], "ferramentas": [] } }, "usuarios": { "testuser1": { "senha": "$2b$12$vNigeVwdz9D/8x9YQm2RzeK42z9k5aGIDtutY1766N5eZx/ub3azO", # password123 "grupos": ["group1"], "papel": "user" }, "admin_group1": { "senha": "$2b$12$Ezb.NwWPT3mBrp9wUwU1FuCgDCDQ.qQ/aXCGu49S2dqn4VihIIiJy", # password123 "grupos": ["group1"], "papel": "admin" }, "globaladmin": { "senha": globaladmin_password_hash, "grupos": [], "papel": "global_admin" }, "plainuser": { "senha": "plainpassword", "grupos": [], "papel": "user" }, "requesteruser": { "senha": "$2b$12$wUoxriexlDcxrzwCbeLPv.KdcW5YjszfEGo1wuIP2HbYkzih/Nfrq", # password123 "grupos": [], "papel": "user" }, "admin_group_for_request": { "senha": "$2b$12$Dg3tXO7RIeVmeI1V/0mWHe44Ifz5IqxSVtnP6bjPBrvPDmAVNkmJi", # password123 "grupos": ["group_for_request"], "papel": "admin" } }, "ferramentas": { "tool_x": { "nome": "Ferramenta X", "url_base": "/tools/ferramenta_x", "descricao": "Ferramenta de Teste X" }, "tool_y": { "nome": "Ferramenta Y", "url_base": "/tools/ferramenta_y", "descricao": "Ferramenta de Teste Y" } } } fallback_requests = {"requests": []} # Sempre usa o arquivo master do RBAC para cada teste if os.path.exists(MASTER_RBAC_FILE): print(f"Copiando dados RBAC do arquivo master: {MASTER_RBAC_FILE}") # Sempre copia o arquivo master para garantir um estado consistente try: with open(MASTER_RBAC_FILE, 'r') as f: master_rbac = json.load(f) # Garante que o master_rbac tem todos os usuários necessários usuarios = master_rbac.get("usuarios", {}) missing_users = [u for u in needed_users if u not in usuarios] if missing_users: print(f"Adicionando usuários ausentes no arquivo master...") # Adiciona usuários ausentes ao arquivo master for user in missing_users: if user in fallback_rbac["usuarios"]: master_rbac["usuarios"][user] = fallback_rbac["usuarios"][user] # Escreve um novo arquivo de trabalho with open(WORKING_RBAC_FILE, 'w') as f: json.dump(master_rbac, f, indent=2) except Exception as e: print(f"Erro ao atualizar {WORKING_RBAC_FILE} a partir do master: {e}") print("Usando dados de fallback...") with open(WORKING_RBAC_FILE, 'w') as f: json.dump(fallback_rbac, f, indent=2) else: print(f"Aviso: MASTER_RBAC_FILE ({MASTER_RBAC_FILE}) não encontrado.") print(f"Criando arquivo de teste RBAC com usuários padrão...") with open(WORKING_RBAC_FILE, 'w') as f: json.dump(fallback_rbac, f, indent=2) # Gerencia o arquivo de solicitações if os.path.exists(MASTER_REQUESTS_FILE): shutil.copyfile(MASTER_REQUESTS_FILE, WORKING_REQUESTS_FILE) else: print(f"Aviso: MASTER_REQUESTS_FILE ({MASTER_REQUESTS_FILE}) não encontrado.") print("Criando arquivo de solicitações vazio...") with open(WORKING_REQUESTS_FILE, 'w') as f: json.dump(fallback_requests, f, indent=2) yield @pytest.fixture(scope="session", autouse=True) def verify_test_data(): """Verifica se o arquivo test_rbac.json contém os usuários necessários para os testes.""" print("Verificando dados de teste para usuários necessários...") try: with open(WORKING_RBAC_FILE, 'r') as f: rbac_data = json.load(f) usuarios = rbac_data.get("usuarios", {}) needed_users = ["globaladmin", "testuser1", "plainuser"] for user in needed_users: if user not in usuarios: print(f"AVISO: Usuário '{user}' não encontrado em {WORKING_RBAC_FILE}") else: print(f"Usuário '{user}' encontrado em {WORKING_RBAC_FILE}") # Verificar senha do globaladmin especificamente if "globaladmin" in usuarios: print(f"Hash da senha para globaladmin: {usuarios['globaladmin']['senha'][:20]}...") except Exception as e: print(f"Erro ao verificar dados de teste: {e}") @pytest.fixture(scope="module") def client(): if not FASTAPI_APP_IMPORTED or app is None: pytest.fail("FastAPI app could not be imported. Check PYTHONPATH and imports in conftest.py.") # Verificar variáveis de ambiente críticas para os testes print(f"SECRET_KEY nos testes: {os.getenv('SECRET_KEY')}") print(f"RBAC_FILE nos testes: {os.getenv('RBAC_FILE')}") with TestClient(app) as c: yield c @pytest.fixture def auth_token_for_user(client: TestClient): def _get_token(username, password): print(f"Tentando obter token para usuário: {username} com senha: {password}") response = client.post("/tools/login", json={"username": username, "password": password}) print(f"Resposta do login: {response.status_code}") if response.status_code == 200: token = response.json()["access_token"] print(f"Token obtido com sucesso: {token[:20]}...") return token else: print(f"Falha ao obter token. Resposta: {response.text}") return None return _get_token

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/jowpereira/mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server