melodix-api / tests /verify_fixes.py
GitHub Action
deploy from github actions
440bac0
Raw
History Blame Contribute Delete
7.56 kB
"""
Script de verificación de correcciones de seguridad y límites de la API.
Este script valida:
1. Permiso de CRUD en letras grupales: el administrador del grupo o miembros con perm_crud_letras pueden editar/borrar letras del grupo creadas por otros usuarios.
2. Restricción de montos negativos y cero en finanzas: la API rechaza montos <= 0 con error 422.
"""
import requests
import uuid
BASE_URL = "http://127.0.0.1:8000"
def test_lyrics_and_finances_fixes():
print("=" * 60)
print("INICIANDO PRUEBAS DE VERIFICACIÓN DE FIXES")
print("=" * 60)
# 1. Crear usuarios de prueba
suffix = str(uuid.uuid4())[:8]
user_a = f"admin_fix_{suffix}"
user_b = f"member_fix_{suffix}"
password = "password123"
print("\n[1] Registrando y logueando usuarios...")
for u in [user_a, user_b]:
reg_res = requests.post(f"{BASE_URL}/auth/register", json={
"username": u,
"email": f"{u}@example.com",
"password": password
})
assert reg_res.status_code in (200, 400), f"Error al registrar {u}: {reg_res.text}"
# Login User A
tok_a_res = requests.post(f"{BASE_URL}/auth/token", data={
"username": f"{user_a}@example.com",
"password": password,
"device_id": f"dev_a_{suffix}",
"device_name": "Device Admin"
})
assert tok_a_res.status_code == 200, f"Error login A: {tok_a_res.text}"
token_a = tok_a_res.json()["access_token"]
headers_a = {"Authorization": f"Bearer {token_a}"}
# Login User B
tok_b_res = requests.post(f"{BASE_URL}/auth/token", data={
"username": f"{user_b}@example.com",
"password": password,
"device_id": f"dev_b_{suffix}",
"device_name": "Device Member"
})
assert tok_b_res.status_code == 200, f"Error login B: {tok_b_res.text}"
token_b = tok_b_res.json()["access_token"]
headers_b = {"Authorization": f"Bearer {token_b}"}
print(" [OK] Usuarios autenticados correctamente.")
# 2. User A crea un grupo
print("\n[2] User A (Admin) creando grupo...")
group_res = requests.post(f"{BASE_URL}/lyrics/groups", json={"name": f"Grupo Fix {suffix}"}, headers=headers_a)
assert group_res.status_code == 200, f"Error al crear grupo: {group_res.text}"
group_id = group_res.json()["id"]
print(f" [OK] Grupo creado con ID {group_id}")
# 3. Invitar a User B al grupo
print("\n[3] Generando invitación y User B uniéndose...")
invite_res = requests.post(f"{BASE_URL}/lyrics/groups/{group_id}/invite", headers=headers_a)
assert invite_res.status_code == 200, f"Error al crear invitación: {invite_res.text}"
code = invite_res.json()["code"]
join_res = requests.post(f"{BASE_URL}/lyrics/join/{code}", headers=headers_b)
assert join_res.status_code == 200, f"Error al unirse: {join_res.text}"
print(" [OK] User B se unió exitosamente al grupo.")
# 4. User B crea una letra en el grupo
print("\n[4] User B creando letra en el grupo...")
lyric_res = requests.post(f"{BASE_URL}/lyrics", json={
"title": "Letra de Prueba Fix",
"artist": "Artista Fix",
"content": "Contenido de la letra",
"group_id": group_id
}, headers=headers_b)
assert lyric_res.status_code == 200, f"Error al crear letra: {lyric_res.text}"
lyric_id = lyric_res.json()["id"]
print(f" [OK] Letra creada por User B con ID {lyric_id}")
# 5. User A (Admin del grupo) intenta editar la letra creada por User B
print("\n[5] User A (Admin) intenta editar la letra de User B (Prueba de Fix Bug 3)...")
edit_res = requests.put(f"{BASE_URL}/lyrics/{lyric_id}", json={
"title": "Letra de Prueba Modificada por Admin",
"artist": "Artista Fix Modificado",
"content": "Nuevo contenido editado por el administrador",
"group_id": group_id
}, headers=headers_a)
print(f" Código de estado de edición: {edit_res.status_code}")
assert edit_res.status_code == 200, f"ERROR: El administrador del grupo no pudo editar la letra (Fix Bug 3 no funciona). Respuesta: {edit_res.text}"
print(" [OK] ¡ÉXITO! El administrador del grupo pudo editar la letra sin ser el creador original.")
# 6. User A (Admin) intenta eliminar la letra creada por User B
print("\n[6] User A (Admin) intenta eliminar la letra de User B...")
del_res = requests.delete(f"{BASE_URL}/lyrics/{lyric_id}", headers=headers_a)
print(f" Código de estado de eliminación: {del_res.status_code}")
assert del_res.status_code == 200, f"ERROR: El administrador no pudo borrar la letra. Respuesta: {del_res.text}"
print(" [OK] ¡ÉXITO! El administrador del grupo pudo eliminar la letra sin ser el creador original.")
# 7. Registrar Iglesia para probar Finanzas
print("\n[7] Registrando iglesia para pruebas de finanzas...")
church_res = requests.post(f"{BASE_URL}/iglesia/crear", json={
"nombre": f"Iglesia Fix {suffix}",
"pastor": "Pastor Fix"
}, headers=headers_a)
assert church_res.status_code == 200, f"Error creando iglesia: {church_res.text}"
print(" [OK] Iglesia creada correctamente.")
# 8. Intentar crear finanza con monto negativo (esperado: 422 Unprocessable Entity)
print("\n[8] Probando montos negativos en finanzas (Prueba de Fix Bug 4)...")
fin_neg_res = requests.post(f"{BASE_URL}/iglesia/finanzas", json={
"tipo": "entrada",
"monto": -150.0,
"concepto": "Intento de monto negativo",
"responsable": "Admin",
"reference_uuid": f"ref_neg_{suffix}"
}, headers=headers_a)
print(f" Código de estado (negativo): {fin_neg_res.status_code}")
assert fin_neg_res.status_code == 422, f"ERROR: La API aceptó un monto negativo (-150.0). Código: {fin_neg_res.status_code}"
print(" [OK] ¡ÉXITO! La API rechazó correctamente un monto negativo con código 422.")
# 9. Intentar crear finanza con monto cero (esperado: 422 Unprocessable Entity)
print("\n[9] Probando monto cero en finanzas...")
fin_zero_res = requests.post(f"{BASE_URL}/iglesia/finanzas", json={
"tipo": "entrada",
"monto": 0.0,
"concepto": "Intento de monto cero",
"responsable": "Admin",
"reference_uuid": f"ref_zero_{suffix}"
}, headers=headers_a)
print(f" Código de estado (cero): {fin_zero_res.status_code}")
assert fin_zero_res.status_code == 422, f"ERROR: La API aceptó un monto de cero (0.0). Código: {fin_zero_res.status_code}"
print(" [OK] ¡ÉXITO! La API rechazó correctamente un monto de cero con código 422.")
# 10. Intentar crear finanza con monto positivo (esperado: 200 OK)
print("\n[10] Probando monto positivo en finanzas...")
fin_pos_res = requests.post(f"{BASE_URL}/iglesia/finanzas", json={
"tipo": "entrada",
"monto": 75.50,
"concepto": "Ofrenda válida",
"responsable": "Admin",
"reference_uuid": f"ref_pos_{suffix}"
}, headers=headers_a)
print(f" Código de estado (positivo): {fin_pos_res.status_code}")
assert fin_pos_res.status_code == 200, f"ERROR: La API rechazó un monto positivo válido (75.50). Código: {fin_pos_res.status_code}. Respuesta: {fin_pos_res.text}"
print(" [OK] ¡ÉXITO! La API registró correctamente el movimiento positivo.")
print("\n" + "=" * 60)
print(" ¡TODAS LAS PRUEBAS DE FIXES DE SEGURIDAD PASARON CON EXITO!")
print("=" * 60 + "\n")
if __name__ == "__main__":
test_lyrics_and_finances_fixes()