178 lines
7.3 KiB
Python
178 lines
7.3 KiB
Python
import os
|
|
import sys
|
|
from datetime import datetime, timezone
|
|
from pathlib import Path
|
|
from typing import Dict
|
|
|
|
import pytest
|
|
from fastapi.testclient import TestClient
|
|
|
|
PROJECT_ROOT = Path(__file__).resolve().parents[1]
|
|
if str(PROJECT_ROOT) not in sys.path:
|
|
sys.path.insert(0, str(PROJECT_ROOT))
|
|
|
|
os.environ.setdefault("APPWRITE_ENDPOINT", "http://localhost/v1")
|
|
os.environ.setdefault("APPWRITE_PROJECT_ID", "test-project")
|
|
os.environ.setdefault("APPWRITE_API_KEY", "test-key")
|
|
os.environ.setdefault("APPWRITE_DATABASE_ID", "test-db")
|
|
os.environ.setdefault("APPWRITE_COLLECTION_CARRINHOS_ID", "test-carts")
|
|
os.environ.setdefault("APPWRITE_COLLECTION_PEDIDOS_ID", "test-orders")
|
|
os.environ.setdefault("APPWRITE_COLLECTION_PRODUTOS_CATALOGO_ID", "test-produtos")
|
|
os.environ.setdefault("APPWRITE_COLLECTION_LABORATORIOS_ID", "test-labs")
|
|
os.environ.setdefault("APPWRITE_COLLECTION_CATEGORIAS_ID", "test-categorias")
|
|
os.environ.setdefault("APPWRITE_COLLECTION_SUBCATEGORIAS_ID", "test-subcat")
|
|
os.environ.setdefault("APPWRITE_COLLECTION_PAGAMENTOS_ID", "test-payments")
|
|
os.environ.setdefault("APPWRITE_COLLECTION_PRODUTOS_ESTOQUE_ID", "test-produtos-estoque")
|
|
os.environ.setdefault("APPWRITE_COLLECTION_PRODUTOS_VENDA_ID", "test-produtos-venda")
|
|
os.environ.setdefault("APPWRITE_COLLECTION_USUARIOS_DATA_ID", "test-usuarios-data")
|
|
os.environ.setdefault("APPWRITE_COLLECTION_USUARIOS_PERFIL_ID", "test-usuarios-perfil")
|
|
os.environ.setdefault("APPWRITE_COLLECTION_USUARIO_EMPRESA_PERFIS_ID", "test-usuario-empresa-perfis")
|
|
os.environ.setdefault("APPWRITE_COLLECTION_FATURAS_ID", "test-faturas")
|
|
os.environ.setdefault("APPWRITE_COLLECTION_USUARIOS_ID", "test-users")
|
|
os.environ.setdefault("APPWRITE_COLLECTION_EMPRESAS_ID", "test-companies")
|
|
os.environ.setdefault("APPWRITE_COLLECTION_EMPRESAS_DADOS_ID", "test-companies-data")
|
|
os.environ.setdefault("APPWRITE_COLLECTION_EMPRESAS_SOCIOS_ID", "test-empresas-socios")
|
|
os.environ.setdefault("APPWRITE_COLLECTION_ENDERECOS_ID", "test-addresses")
|
|
os.environ.setdefault("APPWRITE_COLLECTION_ENTREGAS_ID", "test-entregas")
|
|
os.environ.setdefault("JWT_SECRET", "test-secret")
|
|
os.environ.setdefault("JWT_ALGORITHM", "HS256")
|
|
os.environ.setdefault("SECURITY_API_KEY", "")
|
|
|
|
from src.app.main import app
|
|
from src.core.deps import get_categorias_service, require_api_key, require_user
|
|
from src.modules.categorias.schemas import CategoriaCreate, CategoriaOut, CategoriaUpdate
|
|
from src.modules.categorias.service import _slugify
|
|
|
|
|
|
class InMemoryCategoriasService:
|
|
def __init__(self) -> None:
|
|
self._items: Dict[str, Dict[str, object]] = {}
|
|
self._counter = 0
|
|
|
|
async def list(
|
|
self,
|
|
page: int,
|
|
limit: int | None,
|
|
q: str | None,
|
|
sort: str | None,
|
|
order: str | None,
|
|
) -> Dict[str, object]:
|
|
items = list(self._items.values())
|
|
total = len(items)
|
|
return {
|
|
"items": [CategoriaOut(**item).model_dump() for item in items],
|
|
"total": total,
|
|
}
|
|
|
|
async def get(self, categoria_id: str) -> CategoriaOut:
|
|
if categoria_id not in self._items:
|
|
raise AssertionError("Categoria não encontrada nos testes")
|
|
return CategoriaOut(**self._items[categoria_id])
|
|
|
|
async def create(self, payload: CategoriaCreate) -> CategoriaOut:
|
|
data = payload.model_dump(exclude_unset=True)
|
|
nome = data.get("nome")
|
|
slug = data.get("slug") or (_slugify(nome) if nome else None)
|
|
if not slug:
|
|
raise AssertionError("Falha ao gerar slug")
|
|
for item in self._items.values():
|
|
if item["slug"] == slug:
|
|
from fastapi import HTTPException, status
|
|
|
|
raise HTTPException(status_code=status.HTTP_409_CONFLICT, detail="Categoria já existe")
|
|
self._counter += 1
|
|
identifier = f"cat_{self._counter}"
|
|
timestamp = datetime.now(timezone.utc).isoformat().replace("+00:00", "Z")
|
|
record = {
|
|
"id": identifier,
|
|
"nome": nome,
|
|
"slug": slug,
|
|
"subcategorias": None,
|
|
"produtos_catalogo": None,
|
|
"createdAt": timestamp,
|
|
"updatedAt": timestamp,
|
|
}
|
|
self._items[identifier] = record
|
|
return CategoriaOut(**record)
|
|
|
|
async def update(self, categoria_id: str, payload: CategoriaUpdate) -> CategoriaOut:
|
|
if categoria_id not in self._items:
|
|
raise AssertionError("Categoria não encontrada nos testes")
|
|
stored = self._items[categoria_id].copy()
|
|
data = payload.model_dump(exclude_unset=True)
|
|
if "nome" in data and data["nome"] is not None:
|
|
stored["nome"] = data["nome"]
|
|
if "slug" in data and data["slug"] is not None:
|
|
stored["slug"] = data["slug"]
|
|
stored["updatedAt"] = datetime.now(timezone.utc).isoformat().replace("+00:00", "Z")
|
|
self._items[categoria_id] = stored
|
|
return CategoriaOut(**stored)
|
|
|
|
async def delete(self, categoria_id: str) -> None:
|
|
self._items.pop(categoria_id, None)
|
|
|
|
|
|
@pytest.fixture()
|
|
def test_client() -> TestClient:
|
|
service = InMemoryCategoriasService()
|
|
|
|
def override_service() -> InMemoryCategoriasService:
|
|
return service
|
|
|
|
app.dependency_overrides[get_categorias_service] = override_service
|
|
app.dependency_overrides[require_api_key] = lambda: None
|
|
app.dependency_overrides[require_user] = lambda: {"id": "user_1"}
|
|
|
|
client = TestClient(app)
|
|
yield client
|
|
|
|
app.dependency_overrides.clear()
|
|
client.close()
|
|
|
|
|
|
def test_create_categoria_generates_slug_when_empty(test_client: TestClient) -> None:
|
|
response = test_client.post("/api/v1/categorias", json={"nome": "Summer Wear", "slug": ""})
|
|
assert response.status_code == 201
|
|
body = response.json()
|
|
assert body["slug"] == _slugify("Summer Wear")
|
|
|
|
|
|
def test_list_categorias_returns_created_items(test_client: TestClient) -> None:
|
|
test_client.post("/api/v1/categorias", json={"nome": "Sapatos", "slug": "sapatos"})
|
|
test_client.post("/api/v1/categorias", json={"nome": "Chapeus", "slug": "chapeus"})
|
|
|
|
response = test_client.get("/api/v1/categorias")
|
|
assert response.status_code == 200
|
|
data = response.json()
|
|
assert data["total"] == 2
|
|
assert len(data["items"]) == 2
|
|
|
|
|
|
def test_get_categoria_returns_item(test_client: TestClient) -> None:
|
|
creation = test_client.post("/api/v1/categorias", json={"nome": "Bolsas", "slug": "bolsas"})
|
|
identifier = creation.json()["id"]
|
|
|
|
response = test_client.get(f"/api/v1/categorias/{identifier}")
|
|
assert response.status_code == 200
|
|
assert response.json()["id"] == identifier
|
|
|
|
|
|
def test_delete_categoria_removes_item(test_client: TestClient) -> None:
|
|
creation = test_client.post("/api/v1/categorias", json={"nome": "Cintos", "slug": "cintos"})
|
|
identifier = creation.json()["id"]
|
|
|
|
response = test_client.delete(f"/api/v1/categorias/{identifier}")
|
|
assert response.status_code == 204
|
|
|
|
list_response = test_client.get("/api/v1/categorias")
|
|
assert list_response.json()["total"] == 0
|
|
|
|
|
|
def test_create_categoria_conflict(test_client: TestClient) -> None:
|
|
payload = {"nome": "Cachecois", "slug": "cachecois"}
|
|
first = test_client.post("/api/v1/categorias", json=payload)
|
|
assert first.status_code == 201
|
|
|
|
second = test_client.post("/api/v1/categorias", json=payload)
|
|
assert second.status_code == 409
|
|
assert second.json()["detail"] == "Categoria já existe"
|