336 lines
11 KiB
Python
336 lines
11 KiB
Python
import pytest
|
|
from fastapi_users.authentication import JWTStrategy
|
|
|
|
from app.main import app
|
|
from httpx import AsyncClient
|
|
from datetime import datetime, timedelta
|
|
from app.database.models import Base, RbacUser, RbacPapel, RbacPermissao
|
|
# from fastapi_users_db_sqlalchemy import SQLAlchemyBaseUserTableUUID
|
|
from app.config import URL_BD_TESTE, SECRET
|
|
from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession
|
|
from sqlalchemy.ext.asyncio import async_sessionmaker
|
|
from sqlalchemy import text
|
|
|
|
|
|
from app.rbac.auth import current_active_user
|
|
|
|
# Criação do engine de testes com o URL do banco de dados
|
|
engine = create_async_engine(URL_BD_TESTE)
|
|
selected_user = None
|
|
|
|
# Configurando o async_sessionmaker para usar AsyncSession
|
|
TestSessionLocal = async_sessionmaker(
|
|
bind=engine,
|
|
class_=AsyncSession,
|
|
autoflush=False,
|
|
autocommit=False,
|
|
)
|
|
|
|
|
|
# print("Configuração do sessionmaker concluída")
|
|
# print(URL_BD_TESTE)
|
|
|
|
|
|
def pytest_addoption(parser):
|
|
parser.addoption(
|
|
"--usuario", action="store", default="admin", help="Nome do usuário para executar os testes"
|
|
)
|
|
|
|
|
|
# Função para criar um usuário com permissão e papel
|
|
def create_user(email, papel_nome, permissoes_ids):
|
|
permissoes = [RbacPermissao(id=perm_id, nome=f"Permissao_{perm_id}") for perm_id in permissoes_ids]
|
|
papel = RbacPapel(
|
|
nome=papel_nome,
|
|
permissoes=permissoes
|
|
)
|
|
user = RbacUser(
|
|
email=email,
|
|
hashed_password="hashed-password",
|
|
fk_inquilino_uuid="pytest",
|
|
is_active=True,
|
|
is_superuser=False,
|
|
papeis=[papel]
|
|
)
|
|
|
|
return user
|
|
|
|
|
|
# Fixture para criar múltiplos usuários
|
|
@pytest.fixture(scope="session")
|
|
def create_test_users():
|
|
users = {
|
|
"admin": create_user(
|
|
email="admin@example.com",
|
|
papel_nome="Admin_Papel",
|
|
permissoes_ids=[1]
|
|
),
|
|
"comercial": create_user(
|
|
email="user1@example.com",
|
|
papel_nome="User1_Papel",
|
|
permissoes_ids=[2]
|
|
),
|
|
"estoque": create_user(
|
|
email="user2@example.com",
|
|
papel_nome="User2_Papel",
|
|
permissoes_ids=[4]
|
|
),
|
|
"financeiro": create_user(
|
|
email="user3@example.com",
|
|
papel_nome="User3_Papel",
|
|
permissoes_ids=[5]
|
|
),
|
|
"pessoa": create_user(
|
|
email="user4@example.com",
|
|
papel_nome="User4_Papel",
|
|
permissoes_ids=[4, 5, 33]
|
|
),
|
|
}
|
|
return users
|
|
|
|
|
|
# Fixture para selecionar um usuário
|
|
@pytest.fixture(scope="session")
|
|
def selecionar_usuario(create_test_users, request):
|
|
usuario_nome = request.config.getoption("--usuario", default="admin")
|
|
usuario_selecionado = create_test_users.get(usuario_nome, create_test_users["admin"])
|
|
return usuario_selecionado
|
|
|
|
|
|
def fake_current_user(selecionar_usuario):
|
|
return selecionar_usuario
|
|
|
|
|
|
async def create_test_database():
|
|
tenant_schema = "pytest"
|
|
|
|
# Dropar e recriar o schema "pytest"
|
|
async with engine.begin() as conn:
|
|
try:
|
|
# print("Dropping schema tenant (pytest)...")
|
|
await conn.execute(text(f"DROP SCHEMA IF EXISTS {tenant_schema} CASCADE"))
|
|
# print("Creating schema tenant (pytest)...")
|
|
await conn.execute(text(f"CREATE SCHEMA {tenant_schema}"))
|
|
except Exception as e:
|
|
print(f"Erro ao dropar ou recriar o schema '{tenant_schema}': {e}")
|
|
raise # Propaga o erro para interromper os testes
|
|
|
|
# Atualiza o schema das tabelas que não são do schema "shared"
|
|
for table in Base.metadata.tables.values():
|
|
if table.schema != "shared":
|
|
table.schema = tenant_schema
|
|
|
|
# Cria as tabelas apenas para o schema tenant
|
|
tenant_tables = [table for table in Base.metadata.sorted_tables if table.schema == tenant_schema]
|
|
async with engine.begin() as conn:
|
|
try:
|
|
# print("Criando tabelas no schema tenant (pytest)...")
|
|
await conn.run_sync(Base.metadata.create_all, tables=tenant_tables)
|
|
except Exception as e:
|
|
print(f"Erro ao criar as tabelas no schema '{tenant_schema}': {e}")
|
|
raise
|
|
|
|
|
|
@pytest.fixture(scope="session")
|
|
def anyio_backend():
|
|
return "asyncio"
|
|
|
|
|
|
@pytest.fixture(scope="session")
|
|
async def client(selecionar_usuario):
|
|
# print("Iniciando Cliente")
|
|
# Chama a função para criar o banco de dados de teste
|
|
await create_test_database()
|
|
|
|
app.dependency_overrides[current_active_user] = lambda: selecionar_usuario
|
|
|
|
strategy = JWTStrategy(secret=SECRET, lifetime_seconds=3600)
|
|
token = await strategy.write_token(selecionar_usuario)
|
|
# print(f"Token gerado: {token}")
|
|
|
|
async with AsyncClient(app=app, base_url="http://test") as client:
|
|
client.headers.update({"Authorization": f"Bearer {token}"})
|
|
yield client
|
|
|
|
|
|
# Função para modificar os itens de teste com base nos usuários permitidos
|
|
def pytest_collection_modifyitems(config, items):
|
|
usuario = config.getoption("--usuario")
|
|
|
|
def usuario_esta_permitido(usuarios_permitidos_):
|
|
# print(f"Verificando se o usuário '{usuario}' está na lista de permitidos: {usuarios_permitidos_}")
|
|
return usuario in usuarios_permitidos_
|
|
|
|
selected_items = []
|
|
for item in items:
|
|
usuarios_permitidos_marker = item.get_closest_marker("usuarios_permitidos")
|
|
|
|
if usuarios_permitidos_marker:
|
|
usuarios_permitidos = usuarios_permitidos_marker.args[0]
|
|
if not usuario_esta_permitido(usuarios_permitidos):
|
|
# print(f"Ignorando o teste '{item.name}' porque o usuário '{usuario}' não está permitido.")
|
|
continue # Ignorar o teste se o usuário não estiver permitido
|
|
|
|
selected_items.append(item)
|
|
|
|
# Atualiza a lista de testes que serão executados
|
|
items[:] = selected_items
|
|
|
|
|
|
# FUNÇÕES PARA ROTAS QUE REQUEREM AUTENTICAÇÃO
|
|
|
|
|
|
# MODULOS COM UUID PARA TESTES
|
|
@pytest.fixture(scope="session")
|
|
def datas_referencia():
|
|
data_atual = datetime.now().date()
|
|
return {
|
|
"data_atual": data_atual,
|
|
"data_anterior": data_atual - timedelta(days=1),
|
|
"data_posterior": data_atual + timedelta(days=1),
|
|
}
|
|
|
|
|
|
@pytest.fixture(scope="session")
|
|
def uuid_store_relacao_comercial():
|
|
return {
|
|
"uuid_1": "01915caf-2c4d-7270-a071-d928c87f8e20", # UUID inválido para testes
|
|
"uuid_2": "01915caf-2c4d-7270-a071-d928c87f8e30", # UUID inválido para testes
|
|
"uuid_3": None,
|
|
"uuid_4": None,
|
|
"uuid_5": None,
|
|
"uuid_6": None, # UUID para Relacionamento
|
|
"uuid_7": None, # UUID para Relacionamento
|
|
"uuid_8": None, # UUID para Relacionamento
|
|
"uuid_9": None,
|
|
"uuid_10": None,
|
|
"uuid_11": None,
|
|
}
|
|
|
|
|
|
@pytest.fixture(scope="session")
|
|
def uuid_store_tipo_endereco():
|
|
return {
|
|
"uuid_1": "01915caf-2c4d-7270-a071-d928c87f8e40", # UUID inválido para testes
|
|
"uuid_2": "01915caf-2c4d-7270-a071-d928c87f8e50", # UUID inválido para testes
|
|
"uuid_3": None,
|
|
"uuid_4": None,
|
|
"uuid_5": None,
|
|
"uuid_6": None, # UUID para Relacionamento
|
|
"uuid_7": None, # UUID para Relacionamento
|
|
"uuid_8": None, # UUID para Relacionamento
|
|
}
|
|
|
|
|
|
@pytest.fixture(scope="session")
|
|
def uuid_store_pessoa():
|
|
return {
|
|
"uuid_1": "01915caf-2c4d-7270-a071-d928c87f8e60", # UUID inválido para testes
|
|
"uuid_2": "01915caf-2c4d-7270-a071-d928c87f8e70", # UUID inválido para testes
|
|
"uuid_3": None,
|
|
"uuid_4": None,
|
|
"uuid_5": None,
|
|
"uuid_6": None,
|
|
"uuid_7": None,
|
|
"uuid_8": None,
|
|
}
|
|
|
|
|
|
@pytest.fixture(scope="session")
|
|
def uuid_store_endereco():
|
|
return {
|
|
"uuid_1": "01915caf-2c4d-7270-a071-d928c87f8e80", # UUID inválido para testes
|
|
"uuid_2": "01915caf-2c4d-7270-a071-d928c87f8e90", # UUID inválido para testes
|
|
"uuid_3": None,
|
|
"uuid_4": None,
|
|
"uuid_5": None,
|
|
"uuid_6": None,
|
|
"uuid_7": None,
|
|
"uuid_8": None,
|
|
}
|
|
|
|
|
|
@pytest.fixture(scope="session")
|
|
def uuid_store_setor():
|
|
return {
|
|
"uuid_1": "01915caf-2c4d-7270-a071-d928c87f8e21", # UUID inválido para testes
|
|
"uuid_2": "01915caf-2c4d-7270-a071-d928c87f8e32", # UUID inválido para testes
|
|
"uuid_3": None,
|
|
"uuid_4": None,
|
|
"uuid_5": None,
|
|
"uuid_6": None, # UUID para Relacionamento
|
|
"uuid_7": None, # UUID para Relacionamento
|
|
"uuid_8": None, # UUID para Relacionamento
|
|
"uuid_9": None,
|
|
"uuid_10": None,
|
|
"uuid_11": None,
|
|
}
|
|
|
|
|
|
@pytest.fixture(scope="session")
|
|
def uuid_store_tipo_equipamento():
|
|
return {
|
|
"uuid_1": "01915caf-2c4d-7270-a071-d928c87f8e22", # UUID inválido para testes
|
|
"uuid_2": "01915caf-2c4d-7270-a071-d928c87f8e31", # UUID inválido para testes
|
|
"uuid_3": None,
|
|
"uuid_4": None,
|
|
"uuid_5": None,
|
|
"uuid_6": None, # UUID para Relacionamento
|
|
"uuid_7": None, # UUID para Relacionamento
|
|
"uuid_8": None, # UUID para Relacionamento
|
|
"uuid_9": None,
|
|
"uuid_10": None,
|
|
"uuid_11": None,
|
|
}
|
|
|
|
|
|
@pytest.fixture(scope="session")
|
|
def uuid_store_equipamento():
|
|
return {
|
|
"uuid_1": "01915caf-2c4d-7270-a071-d928c87f8e23", # UUID inválido para testes
|
|
"uuid_2": "01915caf-2c4d-7270-a071-d928c87f8e32", # UUID inválido para testes
|
|
"uuid_3": None,
|
|
"uuid_4": None,
|
|
"uuid_5": None,
|
|
"uuid_6": None, # UUID para Relacionamento
|
|
"uuid_7": None, # UUID para Relacionamento
|
|
"uuid_8": None, # UUID para Relacionamento
|
|
"uuid_9": None,
|
|
"uuid_10": None,
|
|
"uuid_11": None,
|
|
}
|
|
|
|
|
|
@pytest.fixture(scope="session")
|
|
def uuid_store_itens_equipamento():
|
|
return {
|
|
"uuid_1": "01915caf-2c4d-7270-a071-d928c87f8e24", # UUID inválido para testes
|
|
"uuid_2": "01915caf-2c4d-7270-a071-d928c87f8e33", # UUID inválido para testes
|
|
"uuid_3": None,
|
|
"uuid_4": None,
|
|
"uuid_5": None,
|
|
"uuid_6": None, # UUID para Relacionamento
|
|
"uuid_7": None, # UUID para Relacionamento
|
|
"uuid_8": None, # UUID para Relacionamento
|
|
"uuid_9": None,
|
|
"uuid_10": None,
|
|
"uuid_11": None,
|
|
}
|
|
|
|
|
|
@pytest.fixture(scope="session")
|
|
def uuid_store_manutencao_equipamento():
|
|
return {
|
|
"uuid_1": "01915caf-2c4d-7270-a071-d928c87f8e25", # UUID inválido para testes
|
|
"uuid_2": "01915caf-2c4d-7270-a071-d928c87f8e34", # UUID inválido para testes
|
|
"uuid_3": None,
|
|
"uuid_4": None,
|
|
"uuid_5": None,
|
|
"uuid_6": None, # UUID para Relacionamento
|
|
"uuid_7": None, # UUID para Relacionamento
|
|
"uuid_8": None, # UUID para Relacionamento
|
|
"uuid_9": None,
|
|
"uuid_10": None,
|
|
"uuid_11": None,
|
|
}
|